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.
30 DRXJ specific implementation of DRX driver
31 authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
34 /*-----------------------------------------------------------------------------
36 ----------------------------------------------------------------------------*/
38 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
42 #include "drx_driver.h"
44 /*============================================================================*/
45 /*=== DEFINES ================================================================*/
46 /*============================================================================*/
49 * \brief Maximum u32 value.
52 #define MAX_U32 ((u32) (0xFFFFFFFFL))
55 /* Customer configurable hardware settings, etc */
56 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
57 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
60 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
61 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
64 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
65 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
68 #ifndef OOB_CRX_DRIVE_STRENGTH
69 #define OOB_CRX_DRIVE_STRENGTH 0x02
72 #ifndef OOB_DRX_DRIVE_STRENGTH
73 #define OOB_DRX_DRIVE_STRENGTH 0x02
75 /**** START DJCOMBO patches to DRXJ registermap constants *********************/
76 /**** registermap 200706071303 from drxj **************************************/
77 #define ATV_TOP_CR_AMP_TH_FM 0x0
78 #define ATV_TOP_CR_AMP_TH_L 0xA
79 #define ATV_TOP_CR_AMP_TH_LP 0xA
80 #define ATV_TOP_CR_AMP_TH_BG 0x8
81 #define ATV_TOP_CR_AMP_TH_DK 0x8
82 #define ATV_TOP_CR_AMP_TH_I 0x8
83 #define ATV_TOP_CR_CONT_CR_D_MN 0x18
84 #define ATV_TOP_CR_CONT_CR_D_FM 0x0
85 #define ATV_TOP_CR_CONT_CR_D_L 0x20
86 #define ATV_TOP_CR_CONT_CR_D_LP 0x20
87 #define ATV_TOP_CR_CONT_CR_D_BG 0x18
88 #define ATV_TOP_CR_CONT_CR_D_DK 0x18
89 #define ATV_TOP_CR_CONT_CR_D_I 0x18
90 #define ATV_TOP_CR_CONT_CR_I_MN 0x80
91 #define ATV_TOP_CR_CONT_CR_I_FM 0x0
92 #define ATV_TOP_CR_CONT_CR_I_L 0x80
93 #define ATV_TOP_CR_CONT_CR_I_LP 0x80
94 #define ATV_TOP_CR_CONT_CR_I_BG 0x80
95 #define ATV_TOP_CR_CONT_CR_I_DK 0x80
96 #define ATV_TOP_CR_CONT_CR_I_I 0x80
97 #define ATV_TOP_CR_CONT_CR_P_MN 0x4
98 #define ATV_TOP_CR_CONT_CR_P_FM 0x0
99 #define ATV_TOP_CR_CONT_CR_P_L 0x4
100 #define ATV_TOP_CR_CONT_CR_P_LP 0x4
101 #define ATV_TOP_CR_CONT_CR_P_BG 0x4
102 #define ATV_TOP_CR_CONT_CR_P_DK 0x4
103 #define ATV_TOP_CR_CONT_CR_P_I 0x4
104 #define ATV_TOP_CR_OVM_TH_MN 0xA0
105 #define ATV_TOP_CR_OVM_TH_FM 0x0
106 #define ATV_TOP_CR_OVM_TH_L 0xA0
107 #define ATV_TOP_CR_OVM_TH_LP 0xA0
108 #define ATV_TOP_CR_OVM_TH_BG 0xA0
109 #define ATV_TOP_CR_OVM_TH_DK 0xA0
110 #define ATV_TOP_CR_OVM_TH_I 0xA0
111 #define ATV_TOP_EQU0_EQU_C0_FM 0x0
112 #define ATV_TOP_EQU0_EQU_C0_L 0x3
113 #define ATV_TOP_EQU0_EQU_C0_LP 0x3
114 #define ATV_TOP_EQU0_EQU_C0_BG 0x7
115 #define ATV_TOP_EQU0_EQU_C0_DK 0x0
116 #define ATV_TOP_EQU0_EQU_C0_I 0x3
117 #define ATV_TOP_EQU1_EQU_C1_FM 0x0
118 #define ATV_TOP_EQU1_EQU_C1_L 0x1F6
119 #define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
120 #define ATV_TOP_EQU1_EQU_C1_BG 0x197
121 #define ATV_TOP_EQU1_EQU_C1_DK 0x198
122 #define ATV_TOP_EQU1_EQU_C1_I 0x1F6
123 #define ATV_TOP_EQU2_EQU_C2_FM 0x0
124 #define ATV_TOP_EQU2_EQU_C2_L 0x28
125 #define ATV_TOP_EQU2_EQU_C2_LP 0x28
126 #define ATV_TOP_EQU2_EQU_C2_BG 0xC5
127 #define ATV_TOP_EQU2_EQU_C2_DK 0xB0
128 #define ATV_TOP_EQU2_EQU_C2_I 0x28
129 #define ATV_TOP_EQU3_EQU_C3_FM 0x0
130 #define ATV_TOP_EQU3_EQU_C3_L 0x192
131 #define ATV_TOP_EQU3_EQU_C3_LP 0x192
132 #define ATV_TOP_EQU3_EQU_C3_BG 0x12E
133 #define ATV_TOP_EQU3_EQU_C3_DK 0x18E
134 #define ATV_TOP_EQU3_EQU_C3_I 0x192
135 #define ATV_TOP_STD_MODE_MN 0x0
136 #define ATV_TOP_STD_MODE_FM 0x1
137 #define ATV_TOP_STD_MODE_L 0x0
138 #define ATV_TOP_STD_MODE_LP 0x0
139 #define ATV_TOP_STD_MODE_BG 0x0
140 #define ATV_TOP_STD_MODE_DK 0x0
141 #define ATV_TOP_STD_MODE_I 0x0
142 #define ATV_TOP_STD_VID_POL_MN 0x0
143 #define ATV_TOP_STD_VID_POL_FM 0x0
144 #define ATV_TOP_STD_VID_POL_L 0x2
145 #define ATV_TOP_STD_VID_POL_LP 0x2
146 #define ATV_TOP_STD_VID_POL_BG 0x0
147 #define ATV_TOP_STD_VID_POL_DK 0x0
148 #define ATV_TOP_STD_VID_POL_I 0x0
149 #define ATV_TOP_VID_AMP_MN 0x380
150 #define ATV_TOP_VID_AMP_FM 0x0
151 #define ATV_TOP_VID_AMP_L 0xF50
152 #define ATV_TOP_VID_AMP_LP 0xF50
153 #define ATV_TOP_VID_AMP_BG 0x380
154 #define ATV_TOP_VID_AMP_DK 0x394
155 #define ATV_TOP_VID_AMP_I 0x3D8
156 #define IQM_CF_OUT_ENA_OFDM__M 0x4
157 #define IQM_FS_ADJ_SEL_B_QAM 0x1
158 #define IQM_FS_ADJ_SEL_B_OFF 0x0
159 #define IQM_FS_ADJ_SEL_B_VSB 0x2
160 #define IQM_RC_ADJ_SEL_B_OFF 0x0
161 #define IQM_RC_ADJ_SEL_B_QAM 0x1
162 #define IQM_RC_ADJ_SEL_B_VSB 0x2
163 /**** END DJCOMBO patches to DRXJ registermap *********************************/
165 #include "drx_driver_version.h"
167 /* #define DRX_DEBUG */
172 /*-----------------------------------------------------------------------------
174 ----------------------------------------------------------------------------*/
176 /*-----------------------------------------------------------------------------
178 ----------------------------------------------------------------------------*/
179 #ifndef DRXJ_WAKE_UP_KEY
180 #define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
184 * \def DRXJ_DEF_I2C_ADDR
185 * \brief Default I2C addres of a demodulator instance.
187 #define DRXJ_DEF_I2C_ADDR (0x52)
190 * \def DRXJ_DEF_DEMOD_DEV_ID
191 * \brief Default device identifier of a demodultor instance.
193 #define DRXJ_DEF_DEMOD_DEV_ID (1)
196 * \def DRXJ_SCAN_TIMEOUT
197 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
199 #define DRXJ_SCAN_TIMEOUT 1000
203 * \brief Name of structure containing all data access protocol functions.
205 #define DRXJ_DAP drx_dap_drxj_funct_g
209 * \brief HI timing delay for I2C timing (in nano seconds)
211 * Used to compute HI_CFG_DIV
213 #define HI_I2C_DELAY 42
216 * \def HI_I2C_BRIDGE_DELAY
217 * \brief HI timing delay for I2C timing (in nano seconds)
219 * Used to compute HI_CFG_BDL
221 #define HI_I2C_BRIDGE_DELAY 750
224 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
226 #define VSB_TOP_MEASUREMENT_PERIOD 64
227 #define SYMBOLS_PER_SEGMENT 832
230 * \brief bit rate and segment rate constants used for SER and BER.
232 /* values taken from the QAM microcode */
233 #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
234 #define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
235 #define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
236 #define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
237 #define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
238 #define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
239 #define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
240 #define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
242 * \brief Min supported symbolrates.
244 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
245 #define DRXJ_QAM_SYMBOLRATE_MIN (520000)
249 * \brief Max supported symbolrates.
251 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
252 #define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
256 * \def DRXJ_QAM_MAX_WAITTIME
257 * \brief Maximal wait time for QAM auto constellation in ms
259 #ifndef DRXJ_QAM_MAX_WAITTIME
260 #define DRXJ_QAM_MAX_WAITTIME 900
263 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
264 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
267 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
268 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
272 * \def SCU status and results
275 #define DRX_SCU_READY 0
276 #define DRXJ_MAX_WAITTIME 100 /* ms */
277 #define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
278 #define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
281 * \def DRX_AUD_MAX_DEVIATION
282 * \brief Needed for calculation of prescale feature in AUD
284 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
285 #define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
289 * \brief Needed for calculation of NICAM prescale feature in AUD
291 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
292 #define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
296 * \brief Needed for calculation of NICAM prescale feature in AUD
298 #ifndef DRXJ_AUD_MAX_WAITTIME
299 #define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
302 /* ATV config changed flags */
303 #define DRXJ_ATV_CHANGED_COEF (0x00000001UL)
304 #define DRXJ_ATV_CHANGED_PEAK_FLT (0x00000008UL)
305 #define DRXJ_ATV_CHANGED_NOISE_FLT (0x00000010UL)
306 #define DRXJ_ATV_CHANGED_OUTPUT (0x00000020UL)
307 #define DRXJ_ATV_CHANGED_SIF_ATT (0x00000040UL)
310 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
311 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
314 * MICROCODE RELATED DEFINES
317 /* Magic word for checking correct Endianess of microcode data */
318 #define DRX_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L'))
320 /* CRC flag in ucode header, flags field. */
321 #define DRX_UCODE_CRC_FLAG (0x0001)
324 * Maximum size of buffer used to verify the microcode.
325 * Must be an even number
327 #define DRX_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
329 #if DRX_UCODE_MAX_BUF_SIZE & 1
330 #error DRX_UCODE_MAX_BUF_SIZE must be an even number
337 #define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
338 (mode == DRX_POWER_MODE_10) || \
339 (mode == DRX_POWER_MODE_11) || \
340 (mode == DRX_POWER_MODE_12) || \
341 (mode == DRX_POWER_MODE_13) || \
342 (mode == DRX_POWER_MODE_14) || \
343 (mode == DRX_POWER_MODE_15) || \
344 (mode == DRX_POWER_MODE_16) || \
345 (mode == DRX_POWER_DOWN))
347 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
348 /*============================================================================*/
349 /*=== MICROCODE RELATED DEFINES ==============================================*/
350 /*============================================================================*/
353 * \def DRXJ_UCODE_MAGIC_WORD
354 * \brief Magic word for checking correct Endianess of microcode data.
358 #ifndef DRXJ_UCODE_MAGIC_WORD
359 #define DRXJ_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L'))
363 * \def DRXJ_UCODE_CRC_FLAG
364 * \brief CRC flag in ucode header, flags field.
368 #ifndef DRXJ_UCODE_CRC_FLAG
369 #define DRXJ_UCODE_CRC_FLAG (0x0001)
373 * \def DRXJ_UCODE_COMPRESSION_FLAG
374 * \brief Compression flag in ucode header, flags field.
378 #ifndef DRXJ_UCODE_COMPRESSION_FLAG
379 #define DRXJ_UCODE_COMPRESSION_FLAG (0x0002)
383 * \def DRXJ_UCODE_MAX_BUF_SIZE
384 * \brief Maximum size of buffer used to verify the microcode.Must be an even number.
388 #ifndef DRXJ_UCODE_MAX_BUF_SIZE
389 #define DRXJ_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
391 #if DRXJ_UCODE_MAX_BUF_SIZE & 1
392 #error DRXJ_UCODE_MAX_BUF_SIZE must be an even number
395 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
397 /* Pin safe mode macro */
398 #define DRXJ_PIN_SAFE_MODE 0x0000
399 /*============================================================================*/
400 /*=== GLOBAL VARIABLEs =======================================================*/
401 /*============================================================================*/
406 * \brief Temporary register definitions.
407 * (register definitions that are not yet available in register master)
410 /******************************************************************************/
411 /* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
412 /* RAM adresses directly. This must be READ ONLY to avoid problems. */
413 /* Writing to the interface adresses is more than only writing the RAM */
415 /******************************************************************************/
417 * \brief RAM location of MODUS registers
419 #define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
420 #define AUD_DEM_RAM_MODUS_HI__M 0xF000
422 #define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
423 #define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
426 * \brief RAM location of I2S config registers
428 #define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
429 #define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
432 * \brief RAM location of DCO config registers
434 #define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
435 #define AUD_DEM_RAM_DCO_B_LO__A 0x1020462
436 #define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
437 #define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
440 * \brief RAM location of Threshold registers
442 #define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
443 #define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
444 #define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
447 * \brief RAM location of Carrier Threshold registers
449 #define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
450 #define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
453 * \brief FM Matrix register fix
455 #ifdef AUD_DEM_WR_FM_MATRIX__A
456 #undef AUD_DEM_WR_FM_MATRIX__A
458 #define AUD_DEM_WR_FM_MATRIX__A 0x105006F
460 /*============================================================================*/
462 * \brief Defines required for audio
464 #define AUD_VOLUME_ZERO_DB 115
465 #define AUD_VOLUME_DB_MIN -60
466 #define AUD_VOLUME_DB_MAX 12
467 #define AUD_CARRIER_STRENGTH_QP_0DB 0x4000
468 #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 421
469 #define AUD_MAX_AVC_REF_LEVEL 15
470 #define AUD_I2S_FREQUENCY_MAX 48000UL
471 #define AUD_I2S_FREQUENCY_MIN 12000UL
472 #define AUD_RDS_ARRAY_SIZE 18
475 * \brief Needed for calculation of prescale feature in AUD
477 #ifndef DRX_AUD_MAX_FM_DEVIATION
478 #define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
482 * \brief Needed for calculation of NICAM prescale feature in AUD
484 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
485 #define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
488 /*============================================================================*/
489 /* Values for I2S Master/Slave pin configurations */
490 #define SIO_PDR_I2S_CL_CFG_MODE__MASTER 0x0004
491 #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER 0x0008
492 #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE 0x0004
493 #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE 0x0000
495 #define SIO_PDR_I2S_DA_CFG_MODE__MASTER 0x0003
496 #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER 0x0008
497 #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE 0x0003
498 #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE 0x0008
500 #define SIO_PDR_I2S_WS_CFG_MODE__MASTER 0x0004
501 #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER 0x0008
502 #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE 0x0004
503 #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE 0x0000
505 /*============================================================================*/
506 /*=== REGISTER ACCESS MACROS =================================================*/
507 /*============================================================================*/
510 * This macro is used to create byte arrays for block writes.
511 * Block writes speed up I2C traffic between host and demod.
512 * The macro takes care of the required byte order in a 16 bits word.
513 * x -> lowbyte(x), highbyte(x)
515 #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
516 ((u8)((((u16)x)>>8)&0xFF))
518 * This macro is used to convert byte array to 16 bit register value for block read.
519 * Block read speed up I2C traffic between host and demod.
520 * The macro takes care of the required byte order in a 16 bits word.
522 #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
524 /*============================================================================*/
525 /*=== MISC DEFINES ===========================================================*/
526 /*============================================================================*/
528 /*============================================================================*/
529 /*=== HI COMMAND RELATED DEFINES =============================================*/
530 /*============================================================================*/
533 * \brief General maximum number of retries for ucode command interfaces
535 #define DRXJ_MAX_RETRIES (100)
537 /*============================================================================*/
538 /*=== STANDARD RELATED MACROS ================================================*/
539 /*============================================================================*/
541 #define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
542 (std == DRX_STANDARD_PAL_SECAM_DK) || \
543 (std == DRX_STANDARD_PAL_SECAM_I) || \
544 (std == DRX_STANDARD_PAL_SECAM_L) || \
545 (std == DRX_STANDARD_PAL_SECAM_LP) || \
546 (std == DRX_STANDARD_NTSC) || \
547 (std == DRX_STANDARD_FM))
549 #define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
550 (std == DRX_STANDARD_ITU_B) || \
551 (std == DRX_STANDARD_ITU_C) || \
552 (std == DRX_STANDARD_ITU_D))
554 /*-----------------------------------------------------------------------------
556 ----------------------------------------------------------------------------*/
558 * DRXJ DAP structures
561 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
564 u8 *data, u32 flags);
566 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
569 u8 wdata, u8 *rdata);
571 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
574 u16 wdata, u16 *rdata);
576 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
579 u32 wdata, u32 *rdata);
581 static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
583 u8 *data, u32 flags);
585 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
587 u16 *data, u32 flags);
589 static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
591 u32 *data, u32 flags);
593 static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
596 u8 *data, u32 flags);
598 static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
602 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
604 u16 data, u32 flags);
606 static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
608 u32 data, u32 flags);
610 /* The version structure of this protocol implementation */
611 char drx_dap_drxj_module_name[] = "DRXJ Data Access Protocol";
612 char drx_dap_drxj_version_text[] = "0.0.0";
614 struct drx_version drx_dap_drxj_version = {
615 DRX_MODULE_DAP, /**< type identifier of the module */
616 drx_dap_drxj_module_name, /**< name or description of module */
618 0, /**< major version number */
619 0, /**< minor version number */
620 0, /**< patch version number */
621 drx_dap_drxj_version_text /**< version as text string */
624 /* The structure containing the protocol interface */
625 struct drx_access_func drx_dap_drxj_funct_g = {
626 &drx_dap_drxj_version,
627 drxj_dap_write_block, /* Supported */
628 drxj_dap_read_block, /* Supported */
629 drxj_dap_write_reg8, /* Not supported */
630 drxj_dap_read_reg8, /* Not supported */
631 drxj_dap_read_modify_write_reg8, /* Not supported */
632 drxj_dap_write_reg16, /* Supported */
633 drxj_dap_read_reg16, /* Supported */
634 drxj_dap_read_modify_write_reg16, /* Supported */
635 drxj_dap_write_reg32, /* Supported */
636 drxj_dap_read_reg32, /* Supported */
637 drxj_dap_read_modify_write_reg32, /* Not supported */
642 * /brief The driver functions of the drxj
644 struct drx_demod_func drxj_functions_g = {
651 struct drxj_data drxj_data_g = {
652 false, /* has_lna : true if LNA (aka PGA) present */
653 false, /* has_oob : true if OOB supported */
654 false, /* has_ntsc: true if NTSC supported */
655 false, /* has_btsc: true if BTSC supported */
656 false, /* has_smatx: true if SMA_TX pin is available */
657 false, /* has_smarx: true if SMA_RX pin is available */
658 false, /* has_gpio : true if GPIO pin is available */
659 false, /* has_irqn : true if IRQN pin is available */
660 0, /* mfx A1/A2/A... */
663 false, /* tuner mirrors RF signal */
664 /* standard/channel settings */
665 DRX_STANDARD_UNKNOWN, /* current standard */
666 DRX_CONSTELLATION_AUTO, /* constellation */
667 0, /* frequency in KHz */
668 DRX_BANDWIDTH_UNKNOWN, /* curr_bandwidth */
669 DRX_MIRROR_NO, /* mirror */
671 /* signal quality information: */
672 /* default values taken from the QAM Programming guide */
673 /* fec_bits_desired should not be less than 4000000 */
674 4000000, /* fec_bits_desired */
676 4, /* qam_vd_prescale */
677 0xFFFF, /* qamVDPeriod */
678 204 * 8, /* fec_rs_plen annex A */
679 1, /* fec_rs_prescale */
680 FEC_RS_MEASUREMENT_PERIOD, /* fec_rs_period */
681 true, /* reset_pkt_err_acc */
682 0, /* pkt_err_acc_start */
684 /* HI configuration */
685 0, /* hi_cfg_timing_div */
686 0, /* hi_cfg_bridge_delay */
687 0, /* hi_cfg_wake_up_key */
689 0, /* HICfgTimeout */
690 /* UIO configuartion */
691 DRX_UIO_MODE_DISABLE, /* uio_sma_rx_mode */
692 DRX_UIO_MODE_DISABLE, /* uio_sma_tx_mode */
693 DRX_UIO_MODE_DISABLE, /* uioASELMode */
694 DRX_UIO_MODE_DISABLE, /* uio_irqn_mode */
696 0UL, /* iqm_fs_rate_ofs */
697 false, /* pos_image */
699 0UL, /* iqm_rc_rate_ofs */
700 /* AUD information */
701 /* false, * flagSetAUDdone */
702 /* false, * detectedRDS */
703 /* true, * flagASDRequest */
704 /* false, * flagHDevClear */
705 /* false, * flagHDevSet */
706 /* (u16) 0xFFF, * rdsLastCount */
708 /*#ifdef DRXJ_SPLIT_UCODE_UPLOAD
709 false, * flag_aud_mc_uploaded */
710 /*#endif * DRXJ_SPLIT_UCODE_UPLOAD */
711 /* ATV configuartion */
712 0UL, /* flags cfg changes */
713 /* shadow of ATV_TOP_EQU0__A */
715 ATV_TOP_EQU0_EQU_C0_FM,
716 ATV_TOP_EQU0_EQU_C0_L,
717 ATV_TOP_EQU0_EQU_C0_LP,
718 ATV_TOP_EQU0_EQU_C0_BG,
719 ATV_TOP_EQU0_EQU_C0_DK,
720 ATV_TOP_EQU0_EQU_C0_I},
721 /* shadow of ATV_TOP_EQU1__A */
723 ATV_TOP_EQU1_EQU_C1_FM,
724 ATV_TOP_EQU1_EQU_C1_L,
725 ATV_TOP_EQU1_EQU_C1_LP,
726 ATV_TOP_EQU1_EQU_C1_BG,
727 ATV_TOP_EQU1_EQU_C1_DK,
728 ATV_TOP_EQU1_EQU_C1_I},
729 /* shadow of ATV_TOP_EQU2__A */
731 ATV_TOP_EQU2_EQU_C2_FM,
732 ATV_TOP_EQU2_EQU_C2_L,
733 ATV_TOP_EQU2_EQU_C2_LP,
734 ATV_TOP_EQU2_EQU_C2_BG,
735 ATV_TOP_EQU2_EQU_C2_DK,
736 ATV_TOP_EQU2_EQU_C2_I},
737 /* shadow of ATV_TOP_EQU3__A */
739 ATV_TOP_EQU3_EQU_C3_FM,
740 ATV_TOP_EQU3_EQU_C3_L,
741 ATV_TOP_EQU3_EQU_C3_LP,
742 ATV_TOP_EQU3_EQU_C3_BG,
743 ATV_TOP_EQU3_EQU_C3_DK,
744 ATV_TOP_EQU3_EQU_C3_I},
745 false, /* flag: true=bypass */
746 ATV_TOP_VID_PEAK__PRE, /* shadow of ATV_TOP_VID_PEAK__A */
747 ATV_TOP_NOISE_TH__PRE, /* shadow of ATV_TOP_NOISE_TH__A */
748 true, /* flag CVBS ouput enable */
749 false, /* flag SIF ouput enable */
750 DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
751 { /* qam_rf_agc_cfg */
752 DRX_STANDARD_ITU_B, /* standard */
753 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
754 0, /* output_level */
755 0, /* min_output_level */
756 0xFFFF, /* max_output_level */
761 { /* qam_if_agc_cfg */
762 DRX_STANDARD_ITU_B, /* standard */
763 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
764 0, /* output_level */
765 0, /* min_output_level */
766 0xFFFF, /* max_output_level */
768 0x0000, /* top (don't care) */
769 0x0000 /* c.o.c. (don't care) */
771 { /* vsb_rf_agc_cfg */
772 DRX_STANDARD_8VSB, /* standard */
773 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
774 0, /* output_level */
775 0, /* min_output_level */
776 0xFFFF, /* max_output_level */
778 0x0000, /* top (don't care) */
779 0x0000 /* c.o.c. (don't care) */
781 { /* vsb_if_agc_cfg */
782 DRX_STANDARD_8VSB, /* standard */
783 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
784 0, /* output_level */
785 0, /* min_output_level */
786 0xFFFF, /* max_output_level */
788 0x0000, /* top (don't care) */
789 0x0000 /* c.o.c. (don't care) */
793 { /* qam_pre_saw_cfg */
794 DRX_STANDARD_ITU_B, /* standard */
796 false /* use_pre_saw */
798 { /* vsb_pre_saw_cfg */
799 DRX_STANDARD_8VSB, /* standard */
801 false /* use_pre_saw */
804 /* Version information */
807 "01234567890", /* human readable version microcode */
808 "01234567890" /* human readable version device specific code */
811 { /* struct drx_version for microcode */
819 { /* struct drx_version for device specific code */
829 { /* struct drx_version_list for microcode */
830 (struct drx_version *) (NULL),
831 (struct drx_version_list *) (NULL)
833 { /* struct drx_version_list for device specific code */
834 (struct drx_version *) (NULL),
835 (struct drx_version_list *) (NULL)
839 false, /* smart_ant_inverted */
840 /* Tracking filter setting for OOB */
850 false, /* oob_power_on */
851 0, /* mpeg_ts_static_bitrate */
852 false, /* disable_te_ihandling */
853 false, /* bit_reverse_mpeg_outout */
854 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO, /* mpeg_output_clock_rate */
855 DRXJ_MPEG_START_WIDTH_1CLKCYC, /* mpeg_start_width */
857 /* Pre SAW & Agc configuration for ATV */
859 DRX_STANDARD_NTSC, /* standard */
861 true /* use_pre_saw */
864 DRX_STANDARD_NTSC, /* standard */
865 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
866 0, /* output_level */
867 0, /* min_output_level (d.c.) */
868 0, /* max_output_level (d.c.) */
871 4000 /* cut-off current */
874 DRX_STANDARD_NTSC, /* standard */
875 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
876 0, /* output_level */
877 0, /* min_output_level (d.c.) */
878 0, /* max_output_level (d.c.) */
881 0 /* c.o.c. (d.c.) */
883 140, /* ATV PGA config */
884 0, /* curr_symbol_rate */
886 false, /* pdr_safe_mode */
887 SIO_PDR_GPIO_CFG__PRE, /* pdr_safe_restore_val_gpio */
888 SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
889 SIO_PDR_SMA_RX_CFG__PRE, /* pdr_safe_restore_val_sma_rx */
890 SIO_PDR_SMA_TX_CFG__PRE, /* pdr_safe_restore_val_sma_tx */
893 DRXJ_OOB_LO_POW_MINUS10DB, /* oob_lo_pow */
895 false /* aud_data, only first member */
900 * \var drxj_default_addr_g
901 * \brief Default I2C address and device identifier.
903 struct i2c_device_addr drxj_default_addr_g = {
904 DRXJ_DEF_I2C_ADDR, /* i2c address */
905 DRXJ_DEF_DEMOD_DEV_ID /* device id */
909 * \var drxj_default_comm_attr_g
910 * \brief Default common attributes of a drxj demodulator instance.
912 struct drx_common_attr drxj_default_comm_attr_g = {
913 NULL, /* ucode file */
914 true, /* ucode verify switch */
915 {0}, /* version record */
917 44000, /* IF in kHz in case no tuner instance is used */
918 (151875 - 0), /* system clock frequency in kHz */
919 0, /* oscillator frequency kHz */
920 0, /* oscillator deviation in ppm, signed */
921 false, /* If true mirror frequency spectrum */
923 /* MPEG output configuration */
924 true, /* If true, enable MPEG ouput */
925 false, /* If true, insert RS byte */
926 true, /* If true, parallel out otherwise serial */
927 false, /* If true, invert DATA signals */
928 false, /* If true, invert ERR signal */
929 false, /* If true, invert STR signals */
930 false, /* If true, invert VAL signals */
931 false, /* If true, invert CLK signals */
932 true, /* If true, static MPEG clockrate will
933 be used, otherwise clockrate will
934 adapt to the bitrate of the TS */
935 19392658UL, /* Maximum bitrate in b/s in case
936 static clockrate is selected */
937 DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
939 /* Initilisations below can be ommited, they require no user input and
940 are initialy 0, NULL or false. The compiler will initialize them to these
941 values when ommited. */
942 false, /* is_opened */
945 NULL, /* no scan params yet */
946 0, /* current scan index */
947 0, /* next scan frequency */
948 false, /* scan ready flag */
949 0, /* max channels to scan */
950 0, /* nr of channels scanned */
951 NULL, /* default scan function */
952 NULL, /* default context pointer */
953 0, /* millisec to wait for demod lock */
954 DRXJ_DEMOD_LOCK, /* desired lock */
957 /* Power management */
961 1, /* nr of I2C port to wich tuner is */
962 0L, /* minimum RF input frequency, in kHz */
963 0L, /* maximum RF input frequency, in kHz */
964 false, /* Rf Agc Polarity */
965 false, /* If Agc Polarity */
966 false, /* tuner slow mode */
968 { /* current channel (all 0) */
969 0UL /* channel.frequency */
971 DRX_STANDARD_UNKNOWN, /* current standard */
972 DRX_STANDARD_UNKNOWN, /* previous standard */
973 DRX_STANDARD_UNKNOWN, /* di_cache_standard */
974 false, /* use_bootloader */
975 0UL, /* capabilities */
980 * \var drxj_default_demod_g
981 * \brief Default drxj demodulator instance.
983 struct drx_demod_instance drxj_default_demod_g = {
984 &drxj_functions_g, /* demod functions */
985 &DRXJ_DAP, /* data access protocol functions */
986 NULL, /* tuner instance */
987 &drxj_default_addr_g, /* i2c address & device id */
988 &drxj_default_comm_attr_g, /* demod common attributes */
989 &drxj_data_g /* demod device specific attributes */
993 * \brief Default audio data structure for DRK demodulator instance.
995 * This structure is DRXK specific.
998 struct drx_aud_data drxj_default_aud_data_g = {
999 false, /* audio_is_active */
1000 DRX_AUD_STANDARD_AUTO, /* audio_standard */
1004 false, /* output_enable */
1005 48000, /* frequency */
1006 DRX_I2S_MODE_MASTER, /* mode */
1007 DRX_I2S_WORDLENGTH_32, /* word_length */
1008 DRX_I2S_POLARITY_RIGHT, /* polarity */
1009 DRX_I2S_FORMAT_WS_WITH_DATA /* format */
1015 DRX_AUD_AVC_OFF, /* avc_mode */
1016 0, /* avc_ref_level */
1017 DRX_AUD_AVC_MAX_GAIN_12DB, /* avc_max_gain */
1018 DRX_AUD_AVC_MAX_ATTEN_24DB, /* avc_max_atten */
1019 0, /* strength_left */
1020 0 /* strength_right */
1022 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
1023 /* ass_thresholds */
1034 DRX_NO_CARRIER_NOISE, /* opt */
1041 DRX_NO_CARRIER_MUTE, /* opt */
1049 DRX_AUD_SRC_STEREO_OR_A, /* source_i2s */
1050 DRX_AUD_I2S_MATRIX_STEREO, /* matrix_i2s */
1051 DRX_AUD_FM_MATRIX_SOUND_A /* matrix_fm */
1053 DRX_AUD_DEVIATION_NORMAL, /* deviation */
1054 DRX_AUD_AVSYNC_OFF, /* av_sync */
1058 DRX_AUD_MAX_FM_DEVIATION, /* fm_deviation */
1059 DRX_AUD_MAX_NICAM_PRESCALE /* nicam_gain */
1061 DRX_AUD_FM_DEEMPH_75US, /* deemph */
1062 DRX_BTSC_STEREO, /* btsc_detect */
1063 0, /* rds_data_counter */
1064 false /* rds_data_present */
1067 /*-----------------------------------------------------------------------------
1069 ----------------------------------------------------------------------------*/
1070 struct drxjeq_stat {
1078 struct drxj_hi_cmd {
1088 /*============================================================================*/
1089 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
1090 /*============================================================================*/
1093 * struct drxu_code_block_hdr - Structure of the microcode block headers
1095 * @addr: Destination address of the data in this block
1096 * @size: Size of the block data following this header counted in
1098 * @CRC: CRC value of the data block, only valid if CRC flag is
1101 struct drxu_code_block_hdr {
1108 /*-----------------------------------------------------------------------------
1110 ----------------------------------------------------------------------------*/
1111 /* Some prototypes */
1113 hi_command(struct i2c_device_addr *dev_addr,
1114 const struct drxj_hi_cmd *cmd, u16 *result);
1117 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
1120 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
1122 static int power_down_aud(struct drx_demod_instance *demod);
1124 #ifndef DRXJ_DIGITAL_ONLY
1125 static int power_up_aud(struct drx_demod_instance *demod, bool set_standard);
1129 aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard);
1132 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1135 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
1137 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1139 ctrl_u_code_upload(struct drx_demod_instance *demod,
1140 struct drxu_code_info *mc_info,
1141 enum drxu_code_actionaction, bool audio_mc_upload);
1142 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1144 /*============================================================================*/
1145 /*============================================================================*/
1146 /*== HELPER FUNCTIONS ==*/
1147 /*============================================================================*/
1148 /*============================================================================*/
1151 * \fn void mult32(u32 a, u32 b, u32 *h, u32 *l)
1152 * \brief 32bitsx32bits signed multiplication
1153 * \param a 32 bits multiplicant, typecast from signed to unisgned
1154 * \param b 32 bits multiplier, typecast from signed to unisgned
1155 * \param h pointer to high part 64 bits result, typecast from signed to unisgned
1156 * \param l pointer to low part 64 bits result
1158 * For the 2n+n addition a + b:
1159 * if a >= 0, then h += 0 (sign extension = 0)
1160 * but if a < 0, then h += 2^n-1 ==> h -= 1.
1162 * Also, if a + b < 2^n, then a + b >= a && a + b >= b
1163 * but if a + b >= 2^n, then R = a + b - 2^n,
1164 * and because a < 2^n && b < 2*n ==> R < a && R < b.
1165 * Therefore, to detect overflow, simply compare the addition result with
1166 * one of the operands; if the result is smaller, overflow has occurred and
1167 * h must be incremented.
1169 * Booth multiplication uses additions and subtractions to reduce the number
1170 * of iterations. This is done by taking three subsequent bits abc and calculating
1171 * the following multiplication factor: -2a + b + c. This factor is multiplied
1172 * by the second operand and added to the result. Next, the first operand is
1173 * shifted two bits (hence one of the three bits is reused) and the process
1174 * repeated. The last iteration has only two bits left, but we simply add
1175 * a zero to the end.
1178 * 1 * a = 0 * 4a + 1 * a
1179 * 2 * a = 1 * 4a - 2 * a
1180 * 3 * a = 1 * 4a - 1 * a
1181 * -1 * a = 0 * 4a - 1 * a
1182 * -5 * a = -1 * 4a - 1 * a
1186 * Note that the function is type size independent. Any unsigned integer type
1187 * can be substituted for booth_t.
1191 #define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof(u32) * 8 - 1))) != 0)
1193 static void mult32(u32 a, u32 b, u32 *h, u32 *l)
1198 /* n/2 iterations; shift operand a left two bits after each iteration. */
1199 /* This automatically appends a zero to the operand for the last iteration. */
1200 for (i = 0; i < sizeof(a) * 8; i += 2, a = a << 2) {
1201 /* Shift result left two bits */
1202 *h = (*h << 2) + (*l >> (sizeof(*l) * 8 - 2));
1205 /* Take the first three bits of operand a for the Booth conversion: */
1206 /* 0, 7: do nothing */
1209 /* 4 : subtract 2b */
1210 /* 5, 6: subtract b */
1211 switch (a >> (sizeof(a) * 8 - 3)) {
1214 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1218 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1222 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1230 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1240 /*============================================================================*/
1243 * \fn u32 frac28(u32 N, u32 D)
1244 * \brief Compute: (1<<28)*N/D
1247 * \return (1<<28)*N/D
1248 * This function is used to avoid floating-point calculations as they may
1249 * not be present on the target platform.
1251 * frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1252 * fraction used for setting the Frequency Shifter registers.
1253 * N and D can hold numbers up to width: 28-bits.
1254 * The 4 bits integer part and the 28 bits fractional part are calculated.
1256 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1258 * N: 0...(1<<28)-1 = 268435454
1262 static u32 frac28(u32 N, u32 D)
1268 R0 = (N % D) << 4; /* 32-28 == 4 shifts possible at max */
1269 Q1 = N / D; /* integer part, only the 4 least significant bits
1270 will be visible in the result */
1272 /* division using radix 16, 7 nibbles in the result */
1273 for (i = 0; i < 7; i++) {
1274 Q1 = (Q1 << 4) | R0 / D;
1285 * \fn u32 log1_times100( u32 x)
1286 * \brief Compute: 100*log10(x)
1288 * \return 100*log10(x)
1291 * = 100*(log2(x)/log2(10)))
1292 * = (100*(2^15)*log2(x))/((2^15)*log2(10))
1293 * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1294 * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1295 * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1297 * where y = 2^k and 1<= (x/y) < 2
1300 static u32 log1_times100(u32 x)
1302 static const u8 scale = 15;
1303 static const u8 index_width = 5;
1305 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1306 0 <= n < ((1<<INDEXWIDTH)+1)
1309 static const u32 log2lut[] = {
1311 290941, /* 290941.300628 */
1312 573196, /* 573196.476418 */
1313 847269, /* 847269.179851 */
1314 1113620, /* 1113620.489452 */
1315 1372674, /* 1372673.576986 */
1316 1624818, /* 1624817.752104 */
1317 1870412, /* 1870411.981536 */
1318 2109788, /* 2109787.962654 */
1319 2343253, /* 2343252.817465 */
1320 2571091, /* 2571091.461923 */
1321 2793569, /* 2793568.696416 */
1322 3010931, /* 3010931.055901 */
1323 3223408, /* 3223408.452106 */
1324 3431216, /* 3431215.635215 */
1325 3634553, /* 3634553.498355 */
1326 3833610, /* 3833610.244726 */
1327 4028562, /* 4028562.434393 */
1328 4219576, /* 4219575.925308 */
1329 4406807, /* 4406806.721144 */
1330 4590402, /* 4590401.736809 */
1331 4770499, /* 4770499.491025 */
1332 4947231, /* 4947230.734179 */
1333 5120719, /* 5120719.018555 */
1334 5291081, /* 5291081.217197 */
1335 5458428, /* 5458427.996830 */
1336 5622864, /* 5622864.249668 */
1337 5784489, /* 5784489.488298 */
1338 5943398, /* 5943398.207380 */
1339 6099680, /* 6099680.215452 */
1340 6253421, /* 6253420.939751 */
1341 6404702, /* 6404701.706649 */
1342 6553600, /* 6553600.000000 */
1354 /* Scale x (normalize) */
1355 /* computing y in log(x/y) = log(x) - log(y) */
1356 if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
1357 for (k = scale; k > 0; k--) {
1358 if (x & (((u32) 1) << scale))
1363 for (k = scale; k < 31; k++) {
1364 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
1370 Now x has binary point between bit[scale] and bit[scale-1]
1371 and 1.0 <= x < 2.0 */
1373 /* correction for divison: log(x) = log(x/y)+log(y) */
1374 y = k * ((((u32) 1) << scale) * 200);
1376 /* remove integer part */
1377 x &= ((((u32) 1) << scale) - 1);
1379 i = (u8) (x >> (scale - index_width));
1380 /* compute delta (x-a) */
1381 d = x & ((((u32) 1) << (scale - index_width)) - 1);
1382 /* compute log, multiplication ( d* (.. )) must be within range ! */
1384 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
1385 /* Conver to log10() */
1386 y /= 108853; /* (log2(10) << scale) */
1397 * \fn u32 frac_times1e6( u16 N, u32 D)
1398 * \brief Compute: (N/D) * 1000000.
1399 * \param N nominator 16-bits.
1400 * \param D denominator 32-bits.
1402 * \retval ((N/D) * 1000000), 32 bits
1406 static u32 frac_times1e6(u32 N, u32 D)
1412 frac = (N * 1000000) / D
1413 To let it fit in a 32 bits computation:
1414 frac = (N * (1000000 >> 4)) / (D >> 4)
1415 This would result in a problem in case D < 16 (div by 0).
1416 So we do it more elaborate as shown below.
1418 frac = (((u32) N) * (1000000 >> 4)) / D;
1420 remainder = (((u32) N) * (1000000 >> 4)) % D;
1422 frac += remainder / D;
1423 remainder = remainder % D;
1424 if ((remainder * 2) > D)
1430 /*============================================================================*/
1433 * \brief Compute: 100 * 10^( gd_b / 200 ).
1434 * \param u32 gd_b Gain in 0.1dB
1435 * \return u32 Gainfactor in 0.01 resolution
1438 static u32 d_b2lin_times100(u32 gd_b)
1441 u32 nr6d_b_steps = 0;
1443 u32 remainder_fac = 0;
1445 /* start with factors 2 (6.02dB) */
1446 nr6d_b_steps = gd_b * 1000UL / 60206UL;
1447 if (nr6d_b_steps > 17) {
1448 /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
1451 result = (1 << nr6d_b_steps);
1453 /* calculate remaining factor,
1454 poly approximation of 10^(gd_b/200):
1456 y = 1E-04x2 + 0.0106x + 1.0026
1458 max deviation < 0.005 for range x = [0 ... 60]
1460 remainder = ((gd_b * 1000UL) % 60206UL) / 1000UL;
1461 /* using 1e-4 for poly calculation */
1462 remainder_fac = 1 * remainder * remainder;
1463 remainder_fac += 106 * remainder;
1464 remainder_fac += 10026;
1466 /* multiply by remaining factor */
1467 result *= remainder_fac;
1469 /* conversion from 1e-4 to 1e-2 */
1470 return (result + 50) / 100;
1473 #ifndef DRXJ_DIGITAL_ONLY
1474 #define FRAC_FLOOR 0
1476 #define FRAC_ROUND 2
1478 * \fn u32 frac( u32 N, u32 D, u16 RC )
1479 * \brief Compute: N/D.
1480 * \param N nominator 32-bits.
1481 * \param D denominator 32-bits.
1482 * \param RC-result correction: 0-floor; 1-ceil; 2-round
1484 * \retval N/D, 32 bits
1488 static u32 frac(u32 N, u32 D, u16 RC)
1507 while (bit_cnt-- > 0) {
1509 remainder |= ((frac & 0x80000000) >> 31);
1511 if (remainder < D) {
1519 /* result correction if needed */
1520 if ((RC == FRAC_CEIL) && (remainder != 0)) {
1521 /* ceil the result */
1522 /*(remainder is not zero -> value behind decimal point exists) */
1525 if ((RC == FRAC_ROUND) && (remainder >= D >> 1)) {
1526 /* remainder is bigger from D/2 -> round the result */
1535 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1536 /*============================================================================*/
1539 * \fn u16 u_code_read16( u8 *addr)
1540 * \brief Read a 16 bits word, expect big endian data.
1541 * \return u16 The data read.
1543 static u16 u_code_read16(u8 *addr)
1545 /* Works fo any host processor */
1549 word = ((u16) addr[0]);
1551 word |= ((u16) addr[1]);
1556 /*============================================================================*/
1559 * \fn u32 u_code_read32( u8 *addr)
1560 * \brief Read a 32 bits word, expect big endian data.
1561 * \return u32 The data read.
1563 static u32 u_code_read32(u8 *addr)
1565 /* Works fo any host processor */
1569 word = ((u16) addr[0]);
1571 word |= ((u16) addr[1]);
1573 word |= ((u16) addr[2]);
1575 word |= ((u16) addr[3]);
1580 /*============================================================================*/
1583 * \fn u16 u_code_compute_crc (u8 *block_data, u16 nr_words)
1584 * \brief Compute CRC of block of microcode data.
1585 * \param block_data Pointer to microcode data.
1586 * \param nr_words Size of microcode block (number of 16 bits words).
1587 * \return u16 The computed CRC residu.
1589 static u16 u_code_compute_crc(u8 *block_data, u16 nr_words)
1596 while (i < nr_words) {
1597 crc_word |= (u32) u_code_read16(block_data);
1598 for (j = 0; j < 16; j++) {
1601 crc_word ^= 0x80050000UL;
1602 carry = crc_word & 0x80000000UL;
1605 block_data += (sizeof(u16));
1607 return (u16)(crc_word >> 16);
1609 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1612 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1613 * and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1616 static const u16 nicam_presc_table_val[43] = {
1617 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1618 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1619 18, 20, 23, 25, 28, 32, 36, 40, 45,
1620 51, 57, 64, 71, 80, 90, 101, 113, 127
1623 /*============================================================================*/
1624 /*== END HELPER FUNCTIONS ==*/
1625 /*============================================================================*/
1627 /*============================================================================*/
1628 /*============================================================================*/
1629 /*== DRXJ DAP FUNCTIONS ==*/
1630 /*============================================================================*/
1631 /*============================================================================*/
1634 This layer takes care of some device specific register access protocols:
1635 -conversion to short address format
1636 -access to audio block
1637 This layer is placed between the drx_dap_fasi and the rest of the drxj
1638 specific implementation. This layer can use address map knowledge whereas
1639 dap_fasi may not use memory map knowledge.
1641 * For audio currently only 16 bits read and write register access is
1642 supported. More is not needed. RMW and 32 or 8 bit access on audio
1643 registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1644 single/multi master) will be ignored.
1646 TODO: check ignoring single/multimaster is ok for AUD access ?
1649 #define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1650 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
1651 /*============================================================================*/
1654 * \fn bool is_handled_by_aud_tr_if( u32 addr )
1655 * \brief Check if this address is handled by the audio token ring interface.
1658 * \retval true Yes, handled by audio token ring interface
1659 * \retval false No, not handled by audio token ring interface
1663 bool is_handled_by_aud_tr_if(u32 addr)
1665 bool retval = false;
1667 if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1668 (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1669 (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1676 /*============================================================================*/
1678 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
1681 u8 *data, u32 flags)
1683 return drx_dap_fasi_funct_g.read_block_func(dev_addr,
1684 addr, datasize, data, flags);
1687 /*============================================================================*/
1689 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
1692 u8 wdata, u8 *rdata)
1694 return drx_dap_fasi_funct_g.read_modify_write_reg8func(dev_addr,
1696 raddr, wdata, rdata);
1699 /*============================================================================*/
1702 * \fn int drxj_dap_rm_write_reg16short
1703 * \brief Read modify write 16 bits audio register using short format only.
1705 * \param waddr Address to write to
1706 * \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1707 * \param wdata Data to write
1708 * \param rdata Buffer for data to read
1711 * \retval -EIO Timeout, I2C error, illegal bank
1713 * 16 bits register read modify write access using short addressing format only.
1714 * Requires knowledge of the registermap, thus device dependent.
1715 * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1719 /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1720 See comments drxj_dap_read_modify_write_reg16 */
1721 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
1722 static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1725 u16 wdata, u16 *rdata)
1733 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1734 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1735 SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1738 /* Write new data: triggers RMW */
1739 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr, waddr, wdata,
1744 rc = drx_dap_fasi_funct_g.read_reg16func(dev_addr, raddr, rdata,
1748 /* Reset RMW flag */
1749 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1750 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1758 /*============================================================================*/
1760 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1763 u16 wdata, u16 *rdata)
1765 /* TODO: correct short/long addressing format decision,
1766 now long format has higher prio then short because short also
1767 needs virt bnks (not impl yet) for certain audio registers */
1768 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1769 return drx_dap_fasi_funct_g.read_modify_write_reg16func(dev_addr,
1771 raddr, wdata, rdata);
1773 return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
1777 /*============================================================================*/
1779 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
1782 u32 wdata, u32 *rdata)
1784 return drx_dap_fasi_funct_g.read_modify_write_reg32func(dev_addr,
1786 raddr, wdata, rdata);
1789 /*============================================================================*/
1791 static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
1793 u8 *data, u32 flags)
1795 return drx_dap_fasi_funct_g.read_reg8func(dev_addr, addr, data, flags);
1798 /*============================================================================*/
1801 * \fn int drxj_dap_read_aud_reg16
1802 * \brief Read 16 bits audio register
1808 * \retval -EIO Timeout, I2C error, illegal bank
1810 * 16 bits register read access via audio token ring interface.
1813 static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1814 u32 addr, u16 *data)
1816 u32 start_timer = 0;
1817 u32 current_timer = 0;
1818 u32 delta_timer = 0;
1822 /* No read possible for bank 3, return with error */
1823 if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1826 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1828 /* Force reset write bit */
1829 addr &= (~write_bit);
1832 start_timer = drxbsp_hst_clock();
1834 /* RMW to aud TR IF until request is granted or timeout */
1835 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1837 SIO_HI_RA_RAM_S0_RMWBUF__A,
1838 0x0000, &tr_status);
1843 current_timer = drxbsp_hst_clock();
1844 delta_timer = current_timer - start_timer;
1845 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1850 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1851 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1852 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1853 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1854 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1856 /* Wait for read ready status or timeout */
1858 start_timer = drxbsp_hst_clock();
1860 while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1861 AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1862 stat = drxj_dap_read_reg16(dev_addr,
1864 &tr_status, 0x0000);
1868 current_timer = drxbsp_hst_clock();
1869 delta_timer = current_timer - start_timer;
1870 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1874 } /* while ( ... ) */
1879 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1880 AUD_TOP_TR_RD_REG__A,
1881 SIO_HI_RA_RAM_S0_RMWBUF__A,
1886 /*============================================================================*/
1888 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1890 u16 *data, u32 flags)
1895 if ((dev_addr == NULL) || (data == NULL))
1898 if (is_handled_by_aud_tr_if(addr))
1899 stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
1901 stat = drx_dap_fasi_funct_g.read_reg16func(dev_addr,
1907 /*============================================================================*/
1909 static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
1911 u32 *data, u32 flags)
1913 return drx_dap_fasi_funct_g.read_reg32func(dev_addr, addr, data, flags);
1916 /*============================================================================*/
1918 static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
1921 u8 *data, u32 flags)
1923 return drx_dap_fasi_funct_g.write_block_func(dev_addr,
1924 addr, datasize, data, flags);
1927 /*============================================================================*/
1929 static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
1933 return drx_dap_fasi_funct_g.write_reg8func(dev_addr, addr, data, flags);
1936 /*============================================================================*/
1939 * \fn int drxj_dap_write_aud_reg16
1940 * \brief Write 16 bits audio register
1946 * \retval -EIO Timeout, I2C error, illegal bank
1948 * 16 bits register write access via audio token ring interface.
1951 static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
1956 /* No write possible for bank 2, return with error */
1957 if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
1960 u32 start_timer = 0;
1961 u32 current_timer = 0;
1962 u32 delta_timer = 0;
1964 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1966 /* Force write bit */
1968 start_timer = drxbsp_hst_clock();
1970 /* RMW to aud TR IF until request is granted or timeout */
1971 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1973 SIO_HI_RA_RAM_S0_RMWBUF__A,
1978 current_timer = drxbsp_hst_clock();
1979 delta_timer = current_timer - start_timer;
1980 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1985 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1986 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1987 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1988 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1990 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
1995 /*============================================================================*/
1997 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
1999 u16 data, u32 flags)
2004 if (dev_addr == NULL)
2007 if (is_handled_by_aud_tr_if(addr))
2008 stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
2010 stat = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
2016 /*============================================================================*/
2018 static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
2020 u32 data, u32 flags)
2022 return drx_dap_fasi_funct_g.write_reg32func(dev_addr, addr, data, flags);
2025 /*============================================================================*/
2027 /* Free data ram in SIO HI */
2028 #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2029 #define SIO_HI_RA_RAM_USR_END__A 0x420060
2031 #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2032 #define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2033 #define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2034 #define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2037 * \fn int drxj_dap_atomic_read_write_block()
2038 * \brief Basic access routine for atomic read or write access
2039 * \param dev_addr pointer to i2c dev address
2040 * \param addr destination/source address
2041 * \param datasize size of data buffer in bytes
2042 * \param data pointer to data buffer
2045 * \retval -EIO Timeout, I2C error, illegal bank
2049 int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2052 u8 *data, bool read_flag)
2054 struct drxj_hi_cmd hi_cmd;
2060 /* Parameter check */
2061 if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
2064 /* Set up HI parameters to read or write n bytes */
2065 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2067 (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2068 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2070 (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2071 hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2073 hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2075 hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
2076 hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2077 DRXDAP_FASI_ADDR2BANK(addr));
2078 hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
2081 /* write data to buffer */
2082 for (i = 0; i < (datasize / 2); i++) {
2084 word = ((u16) data[2 * i]);
2085 word += (((u16) data[(2 * i) + 1]) << 8);
2086 drxj_dap_write_reg16(dev_addr,
2087 (DRXJ_HI_ATOMIC_BUF_START + i),
2092 rc = hi_command(dev_addr, &hi_cmd, &dummy);
2094 pr_err("error %d\n", rc);
2099 /* read data from buffer */
2100 for (i = 0; i < (datasize / 2); i++) {
2101 drxj_dap_read_reg16(dev_addr,
2102 (DRXJ_HI_ATOMIC_BUF_START + i),
2104 data[2 * i] = (u8) (word & 0xFF);
2105 data[(2 * i) + 1] = (u8) (word >> 8);
2116 /*============================================================================*/
2119 * \fn int drxj_dap_atomic_read_reg32()
2120 * \brief Atomic read of 32 bits words
2123 int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2125 u32 *data, u32 flags)
2127 u8 buf[sizeof(*data)];
2134 rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
2135 sizeof(*data), buf, true);
2140 word = (u32) buf[3];
2142 word |= (u32) buf[2];
2144 word |= (u32) buf[1];
2146 word |= (u32) buf[0];
2153 /*============================================================================*/
2155 /*============================================================================*/
2156 /*== END DRXJ DAP FUNCTIONS ==*/
2157 /*============================================================================*/
2159 /*============================================================================*/
2160 /*============================================================================*/
2161 /*== HOST INTERFACE FUNCTIONS ==*/
2162 /*============================================================================*/
2163 /*============================================================================*/
2166 * \fn int hi_cfg_command()
2167 * \brief Configure HI with settings stored in the demod structure.
2168 * \param demod Demodulator.
2171 * This routine was created because to much orthogonal settings have
2172 * been put into one HI API function (configure). Especially the I2C bridge
2173 * enable/disable should not need re-configuration of the HI.
2176 static int hi_cfg_command(const struct drx_demod_instance *demod)
2178 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2179 struct drxj_hi_cmd hi_cmd;
2183 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2185 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2186 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2187 hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2188 hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2189 hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2190 hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2191 hi_cmd.param6 = ext_attr->hi_cfg_transmit;
2193 rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
2195 pr_err("error %d\n", rc);
2199 /* Reset power down flag (set one call only) */
2200 ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2209 * \fn int hi_command()
2210 * \brief Configure HI with settings stored in the demod structure.
2211 * \param dev_addr I2C address.
2212 * \param cmd HI command.
2213 * \param result HI command result.
2216 * Sends command to HI
2220 hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
2224 bool powerdown_cmd = false;
2227 /* Write parameters */
2230 case SIO_HI_RA_RAM_CMD_CONFIG:
2231 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2232 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
2234 pr_err("error %d\n", rc);
2237 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
2239 pr_err("error %d\n", rc);
2242 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
2244 pr_err("error %d\n", rc);
2247 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
2249 pr_err("error %d\n", rc);
2253 case SIO_HI_RA_RAM_CMD_BRDCTRL:
2254 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
2256 pr_err("error %d\n", rc);
2259 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
2261 pr_err("error %d\n", rc);
2265 case SIO_HI_RA_RAM_CMD_NULL:
2275 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
2277 pr_err("error %d\n", rc);
2281 if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
2282 drxbsp_hst_sleep(1);
2284 /* Detect power down to ommit reading result */
2285 powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2287 param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2288 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2289 if (!powerdown_cmd) {
2290 /* Wait until command rdy */
2293 if (nr_retries > DRXJ_MAX_RETRIES) {
2294 pr_err("timeout\n");
2298 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
2300 pr_err("error %d\n", rc);
2303 } while (wait_cmd != 0);
2306 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
2308 pr_err("error %d\n", rc);
2313 /* if ( powerdown_cmd == true ) */
2320 * \fn int init_hi( const struct drx_demod_instance *demod )
2321 * \brief Initialise and configurate HI.
2322 * \param demod pointer to demod data.
2323 * \return int Return status.
2324 * \retval 0 Success.
2325 * \retval -EIO Failure.
2327 * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2328 * Need to store configuration in driver because of the way I2C
2329 * bridging is controlled.
2332 static int init_hi(const struct drx_demod_instance *demod)
2334 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2335 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2336 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2339 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2340 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2341 dev_addr = demod->my_i2c_dev_addr;
2343 /* PATCH for bug 5003, HI ucode v3.1.0 */
2344 rc = DRXJ_DAP.write_reg16func(dev_addr, 0x4301D7, 0x801, 0);
2346 pr_err("error %d\n", rc);
2350 /* Timing div, 250ns/Psys */
2351 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2352 ext_attr->hi_cfg_timing_div =
2353 (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
2355 if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
2356 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2357 /* Bridge delay, uses oscilator clock */
2358 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2359 /* SDA brdige delay */
2360 ext_attr->hi_cfg_bridge_delay =
2361 (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
2364 if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
2365 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2366 /* SCL bridge delay, same as SDA for now */
2367 ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
2368 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2369 /* Wakeup key, setting the read flag (as suggest in the documentation) does
2370 not always result into a working solution (barebones worked VI2C failed).
2371 Not setting the bit works in all cases . */
2372 ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
2373 /* port/bridge/power down ctrl */
2374 ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2375 /* transit mode time out delay and watch dog divider */
2376 ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
2378 rc = hi_cfg_command(demod);
2380 pr_err("error %d\n", rc);
2390 /*============================================================================*/
2391 /*== END HOST INTERFACE FUNCTIONS ==*/
2392 /*============================================================================*/
2394 /*============================================================================*/
2395 /*============================================================================*/
2396 /*== AUXILIARY FUNCTIONS ==*/
2397 /*============================================================================*/
2398 /*============================================================================*/
2401 * \fn int get_device_capabilities()
2402 * \brief Get and store device capabilities.
2403 * \param demod Pointer to demodulator instance.
2406 * \retval -EIO Failure
2408 * Depending on pulldowns on MDx pins the following internals are set:
2409 * * common_attr->osc_clock_freq
2410 * * ext_attr->has_lna
2411 * * ext_attr->has_ntsc
2412 * * ext_attr->has_btsc
2413 * * ext_attr->has_oob
2416 static int get_device_capabilities(struct drx_demod_instance *demod)
2418 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2419 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
2420 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2421 u16 sio_pdr_ohw_cfg = 0;
2422 u32 sio_top_jtagid_lo = 0;
2426 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2427 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2428 dev_addr = demod->my_i2c_dev_addr;
2430 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2432 pr_err("error %d\n", rc);
2435 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
2437 pr_err("error %d\n", rc);
2440 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2442 pr_err("error %d\n", rc);
2446 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2448 /* ignore (bypass ?) */
2452 common_attr->osc_clock_freq = 27000;
2456 common_attr->osc_clock_freq = 20250;
2460 common_attr->osc_clock_freq = 4000;
2467 Determine device capabilities
2468 Based on pinning v47
2470 rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
2472 pr_err("error %d\n", rc);
2475 ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
2477 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
2479 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2481 pr_err("error %d\n", rc);
2484 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
2486 pr_err("error %d\n", rc);
2489 bid = (bid >> 10) & 0xf;
2490 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2492 pr_err("error %d\n", rc);
2496 ext_attr->has_lna = true;
2497 ext_attr->has_ntsc = false;
2498 ext_attr->has_btsc = false;
2499 ext_attr->has_oob = false;
2500 ext_attr->has_smatx = true;
2501 ext_attr->has_smarx = false;
2502 ext_attr->has_gpio = false;
2503 ext_attr->has_irqn = false;
2506 ext_attr->has_lna = false;
2507 ext_attr->has_ntsc = false;
2508 ext_attr->has_btsc = false;
2509 ext_attr->has_oob = false;
2510 ext_attr->has_smatx = true;
2511 ext_attr->has_smarx = false;
2512 ext_attr->has_gpio = false;
2513 ext_attr->has_irqn = false;
2516 ext_attr->has_lna = true;
2517 ext_attr->has_ntsc = true;
2518 ext_attr->has_btsc = false;
2519 ext_attr->has_oob = false;
2520 ext_attr->has_smatx = true;
2521 ext_attr->has_smarx = true;
2522 ext_attr->has_gpio = true;
2523 ext_attr->has_irqn = false;
2526 ext_attr->has_lna = false;
2527 ext_attr->has_ntsc = true;
2528 ext_attr->has_btsc = false;
2529 ext_attr->has_oob = false;
2530 ext_attr->has_smatx = true;
2531 ext_attr->has_smarx = true;
2532 ext_attr->has_gpio = true;
2533 ext_attr->has_irqn = false;
2536 ext_attr->has_lna = true;
2537 ext_attr->has_ntsc = true;
2538 ext_attr->has_btsc = true;
2539 ext_attr->has_oob = false;
2540 ext_attr->has_smatx = true;
2541 ext_attr->has_smarx = true;
2542 ext_attr->has_gpio = true;
2543 ext_attr->has_irqn = false;
2546 ext_attr->has_lna = false;
2547 ext_attr->has_ntsc = true;
2548 ext_attr->has_btsc = true;
2549 ext_attr->has_oob = false;
2550 ext_attr->has_smatx = true;
2551 ext_attr->has_smarx = true;
2552 ext_attr->has_gpio = true;
2553 ext_attr->has_irqn = false;
2556 ext_attr->has_lna = true;
2557 ext_attr->has_ntsc = false;
2558 ext_attr->has_btsc = false;
2559 ext_attr->has_oob = true;
2560 ext_attr->has_smatx = true;
2561 ext_attr->has_smarx = true;
2562 ext_attr->has_gpio = true;
2563 ext_attr->has_irqn = true;
2566 ext_attr->has_lna = false;
2567 ext_attr->has_ntsc = true;
2568 ext_attr->has_btsc = true;
2569 ext_attr->has_oob = true;
2570 ext_attr->has_smatx = true;
2571 ext_attr->has_smarx = true;
2572 ext_attr->has_gpio = true;
2573 ext_attr->has_irqn = true;
2576 ext_attr->has_lna = true;
2577 ext_attr->has_ntsc = true;
2578 ext_attr->has_btsc = true;
2579 ext_attr->has_oob = true;
2580 ext_attr->has_smatx = true;
2581 ext_attr->has_smarx = true;
2582 ext_attr->has_gpio = true;
2583 ext_attr->has_irqn = true;
2586 ext_attr->has_lna = false;
2587 ext_attr->has_ntsc = true;
2588 ext_attr->has_btsc = true;
2589 ext_attr->has_oob = true;
2590 ext_attr->has_smatx = true;
2591 ext_attr->has_smarx = true;
2592 ext_attr->has_gpio = true;
2593 ext_attr->has_irqn = true;
2596 /* Unknown device variant */
2607 * \fn int power_up_device()
2608 * \brief Power up device.
2609 * \param demod Pointer to demodulator instance.
2612 * \retval -EIO Failure, I2C or max retries reached
2616 #ifndef DRXJ_MAX_RETRIES_POWERUP
2617 #define DRXJ_MAX_RETRIES_POWERUP 10
2620 static int power_up_device(struct drx_demod_instance *demod)
2622 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2624 u16 retry_count = 0;
2625 struct i2c_device_addr wake_up_addr;
2627 dev_addr = demod->my_i2c_dev_addr;
2628 wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2629 wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2630 wake_up_addr.user_data = dev_addr->user_data;
2632 * I2C access may fail in this case: no ack
2633 * dummy write must be used to wake uop device, dummy read must be used to
2634 * reset HI state machine (avoiding actual writes)
2638 drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
2639 (struct i2c_device_addr *)(NULL), 0,
2641 drxbsp_hst_sleep(10);
2643 } while ((drxbsp_i2c_write_read
2644 ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
2646 != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
2648 /* Need some recovery time .... */
2649 drxbsp_hst_sleep(10);
2651 if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
2657 /*----------------------------------------------------------------------------*/
2658 /* MPEG Output Configuration Functions - begin */
2659 /*----------------------------------------------------------------------------*/
2661 * \fn int ctrl_set_cfg_mpeg_output()
2662 * \brief Set MPEG output configuration of the device.
2663 * \param devmod Pointer to demodulator instance.
2664 * \param cfg_data Pointer to mpeg output configuaration.
2667 * Configure MPEG output parameters.
2671 ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
2673 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2674 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2675 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2677 u16 fec_oc_reg_mode = 0;
2678 u16 fec_oc_reg_ipr_mode = 0;
2679 u16 fec_oc_reg_ipr_invert = 0;
2680 u32 max_bit_rate = 0;
2683 u16 sio_pdr_md_cfg = 0;
2684 /* data mask for the output data byte */
2685 u16 invert_data_mask =
2686 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2687 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2688 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2689 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2691 /* check arguments */
2692 if ((demod == NULL) || (cfg_data == NULL))
2695 dev_addr = demod->my_i2c_dev_addr;
2696 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2697 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2699 if (cfg_data->enable_mpeg_output == true) {
2700 /* quick and dirty patch to set MPEG incase current std is not
2702 switch (ext_attr->standard) {
2703 case DRX_STANDARD_8VSB:
2704 case DRX_STANDARD_ITU_A:
2705 case DRX_STANDARD_ITU_B:
2706 case DRX_STANDARD_ITU_C:
2709 /* not an MPEG producing std, just store MPEG cfg */
2710 common_attr->mpeg_cfg.enable_mpeg_output =
2711 cfg_data->enable_mpeg_output;
2712 common_attr->mpeg_cfg.insert_rs_byte =
2713 cfg_data->insert_rs_byte;
2714 common_attr->mpeg_cfg.enable_parallel =
2715 cfg_data->enable_parallel;
2716 common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
2717 common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
2718 common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
2719 common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
2720 common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
2721 common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
2722 common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
2726 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
2728 pr_err("error %d\n", rc);
2731 switch (ext_attr->standard) {
2732 case DRX_STANDARD_8VSB:
2733 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
2735 pr_err("error %d\n", rc);
2737 } /* 2048 bytes fifo ram */
2738 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
2740 pr_err("error %d\n", rc);
2743 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
2745 pr_err("error %d\n", rc);
2748 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
2750 pr_err("error %d\n", rc);
2753 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
2755 pr_err("error %d\n", rc);
2758 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
2760 pr_err("error %d\n", rc);
2763 /* Low Water Mark for synchronization */
2764 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
2766 pr_err("error %d\n", rc);
2769 /* High Water Mark for synchronization */
2770 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
2772 pr_err("error %d\n", rc);
2776 case DRX_STANDARD_ITU_A:
2777 case DRX_STANDARD_ITU_C:
2778 switch (ext_attr->constellation) {
2779 case DRX_CONSTELLATION_QAM256:
2782 case DRX_CONSTELLATION_QAM128:
2785 case DRX_CONSTELLATION_QAM64:
2788 case DRX_CONSTELLATION_QAM32:
2791 case DRX_CONSTELLATION_QAM16:
2796 } /* ext_attr->constellation */
2797 /* max_bit_rate = symbol_rate * nr_bits * coef */
2798 /* coef = 188/204 */
2800 (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
2801 /* pass through b/c Annex A/c need following settings */
2802 case DRX_STANDARD_ITU_B:
2803 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
2805 pr_err("error %d\n", rc);
2808 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
2810 pr_err("error %d\n", rc);
2813 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
2815 pr_err("error %d\n", rc);
2818 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
2820 pr_err("error %d\n", rc);
2823 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
2825 pr_err("error %d\n", rc);
2828 if (cfg_data->static_clk == true) {
2829 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
2831 pr_err("error %d\n", rc);
2835 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
2837 pr_err("error %d\n", rc);
2841 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
2843 pr_err("error %d\n", rc);
2846 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
2848 pr_err("error %d\n", rc);
2854 } /* swtich (standard) */
2856 /* Check insertion of the Reed-Solomon parity bytes */
2857 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
2859 pr_err("error %d\n", rc);
2862 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
2864 pr_err("error %d\n", rc);
2867 if (cfg_data->insert_rs_byte == true) {
2868 /* enable parity symbol forward */
2869 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
2870 /* MVAL disable during parity bytes */
2871 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2872 switch (ext_attr->standard) {
2873 case DRX_STANDARD_8VSB:
2874 rcn_rate = 0x004854D3;
2876 case DRX_STANDARD_ITU_B:
2877 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2878 switch (ext_attr->constellation) {
2879 case DRX_CONSTELLATION_QAM256:
2880 rcn_rate = 0x008945E7;
2882 case DRX_CONSTELLATION_QAM64:
2883 rcn_rate = 0x005F64D4;
2889 case DRX_STANDARD_ITU_A:
2890 case DRX_STANDARD_ITU_C:
2891 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2895 (u32) (common_attr->sys_clock_freq / 8))) /
2900 } /* ext_attr->standard */
2901 } else { /* insert_rs_byte == false */
2903 /* disable parity symbol forward */
2904 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2905 /* MVAL enable during parity bytes */
2906 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2907 switch (ext_attr->standard) {
2908 case DRX_STANDARD_8VSB:
2909 rcn_rate = 0x0041605C;
2911 case DRX_STANDARD_ITU_B:
2912 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2913 switch (ext_attr->constellation) {
2914 case DRX_CONSTELLATION_QAM256:
2915 rcn_rate = 0x0082D6A0;
2917 case DRX_CONSTELLATION_QAM64:
2918 rcn_rate = 0x005AEC1A;
2924 case DRX_STANDARD_ITU_A:
2925 case DRX_STANDARD_ITU_C:
2926 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2930 (u32) (common_attr->sys_clock_freq / 8))) /
2935 } /* ext_attr->standard */
2938 if (cfg_data->enable_parallel == true) { /* MPEG data output is paralel -> clear ipr_mode[0] */
2939 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2940 } else { /* MPEG data output is serial -> set ipr_mode[0] */
2941 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
2944 /* Control slective inversion of output bits */
2945 if (cfg_data->invert_data == true)
2946 fec_oc_reg_ipr_invert |= invert_data_mask;
2948 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2950 if (cfg_data->invert_err == true)
2951 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2953 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2955 if (cfg_data->invert_str == true)
2956 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2958 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2960 if (cfg_data->invert_val == true)
2961 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2963 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2965 if (cfg_data->invert_clk == true)
2966 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
2968 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2970 if (cfg_data->static_clk == true) { /* Static mode */
2973 u16 fec_oc_dto_burst_len = 0;
2974 u16 fec_oc_dto_period = 0;
2976 fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
2978 switch (ext_attr->standard) {
2979 case DRX_STANDARD_8VSB:
2980 fec_oc_dto_period = 4;
2981 if (cfg_data->insert_rs_byte == true)
2982 fec_oc_dto_burst_len = 208;
2984 case DRX_STANDARD_ITU_A:
2986 u32 symbol_rate_th = 6400000;
2987 if (cfg_data->insert_rs_byte == true) {
2988 fec_oc_dto_burst_len = 204;
2989 symbol_rate_th = 5900000;
2991 if (ext_attr->curr_symbol_rate >=
2993 fec_oc_dto_period = 0;
2995 fec_oc_dto_period = 1;
2999 case DRX_STANDARD_ITU_B:
3000 fec_oc_dto_period = 1;
3001 if (cfg_data->insert_rs_byte == true)
3002 fec_oc_dto_burst_len = 128;
3004 case DRX_STANDARD_ITU_C:
3005 fec_oc_dto_period = 1;
3006 if (cfg_data->insert_rs_byte == true)
3007 fec_oc_dto_burst_len = 204;
3013 common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
3016 frac28(bit_rate, common_attr->sys_clock_freq * 1000);
3018 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
3020 pr_err("error %d\n", rc);
3023 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_RATE_LO__A, (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), 0);
3025 pr_err("error %d\n", rc);
3028 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M, 0);
3030 pr_err("error %d\n", rc);
3033 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M, 0);
3035 pr_err("error %d\n", rc);
3038 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
3040 pr_err("error %d\n", rc);
3043 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3044 fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
3045 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
3047 pr_err("error %d\n", rc);
3050 } else { /* Dynamic mode */
3052 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
3054 pr_err("error %d\n", rc);
3057 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
3059 pr_err("error %d\n", rc);
3064 rc = DRXJ_DAP.write_reg32func(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
3066 pr_err("error %d\n", rc);
3070 /* Write appropriate registers with requested configuration */
3071 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
3073 pr_err("error %d\n", rc);
3076 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
3078 pr_err("error %d\n", rc);
3081 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
3083 pr_err("error %d\n", rc);
3087 /* enabling for both parallel and serial now */
3088 /* Write magic word to enable pdr reg write */
3089 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3091 pr_err("error %d\n", rc);
3094 /* Set MPEG TS pads to outputmode */
3095 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
3097 pr_err("error %d\n", rc);
3100 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
3102 pr_err("error %d\n", rc);
3105 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MCLK_CFG__A, MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B | 0x03 << SIO_PDR_MCLK_CFG_MODE__B, 0);
3107 pr_err("error %d\n", rc);
3110 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
3112 pr_err("error %d\n", rc);
3116 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3117 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
3118 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3120 pr_err("error %d\n", rc);
3123 if (cfg_data->enable_parallel == true) { /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
3125 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3126 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3127 SIO_PDR_MD0_CFG_MODE__B;
3128 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3130 pr_err("error %d\n", rc);
3133 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
3135 pr_err("error %d\n", rc);
3138 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
3140 pr_err("error %d\n", rc);
3143 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
3145 pr_err("error %d\n", rc);
3148 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
3150 pr_err("error %d\n", rc);
3153 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
3155 pr_err("error %d\n", rc);
3158 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
3160 pr_err("error %d\n", rc);
3163 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
3165 pr_err("error %d\n", rc);
3168 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3169 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3171 pr_err("error %d\n", rc);
3174 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3176 pr_err("error %d\n", rc);
3179 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3181 pr_err("error %d\n", rc);
3184 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3186 pr_err("error %d\n", rc);
3189 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3191 pr_err("error %d\n", rc);
3194 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3196 pr_err("error %d\n", rc);
3199 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3201 pr_err("error %d\n", rc);
3205 /* Enable Monitor Bus output over MPEG pads and ctl input */
3206 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3208 pr_err("error %d\n", rc);
3211 /* Write nomagic word to enable pdr reg write */
3212 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3214 pr_err("error %d\n", rc);
3218 /* Write magic word to enable pdr reg write */
3219 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3221 pr_err("error %d\n", rc);
3224 /* Set MPEG TS pads to inputmode */
3225 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
3227 pr_err("error %d\n", rc);
3230 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
3232 pr_err("error %d\n", rc);
3235 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
3237 pr_err("error %d\n", rc);
3240 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
3242 pr_err("error %d\n", rc);
3245 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
3247 pr_err("error %d\n", rc);
3250 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3252 pr_err("error %d\n", rc);
3255 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3257 pr_err("error %d\n", rc);
3260 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3262 pr_err("error %d\n", rc);
3265 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3267 pr_err("error %d\n", rc);
3270 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3272 pr_err("error %d\n", rc);
3275 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3277 pr_err("error %d\n", rc);
3280 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3282 pr_err("error %d\n", rc);
3285 /* Enable Monitor Bus output over MPEG pads and ctl input */
3286 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3288 pr_err("error %d\n", rc);
3291 /* Write nomagic word to enable pdr reg write */
3292 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3294 pr_err("error %d\n", rc);
3299 /* save values for restore after re-acquire */
3300 common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3301 common_attr->mpeg_cfg.insert_rs_byte = cfg_data->insert_rs_byte;
3302 common_attr->mpeg_cfg.enable_parallel = cfg_data->enable_parallel;
3303 common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
3304 common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
3305 common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
3306 common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
3307 common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
3308 common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
3309 common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
3316 /*----------------------------------------------------------------------------*/
3319 * \fn int ctrl_get_cfg_mpeg_output()
3320 * \brief Get MPEG output configuration of the device.
3321 * \param devmod Pointer to demodulator instance.
3322 * \param cfg_data Pointer to MPEG output configuaration struct.
3325 * Retrieve MPEG output configuartion.
3329 ctrl_get_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
3331 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3332 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
3333 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
3339 if (cfg_data == NULL)
3342 dev_addr = demod->my_i2c_dev_addr;
3343 common_attr = demod->my_common_attr;
3345 cfg_data->enable_mpeg_output = common_attr->mpeg_cfg.enable_mpeg_output;
3346 cfg_data->insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
3347 cfg_data->enable_parallel = common_attr->mpeg_cfg.enable_parallel;
3348 cfg_data->invert_data = common_attr->mpeg_cfg.invert_data;
3349 cfg_data->invert_err = common_attr->mpeg_cfg.invert_err;
3350 cfg_data->invert_str = common_attr->mpeg_cfg.invert_str;
3351 cfg_data->invert_val = common_attr->mpeg_cfg.invert_val;
3352 cfg_data->invert_clk = common_attr->mpeg_cfg.invert_clk;
3353 cfg_data->static_clk = common_attr->mpeg_cfg.static_clk;
3354 cfg_data->bitrate = 0;
3356 rc = ctrl_lock_status(demod, &lock_status);
3358 pr_err("error %d\n", rc);
3361 if ((lock_status == DRX_LOCKED)) {
3362 rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_RCN_DYN_RATE_LO__A, &rate_reg, 0);
3364 pr_err("error %d\n", rc);
3367 /* Frcn_rate = rate_reg * Fsys / 2 ^ 25 */
3368 mult32(rate_reg, common_attr->sys_clock_freq * 1000, &data64hi,
3370 cfg_data->bitrate = (data64hi << 7) | (data64lo >> 25);
3378 /*----------------------------------------------------------------------------*/
3379 /* MPEG Output Configuration Functions - end */
3380 /*----------------------------------------------------------------------------*/
3382 /*----------------------------------------------------------------------------*/
3383 /* miscellaneous configuartions - begin */
3384 /*----------------------------------------------------------------------------*/
3387 * \fn int set_mpegtei_handling()
3388 * \brief Activate MPEG TEI handling settings.
3389 * \param devmod Pointer to demodulator instance.
3392 * This routine should be called during a set channel of QAM/VSB
3395 static int set_mpegtei_handling(struct drx_demod_instance *demod)
3397 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3398 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3400 u16 fec_oc_dpr_mode = 0;
3401 u16 fec_oc_snc_mode = 0;
3402 u16 fec_oc_ems_mode = 0;
3404 dev_addr = demod->my_i2c_dev_addr;
3405 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3407 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
3409 pr_err("error %d\n", rc);
3412 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
3414 pr_err("error %d\n", rc);
3417 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
3419 pr_err("error %d\n", rc);
3423 /* reset to default, allow TEI bit to be changed */
3424 fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3425 fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3426 FEC_OC_SNC_MODE_CORR_DISABLE__M));
3427 fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
3429 if (ext_attr->disable_te_ihandling) {
3430 /* do not change TEI bit */
3431 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3432 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3433 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3434 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3437 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
3439 pr_err("error %d\n", rc);
3442 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
3444 pr_err("error %d\n", rc);
3447 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
3449 pr_err("error %d\n", rc);
3458 /*----------------------------------------------------------------------------*/
3460 * \fn int bit_reverse_mpeg_output()
3461 * \brief Set MPEG output bit-endian settings.
3462 * \param devmod Pointer to demodulator instance.
3465 * This routine should be called during a set channel of QAM/VSB
3468 static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
3470 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3471 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3473 u16 fec_oc_ipr_mode = 0;
3475 dev_addr = demod->my_i2c_dev_addr;
3476 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3478 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
3480 pr_err("error %d\n", rc);
3484 /* reset to default (normal bit order) */
3485 fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3487 if (ext_attr->bit_reverse_mpeg_outout)
3488 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3490 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
3492 pr_err("error %d\n", rc);
3501 /*----------------------------------------------------------------------------*/
3503 * \fn int set_mpeg_output_clock_rate()
3504 * \brief Set MPEG output clock rate.
3505 * \param devmod Pointer to demodulator instance.
3508 * This routine should be called during a set channel of QAM/VSB
3511 static int set_mpeg_output_clock_rate(struct drx_demod_instance *demod)
3513 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3514 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3517 dev_addr = demod->my_i2c_dev_addr;
3518 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3520 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3521 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_PERIOD__A, ext_attr->mpeg_output_clock_rate - 1, 0);
3523 pr_err("error %d\n", rc);
3533 /*----------------------------------------------------------------------------*/
3535 * \fn int set_mpeg_start_width()
3536 * \brief Set MPEG start width.
3537 * \param devmod Pointer to demodulator instance.
3540 * This routine should be called during a set channel of QAM/VSB
3543 static int set_mpeg_start_width(struct drx_demod_instance *demod)
3545 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3546 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3547 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
3549 u16 fec_oc_comm_mb = 0;
3551 dev_addr = demod->my_i2c_dev_addr;
3552 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3553 common_attr = demod->my_common_attr;
3555 if ((common_attr->mpeg_cfg.static_clk == true)
3556 && (common_attr->mpeg_cfg.enable_parallel == false)) {
3557 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
3559 pr_err("error %d\n", rc);
3562 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3563 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
3564 fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
3565 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
3567 pr_err("error %d\n", rc);
3577 /*----------------------------------------------------------------------------*/
3579 * \fn int ctrl_set_cfg_mpeg_output_misc()
3580 * \brief Set miscellaneous configuartions
3581 * \param devmod Pointer to demodulator instance.
3582 * \param cfg_data pDRXJCfgMisc_t
3585 * This routine can be used to set configuartion options that are DRXJ
3586 * specific and/or added to the requirements at a late stage.
3590 ctrl_set_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3591 struct drxj_cfg_mpeg_output_misc *cfg_data)
3593 struct drxj_data *ext_attr = NULL;
3596 if (cfg_data == NULL)
3599 ext_attr = demod->my_ext_attr;
3602 Set disable TEI bit handling flag.
3603 TEI must be left untouched by device in case of BER measurements using
3604 external equipment that is unable to ignore the TEI bit in the TS.
3605 Default will false (enable TEI bit handling).
3606 Reverse output bit order. Default is false (msb on MD7 (parallel) or out first (serial)).
3607 Set clock rate. Default is auto that is derived from symbol rate.
3608 The flags and values will also be used to set registers during a set channel.
3610 ext_attr->disable_te_ihandling = cfg_data->disable_tei_handling;
3611 ext_attr->bit_reverse_mpeg_outout = cfg_data->bit_reverse_mpeg_outout;
3612 ext_attr->mpeg_output_clock_rate = cfg_data->mpeg_output_clock_rate;
3613 ext_attr->mpeg_start_width = cfg_data->mpeg_start_width;
3614 /* Don't care what the active standard is, activate setting immediatly */
3615 rc = set_mpegtei_handling(demod);
3617 pr_err("error %d\n", rc);
3620 rc = bit_reverse_mpeg_output(demod);
3622 pr_err("error %d\n", rc);
3625 rc = set_mpeg_output_clock_rate(demod);
3627 pr_err("error %d\n", rc);
3630 rc = set_mpeg_start_width(demod);
3632 pr_err("error %d\n", rc);
3641 /*----------------------------------------------------------------------------*/
3644 * \fn int ctrl_get_cfg_mpeg_output_misc()
3645 * \brief Get miscellaneous configuartions.
3646 * \param devmod Pointer to demodulator instance.
3647 * \param cfg_data Pointer to DRXJCfgMisc_t.
3650 * This routine can be used to retreive the current setting of the configuartion
3651 * options that are DRXJ specific and/or added to the requirements at a
3656 ctrl_get_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3657 struct drxj_cfg_mpeg_output_misc *cfg_data)
3659 struct drxj_data *ext_attr = NULL;
3663 if (cfg_data == NULL)
3666 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3667 cfg_data->disable_tei_handling = ext_attr->disable_te_ihandling;
3668 cfg_data->bit_reverse_mpeg_outout = ext_attr->bit_reverse_mpeg_outout;
3669 cfg_data->mpeg_start_width = ext_attr->mpeg_start_width;
3670 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3671 cfg_data->mpeg_output_clock_rate = ext_attr->mpeg_output_clock_rate;
3673 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, FEC_OC_DTO_PERIOD__A, &data, 0);
3675 pr_err("error %d\n", rc);
3678 cfg_data->mpeg_output_clock_rate =
3679 (enum drxj_mpeg_output_clock_rate) (data + 1);
3687 /*----------------------------------------------------------------------------*/
3690 * \fn int ctrl_get_cfg_hw_cfg()
3691 * \brief Get HW configuartions.
3692 * \param devmod Pointer to demodulator instance.
3693 * \param cfg_data Pointer to Bool.
3696 * This routine can be used to retreive the current setting of the configuartion
3697 * options that are DRXJ specific and/or added to the requirements at a
3702 ctrl_get_cfg_hw_cfg(struct drx_demod_instance *demod, struct drxj_cfg_hw_cfg *cfg_data)
3707 if (cfg_data == NULL)
3710 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3712 pr_err("error %d\n", rc);
3715 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_OHW_CFG__A, &data, 0);
3717 pr_err("error %d\n", rc);
3720 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3722 pr_err("error %d\n", rc);
3726 cfg_data->i2c_speed = (enum drxji2c_speed) ((data >> 6) & 0x1);
3727 cfg_data->xtal_freq = (enum drxj_xtal_freq) (data & 0x3);
3734 /*----------------------------------------------------------------------------*/
3735 /* miscellaneous configuartions - end */
3736 /*----------------------------------------------------------------------------*/
3738 /*----------------------------------------------------------------------------*/
3739 /* UIO Configuration Functions - begin */
3740 /*----------------------------------------------------------------------------*/
3742 * \fn int ctrl_set_uio_cfg()
3743 * \brief Configure modus oprandi UIO.
3744 * \param demod Pointer to demodulator instance.
3745 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3748 static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3750 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3753 if ((uio_cfg == NULL) || (demod == NULL))
3756 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3758 /* Write magic word to enable pdr reg write */
3759 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3761 pr_err("error %d\n", rc);
3764 switch (uio_cfg->uio) {
3765 /*====================================================================*/
3767 /* DRX_UIO1: SMA_TX UIO-1 */
3768 if (!ext_attr->has_smatx)
3770 switch (uio_cfg->mode) {
3771 case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
3772 case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
3773 case DRX_UIO_MODE_READWRITE:
3774 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3776 case DRX_UIO_MODE_DISABLE:
3777 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3778 /* pad configuration register is set 0 - input mode */
3779 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
3781 pr_err("error %d\n", rc);
3787 } /* switch ( uio_cfg->mode ) */
3789 /*====================================================================*/
3791 /* DRX_UIO2: SMA_RX UIO-2 */
3792 if (!ext_attr->has_smarx)
3794 switch (uio_cfg->mode) {
3795 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3796 case DRX_UIO_MODE_READWRITE:
3797 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3799 case DRX_UIO_MODE_DISABLE:
3800 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3801 /* pad configuration register is set 0 - input mode */
3802 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
3804 pr_err("error %d\n", rc);
3811 } /* switch ( uio_cfg->mode ) */
3813 /*====================================================================*/
3815 /* DRX_UIO3: GPIO UIO-3 */
3816 if (!ext_attr->has_gpio)
3818 switch (uio_cfg->mode) {
3819 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3820 case DRX_UIO_MODE_READWRITE:
3821 ext_attr->uio_gpio_mode = uio_cfg->mode;
3823 case DRX_UIO_MODE_DISABLE:
3824 ext_attr->uio_gpio_mode = uio_cfg->mode;
3825 /* pad configuration register is set 0 - input mode */
3826 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
3828 pr_err("error %d\n", rc);
3835 } /* switch ( uio_cfg->mode ) */
3837 /*====================================================================*/
3839 /* DRX_UIO4: IRQN UIO-4 */
3840 if (!ext_attr->has_irqn)
3842 switch (uio_cfg->mode) {
3843 case DRX_UIO_MODE_READWRITE:
3844 ext_attr->uio_irqn_mode = uio_cfg->mode;
3846 case DRX_UIO_MODE_DISABLE:
3847 /* pad configuration register is set 0 - input mode */
3848 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
3850 pr_err("error %d\n", rc);
3853 ext_attr->uio_irqn_mode = uio_cfg->mode;
3855 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3859 } /* switch ( uio_cfg->mode ) */
3861 /*====================================================================*/
3864 } /* switch ( uio_cfg->uio ) */
3866 /* Write magic word to disable pdr reg write */
3867 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3869 pr_err("error %d\n", rc);
3878 /*============================================================================*/
3880 * \fn int ctrl_getuio_cfg()
3881 * \brief Get modus oprandi UIO.
3882 * \param demod Pointer to demodulator instance.
3883 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3886 static int ctrl_getuio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3889 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
3890 enum drxuio_mode *uio_mode[4] = { NULL };
3891 bool *uio_available[4] = { NULL };
3893 ext_attr = demod->my_ext_attr;
3895 uio_mode[DRX_UIO1] = &ext_attr->uio_sma_tx_mode;
3896 uio_mode[DRX_UIO2] = &ext_attr->uio_sma_rx_mode;
3897 uio_mode[DRX_UIO3] = &ext_attr->uio_gpio_mode;
3898 uio_mode[DRX_UIO4] = &ext_attr->uio_irqn_mode;
3900 uio_available[DRX_UIO1] = &ext_attr->has_smatx;
3901 uio_available[DRX_UIO2] = &ext_attr->has_smarx;
3902 uio_available[DRX_UIO3] = &ext_attr->has_gpio;
3903 uio_available[DRX_UIO4] = &ext_attr->has_irqn;
3905 if (uio_cfg == NULL)
3908 if ((uio_cfg->uio > DRX_UIO4) || (uio_cfg->uio < DRX_UIO1))
3911 if (!*uio_available[uio_cfg->uio])
3914 uio_cfg->mode = *uio_mode[uio_cfg->uio];
3920 * \fn int ctrl_uio_write()
3921 * \brief Write to a UIO.
3922 * \param demod Pointer to demodulator instance.
3923 * \param uio_data Pointer to data container for a certain UIO.
3927 ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
3929 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3931 u16 pin_cfg_value = 0;
3934 if ((uio_data == NULL) || (demod == NULL))
3937 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3939 /* Write magic word to enable pdr reg write */
3940 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3942 pr_err("error %d\n", rc);
3945 switch (uio_data->uio) {
3946 /*====================================================================*/
3948 /* DRX_UIO1: SMA_TX UIO-1 */
3949 if (!ext_attr->has_smatx)
3951 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3952 && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3956 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3957 pin_cfg_value |= 0x0113;
3958 /* io_pad_cfg_mode output mode is drive always */
3959 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3961 /* write to io pad configuration register - output mode */
3962 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
3964 pr_err("error %d\n", rc);
3968 /* use corresponding bit in io data output registar */
3969 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3971 pr_err("error %d\n", rc);
3974 if (!uio_data->value)
3975 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
3977 value |= 0x8000; /* write one to 15th bit - 1st UIO */
3979 /* write back to io data output register */
3980 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3982 pr_err("error %d\n", rc);
3986 /*======================================================================*/
3988 /* DRX_UIO2: SMA_RX UIO-2 */
3989 if (!ext_attr->has_smarx)
3991 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
3995 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3996 pin_cfg_value |= 0x0113;
3997 /* io_pad_cfg_mode output mode is drive always */
3998 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4000 /* write to io pad configuration register - output mode */
4001 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
4003 pr_err("error %d\n", rc);
4007 /* use corresponding bit in io data output registar */
4008 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
4010 pr_err("error %d\n", rc);
4013 if (!uio_data->value)
4014 value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
4016 value |= 0x4000; /* write one to 14th bit - 2nd UIO */
4018 /* write back to io data output register */
4019 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
4021 pr_err("error %d\n", rc);
4025 /*====================================================================*/
4027 /* DRX_UIO3: ASEL UIO-3 */
4028 if (!ext_attr->has_gpio)
4030 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
4034 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4035 pin_cfg_value |= 0x0113;
4036 /* io_pad_cfg_mode output mode is drive always */
4037 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4039 /* write to io pad configuration register - output mode */
4040 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
4042 pr_err("error %d\n", rc);
4046 /* use corresponding bit in io data output registar */
4047 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
4049 pr_err("error %d\n", rc);
4052 if (!uio_data->value)
4053 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
4055 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
4057 /* write back to io data output register */
4058 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
4060 pr_err("error %d\n", rc);
4064 /*=====================================================================*/
4066 /* DRX_UIO4: IRQN UIO-4 */
4067 if (!ext_attr->has_irqn)
4070 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
4074 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4075 pin_cfg_value |= 0x0113;
4076 /* io_pad_cfg_mode output mode is drive always */
4077 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4079 /* write to io pad configuration register - output mode */
4080 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
4082 pr_err("error %d\n", rc);
4086 /* use corresponding bit in io data output registar */
4087 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
4089 pr_err("error %d\n", rc);
4092 if (uio_data->value == false)
4093 value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
4095 value |= 0x1000; /* write one to 12th bit - 4th UIO */
4097 /* write back to io data output register */
4098 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
4100 pr_err("error %d\n", rc);
4104 /*=====================================================================*/
4107 } /* switch ( uio_data->uio ) */
4109 /* Write magic word to disable pdr reg write */
4110 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4112 pr_err("error %d\n", rc);
4122 *\fn int ctrl_uio_read
4123 *\brief Read from a UIO.
4124 * \param demod Pointer to demodulator instance.
4125 * \param uio_data Pointer to data container for a certain UIO.
4128 static int ctrl_uio_read(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
4130 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
4132 u16 pin_cfg_value = 0;
4135 if ((uio_data == NULL) || (demod == NULL))
4138 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4140 /* Write magic word to enable pdr reg write */
4141 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4143 pr_err("error %d\n", rc);
4146 switch (uio_data->uio) {
4147 /*====================================================================*/
4149 /* DRX_UIO1: SMA_TX UIO-1 */
4150 if (!ext_attr->has_smatx)
4153 if (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
4157 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4158 pin_cfg_value |= 0x0110;
4159 /* io_pad_cfg_mode output mode is drive always */
4160 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4162 /* write to io pad configuration register - input mode */
4163 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
4165 pr_err("error %d\n", rc);
4169 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4171 pr_err("error %d\n", rc);
4174 if ((value & 0x8000) != 0) { /* check 15th bit - 1st UIO */
4175 uio_data->value = true;
4177 uio_data->value = false;
4180 /*======================================================================*/
4182 /* DRX_UIO2: SMA_RX UIO-2 */
4183 if (!ext_attr->has_smarx)
4186 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
4190 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4191 pin_cfg_value |= 0x0110;
4192 /* io_pad_cfg_mode output mode is drive always */
4193 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4195 /* write to io pad configuration register - input mode */
4196 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
4198 pr_err("error %d\n", rc);
4202 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4204 pr_err("error %d\n", rc);
4208 if ((value & 0x4000) != 0) /* check 14th bit - 2nd UIO */
4209 uio_data->value = true;
4211 uio_data->value = false;
4214 /*=====================================================================*/
4216 /* DRX_UIO3: GPIO UIO-3 */
4217 if (!ext_attr->has_gpio)
4220 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
4224 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4225 pin_cfg_value |= 0x0110;
4226 /* io_pad_cfg_mode output mode is drive always */
4227 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4229 /* write to io pad configuration register - input mode */
4230 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
4232 pr_err("error %d\n", rc);
4236 /* read io input data registar */
4237 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_HI__A, &value, 0);
4239 pr_err("error %d\n", rc);
4242 if ((value & 0x0004) != 0) { /* check 2nd bit - 3rd UIO */
4243 uio_data->value = true;
4245 uio_data->value = false;
4248 /*=====================================================================*/
4250 /* DRX_UIO4: IRQN UIO-4 */
4251 if (!ext_attr->has_irqn)
4254 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
4258 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4259 pin_cfg_value |= 0x0110;
4260 /* io_pad_cfg_mode output mode is drive always */
4261 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4263 /* write to io pad configuration register - input mode */
4264 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
4266 pr_err("error %d\n", rc);
4270 /* read io input data registar */
4271 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4273 pr_err("error %d\n", rc);
4276 if ((value & 0x1000) != 0) /* check 12th bit - 4th UIO */
4277 uio_data->value = true;
4279 uio_data->value = false;
4282 /*====================================================================*/
4285 } /* switch ( uio_data->uio ) */
4287 /* Write magic word to disable pdr reg write */
4288 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4290 pr_err("error %d\n", rc);
4299 /*---------------------------------------------------------------------------*/
4300 /* UIO Configuration Functions - end */
4301 /*---------------------------------------------------------------------------*/
4303 /*----------------------------------------------------------------------------*/
4304 /* I2C Bridge Functions - begin */
4305 /*----------------------------------------------------------------------------*/
4307 * \fn int ctrl_i2c_bridge()
4308 * \brief Open or close the I2C switch to tuner.
4309 * \param demod Pointer to demodulator instance.
4310 * \param bridge_closed Pointer to bool indication if bridge is closed not.
4315 ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
4317 struct drxj_hi_cmd hi_cmd;
4320 /* check arguments */
4321 if (bridge_closed == NULL)
4324 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
4325 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
4327 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
4329 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
4331 return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
4334 /*----------------------------------------------------------------------------*/
4335 /* I2C Bridge Functions - end */
4336 /*----------------------------------------------------------------------------*/
4338 /*----------------------------------------------------------------------------*/
4339 /* Smart antenna Functions - begin */
4340 /*----------------------------------------------------------------------------*/
4342 * \fn int smart_ant_init()
4343 * \brief Initialize Smart Antenna.
4344 * \param pointer to struct drx_demod_instance.
4348 static int smart_ant_init(struct drx_demod_instance *demod)
4350 struct drxj_data *ext_attr = NULL;
4351 struct i2c_device_addr *dev_addr = NULL;
4352 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
4356 dev_addr = demod->my_i2c_dev_addr;
4357 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4359 /* Write magic word to enable pdr reg write */
4360 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4362 pr_err("error %d\n", rc);
4365 /* init smart antenna */
4366 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
4368 pr_err("error %d\n", rc);
4371 if (ext_attr->smart_ant_inverted) {
4372 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_COMMAND__A, (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
4374 pr_err("error %d\n", rc);
4378 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_COMMAND__A, (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
4380 pr_err("error %d\n", rc);
4385 /* config SMA_TX pin to smart antenna mode */
4386 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
4388 pr_err("error %d\n", rc);
4391 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
4393 pr_err("error %d\n", rc);
4396 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
4398 pr_err("error %d\n", rc);
4402 /* Write magic word to disable pdr reg write */
4403 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4405 pr_err("error %d\n", rc);
4415 * \fn int ctrl_set_cfg_smart_ant()
4416 * \brief Set Smart Antenna.
4417 * \param pointer to struct drxj_cfg_smart_ant.
4422 ctrl_set_cfg_smart_ant(struct drx_demod_instance *demod, struct drxj_cfg_smart_ant *smart_ant)
4424 struct drxj_data *ext_attr = NULL;
4425 struct i2c_device_addr *dev_addr = NULL;
4429 static bool bit_inverted;
4431 dev_addr = demod->my_i2c_dev_addr;
4432 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4434 /* check arguments */
4435 if (smart_ant == NULL)
4438 if (bit_inverted != ext_attr->smart_ant_inverted
4439 || ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SMA) {
4440 rc = smart_ant_init(demod);
4442 pr_err("error %d\n", rc);
4445 bit_inverted = ext_attr->smart_ant_inverted;
4448 /* Write magic word to enable pdr reg write */
4449 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4451 pr_err("error %d\n", rc);
4455 switch (smart_ant->io) {
4456 case DRXJ_SMT_ANT_OUTPUT:
4457 /* enable Tx if Mode B (input) is supported */
4459 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4460 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
4462 start_time = drxbsp_hst_clock();
4464 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_SA_TX_STATUS__A, &data, 0);
4466 pr_err("error %d\n", rc);
4469 } while ((data & SIO_SA_TX_STATUS_BUSY__M) && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
4471 if (data & SIO_SA_TX_STATUS_BUSY__M)
4474 /* write to smart antenna configuration register */
4475 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA0__A, 0x9200 | ((smart_ant->ctrl_data & 0x0001) << 8) | ((smart_ant->ctrl_data & 0x0002) << 10) | ((smart_ant->ctrl_data & 0x0004) << 12), 0);
4477 pr_err("error %d\n", rc);
4480 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA1__A, 0x4924 | ((smart_ant->ctrl_data & 0x0008) >> 2) | ((smart_ant->ctrl_data & 0x0010)) | ((smart_ant->ctrl_data & 0x0020) << 2) | ((smart_ant->ctrl_data & 0x0040) << 4) | ((smart_ant->ctrl_data & 0x0080) << 6), 0);
4482 pr_err("error %d\n", rc);
4485 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA2__A, 0x2492 | ((smart_ant->ctrl_data & 0x0100) >> 8) | ((smart_ant->ctrl_data & 0x0200) >> 6) | ((smart_ant->ctrl_data & 0x0400) >> 4) | ((smart_ant->ctrl_data & 0x0800) >> 2) | ((smart_ant->ctrl_data & 0x1000)) | ((smart_ant->ctrl_data & 0x2000) << 2), 0);
4487 pr_err("error %d\n", rc);
4490 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA3__A, 0xff8d, 0);
4492 pr_err("error %d\n", rc);
4496 /* trigger the sending */
4497 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_LENGTH__A, 56, 0);
4499 pr_err("error %d\n", rc);
4504 case DRXJ_SMT_ANT_INPUT:
4505 /* disable Tx if Mode B (input) is supported */
4507 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4508 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
4513 /* Write magic word to enable pdr reg write */
4514 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4516 pr_err("error %d\n", rc);
4525 static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
4535 /* Wait until SCU command interface is ready to receive command */
4536 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4538 pr_err("error %d\n", rc);
4541 if (cur_cmd != DRX_SCU_READY)
4544 switch (cmd->parameter_len) {
4546 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
4548 pr_err("error %d\n", rc);
4552 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
4554 pr_err("error %d\n", rc);
4558 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
4560 pr_err("error %d\n", rc);
4564 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
4566 pr_err("error %d\n", rc);
4570 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
4572 pr_err("error %d\n", rc);
4579 /* this number of parameters is not supported */
4582 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
4584 pr_err("error %d\n", rc);
4588 /* Wait until SCU has processed command */
4589 start_time = drxbsp_hst_clock();
4591 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4593 pr_err("error %d\n", rc);
4596 } while (!(cur_cmd == DRX_SCU_READY)
4597 && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
4599 if (cur_cmd != DRX_SCU_READY)
4603 if ((cmd->result_len > 0) && (cmd->result != NULL)) {
4606 switch (cmd->result_len) {
4608 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
4610 pr_err("error %d\n", rc);
4614 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
4616 pr_err("error %d\n", rc);
4620 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
4622 pr_err("error %d\n", rc);
4626 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
4628 pr_err("error %d\n", rc);
4635 /* this number of parameters is not supported */
4639 /* Check if an error was reported by SCU */
4640 err = cmd->result[0];
4642 /* check a few fixed error codes */
4643 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4644 || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4645 || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4646 || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
4650 /* here it is assumed that negative means error, and positive no error */
4664 * \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4665 * \brief Basic access routine for SCU atomic read or write access
4666 * \param dev_addr pointer to i2c dev address
4667 * \param addr destination/source address
4668 * \param datasize size of data buffer in bytes
4669 * \param data pointer to data buffer
4672 * \retval -EIO Timeout, I2C error, illegal bank
4675 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4677 int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 addr, u16 datasize, /* max 30 bytes because the limit of SCU parameter */
4678 u8 *data, bool read_flag)
4680 struct drxjscu_cmd scu_cmd;
4682 u16 set_param_parameters[15];
4685 /* Parameter check */
4686 if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
4689 set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4690 if (read_flag) { /* read */
4691 set_param_parameters[0] = ((~(0x0080)) & datasize);
4692 scu_cmd.parameter_len = 2;
4693 scu_cmd.result_len = datasize / 2 + 2;
4697 set_param_parameters[0] = 0x0080 | datasize;
4698 for (i = 0; i < (datasize / 2); i++) {
4699 set_param_parameters[i + 2] =
4700 (data[2 * i] | (data[(2 * i) + 1] << 8));
4702 scu_cmd.parameter_len = datasize / 2 + 2;
4703 scu_cmd.result_len = 1;
4707 SCU_RAM_COMMAND_STANDARD_TOP |
4708 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4709 scu_cmd.result = cmd_result;
4710 scu_cmd.parameter = set_param_parameters;
4711 rc = scu_command(dev_addr, &scu_cmd);
4713 pr_err("error %d\n", rc);
4719 /* read data from buffer */
4720 for (i = 0; i < (datasize / 2); i++) {
4721 data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4722 data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
4733 /*============================================================================*/
4736 * \fn int DRXJ_DAP_AtomicReadReg16()
4737 * \brief Atomic read of 16 bits words
4740 int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4742 u16 *data, u32 flags)
4751 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
4755 word = (u16) (buf[0] + (buf[1] << 8));
4762 /*============================================================================*/
4764 * \fn int drxj_dap_scu_atomic_write_reg16()
4765 * \brief Atomic read of 16 bits words
4768 int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4770 u16 data, u32 flags)
4775 buf[0] = (u8) (data & 0xff);
4776 buf[1] = (u8) ((data >> 8) & 0xff);
4778 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
4784 ctrl_i2c_write_read(struct drx_demod_instance *demod, struct drxi2c_data *i2c_data)
4789 /* -------------------------------------------------------------------------- */
4791 * \brief Measure result of ADC synchronisation
4792 * \param demod demod instance
4793 * \param count (returned) count
4796 * \retval -EIO Failure: I2C error
4799 static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
4801 struct i2c_device_addr *dev_addr = NULL;
4805 dev_addr = demod->my_i2c_dev_addr;
4807 /* Start measurement */
4808 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
4810 pr_err("error %d\n", rc);
4813 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
4815 pr_err("error %d\n", rc);
4819 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4820 rc = drxbsp_hst_sleep(1);
4822 pr_err("error %d\n", rc);
4827 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE0__A, &data, 0);
4829 pr_err("error %d\n", rc);
4833 *count = *count + 1;
4834 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE1__A, &data, 0);
4836 pr_err("error %d\n", rc);
4840 *count = *count + 1;
4841 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE2__A, &data, 0);
4843 pr_err("error %d\n", rc);
4847 *count = *count + 1;
4855 * \brief Synchronize analog and digital clock domains
4856 * \param demod demod instance
4859 * \retval -EIO Failure: I2C error or failure to synchronize
4861 * An IQM reset will also reset the results of this synchronization.
4862 * After an IQM reset this routine needs to be called again.
4866 static int adc_synchronization(struct drx_demod_instance *demod)
4868 struct i2c_device_addr *dev_addr = NULL;
4872 dev_addr = demod->my_i2c_dev_addr;
4874 rc = adc_sync_measurement(demod, &count);
4876 pr_err("error %d\n", rc);
4881 /* Try sampling on a diffrent edge */
4884 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
4886 pr_err("error %d\n", rc);
4890 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4891 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
4893 pr_err("error %d\n", rc);
4897 rc = adc_sync_measurement(demod, &count);
4899 pr_err("error %d\n", rc);
4904 /* TODO: implement fallback scenarios */
4914 * \brief Configure IQM AF registers
4915 * \param demod instance of demodulator.
4919 static int iqm_set_af(struct drx_demod_instance *demod, bool active)
4921 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
4926 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
4928 pr_err("error %d\n", rc);
4932 data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE));
4934 data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
4935 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
4937 pr_err("error %d\n", rc);
4946 /* -------------------------------------------------------------------------- */
4948 ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg);
4951 * \brief set configuration of pin-safe mode
4952 * \param demod instance of demodulator.
4953 * \param enable boolean; true: activate pin-safe mode, false: de-activate p.s.m.
4957 ctrl_set_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enable)
4959 struct drxj_data *ext_attr = NULL;
4960 struct i2c_device_addr *dev_addr = NULL;
4966 dev_addr = demod->my_i2c_dev_addr;
4967 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4969 /* Write magic word to enable pdr reg write */
4970 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4972 pr_err("error %d\n", rc);
4977 bool bridge_enabled = false;
4979 /* MPEG pins to input */
4980 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4982 pr_err("error %d\n", rc);
4985 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4987 pr_err("error %d\n", rc);
4990 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MCLK_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4992 pr_err("error %d\n", rc);
4995 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4997 pr_err("error %d\n", rc);
5000 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5002 pr_err("error %d\n", rc);
5005 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5007 pr_err("error %d\n", rc);
5010 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5012 pr_err("error %d\n", rc);
5015 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5017 pr_err("error %d\n", rc);
5020 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5022 pr_err("error %d\n", rc);
5025 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5027 pr_err("error %d\n", rc);
5030 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5032 pr_err("error %d\n", rc);
5035 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5037 pr_err("error %d\n", rc);
5041 /* PD_I2C_SDA2 Bridge off, Port2 Inactive
5042 PD_I2C_SCL2 Bridge off, Port2 Inactive */
5043 rc = ctrl_i2c_bridge(demod, &bridge_enabled);
5045 pr_err("error %d\n", rc);
5048 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5050 pr_err("error %d\n", rc);
5053 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5055 pr_err("error %d\n", rc);
5059 /* PD_GPIO Store and set to input
5060 PD_VSYNC Store and set to input
5061 PD_SMA_RX Store and set to input
5062 PD_SMA_TX Store and set to input */
5063 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, &ext_attr->pdr_safe_restore_val_gpio, 0);
5065 pr_err("error %d\n", rc);
5068 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, &ext_attr->pdr_safe_restore_val_v_sync, 0);
5070 pr_err("error %d\n", rc);
5073 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_rx, 0);
5075 pr_err("error %d\n", rc);
5078 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_tx, 0);
5080 pr_err("error %d\n", rc);
5083 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5085 pr_err("error %d\n", rc);
5088 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5090 pr_err("error %d\n", rc);
5093 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5095 pr_err("error %d\n", rc);
5098 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5100 pr_err("error %d\n", rc);
5104 /* PD_RF_AGC Analog DAC outputs, cannot be set to input or tristate!
5105 PD_IF_AGC Analog DAC outputs, cannot be set to input or tristate! */
5106 rc = iqm_set_af(demod, false);
5108 pr_err("error %d\n", rc);
5112 /* PD_CVBS Analog DAC output, standby mode
5113 PD_SIF Analog DAC output, standby mode */
5114 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
5116 pr_err("error %d\n", rc);
5123 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5125 pr_err("error %d\n", rc);
5128 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5130 pr_err("error %d\n", rc);
5133 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_WS_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5135 pr_err("error %d\n", rc);
5139 /* No need to restore MPEG pins;
5140 is done in SetStandard/SetChannel */
5142 /* PD_I2C_SDA2 Port2 active
5143 PD_I2C_SCL2 Port2 active */
5144 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, SIO_PDR_I2C_SDA2_CFG__PRE, 0);
5146 pr_err("error %d\n", rc);
5149 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, SIO_PDR_I2C_SCL2_CFG__PRE, 0);
5151 pr_err("error %d\n", rc);
5158 PD_SMA_TX Restore */
5159 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, ext_attr->pdr_safe_restore_val_gpio, 0);
5161 pr_err("error %d\n", rc);
5164 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, ext_attr->pdr_safe_restore_val_v_sync, 0);
5166 pr_err("error %d\n", rc);
5169 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, ext_attr->pdr_safe_restore_val_sma_rx, 0);
5171 pr_err("error %d\n", rc);
5174 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, ext_attr->pdr_safe_restore_val_sma_tx, 0);
5176 pr_err("error %d\n", rc);
5180 /* PD_RF_AGC, PD_IF_AGC
5181 No need to restore; will be restored in SetStandard/SetChannel */
5184 No need to restore; will be restored in SetStandard/SetChannel */
5186 /* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
5187 Should be restored via DRX_CTRL_SET_AUD */
5190 /* Write magic word to disable pdr reg write */
5191 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
5193 pr_err("error %d\n", rc);
5196 ext_attr->pdr_safe_mode = *enable;
5204 /* -------------------------------------------------------------------------- */
5207 * \brief get configuration of pin-safe mode
5208 * \param demod instance of demodulator.
5209 * \param enable boolean indicating whether pin-safe mode is active
5213 ctrl_get_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enabled)
5215 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
5217 if (enabled == NULL)
5220 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5221 *enabled = ext_attr->pdr_safe_mode;
5227 * \brief Verifies whether microcode can be loaded.
5228 * \param demod Demodulator instance.
5231 static int ctrl_validate_u_code(struct drx_demod_instance *demod)
5233 u32 mc_dev, mc_patch;
5237 * Disallow microcode if:
5238 * - MC has version record AND
5239 * - device ID in version record is not 0 AND
5240 * - product ID in version record's device ID does not
5241 * match DRXJ1 product IDs - 0x393 or 0x394
5243 ver_type = DRX_ATTR_MCRECORD(demod).aux_type;
5244 mc_dev = DRX_ATTR_MCRECORD(demod).mc_dev_type;
5245 mc_patch = DRX_ATTR_MCRECORD(demod).mc_base_version;
5247 if (DRX_ISMCVERTYPE(ver_type)) {
5248 if ((mc_dev != 0) &&
5249 (((mc_dev >> 16) & 0xFFF) != 0x393) &&
5250 (((mc_dev >> 16) & 0xFFF) != 0x394)) {
5251 /* Microcode is marked for another device - error */
5253 } else if (mc_patch != 0) {
5254 /* Patch not allowed because there is no ROM */
5259 /* Everything else: OK */
5263 /*============================================================================*/
5264 /*== END AUXILIARY FUNCTIONS ==*/
5265 /*============================================================================*/
5267 /*============================================================================*/
5268 /*============================================================================*/
5269 /*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5270 /*============================================================================*/
5271 /*============================================================================*/
5273 * \fn int init_agc ()
5274 * \brief Initialize AGC for all standards.
5275 * \param demod instance of demodulator.
5276 * \param channel pointer to channel data.
5279 static int init_agc(struct drx_demod_instance *demod)
5281 struct i2c_device_addr *dev_addr = NULL;
5282 struct drx_common_attr *common_attr = NULL;
5283 struct drxj_data *ext_attr = NULL;
5284 struct drxj_cfg_agc *p_agc_rf_settings = NULL;
5285 struct drxj_cfg_agc *p_agc_if_settings = NULL;
5287 u16 ingain_tgt_max = 0;
5289 u16 sns_sum_max = 0;
5290 u16 clp_sum_max = 0;
5292 u16 ki_innergain_min = 0;
5295 u16 if_iaccu_hi_tgt_min = 0;
5297 u16 agc_ki_dgain = 0;
5299 u16 clp_ctrl_mode = 0;
5303 dev_addr = demod->my_i2c_dev_addr;
5304 common_attr = (struct drx_common_attr *) demod->my_common_attr;
5305 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5307 switch (ext_attr->standard) {
5308 case DRX_STANDARD_8VSB:
5310 clp_dir_to = (u16) (-9);
5312 sns_dir_to = (u16) (-9);
5313 ki_innergain_min = (u16) (-32768);
5316 if_iaccu_hi_tgt_min = 2047;
5318 ingain_tgt_max = 16383;
5320 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
5322 pr_err("error %d\n", rc);
5325 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
5327 pr_err("error %d\n", rc);
5330 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
5332 pr_err("error %d\n", rc);
5335 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
5337 pr_err("error %d\n", rc);
5340 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
5342 pr_err("error %d\n", rc);
5345 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
5347 pr_err("error %d\n", rc);
5350 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
5352 pr_err("error %d\n", rc);
5355 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
5357 pr_err("error %d\n", rc);
5360 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
5362 pr_err("error %d\n", rc);
5365 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
5367 pr_err("error %d\n", rc);
5370 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
5372 pr_err("error %d\n", rc);
5375 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
5377 pr_err("error %d\n", rc);
5380 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
5382 pr_err("error %d\n", rc);
5385 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
5386 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
5388 #ifndef DRXJ_VSB_ONLY
5389 case DRX_STANDARD_ITU_A:
5390 case DRX_STANDARD_ITU_C:
5391 case DRX_STANDARD_ITU_B:
5392 ingain_tgt_max = 5119;
5394 clp_dir_to = (u16) (-5);
5396 sns_dir_to = (u16) (-3);
5397 ki_innergain_min = 0;
5399 if_iaccu_hi_tgt_min = 2047;
5403 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
5405 pr_err("error %d\n", rc);
5408 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
5410 pr_err("error %d\n", rc);
5413 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
5415 pr_err("error %d\n", rc);
5418 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
5420 pr_err("error %d\n", rc);
5423 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
5425 pr_err("error %d\n", rc);
5428 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
5430 pr_err("error %d\n", rc);
5433 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
5435 pr_err("error %d\n", rc);
5438 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
5440 pr_err("error %d\n", rc);
5443 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
5445 pr_err("error %d\n", rc);
5448 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
5450 pr_err("error %d\n", rc);
5453 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
5454 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
5455 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5457 pr_err("error %d\n", rc);
5461 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
5463 pr_err("error %d\n", rc);
5467 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
5469 pr_err("error %d\n", rc);
5474 #ifndef DRXJ_DIGITAL_ONLY
5475 case DRX_STANDARD_FM:
5478 ki_innergain_min = (u16) (-32768);
5479 if_iaccu_hi_tgt_min = 2047;
5483 clp_dir_to = (u16) (-9);
5484 sns_dir_to = (u16) (-9);
5485 ingain_tgt_max = 9000;
5487 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5488 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5489 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5491 pr_err("error %d\n", rc);
5495 case DRX_STANDARD_NTSC:
5496 case DRX_STANDARD_PAL_SECAM_BG:
5497 case DRX_STANDARD_PAL_SECAM_DK:
5498 case DRX_STANDARD_PAL_SECAM_I:
5501 ki_innergain_min = (u16) (-32768);
5502 if_iaccu_hi_tgt_min = 2047;
5506 clp_dir_to = (u16) (-9);
5507 ingain_tgt_max = 9000;
5508 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5509 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5510 sns_dir_to = (u16) (-9);
5512 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5514 pr_err("error %d\n", rc);
5518 case DRX_STANDARD_PAL_SECAM_L:
5519 case DRX_STANDARD_PAL_SECAM_LP:
5522 ki_innergain_min = (u16) (-32768);
5523 if_iaccu_hi_tgt_min = 2047;
5527 clp_dir_to = (u16) (-9);
5528 sns_dir_to = (u16) (-9);
5529 ingain_tgt_max = 9000;
5531 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5532 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5533 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5535 pr_err("error %d\n", rc);
5544 /* for new AGC interface */
5545 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
5547 pr_err("error %d\n", rc);
5550 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
5552 pr_err("error %d\n", rc);
5554 } /* Gain fed from inner to outer AGC */
5555 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
5557 pr_err("error %d\n", rc);
5560 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
5562 pr_err("error %d\n", rc);
5565 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
5567 pr_err("error %d\n", rc);
5569 } /* set to p_agc_settings->top before */
5570 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
5572 pr_err("error %d\n", rc);
5575 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
5577 pr_err("error %d\n", rc);
5580 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
5582 pr_err("error %d\n", rc);
5585 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
5587 pr_err("error %d\n", rc);
5590 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
5592 pr_err("error %d\n", rc);
5595 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
5597 pr_err("error %d\n", rc);
5600 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
5602 pr_err("error %d\n", rc);
5605 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
5607 pr_err("error %d\n", rc);
5610 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
5612 pr_err("error %d\n", rc);
5615 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
5617 pr_err("error %d\n", rc);
5620 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
5622 pr_err("error %d\n", rc);
5625 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
5627 pr_err("error %d\n", rc);
5630 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
5632 pr_err("error %d\n", rc);
5635 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
5637 pr_err("error %d\n", rc);
5640 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
5642 pr_err("error %d\n", rc);
5645 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
5647 pr_err("error %d\n", rc);
5650 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
5652 pr_err("error %d\n", rc);
5655 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
5657 pr_err("error %d\n", rc);
5660 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
5662 pr_err("error %d\n", rc);
5665 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
5667 pr_err("error %d\n", rc);
5670 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
5672 pr_err("error %d\n", rc);
5676 agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
5677 if (common_attr->tuner_rf_agc_pol == true)
5678 agc_rf = 0x87ff - agc_rf;
5681 if (common_attr->tuner_if_agc_pol == true)
5682 agc_rf = 0x87ff - agc_rf;
5684 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
5686 pr_err("error %d\n", rc);
5689 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
5691 pr_err("error %d\n", rc);
5695 /* Set/restore Ki DGAIN factor */
5696 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5698 pr_err("error %d\n", rc);
5701 data &= ~SCU_RAM_AGC_KI_DGAIN__M;
5702 data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
5703 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5705 pr_err("error %d\n", rc);
5715 * \fn int set_frequency ()
5716 * \brief Set frequency shift.
5717 * \param demod instance of demodulator.
5718 * \param channel pointer to channel data.
5719 * \param tuner_freq_offset residual frequency from tuner.
5723 set_frequency(struct drx_demod_instance *demod,
5724 struct drx_channel *channel, s32 tuner_freq_offset)
5726 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5727 struct drxj_data *ext_attr = demod->my_ext_attr;
5729 s32 sampling_frequency = 0;
5730 s32 frequency_shift = 0;
5731 s32 if_freq_actual = 0;
5732 s32 rf_freq_residual = -1 * tuner_freq_offset;
5734 s32 intermediate_freq = 0;
5735 u32 iqm_fs_rate_ofs = 0;
5736 bool adc_flip = true;
5737 bool select_pos_image = false;
5740 bool image_to_select = true;
5741 s32 fm_frequency_shift = 0;
5743 rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
5744 tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
5746 Program frequency shifter
5747 No need to account for mirroring on RF
5749 switch (ext_attr->standard) {
5750 case DRX_STANDARD_ITU_A: /* fallthrough */
5751 case DRX_STANDARD_ITU_C: /* fallthrough */
5752 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
5753 case DRX_STANDARD_8VSB:
5754 select_pos_image = true;
5756 case DRX_STANDARD_FM:
5757 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
5758 Sound carrier is already 3Mhz above centre frequency due
5759 to tuner setting so now add an extra shift of 1MHz... */
5760 fm_frequency_shift = 1000;
5761 case DRX_STANDARD_ITU_B: /* fallthrough */
5762 case DRX_STANDARD_NTSC: /* fallthrough */
5763 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
5764 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
5765 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
5766 case DRX_STANDARD_PAL_SECAM_L:
5767 select_pos_image = false;
5772 intermediate_freq = demod->my_common_attr->intermediate_freq;
5773 sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
5775 if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
5777 if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
5778 if (if_freq_actual > sampling_frequency / 2) {
5780 adc_freq = sampling_frequency - if_freq_actual;
5783 /* adc doesn't mirror */
5784 adc_freq = if_freq_actual;
5788 frequency_shift = adc_freq;
5790 (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
5791 iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
5793 if (image_to_select)
5794 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
5796 /* Program frequency shifter with tuner offset compensation */
5797 /* frequency_shift += tuner_freq_offset; TODO */
5798 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
5800 pr_err("error %d\n", rc);
5803 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
5804 ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
5812 * \fn int get_sig_strength()
5813 * \brief Retrieve signal strength for VSB and QAM.
5814 * \param demod Pointer to demod instance
5815 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
5817 * \retval 0 sig_strength contains valid data.
5818 * \retval -EINVAL sig_strength is NULL.
5819 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5821 #define DRXJ_AGC_TOP 0x2800
5822 #define DRXJ_AGC_SNS 0x1600
5823 #define DRXJ_RFAGC_MAX 0x3fff
5824 #define DRXJ_RFAGC_MIN 0x800
5826 static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
5828 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5837 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
5839 pr_err("error %d\n", rc);
5842 if_gain &= IQM_AF_AGC_IF__M;
5843 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
5845 pr_err("error %d\n", rc);
5848 rf_gain &= IQM_AF_AGC_RF__M;
5850 if_agc_sns = DRXJ_AGC_SNS;
5851 if_agc_top = DRXJ_AGC_TOP;
5852 rf_agc_max = DRXJ_RFAGC_MAX;
5853 rf_agc_min = DRXJ_RFAGC_MIN;
5855 if (if_gain > if_agc_top) {
5856 if (rf_gain > rf_agc_max)
5857 *sig_strength = 100;
5858 else if (rf_gain > rf_agc_min) {
5859 if (rf_agc_max == rf_agc_min) {
5860 pr_err("error: rf_agc_max == rf_agc_min\n");
5864 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
5868 } else if (if_gain > if_agc_sns) {
5869 if (if_agc_top == if_agc_sns) {
5870 pr_err("error: if_agc_top == if_agc_sns\n");
5874 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
5877 pr_err("error: if_agc_sns is zero!\n");
5880 *sig_strength = (20 * if_gain / if_agc_sns);
5889 * \fn int get_acc_pkt_err()
5890 * \brief Retrieve signal strength for VSB and QAM.
5891 * \param demod Pointer to demod instance
5892 * \param packet_err Pointer to packet error
5894 * \retval 0 sig_strength contains valid data.
5895 * \retval -EINVAL sig_strength is NULL.
5896 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5898 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5899 static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
5903 static u16 last_pkt_err;
5905 struct drxj_data *ext_attr = NULL;
5906 struct i2c_device_addr *dev_addr = NULL;
5908 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5909 dev_addr = demod->my_i2c_dev_addr;
5911 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
5913 pr_err("error %d\n", rc);
5916 if (ext_attr->reset_pkt_err_acc) {
5917 last_pkt_err = data;
5919 ext_attr->reset_pkt_err_acc = false;
5922 if (data < last_pkt_err) {
5923 pkt_err += 0xffff - last_pkt_err;
5926 pkt_err += (data - last_pkt_err);
5928 *packet_err = pkt_err;
5929 last_pkt_err = data;
5938 * \fn int ResetAccPktErr()
5939 * \brief Reset Accumulating packet error count.
5940 * \param demod Pointer to demod instance
5943 * \retval -EIO Erroneous data.
5945 static int ctrl_set_cfg_reset_pkt_err(struct drx_demod_instance *demod)
5947 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5948 struct drxj_data *ext_attr = NULL;
5950 u16 packet_error = 0;
5952 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5953 ext_attr->reset_pkt_err_acc = true;
5954 /* call to reset counter */
5955 rc = get_acc_pkt_err(demod, &packet_error);
5957 pr_err("error %d\n", rc);
5968 * \fn static short get_str_freq_offset()
5969 * \brief Get symbol rate offset in QAM & 8VSB mode
5970 * \return Error code
5972 static int get_str_freq_offset(struct drx_demod_instance *demod, s32 *str_freq)
5975 u32 symbol_frequency_ratio = 0;
5976 u32 symbol_nom_frequency_ratio = 0;
5978 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5979 struct drxj_data *ext_attr = demod->my_ext_attr;
5981 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &symbol_frequency_ratio, 0);
5983 pr_err("error %d\n", rc);
5986 symbol_nom_frequency_ratio = ext_attr->iqm_rc_rate_ofs;
5988 if (symbol_frequency_ratio > symbol_nom_frequency_ratio)
5991 frac_times1e6((symbol_frequency_ratio -
5992 symbol_nom_frequency_ratio),
5993 (symbol_frequency_ratio + (1 << 23)));
5996 frac_times1e6((symbol_nom_frequency_ratio -
5997 symbol_frequency_ratio),
5998 (symbol_frequency_ratio + (1 << 23)));
6006 * \fn static short get_ctl_freq_offset
6007 * \brief Get the value of ctl_freq in QAM & ATSC mode
6008 * \return Error code
6010 static int get_ctl_freq_offset(struct drx_demod_instance *demod, s32 *ctl_freq)
6012 s32 sampling_frequency = 0;
6013 s32 current_frequency = 0;
6014 s32 nominal_frequency = 0;
6015 s32 carrier_frequency_shift = 0;
6019 struct drxj_data *ext_attr = NULL;
6020 struct drx_common_attr *common_attr = NULL;
6021 struct i2c_device_addr *dev_addr = NULL;
6024 dev_addr = demod->my_i2c_dev_addr;
6025 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6026 common_attr = (struct drx_common_attr *) demod->my_common_attr;
6028 sampling_frequency = common_attr->sys_clock_freq / 3;
6030 /* both registers are sign extended */
6031 nominal_frequency = ext_attr->iqm_fs_rate_ofs;
6032 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, (u32 *)¤t_frequency, 0);
6034 pr_err("error %d\n", rc);
6038 if (ext_attr->pos_image) {
6039 /* negative image */
6040 carrier_frequency_shift = nominal_frequency - current_frequency;
6042 /* positive image */
6043 carrier_frequency_shift = current_frequency - nominal_frequency;
6046 /* carrier Frequency Shift In Hz */
6047 if (carrier_frequency_shift < 0) {
6049 carrier_frequency_shift *= sign;
6052 /* *ctl_freq = carrier_frequency_shift * 50.625e6 / (1 << 28); */
6053 mult32(carrier_frequency_shift, sampling_frequency, &data64hi, &data64lo);
6055 (s32) ((((data64lo >> 28) & 0xf) | (data64hi << 4)) * sign);
6062 /*============================================================================*/
6065 * \fn int set_agc_rf ()
6066 * \brief Configure RF AGC
6067 * \param demod instance of demodulator.
6068 * \param agc_settings AGC configuration structure
6072 set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
6074 struct i2c_device_addr *dev_addr = NULL;
6075 struct drxj_data *ext_attr = NULL;
6076 struct drxj_cfg_agc *p_agc_settings = NULL;
6077 struct drx_common_attr *common_attr = NULL;
6079 drx_write_reg16func_t scu_wr16 = NULL;
6080 drx_read_reg16func_t scu_rr16 = NULL;
6082 common_attr = (struct drx_common_attr *) demod->my_common_attr;
6083 dev_addr = demod->my_i2c_dev_addr;
6084 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6087 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
6088 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
6090 scu_rr16 = DRXJ_DAP.read_reg16func;
6091 scu_wr16 = DRXJ_DAP.write_reg16func;
6094 /* Configure AGC only if standard is currently active */
6095 if ((ext_attr->standard == agc_settings->standard) ||
6096 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6097 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6098 (DRXJ_ISATVSTD(ext_attr->standard) &&
6099 DRXJ_ISATVSTD(agc_settings->standard))) {
6102 switch (agc_settings->ctrl_mode) {
6103 case DRX_AGC_CTRL_AUTO:
6105 /* Enable RF AGC DAC */
6106 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6108 pr_err("error %d\n", rc);
6111 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
6112 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6114 pr_err("error %d\n", rc);
6118 /* Enable SCU RF AGC loop */
6119 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6121 pr_err("error %d\n", rc);
6124 data &= ~SCU_RAM_AGC_KI_RF__M;
6125 if (ext_attr->standard == DRX_STANDARD_8VSB)
6126 data |= (2 << SCU_RAM_AGC_KI_RF__B);
6127 else if (DRXJ_ISQAMSTD(ext_attr->standard))
6128 data |= (5 << SCU_RAM_AGC_KI_RF__B);
6130 data |= (4 << SCU_RAM_AGC_KI_RF__B);
6132 if (common_attr->tuner_rf_agc_pol)
6133 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
6135 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
6136 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6138 pr_err("error %d\n", rc);
6142 /* Set speed ( using complementary reduction value ) */
6143 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
6145 pr_err("error %d\n", rc);
6148 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
6149 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_RAGC_RED__B) & SCU_RAM_AGC_KI_RED_RAGC_RED__M) | data, 0);
6151 pr_err("error %d\n", rc);
6155 if (agc_settings->standard == DRX_STANDARD_8VSB)
6156 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
6157 else if (DRXJ_ISQAMSTD(agc_settings->standard))
6158 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
6159 else if (DRXJ_ISATVSTD(agc_settings->standard))
6160 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
6164 /* Set TOP, only if IF-AGC is in AUTO mode */
6165 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
6166 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
6168 pr_err("error %d\n", rc);
6171 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
6173 pr_err("error %d\n", rc);
6178 /* Cut-Off current */
6179 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
6181 pr_err("error %d\n", rc);
6185 case DRX_AGC_CTRL_USER:
6187 /* Enable RF AGC DAC */
6188 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6190 pr_err("error %d\n", rc);
6193 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
6194 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6196 pr_err("error %d\n", rc);
6200 /* Disable SCU RF AGC loop */
6201 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6203 pr_err("error %d\n", rc);
6206 data &= ~SCU_RAM_AGC_KI_RF__M;
6207 if (common_attr->tuner_rf_agc_pol)
6208 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
6210 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
6211 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6213 pr_err("error %d\n", rc);
6217 /* Write value to output pin */
6218 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
6220 pr_err("error %d\n", rc);
6224 case DRX_AGC_CTRL_OFF:
6226 /* Disable RF AGC DAC */
6227 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6229 pr_err("error %d\n", rc);
6232 data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
6233 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6235 pr_err("error %d\n", rc);
6239 /* Disable SCU RF AGC loop */
6240 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6242 pr_err("error %d\n", rc);
6245 data &= ~SCU_RAM_AGC_KI_RF__M;
6246 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6248 pr_err("error %d\n", rc);
6254 } /* switch ( agcsettings->ctrl_mode ) */
6257 /* Store rf agc settings */
6258 switch (agc_settings->standard) {
6259 case DRX_STANDARD_8VSB:
6260 ext_attr->vsb_rf_agc_cfg = *agc_settings;
6262 #ifndef DRXJ_VSB_ONLY
6263 case DRX_STANDARD_ITU_A:
6264 case DRX_STANDARD_ITU_B:
6265 case DRX_STANDARD_ITU_C:
6266 ext_attr->qam_rf_agc_cfg = *agc_settings;
6269 #ifndef DRXJ_DIGITAL_ONLY
6270 case DRX_STANDARD_PAL_SECAM_BG:
6271 case DRX_STANDARD_PAL_SECAM_DK:
6272 case DRX_STANDARD_PAL_SECAM_I:
6273 case DRX_STANDARD_PAL_SECAM_L:
6274 case DRX_STANDARD_PAL_SECAM_LP:
6275 case DRX_STANDARD_NTSC:
6276 case DRX_STANDARD_FM:
6277 ext_attr->atv_rf_agc_cfg = *agc_settings;
6290 * \fn int get_agc_rf ()
6291 * \brief get configuration of RF AGC
6292 * \param demod instance of demodulator.
6293 * \param agc_settings AGC configuration structure
6297 get_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6299 struct i2c_device_addr *dev_addr = NULL;
6300 struct drxj_data *ext_attr = NULL;
6301 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6304 dev_addr = demod->my_i2c_dev_addr;
6305 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6307 /* Return stored AGC settings */
6308 standard = agc_settings->standard;
6309 switch (agc_settings->standard) {
6310 case DRX_STANDARD_8VSB:
6311 *agc_settings = ext_attr->vsb_rf_agc_cfg;
6313 #ifndef DRXJ_VSB_ONLY
6314 case DRX_STANDARD_ITU_A:
6315 case DRX_STANDARD_ITU_B:
6316 case DRX_STANDARD_ITU_C:
6317 *agc_settings = ext_attr->qam_rf_agc_cfg;
6320 #ifndef DRXJ_DIGITAL_ONLY
6321 case DRX_STANDARD_PAL_SECAM_BG:
6322 case DRX_STANDARD_PAL_SECAM_DK:
6323 case DRX_STANDARD_PAL_SECAM_I:
6324 case DRX_STANDARD_PAL_SECAM_L:
6325 case DRX_STANDARD_PAL_SECAM_LP:
6326 case DRX_STANDARD_NTSC:
6327 case DRX_STANDARD_FM:
6328 *agc_settings = ext_attr->atv_rf_agc_cfg;
6334 agc_settings->standard = standard;
6336 /* Get AGC output only if standard is currently active. */
6337 if ((ext_attr->standard == agc_settings->standard) ||
6338 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6339 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6340 (DRXJ_ISATVSTD(ext_attr->standard) &&
6341 DRXJ_ISATVSTD(agc_settings->standard))) {
6342 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, &(agc_settings->output_level), 0);
6344 pr_err("error %d\n", rc);
6355 * \fn int set_agc_if ()
6356 * \brief Configure If AGC
6357 * \param demod instance of demodulator.
6358 * \param agc_settings AGC configuration structure
6362 set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
6364 struct i2c_device_addr *dev_addr = NULL;
6365 struct drxj_data *ext_attr = NULL;
6366 struct drxj_cfg_agc *p_agc_settings = NULL;
6367 struct drx_common_attr *common_attr = NULL;
6368 drx_write_reg16func_t scu_wr16 = NULL;
6369 drx_read_reg16func_t scu_rr16 = NULL;
6372 common_attr = (struct drx_common_attr *) demod->my_common_attr;
6373 dev_addr = demod->my_i2c_dev_addr;
6374 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6377 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
6378 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
6380 scu_rr16 = DRXJ_DAP.read_reg16func;
6381 scu_wr16 = DRXJ_DAP.write_reg16func;
6384 /* Configure AGC only if standard is currently active */
6385 if ((ext_attr->standard == agc_settings->standard) ||
6386 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6387 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6388 (DRXJ_ISATVSTD(ext_attr->standard) &&
6389 DRXJ_ISATVSTD(agc_settings->standard))) {
6392 switch (agc_settings->ctrl_mode) {
6393 case DRX_AGC_CTRL_AUTO:
6394 /* Enable IF AGC DAC */
6395 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6397 pr_err("error %d\n", rc);
6400 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
6401 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6403 pr_err("error %d\n", rc);
6407 /* Enable SCU IF AGC loop */
6408 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6410 pr_err("error %d\n", rc);
6413 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6414 data &= ~SCU_RAM_AGC_KI_IF__M;
6415 if (ext_attr->standard == DRX_STANDARD_8VSB)
6416 data |= (3 << SCU_RAM_AGC_KI_IF__B);
6417 else if (DRXJ_ISQAMSTD(ext_attr->standard))
6418 data |= (6 << SCU_RAM_AGC_KI_IF__B);
6420 data |= (5 << SCU_RAM_AGC_KI_IF__B);
6422 if (common_attr->tuner_if_agc_pol)
6423 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
6425 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
6426 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6428 pr_err("error %d\n", rc);
6432 /* Set speed (using complementary reduction value) */
6433 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
6435 pr_err("error %d\n", rc);
6438 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
6439 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_IAGC_RED__B) & SCU_RAM_AGC_KI_RED_IAGC_RED__M) | data, 0);
6441 pr_err("error %d\n", rc);
6445 if (agc_settings->standard == DRX_STANDARD_8VSB)
6446 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
6447 else if (DRXJ_ISQAMSTD(agc_settings->standard))
6448 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
6449 else if (DRXJ_ISATVSTD(agc_settings->standard))
6450 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
6455 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
6456 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
6458 pr_err("error %d\n", rc);
6461 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
6463 pr_err("error %d\n", rc);
6467 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
6469 pr_err("error %d\n", rc);
6472 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
6474 pr_err("error %d\n", rc);
6480 case DRX_AGC_CTRL_USER:
6482 /* Enable IF AGC DAC */
6483 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6485 pr_err("error %d\n", rc);
6488 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
6489 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6491 pr_err("error %d\n", rc);
6495 /* Disable SCU IF AGC loop */
6496 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6498 pr_err("error %d\n", rc);
6501 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6502 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6503 if (common_attr->tuner_if_agc_pol)
6504 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
6506 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
6507 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6509 pr_err("error %d\n", rc);
6513 /* Write value to output pin */
6514 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
6516 pr_err("error %d\n", rc);
6521 case DRX_AGC_CTRL_OFF:
6523 /* Disable If AGC DAC */
6524 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6526 pr_err("error %d\n", rc);
6529 data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
6530 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6532 pr_err("error %d\n", rc);
6536 /* Disable SCU IF AGC loop */
6537 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6539 pr_err("error %d\n", rc);
6542 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6543 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6544 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6546 pr_err("error %d\n", rc);
6552 } /* switch ( agcsettings->ctrl_mode ) */
6554 /* always set the top to support configurations without if-loop */
6555 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
6557 pr_err("error %d\n", rc);
6562 /* Store if agc settings */
6563 switch (agc_settings->standard) {
6564 case DRX_STANDARD_8VSB:
6565 ext_attr->vsb_if_agc_cfg = *agc_settings;
6567 #ifndef DRXJ_VSB_ONLY
6568 case DRX_STANDARD_ITU_A:
6569 case DRX_STANDARD_ITU_B:
6570 case DRX_STANDARD_ITU_C:
6571 ext_attr->qam_if_agc_cfg = *agc_settings;
6574 #ifndef DRXJ_DIGITAL_ONLY
6575 case DRX_STANDARD_PAL_SECAM_BG:
6576 case DRX_STANDARD_PAL_SECAM_DK:
6577 case DRX_STANDARD_PAL_SECAM_I:
6578 case DRX_STANDARD_PAL_SECAM_L:
6579 case DRX_STANDARD_PAL_SECAM_LP:
6580 case DRX_STANDARD_NTSC:
6581 case DRX_STANDARD_FM:
6582 ext_attr->atv_if_agc_cfg = *agc_settings;
6595 * \fn int get_agc_if ()
6596 * \brief get configuration of If AGC
6597 * \param demod instance of demodulator.
6598 * \param agc_settings AGC configuration structure
6602 get_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6604 struct i2c_device_addr *dev_addr = NULL;
6605 struct drxj_data *ext_attr = NULL;
6606 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6609 dev_addr = demod->my_i2c_dev_addr;
6610 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6612 /* Return stored ATV AGC settings */
6613 standard = agc_settings->standard;
6614 switch (agc_settings->standard) {
6615 case DRX_STANDARD_8VSB:
6616 *agc_settings = ext_attr->vsb_if_agc_cfg;
6618 #ifndef DRXJ_VSB_ONLY
6619 case DRX_STANDARD_ITU_A:
6620 case DRX_STANDARD_ITU_B:
6621 case DRX_STANDARD_ITU_C:
6622 *agc_settings = ext_attr->qam_if_agc_cfg;
6625 #ifndef DRXJ_DIGITAL_ONLY
6626 case DRX_STANDARD_PAL_SECAM_BG:
6627 case DRX_STANDARD_PAL_SECAM_DK:
6628 case DRX_STANDARD_PAL_SECAM_I:
6629 case DRX_STANDARD_PAL_SECAM_L:
6630 case DRX_STANDARD_PAL_SECAM_LP:
6631 case DRX_STANDARD_NTSC:
6632 case DRX_STANDARD_FM:
6633 *agc_settings = ext_attr->atv_if_agc_cfg;
6639 agc_settings->standard = standard;
6641 /* Get AGC output only if standard is currently active */
6642 if ((ext_attr->standard == agc_settings->standard) ||
6643 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6644 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6645 (DRXJ_ISATVSTD(ext_attr->standard) &&
6646 DRXJ_ISATVSTD(agc_settings->standard))) {
6647 /* read output level */
6648 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, &(agc_settings->output_level), 0);
6650 pr_err("error %d\n", rc);
6661 * \fn int set_iqm_af ()
6662 * \brief Configure IQM AF registers
6663 * \param demod instance of demodulator.
6667 static int set_iqm_af(struct drx_demod_instance *demod, bool active)
6670 struct i2c_device_addr *dev_addr = NULL;
6673 dev_addr = demod->my_i2c_dev_addr;
6676 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6678 pr_err("error %d\n", rc);
6682 data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE));
6684 data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
6685 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6687 pr_err("error %d\n", rc);
6696 /*============================================================================*/
6697 /*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
6698 /*============================================================================*/
6700 /*============================================================================*/
6701 /*============================================================================*/
6702 /*== 8VSB DATAPATH FUNCTIONS ==*/
6703 /*============================================================================*/
6704 /*============================================================================*/
6707 * \fn int power_down_vsb ()
6708 * \brief Powr down QAM related blocks.
6709 * \param demod instance of demodulator.
6710 * \param channel pointer to channel data.
6713 static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
6715 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6716 struct drxjscu_cmd cmd_scu = { /* command */ 0,
6717 /* parameter_len */ 0,
6719 /* *parameter */ NULL,
6722 struct drx_cfg_mpeg_output cfg_mpeg_output;
6728 reset of FEC and VSB HW
6730 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
6731 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6732 cmd_scu.parameter_len = 0;
6733 cmd_scu.result_len = 1;
6734 cmd_scu.parameter = NULL;
6735 cmd_scu.result = &cmd_result;
6736 rc = scu_command(dev_addr, &cmd_scu);
6738 pr_err("error %d\n", rc);
6742 /* stop all comm_exec */
6743 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
6745 pr_err("error %d\n", rc);
6748 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
6750 pr_err("error %d\n", rc);
6754 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
6756 pr_err("error %d\n", rc);
6759 rc = set_iqm_af(demod, false);
6761 pr_err("error %d\n", rc);
6765 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
6767 pr_err("error %d\n", rc);
6770 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
6772 pr_err("error %d\n", rc);
6775 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
6777 pr_err("error %d\n", rc);
6780 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
6782 pr_err("error %d\n", rc);
6785 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
6787 pr_err("error %d\n", rc);
6792 cfg_mpeg_output.enable_mpeg_output = false;
6793 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6795 pr_err("error %d\n", rc);
6805 * \fn int set_vsb_leak_n_gain ()
6806 * \brief Set ATSC demod.
6807 * \param demod instance of demodulator.
6810 static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
6812 struct i2c_device_addr *dev_addr = NULL;
6815 const u8 vsb_ffe_leak_gain_ram0[] = {
6816 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
6817 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
6818 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
6819 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
6820 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
6821 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
6822 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
6823 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
6824 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
6825 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
6826 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
6827 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
6828 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
6829 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
6830 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
6831 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
6832 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
6833 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
6834 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
6835 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
6836 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
6837 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
6838 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
6839 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
6840 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
6841 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
6842 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
6843 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
6844 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
6845 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
6846 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
6847 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
6848 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
6849 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
6850 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
6851 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
6852 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
6853 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
6854 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
6855 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
6856 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
6857 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
6858 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
6859 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
6860 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
6861 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
6862 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
6863 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
6864 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
6865 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
6866 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
6867 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
6868 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
6869 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
6870 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
6871 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
6872 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
6873 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
6874 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
6875 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
6876 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
6877 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
6878 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
6879 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
6880 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
6881 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
6882 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
6883 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
6884 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
6885 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
6886 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
6887 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
6888 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
6889 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
6890 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
6891 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
6892 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
6893 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
6894 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
6895 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
6896 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
6897 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
6898 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
6899 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
6900 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
6901 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
6902 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
6903 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
6904 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
6905 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
6906 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
6907 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
6908 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
6909 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
6910 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
6911 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
6912 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
6913 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
6914 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
6915 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
6916 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
6917 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
6918 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
6919 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
6920 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
6921 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
6922 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
6923 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
6924 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
6925 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
6926 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
6927 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
6928 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
6929 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
6930 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
6931 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
6932 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
6933 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
6934 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
6935 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
6936 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
6937 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
6938 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
6939 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
6940 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
6941 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
6942 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
6943 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
6946 const u8 vsb_ffe_leak_gain_ram1[] = {
6947 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
6948 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
6949 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
6950 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
6951 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
6952 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
6953 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
6954 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
6955 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
6956 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
6957 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
6958 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
6959 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
6960 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
6961 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
6962 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
6963 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
6964 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
6965 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
6966 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
6967 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
6968 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
6969 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
6970 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
6971 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
6972 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
6973 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
6974 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
6975 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
6976 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
6977 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
6978 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
6979 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
6980 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
6981 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
6982 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
6983 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
6984 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
6985 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
6986 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
6987 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
6988 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
6989 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
6990 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
6991 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
6992 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
6993 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
6994 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
6995 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
6996 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
6997 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
6998 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
6999 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
7000 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
7003 dev_addr = demod->my_i2c_dev_addr;
7004 rc = DRXJ_DAP.write_block_func(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, sizeof(vsb_ffe_leak_gain_ram0), ((u8 *)vsb_ffe_leak_gain_ram0), 0);
7006 pr_err("error %d\n", rc);
7009 rc = DRXJ_DAP.write_block_func(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, sizeof(vsb_ffe_leak_gain_ram1), ((u8 *)vsb_ffe_leak_gain_ram1), 0);
7011 pr_err("error %d\n", rc);
7022 * \brief Set 8VSB demod.
7023 * \param demod instance of demodulator.
7027 static int set_vsb(struct drx_demod_instance *demod)
7029 struct i2c_device_addr *dev_addr = NULL;
7031 struct drx_common_attr *common_attr = NULL;
7032 struct drxjscu_cmd cmd_scu;
7033 struct drxj_data *ext_attr = NULL;
7036 const u8 vsb_taps_re[] = {
7037 DRXJ_16TO8(-2), /* re0 */
7038 DRXJ_16TO8(4), /* re1 */
7039 DRXJ_16TO8(1), /* re2 */
7040 DRXJ_16TO8(-4), /* re3 */
7041 DRXJ_16TO8(1), /* re4 */
7042 DRXJ_16TO8(4), /* re5 */
7043 DRXJ_16TO8(-3), /* re6 */
7044 DRXJ_16TO8(-3), /* re7 */
7045 DRXJ_16TO8(6), /* re8 */
7046 DRXJ_16TO8(1), /* re9 */
7047 DRXJ_16TO8(-9), /* re10 */
7048 DRXJ_16TO8(3), /* re11 */
7049 DRXJ_16TO8(12), /* re12 */
7050 DRXJ_16TO8(-9), /* re13 */
7051 DRXJ_16TO8(-15), /* re14 */
7052 DRXJ_16TO8(17), /* re15 */
7053 DRXJ_16TO8(19), /* re16 */
7054 DRXJ_16TO8(-29), /* re17 */
7055 DRXJ_16TO8(-22), /* re18 */
7056 DRXJ_16TO8(45), /* re19 */
7057 DRXJ_16TO8(25), /* re20 */
7058 DRXJ_16TO8(-70), /* re21 */
7059 DRXJ_16TO8(-28), /* re22 */
7060 DRXJ_16TO8(111), /* re23 */
7061 DRXJ_16TO8(30), /* re24 */
7062 DRXJ_16TO8(-201), /* re25 */
7063 DRXJ_16TO8(-31), /* re26 */
7064 DRXJ_16TO8(629) /* re27 */
7067 dev_addr = demod->my_i2c_dev_addr;
7068 common_attr = (struct drx_common_attr *) demod->my_common_attr;
7069 ext_attr = (struct drxj_data *) demod->my_ext_attr;
7071 /* stop all comm_exec */
7072 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
7074 pr_err("error %d\n", rc);
7077 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
7079 pr_err("error %d\n", rc);
7082 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
7084 pr_err("error %d\n", rc);
7087 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
7089 pr_err("error %d\n", rc);
7092 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
7094 pr_err("error %d\n", rc);
7097 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
7099 pr_err("error %d\n", rc);
7102 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
7104 pr_err("error %d\n", rc);
7108 /* reset demodulator */
7109 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7110 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
7111 cmd_scu.parameter_len = 0;
7112 cmd_scu.result_len = 1;
7113 cmd_scu.parameter = NULL;
7114 cmd_scu.result = &cmd_result;
7115 rc = scu_command(dev_addr, &cmd_scu);
7117 pr_err("error %d\n", rc);
7121 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
7123 pr_err("error %d\n", rc);
7126 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
7128 pr_err("error %d\n", rc);
7131 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
7133 pr_err("error %d\n", rc);
7136 ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
7137 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
7139 pr_err("error %d\n", rc);
7142 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
7144 pr_err("error %d\n", rc);
7147 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
7149 pr_err("error %d\n", rc);
7153 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
7155 pr_err("error %d\n", rc);
7158 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, 28, 0);
7160 pr_err("error %d\n", rc);
7163 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
7165 pr_err("error %d\n", rc);
7168 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
7170 pr_err("error %d\n", rc);
7173 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
7175 pr_err("error %d\n", rc);
7178 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
7180 pr_err("error %d\n", rc);
7183 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE__A, 1393, 0);
7185 pr_err("error %d\n", rc);
7188 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
7190 pr_err("error %d\n", rc);
7193 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
7195 pr_err("error %d\n", rc);
7199 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
7201 pr_err("error %d\n", rc);
7204 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
7206 pr_err("error %d\n", rc);
7210 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
7212 pr_err("error %d\n", rc);
7214 } /* set higher threshold */
7215 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
7217 pr_err("error %d\n", rc);
7219 } /* burst detection on */
7220 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
7222 pr_err("error %d\n", rc);
7224 } /* drop thresholds by 1 dB */
7225 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
7227 pr_err("error %d\n", rc);
7229 } /* drop thresholds by 2 dB */
7230 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
7232 pr_err("error %d\n", rc);
7235 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
7237 pr_err("error %d\n", rc);
7241 /* Initialize the FEC Subsystem */
7242 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
7244 pr_err("error %d\n", rc);
7248 u16 fec_oc_snc_mode = 0;
7249 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
7251 pr_err("error %d\n", rc);
7254 /* output data even when not locked */
7255 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
7257 pr_err("error %d\n", rc);
7263 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
7265 pr_err("error %d\n", rc);
7268 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
7270 pr_err("error %d\n", rc);
7273 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
7275 pr_err("error %d\n", rc);
7278 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
7280 pr_err("error %d\n", rc);
7283 /* no transparent, no A&C framing; parity is set in mpegoutput */
7285 u16 fec_oc_reg_mode = 0;
7286 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
7288 pr_err("error %d\n", rc);
7291 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode & (~(FEC_OC_MODE_TRANSPARENT__M | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)), 0);
7293 pr_err("error %d\n", rc);
7298 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
7300 pr_err("error %d\n", rc);
7302 } /* timeout counter for restarting */
7303 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
7305 pr_err("error %d\n", rc);
7308 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MODE__A, 0, 0);
7310 pr_err("error %d\n", rc);
7312 } /* bypass disabled */
7313 /* initialize RS packet error measurement parameters */
7314 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
7316 pr_err("error %d\n", rc);
7319 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
7321 pr_err("error %d\n", rc);
7325 /* init measurement period of MER/SER */
7326 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
7328 pr_err("error %d\n", rc);
7331 rc = DRXJ_DAP.write_reg32func(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
7333 pr_err("error %d\n", rc);
7336 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
7338 pr_err("error %d\n", rc);
7341 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
7343 pr_err("error %d\n", rc);
7347 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
7349 pr_err("error %d\n", rc);
7352 /* B-Input to ADC, PGA+filter in standby */
7353 if (!ext_attr->has_lna) {
7354 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
7356 pr_err("error %d\n", rc);
7361 /* turn on IQMAF. It has to be in front of setAgc**() */
7362 rc = set_iqm_af(demod, true);
7364 pr_err("error %d\n", rc);
7367 rc = adc_synchronization(demod);
7369 pr_err("error %d\n", rc);
7373 rc = init_agc(demod);
7375 pr_err("error %d\n", rc);
7378 rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
7380 pr_err("error %d\n", rc);
7383 rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
7385 pr_err("error %d\n", rc);
7389 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
7391 struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
7393 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
7394 rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
7396 pr_err("error %d\n", rc);
7400 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
7402 pr_err("error %d\n", rc);
7406 /* Mpeg output has to be in front of FEC active */
7407 rc = set_mpegtei_handling(demod);
7409 pr_err("error %d\n", rc);
7412 rc = bit_reverse_mpeg_output(demod);
7414 pr_err("error %d\n", rc);
7417 rc = set_mpeg_start_width(demod);
7419 pr_err("error %d\n", rc);
7423 /* TODO: move to set_standard after hardware reset value problem is solved */
7424 /* Configure initial MPEG output */
7425 struct drx_cfg_mpeg_output cfg_mpeg_output;
7426 cfg_mpeg_output.enable_mpeg_output = true;
7427 cfg_mpeg_output.insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
7428 cfg_mpeg_output.enable_parallel =
7429 common_attr->mpeg_cfg.enable_parallel;
7430 cfg_mpeg_output.invert_data = common_attr->mpeg_cfg.invert_data;
7431 cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
7432 cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
7433 cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
7434 cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
7435 cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
7436 cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
7437 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
7439 pr_err("error %d\n", rc);
7444 /* TBD: what parameters should be set */
7445 cmd_param = 0x00; /* Default mode AGC on, etc */
7446 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7447 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
7448 cmd_scu.parameter_len = 1;
7449 cmd_scu.result_len = 1;
7450 cmd_scu.parameter = &cmd_param;
7451 cmd_scu.result = &cmd_result;
7452 rc = scu_command(dev_addr, &cmd_scu);
7454 pr_err("error %d\n", rc);
7458 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
7460 pr_err("error %d\n", rc);
7463 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
7465 pr_err("error %d\n", rc);
7468 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
7470 pr_err("error %d\n", rc);
7473 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
7475 pr_err("error %d\n", rc);
7478 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
7480 pr_err("error %d\n", rc);
7483 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
7485 pr_err("error %d\n", rc);
7488 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
7490 pr_err("error %d\n", rc);
7493 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
7495 pr_err("error %d\n", rc);
7499 /* start demodulator */
7500 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7501 | SCU_RAM_COMMAND_CMD_DEMOD_START;
7502 cmd_scu.parameter_len = 0;
7503 cmd_scu.result_len = 1;
7504 cmd_scu.parameter = NULL;
7505 cmd_scu.result = &cmd_result;
7506 rc = scu_command(dev_addr, &cmd_scu);
7508 pr_err("error %d\n", rc);
7512 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
7514 pr_err("error %d\n", rc);
7517 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
7519 pr_err("error %d\n", rc);
7522 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
7524 pr_err("error %d\n", rc);
7534 * \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
7535 * \brief Get the values of packet error in 8VSB mode
7536 * \return Error code
7538 static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *pck_errs)
7544 u16 packet_errors_mant = 0;
7545 u16 packet_errors_exp = 0;
7547 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
7549 pr_err("error %d\n", rc);
7552 packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
7553 packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
7554 >> FEC_RS_NR_FAILURES_EXP__B;
7555 period = FEC_RS_MEASUREMENT_PERIOD;
7556 prescale = FEC_RS_MEASUREMENT_PRESCALE;
7557 /* packet error rate = (error packet number) per second */
7558 /* 77.3 us is time for per packet */
7559 if (period * prescale == 0) {
7560 pr_err("error: period and/or prescale is zero!\n");
7564 (u16) frac_times1e6(packet_errors_mant * (1 << packet_errors_exp),
7565 (period * prescale * 77));
7573 * \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
7574 * \brief Get the values of ber in VSB mode
7575 * \return Error code
7577 static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7583 u16 bit_errors_mant = 0;
7584 u16 bit_errors_exp = 0;
7586 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
7588 pr_err("error %d\n", rc);
7591 period = FEC_RS_MEASUREMENT_PERIOD;
7592 prescale = FEC_RS_MEASUREMENT_PRESCALE;
7594 bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
7595 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
7596 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
7598 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
7601 if (period * prescale == 0) {
7602 pr_err("error: period and/or prescale is zero!\n");
7606 frac_times1e6(bit_errors_mant <<
7608 2) ? (bit_errors_exp - 3) : bit_errors_exp),
7609 period * prescale * 207 *
7610 ((bit_errors_exp > 2) ? 1 : 8));
7619 * \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7620 * \brief Get the values of ber in VSB mode
7621 * \return Error code
7623 static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7628 rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
7630 pr_err("error %d\n", rc);
7635 VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT);
7643 * \fn static short get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ber)
7644 * \brief Get the values of ber in VSB mode
7645 * \return Error code
7647 static int get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ser)
7653 u16 symb_errors_mant = 0;
7654 u16 symb_errors_exp = 0;
7656 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &data, 0);
7658 pr_err("error %d\n", rc);
7661 period = FEC_RS_MEASUREMENT_PERIOD;
7662 prescale = FEC_RS_MEASUREMENT_PRESCALE;
7664 symb_errors_mant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M;
7665 symb_errors_exp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M)
7666 >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B;
7668 if (period * prescale == 0) {
7669 pr_err("error: period and/or prescale is zero!\n");
7672 *ser = (u32) frac_times1e6((symb_errors_mant << symb_errors_exp) * 1000,
7673 (period * prescale * 77318));
7681 * \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7682 * \brief Get the values of MER
7683 * \return Error code
7685 static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7690 rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
7692 pr_err("error %d\n", rc);
7696 (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
7703 /*============================================================================*/
7705 * \fn int ctrl_get_vsb_constel()
7706 * \brief Retreive a VSB constellation point via I2C.
7707 * \param demod Pointer to demodulator instance.
7708 * \param complex_nr Pointer to the structure in which to store the
7709 constellation point.
7713 ctrl_get_vsb_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
7715 struct i2c_device_addr *dev_addr = NULL;
7717 /**< device address */
7718 u16 vsb_top_comm_mb = 0; /**< VSB SL MB configuration */
7719 u16 vsb_top_comm_mb_init = 0; /**< VSB SL MB intial configuration */
7720 u16 re = 0; /**< constellation Re part */
7723 /* read device info */
7724 dev_addr = demod->my_i2c_dev_addr;
7727 /* Monitor bus grabbing is an open external interface issue */
7728 /* Needs to be checked when external interface PG is updated */
7730 /* Configure MB (Monitor bus) */
7731 rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_COMM_MB__A, &vsb_top_comm_mb_init, 0);
7733 pr_err("error %d\n", rc);
7736 /* set observe flag & MB mux */
7737 vsb_top_comm_mb = (vsb_top_comm_mb_init |
7738 VSB_TOP_COMM_MB_OBS_OBS_ON |
7739 VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2);
7740 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb, 0);
7742 pr_err("error %d\n", rc);
7746 /* Enable MB grabber in the FEC OC */
7747 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M, 0);
7749 pr_err("error %d\n", rc);
7753 /* Disable MB grabber in the FEC OC */
7754 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, 0x0, 0);
7756 pr_err("error %d\n", rc);
7761 rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_OCR_GRAB_RD1__A, &data, 0);
7763 pr_err("error %d\n", rc);
7766 re = (u16) (((data >> 10) & 0x300) | ((data >> 2) & 0xff));
7769 complex_nr->re = re;
7772 /* Restore MB (Monitor bus) */
7773 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb_init, 0);
7775 pr_err("error %d\n", rc);
7784 /*============================================================================*/
7785 /*== END 8VSB DATAPATH FUNCTIONS ==*/
7786 /*============================================================================*/
7788 /*============================================================================*/
7789 /*============================================================================*/
7790 /*== QAM DATAPATH FUNCTIONS ==*/
7791 /*============================================================================*/
7792 /*============================================================================*/
7795 * \fn int power_down_qam ()
7796 * \brief Powr down QAM related blocks.
7797 * \param demod instance of demodulator.
7798 * \param channel pointer to channel data.
7801 static int power_down_qam(struct drx_demod_instance *demod, bool primary)
7803 struct drxjscu_cmd cmd_scu = { /* command */ 0,
7804 /* parameter_len */ 0,
7806 /* *parameter */ NULL,
7810 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7811 struct drx_cfg_mpeg_output cfg_mpeg_output;
7816 resets IQM, QAM and FEC HW blocks
7818 /* stop all comm_exec */
7819 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
7821 pr_err("error %d\n", rc);
7824 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
7826 pr_err("error %d\n", rc);
7830 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
7831 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
7832 cmd_scu.parameter_len = 0;
7833 cmd_scu.result_len = 1;
7834 cmd_scu.parameter = NULL;
7835 cmd_scu.result = &cmd_result;
7836 rc = scu_command(dev_addr, &cmd_scu);
7838 pr_err("error %d\n", rc);
7843 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
7845 pr_err("error %d\n", rc);
7848 rc = set_iqm_af(demod, false);
7850 pr_err("error %d\n", rc);
7854 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
7856 pr_err("error %d\n", rc);
7859 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
7861 pr_err("error %d\n", rc);
7864 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
7866 pr_err("error %d\n", rc);
7869 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
7871 pr_err("error %d\n", rc);
7874 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
7876 pr_err("error %d\n", rc);
7881 cfg_mpeg_output.enable_mpeg_output = false;
7882 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
7884 pr_err("error %d\n", rc);
7893 /*============================================================================*/
7896 * \fn int set_qam_measurement ()
7897 * \brief Setup of the QAM Measuremnt intervals for signal quality
7898 * \param demod instance of demod.
7899 * \param constellation current constellation.
7903 * Take into account that for certain settings the errorcounters can overflow.
7904 * The implementation does not check this.
7906 * TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
7907 * constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
7911 #ifndef DRXJ_VSB_ONLY
7913 set_qam_measurement(struct drx_demod_instance *demod,
7914 enum drx_modulation constellation, u32 symbol_rate)
7916 struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */
7917 struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specif data */
7919 u32 fec_bits_desired = 0; /* BER accounting period */
7920 u16 fec_rs_plen = 0; /* defines RS BER measurement period */
7921 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
7922 u32 fec_rs_period = 0; /* Value for corresponding I2C register */
7923 u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
7924 u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
7925 u32 qam_vd_period = 0; /* Value for corresponding I2C register */
7926 u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
7927 u16 fec_vd_plen = 0; /* no of trellis symbols: VD SER measur period */
7928 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
7930 dev_addr = demod->my_i2c_dev_addr;
7931 ext_attr = (struct drxj_data *) demod->my_ext_attr;
7933 fec_bits_desired = ext_attr->fec_bits_desired;
7934 fec_rs_prescale = ext_attr->fec_rs_prescale;
7936 switch (constellation) {
7937 case DRX_CONSTELLATION_QAM16:
7938 fec_bits_desired = 4 * symbol_rate;
7940 case DRX_CONSTELLATION_QAM32:
7941 fec_bits_desired = 5 * symbol_rate;
7943 case DRX_CONSTELLATION_QAM64:
7944 fec_bits_desired = 6 * symbol_rate;
7946 case DRX_CONSTELLATION_QAM128:
7947 fec_bits_desired = 7 * symbol_rate;
7949 case DRX_CONSTELLATION_QAM256:
7950 fec_bits_desired = 8 * symbol_rate;
7956 /* Parameters for Reed-Solomon Decoder */
7957 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
7958 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
7959 /* result is within 32 bit arithmetic -> */
7960 /* no need for mult or frac functions */
7962 /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
7963 switch (ext_attr->standard) {
7964 case DRX_STANDARD_ITU_A:
7965 case DRX_STANDARD_ITU_C:
7966 fec_rs_plen = 204 * 8;
7968 case DRX_STANDARD_ITU_B:
7969 fec_rs_plen = 128 * 7;
7975 ext_attr->fec_rs_plen = fec_rs_plen; /* for getSigQual */
7976 fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage */
7977 if (fec_rs_bit_cnt == 0) {
7978 pr_err("error: fec_rs_bit_cnt is zero!\n");
7981 fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1; /* ceil */
7982 if (ext_attr->standard != DRX_STANDARD_ITU_B)
7983 fec_oc_snc_fail_period = fec_rs_period;
7985 /* limit to max 16 bit value (I2C register width) if needed */
7986 if (fec_rs_period > 0xFFFF)
7987 fec_rs_period = 0xFFFF;
7989 /* write corresponding registers */
7990 switch (ext_attr->standard) {
7991 case DRX_STANDARD_ITU_A:
7992 case DRX_STANDARD_ITU_C:
7994 case DRX_STANDARD_ITU_B:
7995 switch (constellation) {
7996 case DRX_CONSTELLATION_QAM64:
7997 fec_rs_period = 31581;
7998 fec_oc_snc_fail_period = 17932;
8000 case DRX_CONSTELLATION_QAM256:
8001 fec_rs_period = 45446;
8002 fec_oc_snc_fail_period = 25805;
8012 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
8014 pr_err("error %d\n", rc);
8017 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
8019 pr_err("error %d\n", rc);
8022 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
8024 pr_err("error %d\n", rc);
8027 ext_attr->fec_rs_period = (u16) fec_rs_period;
8028 ext_attr->fec_rs_prescale = fec_rs_prescale;
8029 rc = DRXJ_DAP.write_reg32func(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
8031 pr_err("error %d\n", rc);
8034 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
8036 pr_err("error %d\n", rc);
8039 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
8041 pr_err("error %d\n", rc);
8045 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8046 /* Parameters for Viterbi Decoder */
8047 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
8048 /* (qamvd_prescale*plen*(qam_constellation+1))) */
8049 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
8050 /* result is within 32 bit arithmetic -> */
8051 /* no need for mult or frac functions */
8053 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
8054 fec_vd_plen = ext_attr->fec_vd_plen;
8055 qam_vd_prescale = ext_attr->qam_vd_prescale;
8056 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
8058 switch (constellation) {
8059 case DRX_CONSTELLATION_QAM64:
8060 /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
8062 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
8063 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
8065 case DRX_CONSTELLATION_QAM256:
8066 /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
8068 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
8069 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
8074 if (qam_vd_period == 0) {
8075 pr_err("error: qam_vd_period is zero!\n");
8078 qam_vd_period = fec_bits_desired / qam_vd_period;
8079 /* limit to max 16 bit value (I2C register width) if needed */
8080 if (qam_vd_period > 0xFFFF)
8081 qam_vd_period = 0xFFFF;
8083 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
8084 qam_vd_bit_cnt *= qam_vd_period;
8086 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
8088 pr_err("error %d\n", rc);
8091 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
8093 pr_err("error %d\n", rc);
8096 ext_attr->qam_vd_period = (u16) qam_vd_period;
8097 ext_attr->qam_vd_prescale = qam_vd_prescale;
8105 /*============================================================================*/
8108 * \fn int set_qam16 ()
8109 * \brief QAM16 specific setup
8110 * \param demod instance of demod.
8113 static int set_qam16(struct drx_demod_instance *demod)
8115 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8117 const u8 qam_dq_qual_fun[] = {
8118 DRXJ_16TO8(2), /* fun0 */
8119 DRXJ_16TO8(2), /* fun1 */
8120 DRXJ_16TO8(2), /* fun2 */
8121 DRXJ_16TO8(2), /* fun3 */
8122 DRXJ_16TO8(3), /* fun4 */
8123 DRXJ_16TO8(3), /* fun5 */
8125 const u8 qam_eq_cma_rad[] = {
8126 DRXJ_16TO8(13517), /* RAD0 */
8127 DRXJ_16TO8(13517), /* RAD1 */
8128 DRXJ_16TO8(13517), /* RAD2 */
8129 DRXJ_16TO8(13517), /* RAD3 */
8130 DRXJ_16TO8(13517), /* RAD4 */
8131 DRXJ_16TO8(13517), /* RAD5 */
8134 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8136 pr_err("error %d\n", rc);
8139 rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
8141 pr_err("error %d\n", rc);
8145 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
8147 pr_err("error %d\n", rc);
8150 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
8152 pr_err("error %d\n", rc);
8155 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
8157 pr_err("error %d\n", rc);
8160 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
8162 pr_err("error %d\n", rc);
8165 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
8167 pr_err("error %d\n", rc);
8170 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
8172 pr_err("error %d\n", rc);
8176 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8178 pr_err("error %d\n", rc);
8181 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
8183 pr_err("error %d\n", rc);
8186 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8188 pr_err("error %d\n", rc);
8192 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
8194 pr_err("error %d\n", rc);
8197 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
8199 pr_err("error %d\n", rc);
8202 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
8204 pr_err("error %d\n", rc);
8207 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
8209 pr_err("error %d\n", rc);
8212 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
8214 pr_err("error %d\n", rc);
8217 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
8219 pr_err("error %d\n", rc);
8222 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
8224 pr_err("error %d\n", rc);
8228 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8230 pr_err("error %d\n", rc);
8233 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8235 pr_err("error %d\n", rc);
8238 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8240 pr_err("error %d\n", rc);
8243 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
8245 pr_err("error %d\n", rc);
8248 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8250 pr_err("error %d\n", rc);
8253 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8255 pr_err("error %d\n", rc);
8258 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
8260 pr_err("error %d\n", rc);
8263 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
8265 pr_err("error %d\n", rc);
8268 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8270 pr_err("error %d\n", rc);
8273 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8275 pr_err("error %d\n", rc);
8278 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8280 pr_err("error %d\n", rc);
8283 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8285 pr_err("error %d\n", rc);
8288 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8290 pr_err("error %d\n", rc);
8293 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8295 pr_err("error %d\n", rc);
8298 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8300 pr_err("error %d\n", rc);
8303 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8305 pr_err("error %d\n", rc);
8308 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
8310 pr_err("error %d\n", rc);
8313 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8315 pr_err("error %d\n", rc);
8318 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8320 pr_err("error %d\n", rc);
8323 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
8325 pr_err("error %d\n", rc);
8329 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
8331 pr_err("error %d\n", rc);
8340 /*============================================================================*/
8343 * \fn int set_qam32 ()
8344 * \brief QAM32 specific setup
8345 * \param demod instance of demod.
8348 static int set_qam32(struct drx_demod_instance *demod)
8350 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8352 const u8 qam_dq_qual_fun[] = {
8353 DRXJ_16TO8(3), /* fun0 */
8354 DRXJ_16TO8(3), /* fun1 */
8355 DRXJ_16TO8(3), /* fun2 */
8356 DRXJ_16TO8(3), /* fun3 */
8357 DRXJ_16TO8(4), /* fun4 */
8358 DRXJ_16TO8(4), /* fun5 */
8360 const u8 qam_eq_cma_rad[] = {
8361 DRXJ_16TO8(6707), /* RAD0 */
8362 DRXJ_16TO8(6707), /* RAD1 */
8363 DRXJ_16TO8(6707), /* RAD2 */
8364 DRXJ_16TO8(6707), /* RAD3 */
8365 DRXJ_16TO8(6707), /* RAD4 */
8366 DRXJ_16TO8(6707), /* RAD5 */
8369 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8371 pr_err("error %d\n", rc);
8374 rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
8376 pr_err("error %d\n", rc);
8380 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
8382 pr_err("error %d\n", rc);
8385 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
8387 pr_err("error %d\n", rc);
8390 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8392 pr_err("error %d\n", rc);
8395 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
8397 pr_err("error %d\n", rc);
8400 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8402 pr_err("error %d\n", rc);
8405 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
8407 pr_err("error %d\n", rc);
8411 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8413 pr_err("error %d\n", rc);
8416 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
8418 pr_err("error %d\n", rc);
8421 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8423 pr_err("error %d\n", rc);
8427 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
8429 pr_err("error %d\n", rc);
8432 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
8434 pr_err("error %d\n", rc);
8437 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
8439 pr_err("error %d\n", rc);
8442 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
8444 pr_err("error %d\n", rc);
8447 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
8449 pr_err("error %d\n", rc);
8452 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
8454 pr_err("error %d\n", rc);
8457 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
8459 pr_err("error %d\n", rc);
8463 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8465 pr_err("error %d\n", rc);
8468 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8470 pr_err("error %d\n", rc);
8473 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8475 pr_err("error %d\n", rc);
8478 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
8480 pr_err("error %d\n", rc);
8483 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8485 pr_err("error %d\n", rc);
8488 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8490 pr_err("error %d\n", rc);
8493 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
8495 pr_err("error %d\n", rc);
8498 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
8500 pr_err("error %d\n", rc);
8503 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8505 pr_err("error %d\n", rc);
8508 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8510 pr_err("error %d\n", rc);
8513 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8515 pr_err("error %d\n", rc);
8518 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8520 pr_err("error %d\n", rc);
8523 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8525 pr_err("error %d\n", rc);
8528 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8530 pr_err("error %d\n", rc);
8533 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8535 pr_err("error %d\n", rc);
8538 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8540 pr_err("error %d\n", rc);
8543 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
8545 pr_err("error %d\n", rc);
8548 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8550 pr_err("error %d\n", rc);
8553 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8555 pr_err("error %d\n", rc);
8558 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
8560 pr_err("error %d\n", rc);
8564 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
8566 pr_err("error %d\n", rc);
8575 /*============================================================================*/
8578 * \fn int set_qam64 ()
8579 * \brief QAM64 specific setup
8580 * \param demod instance of demod.
8583 static int set_qam64(struct drx_demod_instance *demod)
8585 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8587 const u8 qam_dq_qual_fun[] = { /* this is hw reset value. no necessary to re-write */
8588 DRXJ_16TO8(4), /* fun0 */
8589 DRXJ_16TO8(4), /* fun1 */
8590 DRXJ_16TO8(4), /* fun2 */
8591 DRXJ_16TO8(4), /* fun3 */
8592 DRXJ_16TO8(6), /* fun4 */
8593 DRXJ_16TO8(6), /* fun5 */
8595 const u8 qam_eq_cma_rad[] = {
8596 DRXJ_16TO8(13336), /* RAD0 */
8597 DRXJ_16TO8(12618), /* RAD1 */
8598 DRXJ_16TO8(11988), /* RAD2 */
8599 DRXJ_16TO8(13809), /* RAD3 */
8600 DRXJ_16TO8(13809), /* RAD4 */
8601 DRXJ_16TO8(15609), /* RAD5 */
8604 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8606 pr_err("error %d\n", rc);
8609 rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
8611 pr_err("error %d\n", rc);
8615 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
8617 pr_err("error %d\n", rc);
8620 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
8622 pr_err("error %d\n", rc);
8625 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8627 pr_err("error %d\n", rc);
8630 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
8632 pr_err("error %d\n", rc);
8635 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8637 pr_err("error %d\n", rc);
8640 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
8642 pr_err("error %d\n", rc);
8646 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8648 pr_err("error %d\n", rc);
8651 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
8653 pr_err("error %d\n", rc);
8656 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8658 pr_err("error %d\n", rc);
8662 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
8664 pr_err("error %d\n", rc);
8667 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
8669 pr_err("error %d\n", rc);
8672 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
8674 pr_err("error %d\n", rc);
8677 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
8679 pr_err("error %d\n", rc);
8682 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
8684 pr_err("error %d\n", rc);
8687 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
8689 pr_err("error %d\n", rc);
8692 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
8694 pr_err("error %d\n", rc);
8698 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8700 pr_err("error %d\n", rc);
8703 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8705 pr_err("error %d\n", rc);
8708 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8710 pr_err("error %d\n", rc);
8713 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
8715 pr_err("error %d\n", rc);
8718 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8720 pr_err("error %d\n", rc);
8723 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8725 pr_err("error %d\n", rc);
8728 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
8730 pr_err("error %d\n", rc);
8733 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
8735 pr_err("error %d\n", rc);
8738 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8740 pr_err("error %d\n", rc);
8743 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8745 pr_err("error %d\n", rc);
8748 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8750 pr_err("error %d\n", rc);
8753 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8755 pr_err("error %d\n", rc);
8758 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8760 pr_err("error %d\n", rc);
8763 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8765 pr_err("error %d\n", rc);
8768 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8770 pr_err("error %d\n", rc);
8773 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
8775 pr_err("error %d\n", rc);
8778 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
8780 pr_err("error %d\n", rc);
8783 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8785 pr_err("error %d\n", rc);
8788 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8790 pr_err("error %d\n", rc);
8793 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
8795 pr_err("error %d\n", rc);
8799 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
8801 pr_err("error %d\n", rc);
8810 /*============================================================================*/
8813 * \fn int set_qam128 ()
8814 * \brief QAM128 specific setup
8815 * \param demod: instance of demod.
8818 static int set_qam128(struct drx_demod_instance *demod)
8820 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8822 const u8 qam_dq_qual_fun[] = {
8823 DRXJ_16TO8(6), /* fun0 */
8824 DRXJ_16TO8(6), /* fun1 */
8825 DRXJ_16TO8(6), /* fun2 */
8826 DRXJ_16TO8(6), /* fun3 */
8827 DRXJ_16TO8(9), /* fun4 */
8828 DRXJ_16TO8(9), /* fun5 */
8830 const u8 qam_eq_cma_rad[] = {
8831 DRXJ_16TO8(6164), /* RAD0 */
8832 DRXJ_16TO8(6598), /* RAD1 */
8833 DRXJ_16TO8(6394), /* RAD2 */
8834 DRXJ_16TO8(6409), /* RAD3 */
8835 DRXJ_16TO8(6656), /* RAD4 */
8836 DRXJ_16TO8(7238), /* RAD5 */
8839 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8841 pr_err("error %d\n", rc);
8844 rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
8846 pr_err("error %d\n", rc);
8850 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
8852 pr_err("error %d\n", rc);
8855 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
8857 pr_err("error %d\n", rc);
8860 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8862 pr_err("error %d\n", rc);
8865 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
8867 pr_err("error %d\n", rc);
8870 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8872 pr_err("error %d\n", rc);
8875 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
8877 pr_err("error %d\n", rc);
8881 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8883 pr_err("error %d\n", rc);
8886 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
8888 pr_err("error %d\n", rc);
8891 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8893 pr_err("error %d\n", rc);
8897 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
8899 pr_err("error %d\n", rc);
8902 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
8904 pr_err("error %d\n", rc);
8907 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
8909 pr_err("error %d\n", rc);
8912 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
8914 pr_err("error %d\n", rc);
8917 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
8919 pr_err("error %d\n", rc);
8922 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
8924 pr_err("error %d\n", rc);
8927 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
8929 pr_err("error %d\n", rc);
8933 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8935 pr_err("error %d\n", rc);
8938 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8940 pr_err("error %d\n", rc);
8943 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8945 pr_err("error %d\n", rc);
8948 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
8950 pr_err("error %d\n", rc);
8953 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8955 pr_err("error %d\n", rc);
8958 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8960 pr_err("error %d\n", rc);
8963 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
8965 pr_err("error %d\n", rc);
8968 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
8970 pr_err("error %d\n", rc);
8973 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8975 pr_err("error %d\n", rc);
8978 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8980 pr_err("error %d\n", rc);
8983 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8985 pr_err("error %d\n", rc);
8988 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8990 pr_err("error %d\n", rc);
8993 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8995 pr_err("error %d\n", rc);
8998 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9000 pr_err("error %d\n", rc);
9003 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9005 pr_err("error %d\n", rc);
9008 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
9010 pr_err("error %d\n", rc);
9013 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
9015 pr_err("error %d\n", rc);
9018 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9020 pr_err("error %d\n", rc);
9023 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9025 pr_err("error %d\n", rc);
9028 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9030 pr_err("error %d\n", rc);
9034 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
9036 pr_err("error %d\n", rc);
9045 /*============================================================================*/
9048 * \fn int set_qam256 ()
9049 * \brief QAM256 specific setup
9050 * \param demod: instance of demod.
9053 static int set_qam256(struct drx_demod_instance *demod)
9055 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9057 const u8 qam_dq_qual_fun[] = {
9058 DRXJ_16TO8(8), /* fun0 */
9059 DRXJ_16TO8(8), /* fun1 */
9060 DRXJ_16TO8(8), /* fun2 */
9061 DRXJ_16TO8(8), /* fun3 */
9062 DRXJ_16TO8(12), /* fun4 */
9063 DRXJ_16TO8(12), /* fun5 */
9065 const u8 qam_eq_cma_rad[] = {
9066 DRXJ_16TO8(12345), /* RAD0 */
9067 DRXJ_16TO8(12345), /* RAD1 */
9068 DRXJ_16TO8(13626), /* RAD2 */
9069 DRXJ_16TO8(12931), /* RAD3 */
9070 DRXJ_16TO8(14719), /* RAD4 */
9071 DRXJ_16TO8(15356), /* RAD5 */
9074 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9076 pr_err("error %d\n", rc);
9079 rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
9081 pr_err("error %d\n", rc);
9085 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
9087 pr_err("error %d\n", rc);
9090 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9092 pr_err("error %d\n", rc);
9095 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9097 pr_err("error %d\n", rc);
9100 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
9102 pr_err("error %d\n", rc);
9105 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9107 pr_err("error %d\n", rc);
9110 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
9112 pr_err("error %d\n", rc);
9116 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9118 pr_err("error %d\n", rc);
9121 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
9123 pr_err("error %d\n", rc);
9126 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9128 pr_err("error %d\n", rc);
9132 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
9134 pr_err("error %d\n", rc);
9137 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
9139 pr_err("error %d\n", rc);
9142 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
9144 pr_err("error %d\n", rc);
9147 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
9149 pr_err("error %d\n", rc);
9152 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
9154 pr_err("error %d\n", rc);
9157 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
9159 pr_err("error %d\n", rc);
9162 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
9164 pr_err("error %d\n", rc);
9168 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9170 pr_err("error %d\n", rc);
9173 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9175 pr_err("error %d\n", rc);
9178 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9180 pr_err("error %d\n", rc);
9183 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
9185 pr_err("error %d\n", rc);
9188 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9190 pr_err("error %d\n", rc);
9193 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9195 pr_err("error %d\n", rc);
9198 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
9200 pr_err("error %d\n", rc);
9203 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9205 pr_err("error %d\n", rc);
9208 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9210 pr_err("error %d\n", rc);
9213 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9215 pr_err("error %d\n", rc);
9218 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9220 pr_err("error %d\n", rc);
9223 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9225 pr_err("error %d\n", rc);
9228 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9230 pr_err("error %d\n", rc);
9233 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9235 pr_err("error %d\n", rc);
9238 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9240 pr_err("error %d\n", rc);
9243 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
9245 pr_err("error %d\n", rc);
9248 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
9250 pr_err("error %d\n", rc);
9253 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9255 pr_err("error %d\n", rc);
9258 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9260 pr_err("error %d\n", rc);
9263 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9265 pr_err("error %d\n", rc);
9269 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
9271 pr_err("error %d\n", rc);
9280 /*============================================================================*/
9281 #define QAM_SET_OP_ALL 0x1
9282 #define QAM_SET_OP_CONSTELLATION 0x2
9283 #define QAM_SET_OP_SPECTRUM 0X4
9286 * \fn int set_qam ()
9287 * \brief Set QAM demod.
9288 * \param demod: instance of demod.
9289 * \param channel: pointer to channel data.
9293 set_qam(struct drx_demod_instance *demod,
9294 struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
9296 struct i2c_device_addr *dev_addr = NULL;
9297 struct drxj_data *ext_attr = NULL;
9298 struct drx_common_attr *common_attr = NULL;
9300 u32 adc_frequency = 0;
9301 u32 iqm_rc_rate = 0;
9303 u16 lc_symbol_freq = 0;
9304 u16 iqm_rc_stretch = 0;
9305 u16 set_env_parameters = 0;
9306 u16 set_param_parameters[2] = { 0 };
9307 struct drxjscu_cmd cmd_scu = { /* command */ 0,
9308 /* parameter_len */ 0,
9310 /* parameter */ NULL,
9313 const u8 qam_a_taps[] = {
9314 DRXJ_16TO8(-1), /* re0 */
9315 DRXJ_16TO8(1), /* re1 */
9316 DRXJ_16TO8(1), /* re2 */
9317 DRXJ_16TO8(-1), /* re3 */
9318 DRXJ_16TO8(-1), /* re4 */
9319 DRXJ_16TO8(2), /* re5 */
9320 DRXJ_16TO8(1), /* re6 */
9321 DRXJ_16TO8(-2), /* re7 */
9322 DRXJ_16TO8(0), /* re8 */
9323 DRXJ_16TO8(3), /* re9 */
9324 DRXJ_16TO8(-1), /* re10 */
9325 DRXJ_16TO8(-3), /* re11 */
9326 DRXJ_16TO8(4), /* re12 */
9327 DRXJ_16TO8(1), /* re13 */
9328 DRXJ_16TO8(-8), /* re14 */
9329 DRXJ_16TO8(4), /* re15 */
9330 DRXJ_16TO8(13), /* re16 */
9331 DRXJ_16TO8(-13), /* re17 */
9332 DRXJ_16TO8(-19), /* re18 */
9333 DRXJ_16TO8(28), /* re19 */
9334 DRXJ_16TO8(25), /* re20 */
9335 DRXJ_16TO8(-53), /* re21 */
9336 DRXJ_16TO8(-31), /* re22 */
9337 DRXJ_16TO8(96), /* re23 */
9338 DRXJ_16TO8(37), /* re24 */
9339 DRXJ_16TO8(-190), /* re25 */
9340 DRXJ_16TO8(-40), /* re26 */
9341 DRXJ_16TO8(619) /* re27 */
9343 const u8 qam_b64_taps[] = {
9344 DRXJ_16TO8(0), /* re0 */
9345 DRXJ_16TO8(-2), /* re1 */
9346 DRXJ_16TO8(1), /* re2 */
9347 DRXJ_16TO8(2), /* re3 */
9348 DRXJ_16TO8(-2), /* re4 */
9349 DRXJ_16TO8(0), /* re5 */
9350 DRXJ_16TO8(4), /* re6 */
9351 DRXJ_16TO8(-2), /* re7 */
9352 DRXJ_16TO8(-4), /* re8 */
9353 DRXJ_16TO8(4), /* re9 */
9354 DRXJ_16TO8(3), /* re10 */
9355 DRXJ_16TO8(-6), /* re11 */
9356 DRXJ_16TO8(0), /* re12 */
9357 DRXJ_16TO8(6), /* re13 */
9358 DRXJ_16TO8(-5), /* re14 */
9359 DRXJ_16TO8(-3), /* re15 */
9360 DRXJ_16TO8(11), /* re16 */
9361 DRXJ_16TO8(-4), /* re17 */
9362 DRXJ_16TO8(-19), /* re18 */
9363 DRXJ_16TO8(19), /* re19 */
9364 DRXJ_16TO8(28), /* re20 */
9365 DRXJ_16TO8(-45), /* re21 */
9366 DRXJ_16TO8(-36), /* re22 */
9367 DRXJ_16TO8(90), /* re23 */
9368 DRXJ_16TO8(42), /* re24 */
9369 DRXJ_16TO8(-185), /* re25 */
9370 DRXJ_16TO8(-46), /* re26 */
9371 DRXJ_16TO8(614) /* re27 */
9373 const u8 qam_b256_taps[] = {
9374 DRXJ_16TO8(-2), /* re0 */
9375 DRXJ_16TO8(4), /* re1 */
9376 DRXJ_16TO8(1), /* re2 */
9377 DRXJ_16TO8(-4), /* re3 */
9378 DRXJ_16TO8(0), /* re4 */
9379 DRXJ_16TO8(4), /* re5 */
9380 DRXJ_16TO8(-2), /* re6 */
9381 DRXJ_16TO8(-4), /* re7 */
9382 DRXJ_16TO8(5), /* re8 */
9383 DRXJ_16TO8(2), /* re9 */
9384 DRXJ_16TO8(-8), /* re10 */
9385 DRXJ_16TO8(2), /* re11 */
9386 DRXJ_16TO8(11), /* re12 */
9387 DRXJ_16TO8(-8), /* re13 */
9388 DRXJ_16TO8(-15), /* re14 */
9389 DRXJ_16TO8(16), /* re15 */
9390 DRXJ_16TO8(19), /* re16 */
9391 DRXJ_16TO8(-27), /* re17 */
9392 DRXJ_16TO8(-22), /* re18 */
9393 DRXJ_16TO8(44), /* re19 */
9394 DRXJ_16TO8(26), /* re20 */
9395 DRXJ_16TO8(-69), /* re21 */
9396 DRXJ_16TO8(-28), /* re22 */
9397 DRXJ_16TO8(110), /* re23 */
9398 DRXJ_16TO8(31), /* re24 */
9399 DRXJ_16TO8(-201), /* re25 */
9400 DRXJ_16TO8(-32), /* re26 */
9401 DRXJ_16TO8(628) /* re27 */
9403 const u8 qam_c_taps[] = {
9404 DRXJ_16TO8(-3), /* re0 */
9405 DRXJ_16TO8(3), /* re1 */
9406 DRXJ_16TO8(2), /* re2 */
9407 DRXJ_16TO8(-4), /* re3 */
9408 DRXJ_16TO8(0), /* re4 */
9409 DRXJ_16TO8(4), /* re5 */
9410 DRXJ_16TO8(-1), /* re6 */
9411 DRXJ_16TO8(-4), /* re7 */
9412 DRXJ_16TO8(3), /* re8 */
9413 DRXJ_16TO8(3), /* re9 */
9414 DRXJ_16TO8(-5), /* re10 */
9415 DRXJ_16TO8(0), /* re11 */
9416 DRXJ_16TO8(9), /* re12 */
9417 DRXJ_16TO8(-4), /* re13 */
9418 DRXJ_16TO8(-12), /* re14 */
9419 DRXJ_16TO8(10), /* re15 */
9420 DRXJ_16TO8(16), /* re16 */
9421 DRXJ_16TO8(-21), /* re17 */
9422 DRXJ_16TO8(-20), /* re18 */
9423 DRXJ_16TO8(37), /* re19 */
9424 DRXJ_16TO8(25), /* re20 */
9425 DRXJ_16TO8(-62), /* re21 */
9426 DRXJ_16TO8(-28), /* re22 */
9427 DRXJ_16TO8(105), /* re23 */
9428 DRXJ_16TO8(31), /* re24 */
9429 DRXJ_16TO8(-197), /* re25 */
9430 DRXJ_16TO8(-33), /* re26 */
9431 DRXJ_16TO8(626) /* re27 */
9434 dev_addr = demod->my_i2c_dev_addr;
9435 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9436 common_attr = (struct drx_common_attr *) demod->my_common_attr;
9438 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9439 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9440 switch (channel->constellation) {
9441 case DRX_CONSTELLATION_QAM256:
9442 iqm_rc_rate = 0x00AE3562;
9444 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
9445 channel->symbolrate = 5360537;
9446 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
9448 case DRX_CONSTELLATION_QAM64:
9449 iqm_rc_rate = 0x00C05A0E;
9450 lc_symbol_freq = 409;
9451 channel->symbolrate = 5056941;
9452 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
9458 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
9459 if (channel->symbolrate == 0) {
9460 pr_err("error: channel symbolrate is zero!\n");
9464 (adc_frequency / channel->symbolrate) * (1 << 21) +
9466 ((adc_frequency % channel->symbolrate),
9467 channel->symbolrate) >> 7) - (1 << 23);
9470 (channel->symbolrate +
9471 (adc_frequency >> 13),
9472 adc_frequency) >> 16);
9473 if (lc_symbol_freq > 511)
9474 lc_symbol_freq = 511;
9476 iqm_rc_stretch = 21;
9479 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
9480 set_env_parameters = QAM_TOP_ANNEX_A; /* annex */
9481 set_param_parameters[0] = channel->constellation; /* constellation */
9482 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
9483 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9484 set_env_parameters = QAM_TOP_ANNEX_B; /* annex */
9485 set_param_parameters[0] = channel->constellation; /* constellation */
9486 set_param_parameters[1] = channel->interleavemode; /* interleave mode */
9487 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9488 set_env_parameters = QAM_TOP_ANNEX_C; /* annex */
9489 set_param_parameters[0] = channel->constellation; /* constellation */
9490 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
9496 if (op & QAM_SET_OP_ALL) {
9498 STEP 1: reset demodulator
9499 resets IQM, QAM and FEC HW blocks
9500 resets SCU variables
9502 /* stop all comm_exec */
9503 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9505 pr_err("error %d\n", rc);
9508 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
9510 pr_err("error %d\n", rc);
9513 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9515 pr_err("error %d\n", rc);
9518 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9520 pr_err("error %d\n", rc);
9523 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9525 pr_err("error %d\n", rc);
9528 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9530 pr_err("error %d\n", rc);
9533 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9535 pr_err("error %d\n", rc);
9539 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9540 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
9541 cmd_scu.parameter_len = 0;
9542 cmd_scu.result_len = 1;
9543 cmd_scu.parameter = NULL;
9544 cmd_scu.result = &cmd_result;
9545 rc = scu_command(dev_addr, &cmd_scu);
9547 pr_err("error %d\n", rc);
9552 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9554 STEP 2: configure demodulator
9556 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
9558 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9559 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
9560 cmd_scu.parameter_len = 1;
9561 cmd_scu.result_len = 1;
9562 cmd_scu.parameter = &set_env_parameters;
9563 cmd_scu.result = &cmd_result;
9564 rc = scu_command(dev_addr, &cmd_scu);
9566 pr_err("error %d\n", rc);
9570 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9571 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
9572 cmd_scu.parameter_len = 2;
9573 cmd_scu.result_len = 1;
9574 cmd_scu.parameter = set_param_parameters;
9575 cmd_scu.result = &cmd_result;
9576 rc = scu_command(dev_addr, &cmd_scu);
9578 pr_err("error %d\n", rc);
9581 /* set symbol rate */
9582 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
9584 pr_err("error %d\n", rc);
9587 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
9588 rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
9590 pr_err("error %d\n", rc);
9594 /* STEP 3: enable the system in a mode where the ADC provides valid signal
9595 setup constellation independent registers */
9596 /* from qam_cmd.py script (qam_driver_b) */
9597 /* TODO: remove re-writes of HW reset values */
9598 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
9599 rc = set_frequency(demod, channel, tuner_freq_offset);
9601 pr_err("error %d\n", rc);
9606 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9608 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
9610 pr_err("error %d\n", rc);
9613 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
9615 pr_err("error %d\n", rc);
9620 if (op & QAM_SET_OP_ALL) {
9621 if (!ext_attr->has_lna) {
9622 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
9624 pr_err("error %d\n", rc);
9628 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
9630 pr_err("error %d\n", rc);
9633 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
9635 pr_err("error %d\n", rc);
9638 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
9640 pr_err("error %d\n", rc);
9644 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
9646 pr_err("error %d\n", rc);
9648 } /* scu temporary shut down agc */
9650 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
9652 pr_err("error %d\n", rc);
9655 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
9657 pr_err("error %d\n", rc);
9660 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
9662 pr_err("error %d\n", rc);
9665 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
9667 pr_err("error %d\n", rc);
9670 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PDREF__A, 4, 0);
9672 pr_err("error %d\n", rc);
9675 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
9677 pr_err("error %d\n", rc);
9680 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
9682 pr_err("error %d\n", rc);
9686 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
9688 pr_err("error %d\n", rc);
9691 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
9693 pr_err("error %d\n", rc);
9695 } /*! reset default val ! */
9697 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
9699 pr_err("error %d\n", rc);
9701 } /*! reset default val ! */
9702 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9703 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
9705 pr_err("error %d\n", rc);
9707 } /*! reset default val ! */
9708 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
9710 pr_err("error %d\n", rc);
9712 } /*! reset default val ! */
9713 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9715 pr_err("error %d\n", rc);
9717 } /*! reset default val ! */
9719 switch (channel->constellation) {
9720 case DRX_CONSTELLATION_QAM16:
9721 case DRX_CONSTELLATION_QAM64:
9722 case DRX_CONSTELLATION_QAM256:
9723 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9725 pr_err("error %d\n", rc);
9728 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
9730 pr_err("error %d\n", rc);
9733 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9735 pr_err("error %d\n", rc);
9737 } /*! reset default val ! */
9739 case DRX_CONSTELLATION_QAM32:
9740 case DRX_CONSTELLATION_QAM128:
9741 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9743 pr_err("error %d\n", rc);
9746 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
9748 pr_err("error %d\n", rc);
9751 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
9753 pr_err("error %d\n", rc);
9762 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
9764 pr_err("error %d\n", rc);
9766 } /*! reset default val ! */
9767 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
9769 pr_err("error %d\n", rc);
9772 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
9774 pr_err("error %d\n", rc);
9777 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
9779 pr_err("error %d\n", rc);
9782 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_MODE__A, 7, 0);
9784 pr_err("error %d\n", rc);
9787 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
9789 pr_err("error %d\n", rc);
9792 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
9794 pr_err("error %d\n", rc);
9797 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
9799 pr_err("error %d\n", rc);
9802 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
9804 pr_err("error %d\n", rc);
9807 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
9809 pr_err("error %d\n", rc);
9812 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
9814 pr_err("error %d\n", rc);
9817 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
9819 pr_err("error %d\n", rc);
9822 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
9824 pr_err("error %d\n", rc);
9827 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
9829 pr_err("error %d\n", rc);
9832 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
9834 pr_err("error %d\n", rc);
9837 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
9839 pr_err("error %d\n", rc);
9842 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
9844 pr_err("error %d\n", rc);
9847 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
9849 pr_err("error %d\n", rc);
9852 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
9854 pr_err("error %d\n", rc);
9857 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
9859 pr_err("error %d\n", rc);
9863 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
9865 pr_err("error %d\n", rc);
9868 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
9870 pr_err("error %d\n", rc);
9873 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
9875 pr_err("error %d\n", rc);
9878 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
9880 pr_err("error %d\n", rc);
9883 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
9885 pr_err("error %d\n", rc);
9889 /* No more resets of the IQM, current standard correctly set =>
9890 now AGCs can be configured. */
9891 /* turn on IQMAF. It has to be in front of setAgc**() */
9892 rc = set_iqm_af(demod, true);
9894 pr_err("error %d\n", rc);
9897 rc = adc_synchronization(demod);
9899 pr_err("error %d\n", rc);
9903 rc = init_agc(demod);
9905 pr_err("error %d\n", rc);
9908 rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
9910 pr_err("error %d\n", rc);
9913 rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
9915 pr_err("error %d\n", rc);
9919 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
9921 struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
9923 qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
9924 rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
9926 pr_err("error %d\n", rc);
9930 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
9932 pr_err("error %d\n", rc);
9937 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9938 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
9939 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9941 pr_err("error %d\n", rc);
9944 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9946 pr_err("error %d\n", rc);
9949 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9950 switch (channel->constellation) {
9951 case DRX_CONSTELLATION_QAM64:
9952 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9954 pr_err("error %d\n", rc);
9957 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9959 pr_err("error %d\n", rc);
9963 case DRX_CONSTELLATION_QAM256:
9964 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9966 pr_err("error %d\n", rc);
9969 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9971 pr_err("error %d\n", rc);
9978 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9979 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9981 pr_err("error %d\n", rc);
9984 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9986 pr_err("error %d\n", rc);
9991 /* SETP 4: constellation specific setup */
9992 switch (channel->constellation) {
9993 case DRX_CONSTELLATION_QAM16:
9994 rc = set_qam16(demod);
9996 pr_err("error %d\n", rc);
10000 case DRX_CONSTELLATION_QAM32:
10001 rc = set_qam32(demod);
10003 pr_err("error %d\n", rc);
10007 case DRX_CONSTELLATION_QAM64:
10008 rc = set_qam64(demod);
10010 pr_err("error %d\n", rc);
10014 case DRX_CONSTELLATION_QAM128:
10015 rc = set_qam128(demod);
10017 pr_err("error %d\n", rc);
10021 case DRX_CONSTELLATION_QAM256:
10022 rc = set_qam256(demod);
10024 pr_err("error %d\n", rc);
10033 if ((op & QAM_SET_OP_ALL)) {
10034 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
10036 pr_err("error %d\n", rc);
10040 /* Mpeg output has to be in front of FEC active */
10041 rc = set_mpegtei_handling(demod);
10043 pr_err("error %d\n", rc);
10046 rc = bit_reverse_mpeg_output(demod);
10048 pr_err("error %d\n", rc);
10051 rc = set_mpeg_start_width(demod);
10053 pr_err("error %d\n", rc);
10057 /* TODO: move to set_standard after hardware reset value problem is solved */
10058 /* Configure initial MPEG output */
10059 struct drx_cfg_mpeg_output cfg_mpeg_output;
10061 cfg_mpeg_output.enable_mpeg_output = true;
10062 cfg_mpeg_output.insert_rs_byte =
10063 common_attr->mpeg_cfg.insert_rs_byte;
10064 cfg_mpeg_output.enable_parallel =
10065 common_attr->mpeg_cfg.enable_parallel;
10066 cfg_mpeg_output.invert_data =
10067 common_attr->mpeg_cfg.invert_data;
10068 cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
10069 cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
10070 cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
10071 cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
10072 cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
10073 cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
10074 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
10076 pr_err("error %d\n", rc);
10082 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
10084 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
10085 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10086 SCU_RAM_COMMAND_CMD_DEMOD_START;
10087 cmd_scu.parameter_len = 0;
10088 cmd_scu.result_len = 1;
10089 cmd_scu.parameter = NULL;
10090 cmd_scu.result = &cmd_result;
10091 rc = scu_command(dev_addr, &cmd_scu);
10093 pr_err("error %d\n", rc);
10098 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
10100 pr_err("error %d\n", rc);
10103 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
10105 pr_err("error %d\n", rc);
10108 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
10110 pr_err("error %d\n", rc);
10119 /*============================================================================*/
10121 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality);
10122 static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
10125 u32 iqm_fs_rate_ofs = 0;
10126 u32 iqm_fs_rate_lo = 0;
10127 u16 qam_ctl_ena = 0;
10133 struct i2c_device_addr *dev_addr = NULL;
10134 struct drxj_data *ext_attr = NULL;
10136 dev_addr = demod->my_i2c_dev_addr;
10137 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10139 /* Silence the controlling of lc, equ, and the acquisition state machine */
10140 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10142 pr_err("error %d\n", rc);
10145 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M), 0);
10147 pr_err("error %d\n", rc);
10151 /* freeze the frequency control loop */
10152 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CF__A, 0, 0);
10154 pr_err("error %d\n", rc);
10157 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CF1__A, 0, 0);
10159 pr_err("error %d\n", rc);
10163 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
10165 pr_err("error %d\n", rc);
10168 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
10170 pr_err("error %d\n", rc);
10173 ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
10174 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
10175 iqm_fs_rate_ofs -= 2 * ofsofs;
10177 /* freeze dq/fq updating */
10178 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_MODE__A, &data, 0);
10180 pr_err("error %d\n", rc);
10183 data = (data & 0xfff9);
10184 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10186 pr_err("error %d\n", rc);
10189 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10191 pr_err("error %d\n", rc);
10195 /* lc_cp / _ci / _ca */
10196 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CI__A, 0, 0);
10198 pr_err("error %d\n", rc);
10201 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_EP__A, 0, 0);
10203 pr_err("error %d\n", rc);
10206 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
10208 pr_err("error %d\n", rc);
10212 /* flip the spec */
10213 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
10215 pr_err("error %d\n", rc);
10218 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
10219 ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
10221 /* freeze dq/fq updating */
10222 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_MODE__A, &data, 0);
10224 pr_err("error %d\n", rc);
10228 data = (data & 0xfff9);
10229 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10231 pr_err("error %d\n", rc);
10234 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10236 pr_err("error %d\n", rc);
10240 for (i = 0; i < 28; i++) {
10241 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
10243 pr_err("error %d\n", rc);
10246 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
10248 pr_err("error %d\n", rc);
10253 for (i = 0; i < 24; i++) {
10254 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
10256 pr_err("error %d\n", rc);
10259 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
10261 pr_err("error %d\n", rc);
10267 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10269 pr_err("error %d\n", rc);
10272 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10274 pr_err("error %d\n", rc);
10278 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
10280 pr_err("error %d\n", rc);
10285 while ((fsm_state != 4) && (i++ < 100)) {
10286 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
10288 pr_err("error %d\n", rc);
10292 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
10294 pr_err("error %d\n", rc);
10304 #define NO_LOCK 0x0
10305 #define DEMOD_LOCKED 0x1
10306 #define SYNC_FLIPPED 0x2
10307 #define SPEC_MIRRORED 0x4
10309 * \fn int qam64auto ()
10310 * \brief auto do sync pattern switching and mirroring.
10311 * \param demod: instance of demod.
10312 * \param channel: pointer to channel data.
10313 * \param tuner_freq_offset: tuner frequency offset.
10314 * \param lock_status: pointer to lock status.
10318 qam64auto(struct drx_demod_instance *demod,
10319 struct drx_channel *channel,
10320 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
10322 struct drx_sig_quality sig_quality;
10323 struct drxj_data *ext_attr = NULL;
10325 u32 state = NO_LOCK;
10326 u32 start_time = 0;
10327 u32 d_locked_time = 0;
10328 u32 timeout_ofs = 0;
10331 /* external attributes for storing aquired channel constellation */
10332 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10333 *lock_status = DRX_NOT_LOCKED;
10334 start_time = drxbsp_hst_clock();
10337 rc = ctrl_lock_status(demod, lock_status);
10339 pr_err("error %d\n", rc);
10345 if (*lock_status == DRXJ_DEMOD_LOCK) {
10346 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10348 pr_err("error %d\n", rc);
10351 if (sig_quality.MER > 208) {
10352 state = DEMOD_LOCKED;
10353 /* some delay to see if fec_lock possible TODO find the right value */
10354 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
10355 d_locked_time = drxbsp_hst_clock();
10360 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
10361 ((drxbsp_hst_clock() - d_locked_time) >
10362 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10363 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10365 pr_err("error %d\n", rc);
10368 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
10370 pr_err("error %d\n", rc);
10373 state = SYNC_FLIPPED;
10374 drxbsp_hst_sleep(10);
10378 if (*lock_status == DRXJ_DEMOD_LOCK) {
10379 if (channel->mirror == DRX_MIRROR_AUTO) {
10380 /* flip sync pattern back */
10381 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10383 pr_err("error %d\n", rc);
10386 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
10388 pr_err("error %d\n", rc);
10391 /* flip spectrum */
10392 ext_attr->mirror = DRX_MIRROR_YES;
10393 rc = qam_flip_spec(demod, channel);
10395 pr_err("error %d\n", rc);
10398 state = SPEC_MIRRORED;
10399 /* reset timer TODO: still need 500ms? */
10400 start_time = d_locked_time =
10401 drxbsp_hst_clock();
10403 } else { /* no need to wait lock */
10406 drxbsp_hst_clock() -
10407 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
10411 case SPEC_MIRRORED:
10412 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
10413 ((drxbsp_hst_clock() - d_locked_time) >
10414 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10415 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10417 pr_err("error %d\n", rc);
10420 if (sig_quality.MER > 208) {
10421 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10423 pr_err("error %d\n", rc);
10426 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
10428 pr_err("error %d\n", rc);
10431 /* no need to wait lock */
10433 drxbsp_hst_clock() -
10434 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
10441 drxbsp_hst_sleep(10);
10443 ((*lock_status != DRX_LOCKED) &&
10444 (*lock_status != DRX_NEVER_LOCK) &&
10445 ((drxbsp_hst_clock() - start_time) <
10446 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
10448 /* Returning control to apllication ... */
10456 * \fn int qam256auto ()
10457 * \brief auto do sync pattern switching and mirroring.
10458 * \param demod: instance of demod.
10459 * \param channel: pointer to channel data.
10460 * \param tuner_freq_offset: tuner frequency offset.
10461 * \param lock_status: pointer to lock status.
10465 qam256auto(struct drx_demod_instance *demod,
10466 struct drx_channel *channel,
10467 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
10469 struct drx_sig_quality sig_quality;
10470 struct drxj_data *ext_attr = NULL;
10472 u32 state = NO_LOCK;
10473 u32 start_time = 0;
10474 u32 d_locked_time = 0;
10475 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
10477 /* external attributes for storing aquired channel constellation */
10478 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10479 *lock_status = DRX_NOT_LOCKED;
10480 start_time = drxbsp_hst_clock();
10483 rc = ctrl_lock_status(demod, lock_status);
10485 pr_err("error %d\n", rc);
10490 if (*lock_status == DRXJ_DEMOD_LOCK) {
10491 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10493 pr_err("error %d\n", rc);
10496 if (sig_quality.MER > 268) {
10497 state = DEMOD_LOCKED;
10498 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
10499 d_locked_time = drxbsp_hst_clock();
10504 if (*lock_status == DRXJ_DEMOD_LOCK) {
10505 if ((channel->mirror == DRX_MIRROR_AUTO) &&
10506 ((drxbsp_hst_clock() - d_locked_time) >
10507 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10508 ext_attr->mirror = DRX_MIRROR_YES;
10509 rc = qam_flip_spec(demod, channel);
10511 pr_err("error %d\n", rc);
10514 state = SPEC_MIRRORED;
10515 /* reset timer TODO: still need 300ms? */
10516 start_time = drxbsp_hst_clock();
10517 timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
10521 case SPEC_MIRRORED:
10526 drxbsp_hst_sleep(10);
10528 ((*lock_status < DRX_LOCKED) &&
10529 (*lock_status != DRX_NEVER_LOCK) &&
10530 ((drxbsp_hst_clock() - start_time) <
10531 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
10539 * \fn int set_qam_channel ()
10540 * \brief Set QAM channel according to the requested constellation.
10541 * \param demod: instance of demod.
10542 * \param channel: pointer to channel data.
10546 set_qam_channel(struct drx_demod_instance *demod,
10547 struct drx_channel *channel, s32 tuner_freq_offset)
10549 struct drxj_data *ext_attr = NULL;
10551 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
10552 bool auto_flag = false;
10554 /* external attributes for storing aquired channel constellation */
10555 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10557 /* set QAM channel constellation */
10558 switch (channel->constellation) {
10559 case DRX_CONSTELLATION_QAM16:
10560 case DRX_CONSTELLATION_QAM32:
10561 case DRX_CONSTELLATION_QAM64:
10562 case DRX_CONSTELLATION_QAM128:
10563 case DRX_CONSTELLATION_QAM256:
10564 ext_attr->constellation = channel->constellation;
10565 if (channel->mirror == DRX_MIRROR_AUTO)
10566 ext_attr->mirror = DRX_MIRROR_NO;
10568 ext_attr->mirror = channel->mirror;
10569 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
10571 pr_err("error %d\n", rc);
10575 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
10576 (channel->constellation == DRX_CONSTELLATION_QAM64)) {
10577 rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10579 pr_err("error %d\n", rc);
10584 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
10585 (channel->mirror == DRX_MIRROR_AUTO) &&
10586 (channel->constellation == DRX_CONSTELLATION_QAM256)) {
10587 rc = qam256auto(demod, channel, tuner_freq_offset, &lock_status);
10589 pr_err("error %d\n", rc);
10594 case DRX_CONSTELLATION_AUTO: /* for channel scan */
10595 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
10597 /* try to lock default QAM constellation: QAM64 */
10598 channel->constellation = DRX_CONSTELLATION_QAM256;
10599 ext_attr->constellation = DRX_CONSTELLATION_QAM256;
10600 if (channel->mirror == DRX_MIRROR_AUTO)
10601 ext_attr->mirror = DRX_MIRROR_NO;
10603 ext_attr->mirror = channel->mirror;
10604 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
10606 pr_err("error %d\n", rc);
10609 rc = qam256auto(demod, channel, tuner_freq_offset, &lock_status);
10611 pr_err("error %d\n", rc);
10615 if (lock_status < DRX_LOCKED) {
10616 /* QAM254 not locked -> try to lock QAM64 constellation */
10617 channel->constellation =
10618 DRX_CONSTELLATION_QAM64;
10619 ext_attr->constellation =
10620 DRX_CONSTELLATION_QAM64;
10621 if (channel->mirror == DRX_MIRROR_AUTO)
10622 ext_attr->mirror = DRX_MIRROR_NO;
10624 ext_attr->mirror = channel->mirror;
10626 u16 qam_ctl_ena = 0;
10627 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10629 pr_err("error %d\n", rc);
10632 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
10634 pr_err("error %d\n", rc);
10637 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2, 0);
10639 pr_err("error %d\n", rc);
10641 } /* force to rate hunting */
10643 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_CONSTELLATION);
10645 pr_err("error %d\n", rc);
10648 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena, 0);
10650 pr_err("error %d\n", rc);
10654 rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10656 pr_err("error %d\n", rc);
10660 channel->constellation = DRX_CONSTELLATION_AUTO;
10661 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
10662 channel->constellation = DRX_CONSTELLATION_QAM64;
10663 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
10666 if (channel->mirror == DRX_MIRROR_AUTO)
10667 ext_attr->mirror = DRX_MIRROR_NO;
10669 ext_attr->mirror = channel->mirror;
10671 u16 qam_ctl_ena = 0;
10672 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10674 pr_err("error %d\n", rc);
10677 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
10679 pr_err("error %d\n", rc);
10682 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2, 0);
10684 pr_err("error %d\n", rc);
10686 } /* force to rate hunting */
10688 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_CONSTELLATION);
10690 pr_err("error %d\n", rc);
10693 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena, 0);
10695 pr_err("error %d\n", rc);
10699 rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10701 pr_err("error %d\n", rc);
10704 channel->constellation = DRX_CONSTELLATION_AUTO;
10706 channel->constellation = DRX_CONSTELLATION_AUTO;
10716 /* restore starting value */
10718 channel->constellation = DRX_CONSTELLATION_AUTO;
10722 /*============================================================================*/
10725 * \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
10726 * \brief Get RS error count in QAM mode (used for post RS BER calculation)
10727 * \return Error code
10729 * precondition: measurement period & measurement prescale must be set
10733 get_qamrs_err_count(struct i2c_device_addr *dev_addr, struct drxjrs_errors *rs_errors)
10736 u16 nr_bit_errors = 0,
10737 nr_symbol_errors = 0,
10738 nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
10740 /* check arguments */
10741 if (dev_addr == NULL)
10744 /* all reported errors are received in the */
10745 /* most recently finished measurment period */
10746 /* no of pre RS bit errors */
10747 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
10749 pr_err("error %d\n", rc);
10752 /* no of symbol errors */
10753 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
10755 pr_err("error %d\n", rc);
10758 /* no of packet errors */
10759 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
10761 pr_err("error %d\n", rc);
10764 /* no of failures to decode */
10765 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
10767 pr_err("error %d\n", rc);
10770 /* no of post RS bit erros */
10771 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
10773 pr_err("error %d\n", rc);
10777 /* These register values are fetched in non-atomic fashion */
10778 /* It is possible that the read values contain unrelated information */
10780 rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
10781 rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
10782 rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
10783 rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
10784 rs_errors->nr_snc_par_fail_count =
10785 nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
10792 /*============================================================================*/
10795 * \fn int ctrl_get_qam_sig_quality()
10796 * \brief Retreive QAM signal quality from device.
10797 * \param devmod Pointer to demodulator instance.
10798 * \param sig_quality Pointer to signal quality data.
10800 * \retval 0 sig_quality contains valid data.
10801 * \retval -EINVAL sig_quality is NULL.
10802 * \retval -EIO Erroneous data, sig_quality contains invalid data.
10804 * Pre-condition: Device must be started and in lock.
10807 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
10809 struct i2c_device_addr *dev_addr = NULL;
10810 struct drxj_data *ext_attr = NULL;
10812 enum drx_modulation constellation = DRX_CONSTELLATION_UNKNOWN;
10813 struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
10815 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
10816 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
10817 u32 pkt_errs = 0; /* no of packet errors in RS */
10818 u16 qam_sl_err_power = 0; /* accumulated error between raw and sliced symbols */
10819 u16 qsym_err_vd = 0; /* quadrature symbol errors in QAM_VD */
10820 u16 fec_oc_period = 0; /* SNC sync failure measurement period */
10821 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
10822 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
10823 /* calculation constants */
10824 u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
10825 u32 qam_sl_sig_power = 0; /* used for MER, depends of QAM constellation */
10826 /* intermediate results */
10827 u32 e = 0; /* exponent value used for QAM BER/SER */
10828 u32 m = 0; /* mantisa value used for QAM BER/SER */
10829 u32 ber_cnt = 0; /* BER count */
10830 /* signal quality info */
10831 u32 qam_sl_mer = 0; /* QAM MER */
10832 u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
10833 u32 qam_post_rs_ber = 0; /* Post RedSolomon BER */
10834 u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
10835 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
10836 u16 qam_vd_period = 0; /* Viterbi Measurement period */
10837 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
10839 /* get device basic information */
10840 dev_addr = demod->my_i2c_dev_addr;
10841 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10842 constellation = ext_attr->constellation;
10844 /* read the physical registers */
10845 /* Get the RS error data */
10846 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
10848 pr_err("error %d\n", rc);
10851 /* get the register value needed for MER */
10852 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
10854 pr_err("error %d\n", rc);
10857 /* get the register value needed for post RS BER */
10858 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
10860 pr_err("error %d\n", rc);
10864 /* get constants needed for signal quality calculation */
10865 fec_rs_period = ext_attr->fec_rs_period;
10866 fec_rs_prescale = ext_attr->fec_rs_prescale;
10867 rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
10868 qam_vd_period = ext_attr->qam_vd_period;
10869 qam_vd_prescale = ext_attr->qam_vd_prescale;
10870 vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
10872 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
10873 switch (constellation) {
10874 case DRX_CONSTELLATION_QAM16:
10875 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
10877 case DRX_CONSTELLATION_QAM32:
10878 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
10880 case DRX_CONSTELLATION_QAM64:
10881 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
10883 case DRX_CONSTELLATION_QAM128:
10884 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
10886 case DRX_CONSTELLATION_QAM256:
10887 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
10893 /* ------------------------------ */
10894 /* MER Calculation */
10895 /* ------------------------------ */
10896 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
10898 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
10899 if (qam_sl_err_power == 0)
10902 qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
10904 /* ----------------------------------------- */
10905 /* Pre Viterbi Symbol Error Rate Calculation */
10906 /* ----------------------------------------- */
10907 /* pre viterbi SER is good if it is bellow 0.025 */
10909 /* get the register value */
10910 /* no of quadrature symbol errors */
10911 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
10913 pr_err("error %d\n", rc);
10916 /* Extract the Exponent and the Mantisa */
10917 /* of number of quadrature symbol errors */
10918 e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
10919 QAM_VD_NR_QSYM_ERRORS_EXP__B;
10920 m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
10921 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
10923 if ((m << e) >> 3 > 549752)
10924 qam_vd_ser = 500000;
10926 qam_vd_ser = frac_times1e6(m << ((e > 2) ? (e - 3) : e), vd_bit_cnt * ((e > 2) ? 1 : 8) / 8);
10928 /* --------------------------------------- */
10929 /* pre and post RedSolomon BER Calculation */
10930 /* --------------------------------------- */
10931 /* pre RS BER is good if it is below 3.5e-4 */
10933 /* get the register values */
10934 pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
10935 pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
10937 /* Extract the Exponent and the Mantisa of the */
10938 /* pre Reed-Solomon bit error count */
10939 e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
10940 FEC_RS_NR_BIT_ERRORS_EXP__B;
10941 m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
10942 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
10946 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
10947 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
10948 qam_pre_rs_ber = 500000;
10950 qam_pre_rs_ber = frac_times1e6(m, rs_bit_cnt >> e);
10952 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
10953 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
10955 => c = (1000000*100*11.17)/1504 =
10956 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
10957 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
10958 *100 and /100 is for more precision.
10959 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
10961 Precision errors still possible.
10963 e = post_bit_err_rs * 742686;
10964 m = fec_oc_period * 100;
10965 if (fec_oc_period == 0)
10966 qam_post_rs_ber = 0xFFFFFFFF;
10968 qam_post_rs_ber = e / m;
10970 /* fill signal quality data structure */
10971 sig_quality->MER = ((u16) qam_sl_mer);
10972 if (ext_attr->standard == DRX_STANDARD_ITU_B)
10973 sig_quality->pre_viterbi_ber = qam_vd_ser;
10975 sig_quality->pre_viterbi_ber = qam_pre_rs_ber;
10976 sig_quality->post_viterbi_ber = qam_pre_rs_ber;
10977 sig_quality->post_reed_solomon_ber = qam_post_rs_ber;
10978 sig_quality->scale_factor_ber = ((u32) 1000000);
10979 #ifdef DRXJ_SIGNAL_ACCUM_ERR
10980 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
10982 pr_err("error %d\n", rc);
10986 sig_quality->packet_error = ((u16) pkt_errs);
10995 * \fn int ctrl_get_qam_constel()
10996 * \brief Retreive a QAM constellation point via I2C.
10997 * \param demod Pointer to demodulator instance.
10998 * \param complex_nr Pointer to the structure in which to store the
10999 constellation point.
11003 ctrl_get_qam_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
11005 struct i2c_device_addr *dev_addr = NULL;
11008 u16 fec_oc_ocr_mode = 0;
11009 /**< FEC OCR grabber configuration */
11010 u16 qam_sl_comm_mb = 0;/**< QAM SL MB configuration */
11011 u16 qam_sl_comm_mb_init = 0;
11012 /**< QAM SL MB intial configuration */
11013 u16 im = 0; /**< constellation Im part */
11014 u16 re = 0; /**< constellation Re part */
11015 /**< device address */
11017 /* read device info */
11018 dev_addr = demod->my_i2c_dev_addr;
11021 /* Monitor bus grabbing is an open external interface issue */
11022 /* Needs to be checked when external interface PG is updated */
11024 /* Configure MB (Monitor bus) */
11025 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_SL_COMM_MB__A, &qam_sl_comm_mb_init, 0);
11027 pr_err("error %d\n", rc);
11030 /* set observe flag & MB mux */
11031 qam_sl_comm_mb = qam_sl_comm_mb_init & (~(QAM_SL_COMM_MB_OBS__M +
11032 QAM_SL_COMM_MB_MUX_OBS__M));
11033 qam_sl_comm_mb |= (QAM_SL_COMM_MB_OBS_ON +
11034 QAM_SL_COMM_MB_MUX_OBS_CONST_CORR);
11035 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb, 0);
11037 pr_err("error %d\n", rc);
11041 /* Enable MB grabber in the FEC OC */
11042 fec_oc_ocr_mode = (/* output select: observe bus */
11043 (FEC_OC_OCR_MODE_MB_SELECT__M &
11044 (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B)) |
11045 /* grabber enable: on */
11046 (FEC_OC_OCR_MODE_GRAB_ENABLE__M &
11047 (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B)) |
11048 /* grabber select: observe bus */
11049 (FEC_OC_OCR_MODE_GRAB_SELECT__M &
11050 (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B)) |
11051 /* grabber mode: continuous */
11052 (FEC_OC_OCR_MODE_GRAB_COUNTED__M &
11053 (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B)));
11054 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, fec_oc_ocr_mode, 0);
11056 pr_err("error %d\n", rc);
11060 /* Disable MB grabber in the FEC OC */
11061 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, 0x00, 0);
11063 pr_err("error %d\n", rc);
11068 rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_OCR_GRAB_RD0__A, &data, 0);
11070 pr_err("error %d\n", rc);
11073 re = (u16) (data & FEC_OC_OCR_GRAB_RD0__M);
11074 im = (u16) ((data >> 16) & FEC_OC_OCR_GRAB_RD1__M);
11077 /* interpret data (re & im) according to the Monitor bus mapping ?? */
11079 /* sign extension, 10th bit is sign bit */
11080 if ((re & 0x0200) == 0x0200)
11082 if ((im & 0x0200) == 0x0200)
11084 complex_nr->re = ((s16) re);
11085 complex_nr->im = ((s16) im);
11087 /* Restore MB (Monitor bus) */
11088 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb_init, 0);
11090 pr_err("error %d\n", rc);
11098 #endif /* #ifndef DRXJ_VSB_ONLY */
11100 /*============================================================================*/
11101 /*== END QAM DATAPATH FUNCTIONS ==*/
11102 /*============================================================================*/
11104 /*============================================================================*/
11105 /*============================================================================*/
11106 /*== ATV DATAPATH FUNCTIONS ==*/
11107 /*============================================================================*/
11108 /*============================================================================*/
11111 Implementation notes.
11115 Four AGCs are used for NTSC:
11116 (1) RF (used to attenuate the input signal in case of to much power)
11117 (2) IF (used to attenuate the input signal in case of to much power)
11118 (3) Video AGC (used to amplify the output signal in case input to low)
11119 (4) SIF AGC (used to amplify the output signal in case input to low)
11121 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
11122 that the coupling between Video AGC and the RF and IF AGCs also works in
11123 favor of the SIF AGC.
11125 Three AGCs are used for FM:
11126 (1) RF (used to attenuate the input signal in case of to much power)
11127 (2) IF (used to attenuate the input signal in case of to much power)
11128 (3) SIF AGC (used to amplify the output signal in case input to low)
11130 The SIF AGC is now coupled to the RF/IF AGCs.
11131 The SIF AGC is needed for both SIF ouput and the internal SIF signal to
11134 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
11135 the ATV block. The AGC control algorithms are all implemented in
11140 (Shadow settings will not be used for now, they will be implemented
11141 later on because of the schedule)
11143 Several HW/SCU "settings" can be used for ATV. The standard selection
11144 will reset most of these settings. To avoid that the end user apllication
11145 has to perform these settings each time the ATV or FM standards is
11146 selected the driver will shadow these settings. This enables the end user
11147 to perform the settings only once after a drx_open(). The driver must
11148 write the shadow settings to HW/SCU incase:
11149 ( setstandard FM/ATV) ||
11150 ( settings have changed && FM/ATV standard is active)
11151 The shadow settings will be stored in the device specific data container.
11152 A set of flags will be defined to flag changes in shadow settings.
11153 A routine will be implemented to write all changed shadow settings to
11156 The "settings" will consist of: AGC settings, filter settings etc.
11158 Disadvantage of use of shadow settings:
11159 Direct changes in HW/SCU registers will not be reflected in the
11160 shadow settings and these changes will be overwritten during a next
11161 update. This can happen during evaluation. This will not be a problem
11162 for normal customer usage.
11164 /* -------------------------------------------------------------------------- */
11167 * \brief Get array index for atv coef (ext_attr->atvTopCoefX[index])
11169 * \param pointer to index
11173 static int atv_equ_coef_index(enum drx_standard standard, int *index)
11175 switch (standard) {
11176 case DRX_STANDARD_PAL_SECAM_BG:
11177 *index = (int)DRXJ_COEF_IDX_BG;
11179 case DRX_STANDARD_PAL_SECAM_DK:
11180 *index = (int)DRXJ_COEF_IDX_DK;
11182 case DRX_STANDARD_PAL_SECAM_I:
11183 *index = (int)DRXJ_COEF_IDX_I;
11185 case DRX_STANDARD_PAL_SECAM_L:
11186 *index = (int)DRXJ_COEF_IDX_L;
11188 case DRX_STANDARD_PAL_SECAM_LP:
11189 *index = (int)DRXJ_COEF_IDX_LP;
11191 case DRX_STANDARD_NTSC:
11192 *index = (int)DRXJ_COEF_IDX_MN;
11194 case DRX_STANDARD_FM:
11195 *index = (int)DRXJ_COEF_IDX_FM;
11198 *index = (int)DRXJ_COEF_IDX_MN; /* still return a valid index */
11206 /* -------------------------------------------------------------------------- */
11208 * \fn int atv_update_config ()
11209 * \brief Flush changes in ATV shadow registers to physical registers.
11210 * \param demod instance of demodulator
11211 * \param force_update don't look at standard or change flags, flush all.
11216 atv_update_config(struct drx_demod_instance *demod, bool force_update)
11218 struct i2c_device_addr *dev_addr = NULL;
11219 struct drxj_data *ext_attr = NULL;
11222 dev_addr = demod->my_i2c_dev_addr;
11223 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11225 /* equalizer coefficients */
11226 if (force_update ||
11227 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_COEF) != 0)) {
11230 rc = atv_equ_coef_index(ext_attr->standard, &index);
11232 pr_err("error %d\n", rc);
11235 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU0__A, ext_attr->atv_top_equ0[index], 0);
11237 pr_err("error %d\n", rc);
11240 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU1__A, ext_attr->atv_top_equ1[index], 0);
11242 pr_err("error %d\n", rc);
11245 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU2__A, ext_attr->atv_top_equ2[index], 0);
11247 pr_err("error %d\n", rc);
11250 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU3__A, ext_attr->atv_top_equ3[index], 0);
11252 pr_err("error %d\n", rc);
11257 /* bypass fast carrier recovery */
11258 if (force_update) {
11261 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_RT_ROT_BP__A, &data, 0);
11263 pr_err("error %d\n", rc);
11266 data &= (~((u16) IQM_RT_ROT_BP_ROT_OFF__M));
11267 if (ext_attr->phase_correction_bypass)
11268 data |= IQM_RT_ROT_BP_ROT_OFF_OFF;
11270 data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE;
11271 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ROT_BP__A, data, 0);
11273 pr_err("error %d\n", rc);
11278 /* peak filter setting */
11279 if (force_update ||
11280 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0)) {
11281 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_PEAK__A, ext_attr->atv_top_vid_peak, 0);
11283 pr_err("error %d\n", rc);
11288 /* noise filter setting */
11289 if (force_update ||
11290 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0)) {
11291 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_NOISE_TH__A, ext_attr->atv_top_noise_th, 0);
11293 pr_err("error %d\n", rc);
11298 /* SIF attenuation */
11299 if (force_update ||
11300 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_SIF_ATT) != 0)) {
11301 u16 attenuation = 0;
11303 switch (ext_attr->sif_attenuation) {
11304 case DRXJ_SIF_ATTENUATION_0DB:
11305 attenuation = ATV_TOP_AF_SIF_ATT_0DB;
11307 case DRXJ_SIF_ATTENUATION_3DB:
11308 attenuation = ATV_TOP_AF_SIF_ATT_M3DB;
11310 case DRXJ_SIF_ATTENUATION_6DB:
11311 attenuation = ATV_TOP_AF_SIF_ATT_M6DB;
11313 case DRXJ_SIF_ATTENUATION_9DB:
11314 attenuation = ATV_TOP_AF_SIF_ATT_M9DB;
11320 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_AF_SIF_ATT__A, attenuation, 0);
11322 pr_err("error %d\n", rc);
11327 /* SIF & CVBS enable */
11328 if (force_update ||
11329 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_OUTPUT) != 0)) {
11332 rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_STDBY__A, &data, 0);
11334 pr_err("error %d\n", rc);
11337 if (ext_attr->enable_cvbs_output)
11338 data |= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE;
11340 data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE);
11342 if (ext_attr->enable_sif_output)
11343 data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY);
11345 data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY;
11346 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, data, 0);
11348 pr_err("error %d\n", rc);
11353 ext_attr->atv_cfg_changed_flags = 0;
11360 /* -------------------------------------------------------------------------- */
11362 * \fn int ctrl_set_cfg_atv_output()
11363 * \brief Configure ATV ouputs
11364 * \param demod instance of demodulator
11365 * \param output_cfg output configuaration
11370 ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11372 struct drxj_data *ext_attr = NULL;
11375 /* Check arguments */
11376 if (output_cfg == NULL)
11379 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11380 if (output_cfg->enable_sif_output) {
11381 switch (output_cfg->sif_attenuation) {
11382 case DRXJ_SIF_ATTENUATION_0DB: /* fallthrough */
11383 case DRXJ_SIF_ATTENUATION_3DB: /* fallthrough */
11384 case DRXJ_SIF_ATTENUATION_6DB: /* fallthrough */
11385 case DRXJ_SIF_ATTENUATION_9DB:
11393 if (ext_attr->sif_attenuation != output_cfg->sif_attenuation) {
11394 ext_attr->sif_attenuation = output_cfg->sif_attenuation;
11395 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_SIF_ATT;
11399 if (ext_attr->enable_cvbs_output != output_cfg->enable_cvbs_output) {
11400 ext_attr->enable_cvbs_output = output_cfg->enable_cvbs_output;
11401 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11404 if (ext_attr->enable_sif_output != output_cfg->enable_sif_output) {
11405 ext_attr->enable_sif_output = output_cfg->enable_sif_output;
11406 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11409 rc = atv_update_config(demod, false);
11411 pr_err("error %d\n", rc);
11420 /* -------------------------------------------------------------------------- */
11421 #ifndef DRXJ_DIGITAL_ONLY
11423 * \fn int ctrl_set_cfg_atv_equ_coef()
11424 * \brief Set ATV equalizer coefficients
11425 * \param demod instance of demodulator
11426 * \param coef the equalizer coefficients
11431 ctrl_set_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11433 struct drxj_data *ext_attr = NULL;
11437 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11439 /* current standard needs to be an ATV standard */
11440 if (!DRXJ_ISATVSTD(ext_attr->standard))
11443 /* Check arguments */
11444 if ((coef == NULL) ||
11445 (coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2)) ||
11446 (coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2)) ||
11447 (coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2)) ||
11448 (coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2)) ||
11449 (coef->coef0 < ((s16) ~(ATV_TOP_EQU0_EQU_C0__M >> 1))) ||
11450 (coef->coef1 < ((s16) ~(ATV_TOP_EQU1_EQU_C1__M >> 1))) ||
11451 (coef->coef2 < ((s16) ~(ATV_TOP_EQU2_EQU_C2__M >> 1))) ||
11452 (coef->coef3 < ((s16) ~(ATV_TOP_EQU3_EQU_C3__M >> 1)))) {
11456 rc = atv_equ_coef_index(ext_attr->standard, &index);
11458 pr_err("error %d\n", rc);
11461 ext_attr->atv_top_equ0[index] = coef->coef0;
11462 ext_attr->atv_top_equ1[index] = coef->coef1;
11463 ext_attr->atv_top_equ2[index] = coef->coef2;
11464 ext_attr->atv_top_equ3[index] = coef->coef3;
11465 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_COEF;
11467 rc = atv_update_config(demod, false);
11469 pr_err("error %d\n", rc);
11478 /* -------------------------------------------------------------------------- */
11480 * \fn int ctrl_get_cfg_atv_equ_coef()
11481 * \brief Get ATV equ coef settings
11482 * \param demod instance of demodulator
11483 * \param coef The ATV equ coefficients
11486 * The values are read from the shadow registers maintained by the drxdriver
11487 * If registers are manipulated outside of the drxdriver scope the reported
11488 * settings will not reflect these changes because of the use of shadow
11493 ctrl_get_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11495 struct drxj_data *ext_attr = NULL;
11499 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11501 /* current standard needs to be an ATV standard */
11502 if (!DRXJ_ISATVSTD(ext_attr->standard))
11505 /* Check arguments */
11509 rc = atv_equ_coef_index(ext_attr->standard, &index);
11511 pr_err("error %d\n", rc);
11514 coef->coef0 = ext_attr->atv_top_equ0[index];
11515 coef->coef1 = ext_attr->atv_top_equ1[index];
11516 coef->coef2 = ext_attr->atv_top_equ2[index];
11517 coef->coef3 = ext_attr->atv_top_equ3[index];
11524 /* -------------------------------------------------------------------------- */
11526 * \fn int ctrl_set_cfg_atv_misc()
11527 * \brief Set misc. settings for ATV.
11528 * \param demod instance of demodulator
11534 ctrl_set_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11536 struct drxj_data *ext_attr = NULL;
11539 /* Check arguments */
11540 if ((settings == NULL) ||
11541 ((settings->peak_filter) < (s16) (-8)) ||
11542 ((settings->peak_filter) > (s16) (15)) ||
11543 ((settings->noise_filter) > 15)) {
11547 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11549 if (settings->peak_filter != ext_attr->atv_top_vid_peak) {
11550 ext_attr->atv_top_vid_peak = settings->peak_filter;
11551 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_PEAK_FLT;
11554 if (settings->noise_filter != ext_attr->atv_top_noise_th) {
11555 ext_attr->atv_top_noise_th = settings->noise_filter;
11556 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_NOISE_FLT;
11559 rc = atv_update_config(demod, false);
11561 pr_err("error %d\n", rc);
11570 /* -------------------------------------------------------------------------- */
11572 * \fn int ctrl_get_cfg_atv_misc()
11573 * \brief Get misc settings of ATV.
11574 * \param demod instance of demodulator
11575 * \param settings misc. ATV settings
11578 * The values are read from the shadow registers maintained by the drxdriver
11579 * If registers are manipulated outside of the drxdriver scope the reported
11580 * settings will not reflect these changes because of the use of shadow
11584 ctrl_get_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11586 struct drxj_data *ext_attr = NULL;
11588 /* Check arguments */
11589 if (settings == NULL)
11592 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11594 settings->peak_filter = ext_attr->atv_top_vid_peak;
11595 settings->noise_filter = ext_attr->atv_top_noise_th;
11600 /* -------------------------------------------------------------------------- */
11602 /* -------------------------------------------------------------------------- */
11604 * \fn int ctrl_get_cfg_atv_output()
11606 * \param demod instance of demodulator
11607 * \param output_cfg output configuaration
11612 ctrl_get_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11617 /* Check arguments */
11618 if (output_cfg == NULL)
11621 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, ATV_TOP_STDBY__A, &data, 0);
11623 pr_err("error %d\n", rc);
11626 if (data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)
11627 output_cfg->enable_cvbs_output = true;
11629 output_cfg->enable_cvbs_output = false;
11631 if (data & ATV_TOP_STDBY_SIF_STDBY_STANDBY) {
11632 output_cfg->enable_sif_output = false;
11634 output_cfg->enable_sif_output = true;
11635 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, ATV_TOP_AF_SIF_ATT__A, &data, 0);
11637 pr_err("error %d\n", rc);
11640 output_cfg->sif_attenuation = (enum drxjsif_attenuation) data;
11648 /* -------------------------------------------------------------------------- */
11650 * \fn int ctrl_get_cfg_atv_agc_status()
11652 * \param demod instance of demodulator
11653 * \param agc_status agc status
11658 ctrl_get_cfg_atv_agc_status(struct drx_demod_instance *demod,
11659 struct drxj_cfg_atv_agc_status *agc_status)
11661 struct i2c_device_addr *dev_addr = NULL;
11666 /* Check arguments */
11667 if (agc_status == NULL)
11670 dev_addr = demod->my_i2c_dev_addr;
11673 RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
11674 = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
11676 IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
11678 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &data, 0);
11680 pr_err("error %d\n", rc);
11683 tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */
11684 agc_status->rf_agc_gain = (u16) (tmp / 1000); /* uA */
11686 if (tmp % 1000 >= 500)
11687 (agc_status->rf_agc_gain)++;
11690 IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
11691 = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
11693 IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
11695 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &data, 0);
11697 pr_err("error %d\n", rc);
11700 tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */
11701 agc_status->if_agc_gain = (u16) (tmp / 1000); /* uA */
11703 if (tmp % 1000 >= 500)
11704 (agc_status->if_agc_gain)++;
11707 videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
11708 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
11709 = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
11710 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
11711 = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
11714 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &data, 0);
11716 pr_err("error %d\n", rc);
11719 /* dividing by 32 inclusive rounding */
11721 if ((data & 1) != 0)
11724 agc_status->video_agc_gain = ((s16) data) - 75; /* 0.1 dB */
11727 audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
11728 = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
11729 = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
11730 = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
11731 = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
11734 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &data, 0);
11736 pr_err("error %d\n", rc);
11739 data &= SCU_RAM_ATV_SIF_GAIN__M;
11740 /* dividing by 2 inclusive rounding */
11741 if ((data & 1) != 0)
11744 agc_status->audio_agc_gain = ((s16) data) - 4; /* 0.1 dB */
11747 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
11749 pr_err("error %d\n", rc);
11752 agc_status->video_agc_loop_gain =
11753 ((data & SCU_RAM_AGC_KI_DGAIN__M) >> SCU_RAM_AGC_KI_DGAIN__B);
11754 agc_status->rf_agc_loop_gain =
11755 ((data & SCU_RAM_AGC_KI_RF__M) >> SCU_RAM_AGC_KI_RF__B);
11756 agc_status->if_agc_loop_gain =
11757 ((data & SCU_RAM_AGC_KI_IF__M) >> SCU_RAM_AGC_KI_IF__B);
11764 /* -------------------------------------------------------------------------- */
11767 * \fn int power_up_atv ()
11768 * \brief Power up ATV.
11769 * \param demod instance of demodulator
11770 * \param standard either NTSC or FM (sub strandard for ATV )
11773 * * Starts ATV and IQM
11774 * * AUdio already started during standard init for ATV.
11776 static int power_up_atv(struct drx_demod_instance *demod, enum drx_standard standard)
11778 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11782 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE, 0);
11784 pr_err("error %d\n", rc);
11787 /* turn on IQM_AF */
11788 rc = set_iqm_af(demod, true);
11790 pr_err("error %d\n", rc);
11793 rc = adc_synchronization(demod);
11795 pr_err("error %d\n", rc);
11799 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
11801 pr_err("error %d\n", rc);
11805 /* Audio, already done during set standard */
11811 #endif /* #ifndef DRXJ_DIGITAL_ONLY */
11813 /* -------------------------------------------------------------------------- */
11816 * \fn int power_down_atv ()
11817 * \brief Power down ATV.
11818 * \param demod instance of demodulator
11819 * \param standard either NTSC or FM (sub strandard for ATV )
11822 * Stops and thus resets ATV and IQM block
11823 * SIF and CVBS ADC are powered down
11824 * Calls audio power down
11827 power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
11829 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11830 struct drxjscu_cmd cmd_scu = { /* command */ 0,
11831 /* parameter_len */ 0,
11832 /* result_len */ 0,
11833 /* *parameter */ NULL,
11837 u16 cmd_result = 0;
11841 /* Stop ATV SCU (will reset ATV and IQM hardware */
11842 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
11843 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
11844 cmd_scu.parameter_len = 0;
11845 cmd_scu.result_len = 1;
11846 cmd_scu.parameter = NULL;
11847 cmd_scu.result = &cmd_result;
11848 rc = scu_command(dev_addr, &cmd_scu);
11850 pr_err("error %d\n", rc);
11853 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
11854 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
11856 pr_err("error %d\n", rc);
11860 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
11862 pr_err("error %d\n", rc);
11866 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
11868 pr_err("error %d\n", rc);
11871 rc = set_iqm_af(demod, false);
11873 pr_err("error %d\n", rc);
11877 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
11879 pr_err("error %d\n", rc);
11882 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
11884 pr_err("error %d\n", rc);
11887 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
11889 pr_err("error %d\n", rc);
11892 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
11894 pr_err("error %d\n", rc);
11897 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
11899 pr_err("error %d\n", rc);
11903 rc = power_down_aud(demod);
11905 pr_err("error %d\n", rc);
11914 /* -------------------------------------------------------------------------- */
11916 * \fn int set_atv_standard ()
11917 * \brief Set up ATV demodulator.
11918 * \param demod instance of demodulator
11919 * \param standard either NTSC or FM (sub strandard for ATV )
11922 * Init all channel independent registers.
11923 * Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
11926 #ifndef DRXJ_DIGITAL_ONLY
11927 #define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */
11929 set_atv_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
11931 /* TODO: enable alternative for tap settings via external file
11934 #ifdef DRXJ_ATV_COEF_FILE
11935 #include DRXJ_ATV_COEF_FILE
11937 ... code defining fixed coef's ...
11940 Cutsomer must create file "customer_coefs.c.inc" containing
11941 modified copy off the constants below, and define the compiler
11942 switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
11944 Still to check if this will work; DRXJ_16TO8 macro may cause
11947 const u8 ntsc_taps_re[] = {
11948 DRXJ_16TO8(-12), /* re0 */
11949 DRXJ_16TO8(-9), /* re1 */
11950 DRXJ_16TO8(9), /* re2 */
11951 DRXJ_16TO8(19), /* re3 */
11952 DRXJ_16TO8(-4), /* re4 */
11953 DRXJ_16TO8(-24), /* re5 */
11954 DRXJ_16TO8(-6), /* re6 */
11955 DRXJ_16TO8(16), /* re7 */
11956 DRXJ_16TO8(6), /* re8 */
11957 DRXJ_16TO8(-16), /* re9 */
11958 DRXJ_16TO8(-5), /* re10 */
11959 DRXJ_16TO8(13), /* re11 */
11960 DRXJ_16TO8(-2), /* re12 */
11961 DRXJ_16TO8(-20), /* re13 */
11962 DRXJ_16TO8(4), /* re14 */
11963 DRXJ_16TO8(25), /* re15 */
11964 DRXJ_16TO8(-6), /* re16 */
11965 DRXJ_16TO8(-36), /* re17 */
11966 DRXJ_16TO8(2), /* re18 */
11967 DRXJ_16TO8(38), /* re19 */
11968 DRXJ_16TO8(-10), /* re20 */
11969 DRXJ_16TO8(-48), /* re21 */
11970 DRXJ_16TO8(35), /* re22 */
11971 DRXJ_16TO8(94), /* re23 */
11972 DRXJ_16TO8(-59), /* re24 */
11973 DRXJ_16TO8(-217), /* re25 */
11974 DRXJ_16TO8(50), /* re26 */
11975 DRXJ_16TO8(679) /* re27 */
11977 const u8 ntsc_taps_im[] = {
11978 DRXJ_16TO8(11), /* im0 */
11979 DRXJ_16TO8(1), /* im1 */
11980 DRXJ_16TO8(-10), /* im2 */
11981 DRXJ_16TO8(2), /* im3 */
11982 DRXJ_16TO8(24), /* im4 */
11983 DRXJ_16TO8(21), /* im5 */
11984 DRXJ_16TO8(1), /* im6 */
11985 DRXJ_16TO8(-4), /* im7 */
11986 DRXJ_16TO8(7), /* im8 */
11987 DRXJ_16TO8(14), /* im9 */
11988 DRXJ_16TO8(27), /* im10 */
11989 DRXJ_16TO8(42), /* im11 */
11990 DRXJ_16TO8(22), /* im12 */
11991 DRXJ_16TO8(-20), /* im13 */
11992 DRXJ_16TO8(2), /* im14 */
11993 DRXJ_16TO8(98), /* im15 */
11994 DRXJ_16TO8(122), /* im16 */
11995 DRXJ_16TO8(0), /* im17 */
11996 DRXJ_16TO8(-85), /* im18 */
11997 DRXJ_16TO8(51), /* im19 */
11998 DRXJ_16TO8(247), /* im20 */
11999 DRXJ_16TO8(192), /* im21 */
12000 DRXJ_16TO8(-55), /* im22 */
12001 DRXJ_16TO8(-95), /* im23 */
12002 DRXJ_16TO8(217), /* im24 */
12003 DRXJ_16TO8(544), /* im25 */
12004 DRXJ_16TO8(553), /* im26 */
12005 DRXJ_16TO8(302) /* im27 */
12007 const u8 bg_taps_re[] = {
12008 DRXJ_16TO8(-18), /* re0 */
12009 DRXJ_16TO8(18), /* re1 */
12010 DRXJ_16TO8(19), /* re2 */
12011 DRXJ_16TO8(-26), /* re3 */
12012 DRXJ_16TO8(-20), /* re4 */
12013 DRXJ_16TO8(36), /* re5 */
12014 DRXJ_16TO8(5), /* re6 */
12015 DRXJ_16TO8(-51), /* re7 */
12016 DRXJ_16TO8(15), /* re8 */
12017 DRXJ_16TO8(45), /* re9 */
12018 DRXJ_16TO8(-46), /* re10 */
12019 DRXJ_16TO8(-24), /* re11 */
12020 DRXJ_16TO8(71), /* re12 */
12021 DRXJ_16TO8(-17), /* re13 */
12022 DRXJ_16TO8(-83), /* re14 */
12023 DRXJ_16TO8(74), /* re15 */
12024 DRXJ_16TO8(75), /* re16 */
12025 DRXJ_16TO8(-134), /* re17 */
12026 DRXJ_16TO8(-40), /* re18 */
12027 DRXJ_16TO8(191), /* re19 */
12028 DRXJ_16TO8(-11), /* re20 */
12029 DRXJ_16TO8(-233), /* re21 */
12030 DRXJ_16TO8(74), /* re22 */
12031 DRXJ_16TO8(271), /* re23 */
12032 DRXJ_16TO8(-132), /* re24 */
12033 DRXJ_16TO8(-341), /* re25 */
12034 DRXJ_16TO8(172), /* re26 */
12035 DRXJ_16TO8(801) /* re27 */
12037 const u8 bg_taps_im[] = {
12038 DRXJ_16TO8(-24), /* im0 */
12039 DRXJ_16TO8(-10), /* im1 */
12040 DRXJ_16TO8(9), /* im2 */
12041 DRXJ_16TO8(-5), /* im3 */
12042 DRXJ_16TO8(-51), /* im4 */
12043 DRXJ_16TO8(-17), /* im5 */
12044 DRXJ_16TO8(31), /* im6 */
12045 DRXJ_16TO8(-48), /* im7 */
12046 DRXJ_16TO8(-95), /* im8 */
12047 DRXJ_16TO8(25), /* im9 */
12048 DRXJ_16TO8(37), /* im10 */
12049 DRXJ_16TO8(-123), /* im11 */
12050 DRXJ_16TO8(-77), /* im12 */
12051 DRXJ_16TO8(94), /* im13 */
12052 DRXJ_16TO8(-10), /* im14 */
12053 DRXJ_16TO8(-149), /* im15 */
12054 DRXJ_16TO8(10), /* im16 */
12055 DRXJ_16TO8(108), /* im17 */
12056 DRXJ_16TO8(-49), /* im18 */
12057 DRXJ_16TO8(-59), /* im19 */
12058 DRXJ_16TO8(90), /* im20 */
12059 DRXJ_16TO8(73), /* im21 */
12060 DRXJ_16TO8(55), /* im22 */
12061 DRXJ_16TO8(148), /* im23 */
12062 DRXJ_16TO8(86), /* im24 */
12063 DRXJ_16TO8(146), /* im25 */
12064 DRXJ_16TO8(687), /* im26 */
12065 DRXJ_16TO8(877) /* im27 */
12067 const u8 dk_i_l_lp_taps_re[] = {
12068 DRXJ_16TO8(-23), /* re0 */
12069 DRXJ_16TO8(9), /* re1 */
12070 DRXJ_16TO8(16), /* re2 */
12071 DRXJ_16TO8(-26), /* re3 */
12072 DRXJ_16TO8(-3), /* re4 */
12073 DRXJ_16TO8(13), /* re5 */
12074 DRXJ_16TO8(-19), /* re6 */
12075 DRXJ_16TO8(-3), /* re7 */
12076 DRXJ_16TO8(13), /* re8 */
12077 DRXJ_16TO8(-26), /* re9 */
12078 DRXJ_16TO8(-4), /* re10 */
12079 DRXJ_16TO8(28), /* re11 */
12080 DRXJ_16TO8(-15), /* re12 */
12081 DRXJ_16TO8(-14), /* re13 */
12082 DRXJ_16TO8(10), /* re14 */
12083 DRXJ_16TO8(1), /* re15 */
12084 DRXJ_16TO8(39), /* re16 */
12085 DRXJ_16TO8(-18), /* re17 */
12086 DRXJ_16TO8(-90), /* re18 */
12087 DRXJ_16TO8(109), /* re19 */
12088 DRXJ_16TO8(113), /* re20 */
12089 DRXJ_16TO8(-235), /* re21 */
12090 DRXJ_16TO8(-49), /* re22 */
12091 DRXJ_16TO8(359), /* re23 */
12092 DRXJ_16TO8(-79), /* re24 */
12093 DRXJ_16TO8(-459), /* re25 */
12094 DRXJ_16TO8(206), /* re26 */
12095 DRXJ_16TO8(894) /* re27 */
12097 const u8 dk_i_l_lp_taps_im[] = {
12098 DRXJ_16TO8(-8), /* im0 */
12099 DRXJ_16TO8(-20), /* im1 */
12100 DRXJ_16TO8(17), /* im2 */
12101 DRXJ_16TO8(-14), /* im3 */
12102 DRXJ_16TO8(-52), /* im4 */
12103 DRXJ_16TO8(4), /* im5 */
12104 DRXJ_16TO8(9), /* im6 */
12105 DRXJ_16TO8(-62), /* im7 */
12106 DRXJ_16TO8(-47), /* im8 */
12107 DRXJ_16TO8(0), /* im9 */
12108 DRXJ_16TO8(-20), /* im10 */
12109 DRXJ_16TO8(-48), /* im11 */
12110 DRXJ_16TO8(-65), /* im12 */
12111 DRXJ_16TO8(-23), /* im13 */
12112 DRXJ_16TO8(44), /* im14 */
12113 DRXJ_16TO8(-60), /* im15 */
12114 DRXJ_16TO8(-113), /* im16 */
12115 DRXJ_16TO8(92), /* im17 */
12116 DRXJ_16TO8(81), /* im18 */
12117 DRXJ_16TO8(-125), /* im19 */
12118 DRXJ_16TO8(28), /* im20 */
12119 DRXJ_16TO8(182), /* im21 */
12120 DRXJ_16TO8(35), /* im22 */
12121 DRXJ_16TO8(94), /* im23 */
12122 DRXJ_16TO8(180), /* im24 */
12123 DRXJ_16TO8(134), /* im25 */
12124 DRXJ_16TO8(657), /* im26 */
12125 DRXJ_16TO8(1023) /* im27 */
12127 const u8 fm_taps_re[] = {
12128 DRXJ_16TO8(0), /* re0 */
12129 DRXJ_16TO8(0), /* re1 */
12130 DRXJ_16TO8(0), /* re2 */
12131 DRXJ_16TO8(0), /* re3 */
12132 DRXJ_16TO8(0), /* re4 */
12133 DRXJ_16TO8(0), /* re5 */
12134 DRXJ_16TO8(0), /* re6 */
12135 DRXJ_16TO8(0), /* re7 */
12136 DRXJ_16TO8(0), /* re8 */
12137 DRXJ_16TO8(0), /* re9 */
12138 DRXJ_16TO8(0), /* re10 */
12139 DRXJ_16TO8(0), /* re11 */
12140 DRXJ_16TO8(0), /* re12 */
12141 DRXJ_16TO8(0), /* re13 */
12142 DRXJ_16TO8(0), /* re14 */
12143 DRXJ_16TO8(0), /* re15 */
12144 DRXJ_16TO8(0), /* re16 */
12145 DRXJ_16TO8(0), /* re17 */
12146 DRXJ_16TO8(0), /* re18 */
12147 DRXJ_16TO8(0), /* re19 */
12148 DRXJ_16TO8(0), /* re20 */
12149 DRXJ_16TO8(0), /* re21 */
12150 DRXJ_16TO8(0), /* re22 */
12151 DRXJ_16TO8(0), /* re23 */
12152 DRXJ_16TO8(0), /* re24 */
12153 DRXJ_16TO8(0), /* re25 */
12154 DRXJ_16TO8(0), /* re26 */
12155 DRXJ_16TO8(0) /* re27 */
12157 const u8 fm_taps_im[] = {
12158 DRXJ_16TO8(-6), /* im0 */
12159 DRXJ_16TO8(2), /* im1 */
12160 DRXJ_16TO8(14), /* im2 */
12161 DRXJ_16TO8(-38), /* im3 */
12162 DRXJ_16TO8(58), /* im4 */
12163 DRXJ_16TO8(-62), /* im5 */
12164 DRXJ_16TO8(42), /* im6 */
12165 DRXJ_16TO8(0), /* im7 */
12166 DRXJ_16TO8(-45), /* im8 */
12167 DRXJ_16TO8(73), /* im9 */
12168 DRXJ_16TO8(-65), /* im10 */
12169 DRXJ_16TO8(23), /* im11 */
12170 DRXJ_16TO8(34), /* im12 */
12171 DRXJ_16TO8(-77), /* im13 */
12172 DRXJ_16TO8(80), /* im14 */
12173 DRXJ_16TO8(-39), /* im15 */
12174 DRXJ_16TO8(-25), /* im16 */
12175 DRXJ_16TO8(78), /* im17 */
12176 DRXJ_16TO8(-90), /* im18 */
12177 DRXJ_16TO8(52), /* im19 */
12178 DRXJ_16TO8(16), /* im20 */
12179 DRXJ_16TO8(-77), /* im21 */
12180 DRXJ_16TO8(97), /* im22 */
12181 DRXJ_16TO8(-62), /* im23 */
12182 DRXJ_16TO8(-8), /* im24 */
12183 DRXJ_16TO8(75), /* im25 */
12184 DRXJ_16TO8(-100), /* im26 */
12185 DRXJ_16TO8(70) /* im27 */
12188 struct i2c_device_addr *dev_addr = NULL;
12189 struct drxjscu_cmd cmd_scu = { /* command */ 0,
12190 /* parameter_len */ 0,
12191 /* result_len */ 0,
12192 /* *parameter */ NULL,
12195 u16 cmd_result = 0;
12197 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
12198 struct drxu_code_info ucode_info;
12199 struct drx_common_attr *common_attr = NULL;
12200 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
12201 struct drxj_data *ext_attr = NULL;
12204 ext_attr = (struct drxj_data *) demod->my_ext_attr;
12205 dev_addr = demod->my_i2c_dev_addr;
12207 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
12208 common_attr = demod->my_common_attr;
12210 /* Check if audio microcode is already uploaded */
12211 if (!(ext_attr->flag_aud_mc_uploaded)) {
12212 ucode_info.mc_data = common_attr->microcode;
12214 /* Upload only audio microcode */
12215 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_UPLOAD, true);
12217 pr_err("error %d\n", rc);
12221 if (common_attr->verify_microcode == true) {
12222 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_VERIFY, true);
12224 pr_err("error %d\n", rc);
12229 /* Prevent uploading audio microcode again */
12230 ext_attr->flag_aud_mc_uploaded = true;
12232 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
12234 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
12236 pr_err("error %d\n", rc);
12239 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
12241 pr_err("error %d\n", rc);
12244 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
12246 pr_err("error %d\n", rc);
12249 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
12251 pr_err("error %d\n", rc);
12254 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
12256 pr_err("error %d\n", rc);
12259 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
12261 pr_err("error %d\n", rc);
12264 /* Reset ATV SCU */
12265 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12266 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
12267 cmd_scu.parameter_len = 0;
12268 cmd_scu.result_len = 1;
12269 cmd_scu.parameter = NULL;
12270 cmd_scu.result = &cmd_result;
12271 rc = scu_command(dev_addr, &cmd_scu);
12273 pr_err("error %d\n", rc);
12277 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE, 0);
12279 pr_err("error %d\n", rc);
12283 /* TODO remove AUTO/OFF patches after ucode fix. */
12284 switch (*standard) {
12285 case DRX_STANDARD_NTSC:
12287 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_MN;
12289 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, IQM_RT_LO_INCR_MN, 0);
12291 pr_err("error %d\n", rc);
12294 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12296 pr_err("error %d\n", rc);
12299 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(ntsc_taps_re), ((u8 *)ntsc_taps_re), 0);
12301 pr_err("error %d\n", rc);
12304 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(ntsc_taps_im), ((u8 *)ntsc_taps_im), 0);
12306 pr_err("error %d\n", rc);
12310 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_MN, 0);
12312 pr_err("error %d\n", rc);
12315 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_MN | ATV_TOP_CR_CONT_CR_D_MN | ATV_TOP_CR_CONT_CR_I_MN), 0);
12317 pr_err("error %d\n", rc);
12320 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_MN, 0);
12322 pr_err("error %d\n", rc);
12325 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_MN | ATV_TOP_STD_VID_POL_MN), 0);
12327 pr_err("error %d\n", rc);
12330 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_MN, 0);
12332 pr_err("error %d\n", rc);
12336 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
12338 pr_err("error %d\n", rc);
12341 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12343 pr_err("error %d\n", rc);
12346 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12348 pr_err("error %d\n", rc);
12351 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN, 0);
12353 pr_err("error %d\n", rc);
12356 ext_attr->phase_correction_bypass = false;
12357 ext_attr->enable_cvbs_output = true;
12359 case DRX_STANDARD_FM:
12361 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_FM;
12363 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2994, 0);
12365 pr_err("error %d\n", rc);
12368 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 0, 0);
12370 pr_err("error %d\n", rc);
12373 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(fm_taps_re), ((u8 *)fm_taps_re), 0);
12375 pr_err("error %d\n", rc);
12378 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(fm_taps_im), ((u8 *)fm_taps_im), 0);
12380 pr_err("error %d\n", rc);
12383 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_FM | ATV_TOP_STD_VID_POL_FM), 0);
12385 pr_err("error %d\n", rc);
12388 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_CONTROL__A, 0, 0);
12390 pr_err("error %d\n", rc);
12393 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, 0, 0);
12395 pr_err("error %d\n", rc);
12399 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW | SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM), 0);
12401 pr_err("error %d\n", rc);
12404 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF, 0);
12406 pr_err("error %d\n", rc);
12409 ext_attr->phase_correction_bypass = true;
12410 ext_attr->enable_cvbs_output = false;
12412 case DRX_STANDARD_PAL_SECAM_BG:
12413 /* PAL/SECAM B/G */
12414 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_B;
12416 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 1820, 0);
12418 pr_err("error %d\n", rc);
12420 } /* TODO check with IS */
12421 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12423 pr_err("error %d\n", rc);
12426 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(bg_taps_re), ((u8 *)bg_taps_re), 0);
12428 pr_err("error %d\n", rc);
12431 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(bg_taps_im), ((u8 *)bg_taps_im), 0);
12433 pr_err("error %d\n", rc);
12436 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_BG, 0);
12438 pr_err("error %d\n", rc);
12441 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG, 0);
12443 pr_err("error %d\n", rc);
12446 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_BG | ATV_TOP_CR_CONT_CR_D_BG | ATV_TOP_CR_CONT_CR_I_BG), 0);
12448 pr_err("error %d\n", rc);
12451 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_BG, 0);
12453 pr_err("error %d\n", rc);
12456 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_BG | ATV_TOP_STD_VID_POL_BG), 0);
12458 pr_err("error %d\n", rc);
12461 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
12463 pr_err("error %d\n", rc);
12466 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12468 pr_err("error %d\n", rc);
12471 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12473 pr_err("error %d\n", rc);
12476 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN, 0);
12478 pr_err("error %d\n", rc);
12481 ext_attr->phase_correction_bypass = false;
12482 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12483 ext_attr->enable_cvbs_output = true;
12485 case DRX_STANDARD_PAL_SECAM_DK:
12486 /* PAL/SECAM D/K */
12487 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_DK;
12489 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12491 pr_err("error %d\n", rc);
12493 } /* TODO check with IS */
12494 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12496 pr_err("error %d\n", rc);
12499 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
12501 pr_err("error %d\n", rc);
12504 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
12506 pr_err("error %d\n", rc);
12509 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_DK, 0);
12511 pr_err("error %d\n", rc);
12514 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_DK, 0);
12516 pr_err("error %d\n", rc);
12519 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_DK | ATV_TOP_CR_CONT_CR_D_DK | ATV_TOP_CR_CONT_CR_I_DK), 0);
12521 pr_err("error %d\n", rc);
12524 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_DK, 0);
12526 pr_err("error %d\n", rc);
12529 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_DK | ATV_TOP_STD_VID_POL_DK), 0);
12531 pr_err("error %d\n", rc);
12534 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
12536 pr_err("error %d\n", rc);
12539 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12541 pr_err("error %d\n", rc);
12544 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12546 pr_err("error %d\n", rc);
12549 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_DK, 0);
12551 pr_err("error %d\n", rc);
12554 ext_attr->phase_correction_bypass = false;
12555 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12556 ext_attr->enable_cvbs_output = true;
12558 case DRX_STANDARD_PAL_SECAM_I:
12560 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_I;
12562 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12564 pr_err("error %d\n", rc);
12566 } /* TODO check with IS */
12567 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12569 pr_err("error %d\n", rc);
12572 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
12574 pr_err("error %d\n", rc);
12577 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
12579 pr_err("error %d\n", rc);
12582 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_I, 0);
12584 pr_err("error %d\n", rc);
12587 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_I, 0);
12589 pr_err("error %d\n", rc);
12592 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_I | ATV_TOP_CR_CONT_CR_D_I | ATV_TOP_CR_CONT_CR_I_I), 0);
12594 pr_err("error %d\n", rc);
12597 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_I, 0);
12599 pr_err("error %d\n", rc);
12602 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_I | ATV_TOP_STD_VID_POL_I), 0);
12604 pr_err("error %d\n", rc);
12607 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
12609 pr_err("error %d\n", rc);
12612 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12614 pr_err("error %d\n", rc);
12617 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12619 pr_err("error %d\n", rc);
12622 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_I, 0);
12624 pr_err("error %d\n", rc);
12627 ext_attr->phase_correction_bypass = false;
12628 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12629 ext_attr->enable_cvbs_output = true;
12631 case DRX_STANDARD_PAL_SECAM_L:
12632 /* PAL/SECAM L with negative modulation */
12633 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_L;
12635 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12637 pr_err("error %d\n", rc);
12639 } /* TODO check with IS */
12640 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_L, 0);
12642 pr_err("error %d\n", rc);
12645 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12647 pr_err("error %d\n", rc);
12650 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
12652 pr_err("error %d\n", rc);
12655 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
12657 pr_err("error %d\n", rc);
12660 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12662 pr_err("error %d\n", rc);
12664 } /* TODO check with IS */
12665 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_L | ATV_TOP_CR_CONT_CR_D_L | ATV_TOP_CR_CONT_CR_I_L), 0);
12667 pr_err("error %d\n", rc);
12670 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_L, 0);
12672 pr_err("error %d\n", rc);
12675 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_L | ATV_TOP_STD_VID_POL_L), 0);
12677 pr_err("error %d\n", rc);
12680 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM | SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE | SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW), 0);
12682 pr_err("error %d\n", rc);
12685 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12687 pr_err("error %d\n", rc);
12690 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12692 pr_err("error %d\n", rc);
12695 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP, 0);
12697 pr_err("error %d\n", rc);
12700 ext_attr->phase_correction_bypass = false;
12701 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12702 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12703 ext_attr->enable_cvbs_output = true;
12705 case DRX_STANDARD_PAL_SECAM_LP:
12706 /* PAL/SECAM L with positive modulation */
12707 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_LP;
12709 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_LP, 0);
12711 pr_err("error %d\n", rc);
12714 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12716 pr_err("error %d\n", rc);
12718 } /* TODO check with IS */
12719 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12721 pr_err("error %d\n", rc);
12724 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
12726 pr_err("error %d\n", rc);
12729 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
12731 pr_err("error %d\n", rc);
12734 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12736 pr_err("error %d\n", rc);
12738 } /* TODO check with IS */
12739 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_LP | ATV_TOP_CR_CONT_CR_D_LP | ATV_TOP_CR_CONT_CR_I_LP), 0);
12741 pr_err("error %d\n", rc);
12744 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_LP, 0);
12746 pr_err("error %d\n", rc);
12749 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_LP | ATV_TOP_STD_VID_POL_LP), 0);
12751 pr_err("error %d\n", rc);
12754 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM | SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE | SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW), 0);
12756 pr_err("error %d\n", rc);
12759 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12761 pr_err("error %d\n", rc);
12764 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12766 pr_err("error %d\n", rc);
12769 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP, 0);
12771 pr_err("error %d\n", rc);
12774 ext_attr->phase_correction_bypass = false;
12775 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12776 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12777 ext_attr->enable_cvbs_output = true;
12783 /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
12784 if (!ext_attr->has_lna) {
12785 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x01, 0);
12787 pr_err("error %d\n", rc);
12792 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_STANDARD__A, 0x002, 0);
12794 pr_err("error %d\n", rc);
12797 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, IQM_AF_CLP_LEN_ATV, 0);
12799 pr_err("error %d\n", rc);
12802 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, IQM_AF_CLP_TH_ATV, 0);
12804 pr_err("error %d\n", rc);
12807 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, IQM_AF_SNS_LEN_ATV, 0);
12809 pr_err("error %d\n", rc);
12812 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12814 pr_err("error %d\n", rc);
12817 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_IF__A, 10248, 0);
12819 pr_err("error %d\n", rc);
12823 ext_attr->iqm_rc_rate_ofs = 0x00200000L;
12824 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
12826 pr_err("error %d\n", rc);
12829 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_OFF, 0);
12831 pr_err("error %d\n", rc);
12834 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, IQM_RC_STRETCH_ATV, 0);
12836 pr_err("error %d\n", rc);
12840 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ACTIVE__A, IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_ON | IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_ON, 0);
12842 pr_err("error %d\n", rc);
12846 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_ATV__M, 0);
12848 pr_err("error %d\n", rc);
12851 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, IQM_CF_SYMMETRIC_IM__M, 0);
12853 pr_err("error %d\n", rc);
12856 /* default: SIF in standby */
12857 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_SYNC_SLICE__A, ATV_TOP_SYNC_SLICE_MN, 0);
12859 pr_err("error %d\n", rc);
12862 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_ACCU__A, ATV_TOP_MOD_ACCU__PRE, 0);
12864 pr_err("error %d\n", rc);
12868 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, 0x080, 0);
12870 pr_err("error %d\n", rc);
12873 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_FAGC_TH_RED__A, 10, 0);
12875 pr_err("error %d\n", rc);
12878 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AAGC_CNT__A, 7, 0);
12880 pr_err("error %d\n", rc);
12883 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_NAGC_KI_MIN__A, 0x0225, 0);
12885 pr_err("error %d\n", rc);
12888 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_NAGC_KI_MAX__A, 0x0547, 0);
12890 pr_err("error %d\n", rc);
12893 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_KI_CHANGE_TH__A, 20, 0);
12895 pr_err("error %d\n", rc);
12898 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_LOCK__A, 0, 0);
12900 pr_err("error %d\n", rc);
12904 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_DELAY__A, IQM_RT_DELAY__PRE, 0);
12906 pr_err("error %d\n", rc);
12909 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BPC_KI_MIN__A, 531, 0);
12911 pr_err("error %d\n", rc);
12914 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061, 0);
12916 pr_err("error %d\n", rc);
12919 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_REF_MIN__A, 100, 0);
12921 pr_err("error %d\n", rc);
12924 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_REF_MAX__A, 260, 0);
12926 pr_err("error %d\n", rc);
12929 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_LVL__A, 0, 0);
12931 pr_err("error %d\n", rc);
12934 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX__A, 0, 0);
12936 pr_err("error %d\n", rc);
12939 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MIN__A, 2047, 0);
12941 pr_err("error %d\n", rc);
12944 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
12946 pr_err("error %d\n", rc);
12950 /* Override reset values with current shadow settings */
12951 rc = atv_update_config(demod, true);
12953 pr_err("error %d\n", rc);
12957 /* Configure/restore AGC settings */
12958 rc = init_agc(demod);
12960 pr_err("error %d\n", rc);
12963 rc = set_agc_if(demod, &(ext_attr->atv_if_agc_cfg), false);
12965 pr_err("error %d\n", rc);
12968 rc = set_agc_rf(demod, &(ext_attr->atv_rf_agc_cfg), false);
12970 pr_err("error %d\n", rc);
12973 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12975 pr_err("error %d\n", rc);
12979 /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
12980 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12981 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
12982 cmd_scu.parameter_len = 1;
12983 cmd_scu.result_len = 1;
12984 cmd_scu.parameter = &cmd_param;
12985 cmd_scu.result = &cmd_result;
12986 rc = scu_command(dev_addr, &cmd_scu);
12988 pr_err("error %d\n", rc);
12992 /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
12993 if (ext_attr->mfx == 0x03) {
12994 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0, 0);
12996 pr_err("error %d\n", rc);
13000 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1, 0);
13002 pr_err("error %d\n", rc);
13005 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_IIR_CRIT__A, 225, 0);
13007 pr_err("error %d\n", rc);
13018 /* -------------------------------------------------------------------------- */
13020 #ifndef DRXJ_DIGITAL_ONLY
13022 * \fn int set_atv_channel ()
13023 * \brief Set ATV channel.
13024 * \param demod: instance of demod.
13027 * Not much needs to be done here, only start the SCU for NTSC/FM.
13028 * Mirrored channels are not expected in the RF domain, so IQM FS setting
13029 * doesn't need to be remembered.
13030 * The channel->mirror parameter is therefor ignored.
13034 set_atv_channel(struct drx_demod_instance *demod,
13035 s32 tuner_freq_offset,
13036 struct drx_channel *channel, enum drx_standard standard)
13038 struct drxjscu_cmd cmd_scu = { /* command */ 0,
13039 /* parameter_len */ 0,
13040 /* result_len */ 0,
13041 /* parameter */ NULL,
13044 u16 cmd_result = 0;
13045 struct drxj_data *ext_attr = NULL;
13046 struct i2c_device_addr *dev_addr = NULL;
13049 dev_addr = demod->my_i2c_dev_addr;
13050 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13053 Program frequency shifter
13054 No need to account for mirroring on RF
13056 if (channel->mirror == DRX_MIRROR_AUTO)
13057 ext_attr->mirror = DRX_MIRROR_NO;
13059 ext_attr->mirror = channel->mirror;
13061 rc = set_frequency(demod, channel, tuner_freq_offset);
13063 pr_err("error %d\n", rc);
13066 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE, 0);
13068 pr_err("error %d\n", rc);
13072 /* Start ATV SCU */
13073 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
13074 SCU_RAM_COMMAND_CMD_DEMOD_START;
13075 cmd_scu.parameter_len = 0;
13076 cmd_scu.result_len = 1;
13077 cmd_scu.parameter = NULL;
13078 cmd_scu.result = &cmd_result;
13079 rc = scu_command(dev_addr, &cmd_scu);
13081 pr_err("error %d\n", rc);
13085 /* if ( (ext_attr->standard == DRX_STANDARD_FM) && (ext_attr->flagSetAUDdone == true) )
13087 ext_attr->detectedRDS = (bool)false;
13096 /* -------------------------------------------------------------------------- */
13099 * \fn int get_atv_channel ()
13100 * \brief Set ATV channel.
13101 * \param demod: instance of demod.
13102 * \param channel: pointer to channel data.
13103 * \param standard: NTSC or FM.
13106 * Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
13107 * Computes the frequency offset in te RF domain and adds it to
13108 * channel->frequency. Determines the value for channel->bandwidth.
13111 #ifndef DRXJ_DIGITAL_ONLY
13113 get_atv_channel(struct drx_demod_instance *demod,
13114 struct drx_channel *channel, enum drx_standard standard)
13117 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
13121 channel->bandwidth = ((struct drxj_data *) demod->my_ext_attr)->curr_bandwidth;
13123 switch (standard) {
13124 case DRX_STANDARD_NTSC:
13125 case DRX_STANDARD_PAL_SECAM_BG:
13126 case DRX_STANDARD_PAL_SECAM_DK:
13127 case DRX_STANDARD_PAL_SECAM_I:
13128 case DRX_STANDARD_PAL_SECAM_L:
13130 u16 measured_offset = 0;
13132 /* get measured frequency offset */
13133 rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13135 pr_err("error %d\n", rc);
13138 /* Signed 8 bit register => sign extension needed */
13139 if ((measured_offset & 0x0080) != 0)
13140 measured_offset |= 0xFF80;
13142 (s32) (((s16) measured_offset) * 10);
13145 case DRX_STANDARD_PAL_SECAM_LP:
13147 u16 measured_offset = 0;
13149 /* get measured frequency offset */
13150 rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13152 pr_err("error %d\n", rc);
13155 /* Signed 8 bit register => sign extension needed */
13156 if ((measured_offset & 0x0080) != 0)
13157 measured_offset |= 0xFF80;
13159 (s32) (((s16) measured_offset) * 10);
13162 case DRX_STANDARD_FM:
13163 /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
13164 AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
13166 /* No bandwidth know for FM */
13167 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
13173 channel->frequency -= offset;
13180 /* -------------------------------------------------------------------------- */
13182 * \fn int get_atv_sig_strength()
13183 * \brief Retrieve signal strength for ATV & FM.
13184 * \param devmod Pointer to demodulator instance.
13185 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
13187 * \retval 0 sig_strength contains valid data.
13188 * \retval -EIO Erroneous data, sig_strength equals 0.
13190 * Taking into account:
13192 * * IF gain (not implemented yet, waiting for IF gain control by ucode)
13195 * All weights (digital, if, rf) must add up to 100.
13197 * TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
13201 get_atv_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
13203 struct i2c_device_addr *dev_addr = NULL;
13204 struct drxj_data *ext_attr = NULL;
13207 /* All weights must add up to 100 (%)
13208 TODO: change weights when IF ctrl is available */
13209 u32 digital_weight = 50; /* 0 .. 100 */
13210 u32 rf_weight = 50; /* 0 .. 100 */
13211 u32 if_weight = 0; /* 0 .. 100 */
13213 u16 digital_curr_gain = 0;
13214 u32 digital_max_gain = 0;
13215 u32 digital_min_gain = 0;
13216 u16 rf_curr_gain = 0;
13217 u32 rf_max_gain = 0x800; /* taken from ucode */
13218 u32 rf_min_gain = 0x7fff;
13219 u16 if_curr_gain = 0;
13220 u32 if_max_gain = 0x800; /* taken from ucode */
13221 u32 if_min_gain = 0x7fff;
13223 u32 digital_strength = 0; /* 0.. 100 */
13224 u32 rf_strength = 0; /* 0.. 100 */
13225 u32 if_strength = 0; /* 0.. 100 */
13227 dev_addr = demod->my_i2c_dev_addr;
13228 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13232 switch (ext_attr->standard) {
13233 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13234 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13235 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13236 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13237 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
13238 case DRX_STANDARD_NTSC:
13239 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &digital_curr_gain, 0);
13241 pr_err("error %d\n", rc);
13244 digital_max_gain = 22512; /* taken from ucode */
13245 digital_min_gain = 2400; /* taken from ucode */
13247 case DRX_STANDARD_FM:
13248 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &digital_curr_gain, 0);
13250 pr_err("error %d\n", rc);
13253 digital_max_gain = 0x4ff; /* taken from ucode */
13254 digital_min_gain = 0; /* taken from ucode */
13260 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &rf_curr_gain, 0);
13262 pr_err("error %d\n", rc);
13265 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &if_curr_gain, 0);
13267 pr_err("error %d\n", rc);
13272 if (digital_curr_gain >= digital_max_gain)
13273 digital_curr_gain = (u16)digital_max_gain;
13274 if (digital_curr_gain <= digital_min_gain)
13275 digital_curr_gain = (u16)digital_min_gain;
13276 if (if_curr_gain <= if_max_gain)
13277 if_curr_gain = (u16)if_max_gain;
13278 if (if_curr_gain >= if_min_gain)
13279 if_curr_gain = (u16)if_min_gain;
13280 if (rf_curr_gain <= rf_max_gain)
13281 rf_curr_gain = (u16)rf_max_gain;
13282 if (rf_curr_gain >= rf_min_gain)
13283 rf_curr_gain = (u16)rf_min_gain;
13285 /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
13286 of clipping at ADC */
13288 /* Compute signal strength (in %) per "gain domain" */
13291 /* TODO: ADC clipping not handled */
13292 digital_strength = (100 * (digital_max_gain - (u32) digital_curr_gain)) /
13293 (digital_max_gain - digital_min_gain);
13295 /* TODO: IF gain not implemented yet in microcode, check after impl. */
13296 if_strength = (100 * ((u32) if_curr_gain - if_max_gain)) /
13297 (if_min_gain - if_max_gain);
13300 /* TODO: ADC clipping not handled */
13301 rf_strength = (100 * ((u32) rf_curr_gain - rf_max_gain)) /
13302 (rf_min_gain - rf_max_gain);
13304 /* Compute a weighted signal strength (in %) */
13305 *sig_strength = (u16) (digital_weight * digital_strength +
13306 rf_weight * rf_strength + if_weight * if_strength);
13307 *sig_strength /= 100;
13314 /* -------------------------------------------------------------------------- */
13316 * \fn int atv_sig_quality()
13317 * \brief Retrieve signal quality indication for ATV.
13318 * \param devmod Pointer to demodulator instance.
13319 * \param sig_quality Pointer to signal quality structure.
13321 * \retval 0 sig_quality contains valid data.
13322 * \retval -EIO Erroneous data, sig_quality indicator equals 0.
13327 atv_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
13329 struct i2c_device_addr *dev_addr = NULL;
13330 u16 quality_indicator = 0;
13333 dev_addr = demod->my_i2c_dev_addr;
13335 /* defined values for fields not used */
13336 sig_quality->MER = 0;
13337 sig_quality->pre_viterbi_ber = 0;
13338 sig_quality->post_viterbi_ber = 0;
13339 sig_quality->scale_factor_ber = 1;
13340 sig_quality->packet_error = 0;
13341 sig_quality->post_reed_solomon_ber = 0;
13345 0x000..0x080: strong signal => 80% .. 100%
13346 0x080..0x700: weak signal => 30% .. 80%
13347 0x700..0x7ff: no signal => 0% .. 30%
13350 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_CR_LOCK__A, &quality_indicator, 0);
13352 pr_err("error %d\n", rc);
13355 quality_indicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
13356 if (quality_indicator <= 0x80) {
13357 sig_quality->indicator =
13358 80 + ((20 * (0x80 - quality_indicator)) / 0x80);
13359 } else if (quality_indicator <= 0x700)
13360 sig_quality->indicator = 30 + ((50 * (0x700 - quality_indicator)) / (0x700 - 0x81));
13362 sig_quality->indicator = (30 * (0x7FF - quality_indicator)) / (0x7FF - 0x701);
13368 #endif /* DRXJ_DIGITAL_ONLY */
13370 /*============================================================================*/
13371 /*== END ATV DATAPATH FUNCTIONS ==*/
13372 /*============================================================================*/
13374 #ifndef DRXJ_EXCLUDE_AUDIO
13375 /*===========================================================================*/
13376 /*===========================================================================*/
13377 /*== AUDIO DATAPATH FUNCTIONS ==*/
13378 /*===========================================================================*/
13379 /*===========================================================================*/
13382 * \brief Power up AUD.
13383 * \param demod instance of demodulator
13387 static int power_up_aud(struct drx_demod_instance *demod, bool set_standard)
13389 enum drx_aud_standard aud_standard = DRX_AUD_STANDARD_AUTO;
13390 struct i2c_device_addr *dev_addr = NULL;
13393 dev_addr = demod->my_i2c_dev_addr;
13395 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE, 0);
13397 pr_err("error %d\n", rc);
13400 /* setup TR interface: R/W mode, fifosize=8 */
13401 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_TOP_TR_MDE__A, 8, 0);
13403 pr_err("error %d\n", rc);
13406 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE, 0);
13408 pr_err("error %d\n", rc);
13412 if (set_standard) {
13413 rc = aud_ctrl_set_standard(demod, &aud_standard);
13415 pr_err("error %d\n", rc);
13425 /*============================================================================*/
13428 * \brief Power up AUD.
13429 * \param demod instance of demodulator
13433 static int power_down_aud(struct drx_demod_instance *demod)
13435 struct i2c_device_addr *dev_addr = NULL;
13436 struct drxj_data *ext_attr = NULL;
13439 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13440 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13442 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
13444 pr_err("error %d\n", rc);
13448 ext_attr->aud_data.audio_is_active = false;
13455 /*============================================================================*/
13457 * \brief Get Modus data from audio RAM
13458 * \param demod instance of demodulator
13459 * \param pointer to modus
13463 static int aud_get_modus(struct drx_demod_instance *demod, u16 *modus)
13465 struct i2c_device_addr *dev_addr = NULL;
13466 struct drxj_data *ext_attr = NULL;
13470 u16 r_modus_hi = 0;
13471 u16 r_modus_lo = 0;
13476 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13477 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13480 if (ext_attr->aud_data.audio_is_active == false) {
13481 rc = power_up_aud(demod, true);
13483 pr_err("error %d\n", rc);
13486 ext_attr->aud_data.audio_is_active = true;
13489 /* Modus register is combined in to RAM location */
13490 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_MODUS_HI__A, &r_modus_hi, 0);
13492 pr_err("error %d\n", rc);
13495 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_MODUS_LO__A, &r_modus_lo, 0);
13497 pr_err("error %d\n", rc);
13501 r_modus = ((r_modus_hi << 12) & AUD_DEM_RAM_MODUS_HI__M)
13502 | (((r_modus_lo & AUD_DEM_RAM_MODUS_LO__M)));
13512 /*============================================================================*/
13514 * \brief Get audio RDS dat
13515 * \param demod instance of demodulator
13516 * \param pointer to struct drx_cfg_aud_rds * \return int.
13520 aud_ctrl_get_cfg_rds(struct drx_demod_instance *demod, struct drx_cfg_aud_rds *status)
13522 struct i2c_device_addr *addr = NULL;
13523 struct drxj_data *ext_attr = NULL;
13526 u16 r_rds_array_cnt_init = 0;
13527 u16 r_rds_array_cnt_check = 0;
13528 u16 r_rds_data = 0;
13529 u16 rds_data_cnt = 0;
13531 addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13532 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13534 if (status == NULL)
13538 if (ext_attr->aud_data.audio_is_active == false) {
13539 rc = power_up_aud(demod, true);
13541 pr_err("error %d\n", rc);
13544 ext_attr->aud_data.audio_is_active = true;
13547 status->valid = false;
13549 rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_init, 0);
13551 pr_err("error %d\n", rc);
13555 if (r_rds_array_cnt_init ==
13556 AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID) {
13561 if (ext_attr->aud_data.rds_data_counter == r_rds_array_cnt_init) {
13566 /* RDS is detected, as long as FM radio is selected assume
13567 RDS will be available */
13568 ext_attr->aud_data.rds_data_present = true;
13571 /* read the data */
13572 for (rds_data_cnt = 0; rds_data_cnt < AUD_RDS_ARRAY_SIZE; rds_data_cnt++) {
13573 rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_DATA__A, &r_rds_data, 0);
13575 pr_err("error %d\n", rc);
13578 status->data[rds_data_cnt] = r_rds_data;
13581 rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_check, 0);
13583 pr_err("error %d\n", rc);
13587 if (r_rds_array_cnt_check == r_rds_array_cnt_init) {
13588 status->valid = true;
13589 ext_attr->aud_data.rds_data_counter = r_rds_array_cnt_check;
13597 /*============================================================================*/
13599 * \brief Get the current audio carrier detection status
13600 * \param demod instance of demodulator
13601 * \param pointer to aud_ctrl_get_status
13606 aud_ctrl_get_carrier_detect_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13608 struct drxj_data *ext_attr = NULL;
13609 struct i2c_device_addr *dev_addr = NULL;
13613 if (status == NULL)
13616 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13617 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13620 if (ext_attr->aud_data.audio_is_active == false) {
13621 rc = power_up_aud(demod, true);
13623 pr_err("error %d\n", rc);
13626 ext_attr->aud_data.audio_is_active = true;
13629 /* initialize the variables */
13630 status->carrier_a = false;
13631 status->carrier_b = false;
13632 status->nicam_status = DRX_AUD_NICAM_NOT_DETECTED;
13633 status->sap = false;
13634 status->stereo = false;
13636 /* read stereo sound mode indication */
13637 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RD_STATUS__A, &r_data, 0);
13639 pr_err("error %d\n", rc);
13643 /* carrier a detected */
13644 if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_A__M) == AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED)
13645 status->carrier_a = true;
13647 /* carrier b detected */
13648 if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_B__M) == AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED)
13649 status->carrier_b = true;
13650 /* nicam detected */
13651 if ((r_data & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
13652 AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED) {
13653 if ((r_data & AUD_DEM_RD_STATUS_BAD_NICAM__M) == AUD_DEM_RD_STATUS_BAD_NICAM_OK)
13654 status->nicam_status = DRX_AUD_NICAM_DETECTED;
13656 status->nicam_status = DRX_AUD_NICAM_BAD;
13659 /* audio mode bilingual or SAP detected */
13660 if ((r_data & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) == AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP)
13661 status->sap = true;
13663 /* stereo detected */
13664 if ((r_data & AUD_DEM_RD_STATUS_STAT_STEREO__M) == AUD_DEM_RD_STATUS_STAT_STEREO_STEREO)
13665 status->stereo = true;
13672 /*============================================================================*/
13674 * \brief Get the current audio status parameters
13675 * \param demod instance of demodulator
13676 * \param pointer to aud_ctrl_get_status
13681 aud_ctrl_get_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13683 struct drxj_data *ext_attr = NULL;
13684 struct i2c_device_addr *dev_addr = NULL;
13685 struct drx_cfg_aud_rds rds = { false, {0} };
13689 if (status == NULL)
13692 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13693 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13695 /* carrier detection */
13696 rc = aud_ctrl_get_carrier_detect_status(demod, status);
13698 pr_err("error %d\n", rc);
13703 status->rds = false;
13704 rc = aud_ctrl_get_cfg_rds(demod, &rds);
13706 pr_err("error %d\n", rc);
13709 status->rds = ext_attr->aud_data.rds_data_present;
13712 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_IDENT_VALUE__A, &r_data, 0);
13714 pr_err("error %d\n", rc);
13717 r_data >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
13718 status->fm_ident = (s8) r_data;
13725 /*============================================================================*/
13727 * \brief Get the current volume settings
13728 * \param demod instance of demodulator
13729 * \param pointer to struct drx_cfg_aud_volume * \return int.
13733 aud_ctrl_get_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13735 struct i2c_device_addr *dev_addr = NULL;
13736 struct drxj_data *ext_attr = NULL;
13741 u16 r_strength_left = 0;
13742 u16 r_strength_right = 0;
13744 if (volume == NULL)
13747 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13748 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13751 if (ext_attr->aud_data.audio_is_active == false) {
13752 rc = power_up_aud(demod, true);
13754 pr_err("error %d\n", rc);
13757 ext_attr->aud_data.audio_is_active = true;
13761 volume->mute = ext_attr->aud_data.volume.mute;
13762 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, &r_volume, 0);
13764 pr_err("error %d\n", rc);
13767 if (r_volume == 0) {
13768 volume->mute = true;
13769 volume->volume = ext_attr->aud_data.volume.volume;
13771 volume->mute = false;
13772 volume->volume = ((r_volume & AUD_DSP_WR_VOLUME_VOL_MAIN__M) >>
13773 AUD_DSP_WR_VOLUME_VOL_MAIN__B) -
13774 AUD_VOLUME_ZERO_DB;
13775 if (volume->volume < AUD_VOLUME_DB_MIN)
13776 volume->volume = AUD_VOLUME_DB_MIN;
13777 if (volume->volume > AUD_VOLUME_DB_MAX)
13778 volume->volume = AUD_VOLUME_DB_MAX;
13781 /* automatic volume control */
13782 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AVC__A, &r_avc, 0);
13784 pr_err("error %d\n", rc);
13788 if ((r_avc & AUD_DSP_WR_AVC_AVC_ON__M) == AUD_DSP_WR_AVC_AVC_ON_OFF) {
13789 volume->avc_mode = DRX_AUD_AVC_OFF;
13791 switch (r_avc & AUD_DSP_WR_AVC_AVC_DECAY__M) {
13792 case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
13793 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_20MS;
13795 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
13796 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_8S;
13798 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
13799 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_4S;
13801 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
13802 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_2S;
13810 /* max attenuation */
13811 switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_ATT__M) {
13812 case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
13813 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_12DB;
13815 case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
13816 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_18DB;
13818 case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
13819 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_24DB;
13827 switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M) {
13828 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
13829 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_0DB;
13831 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
13832 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_6DB;
13834 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
13835 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_12DB;
13842 /* reference level */
13843 volume->avc_ref_level = (u16) ((r_avc & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
13844 AUD_DSP_WR_AVC_AVC_REF_LEV__B);
13846 /* read qpeak registers and calculate strength of left and right carrier */
13847 /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
13848 /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
13853 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_QPEAK_L__A, &r_strength_left, 0);
13855 pr_err("error %d\n", rc);
13858 volume->strength_left = (((s16) log1_times100(r_strength_left)) -
13859 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
13861 /* right carrier */
13862 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_QPEAK_R__A, &r_strength_right, 0);
13864 pr_err("error %d\n", rc);
13867 volume->strength_right = (((s16) log1_times100(r_strength_right)) -
13868 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
13875 /*============================================================================*/
13877 * \brief Set the current volume settings
13878 * \param demod instance of demodulator
13879 * \param pointer to struct drx_cfg_aud_volume * \return int.
13883 aud_ctrl_set_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13885 struct i2c_device_addr *dev_addr = NULL;
13886 struct drxj_data *ext_attr = NULL;
13892 if (volume == NULL)
13895 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13896 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13899 if (ext_attr->aud_data.audio_is_active == false) {
13900 rc = power_up_aud(demod, true);
13902 pr_err("error %d\n", rc);
13905 ext_attr->aud_data.audio_is_active = true;
13909 /* volume range from -60 to 12 (expressed in dB) */
13910 if ((volume->volume < AUD_VOLUME_DB_MIN) ||
13911 (volume->volume > AUD_VOLUME_DB_MAX))
13914 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, &w_volume, 0);
13916 pr_err("error %d\n", rc);
13920 /* clear the volume mask */
13921 w_volume &= (u16) ~AUD_DSP_WR_VOLUME_VOL_MAIN__M;
13922 if (volume->mute == true)
13923 w_volume |= (u16)(0);
13925 w_volume |= (u16)((volume->volume + AUD_VOLUME_ZERO_DB) << AUD_DSP_WR_VOLUME_VOL_MAIN__B);
13927 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
13929 pr_err("error %d\n", rc);
13933 /* automatic volume control */
13934 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AVC__A, &w_avc, 0);
13936 pr_err("error %d\n", rc);
13940 /* clear masks that require writing */
13941 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_ON__M;
13942 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_DECAY__M;
13944 if (volume->avc_mode == DRX_AUD_AVC_OFF) {
13945 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_OFF);
13948 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_ON);
13951 switch (volume->avc_mode) {
13952 case DRX_AUD_AVC_DECAYTIME_20MS:
13953 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
13955 case DRX_AUD_AVC_DECAYTIME_8S:
13956 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
13958 case DRX_AUD_AVC_DECAYTIME_4S:
13959 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
13961 case DRX_AUD_AVC_DECAYTIME_2S:
13962 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
13969 /* max attenuation */
13970 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
13971 switch (volume->avc_max_atten) {
13972 case DRX_AUD_AVC_MAX_ATTEN_12DB:
13973 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
13975 case DRX_AUD_AVC_MAX_ATTEN_18DB:
13976 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
13978 case DRX_AUD_AVC_MAX_ATTEN_24DB:
13979 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
13986 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
13987 switch (volume->avc_max_gain) {
13988 case DRX_AUD_AVC_MAX_GAIN_0DB:
13989 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
13991 case DRX_AUD_AVC_MAX_GAIN_6DB:
13992 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
13994 case DRX_AUD_AVC_MAX_GAIN_12DB:
13995 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
14001 /* avc reference level */
14002 if (volume->avc_ref_level > AUD_MAX_AVC_REF_LEVEL)
14005 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_REF_LEV__M;
14006 w_avc |= (u16) (volume->avc_ref_level << AUD_DSP_WR_AVC_AVC_REF_LEV__B);
14008 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_AVC__A, w_avc, 0);
14010 pr_err("error %d\n", rc);
14014 /* all done, store config in data structure */
14015 ext_attr->aud_data.volume = *volume;
14022 /*============================================================================*/
14024 * \brief Get the I2S settings
14025 * \param demod instance of demodulator
14026 * \param pointer to struct drx_cfg_i2s_output * \return int.
14030 aud_ctrl_get_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
14032 struct i2c_device_addr *dev_addr = NULL;
14033 struct drxj_data *ext_attr = NULL;
14035 u16 w_i2s_config = 0;
14036 u16 r_i2s_freq = 0;
14038 if (output == NULL)
14041 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14042 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14045 if (ext_attr->aud_data.audio_is_active == false) {
14046 rc = power_up_aud(demod, true);
14048 pr_err("error %d\n", rc);
14051 ext_attr->aud_data.audio_is_active = true;
14054 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14056 pr_err("error %d\n", rc);
14059 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, &r_i2s_freq, 0);
14061 pr_err("error %d\n", rc);
14066 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M) {
14067 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
14068 output->mode = DRX_I2S_MODE_MASTER;
14070 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
14071 output->mode = DRX_I2S_MODE_SLAVE;
14078 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M) {
14079 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
14080 output->format = DRX_I2S_FORMAT_WS_ADVANCED;
14082 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
14083 output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
14089 /* I2S word length */
14090 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M) {
14091 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
14092 output->word_length = DRX_I2S_WORDLENGTH_16;
14094 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
14095 output->word_length = DRX_I2S_WORDLENGTH_32;
14102 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M) {
14103 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
14104 output->polarity = DRX_I2S_POLARITY_LEFT;
14106 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
14107 output->polarity = DRX_I2S_POLARITY_RIGHT;
14113 /* I2S output enabled */
14114 if ((w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M) == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE)
14115 output->output_enable = true;
14117 output->output_enable = false;
14119 if (r_i2s_freq > 0) {
14120 output->frequency = 6144UL * 48000 / r_i2s_freq;
14121 if (output->word_length == DRX_I2S_WORDLENGTH_16)
14122 output->frequency *= 2;
14124 output->frequency = AUD_I2S_FREQUENCY_MAX;
14132 /*============================================================================*/
14134 * \brief Set the I2S settings
14135 * \param demod instance of demodulator
14136 * \param pointer to struct drx_cfg_i2s_output * \return int.
14140 aud_ctrl_set_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
14142 struct i2c_device_addr *dev_addr = NULL;
14143 struct drxj_data *ext_attr = NULL;
14145 u16 w_i2s_config = 0;
14146 u16 w_i2s_pads_data_da = 0;
14147 u16 w_i2s_pads_data_cl = 0;
14148 u16 w_i2s_pads_data_ws = 0;
14149 u32 w_i2s_freq = 0;
14151 if (output == NULL)
14154 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14155 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14158 if (ext_attr->aud_data.audio_is_active == false) {
14159 rc = power_up_aud(demod, true);
14161 pr_err("error %d\n", rc);
14164 ext_attr->aud_data.audio_is_active = true;
14167 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14169 pr_err("error %d\n", rc);
14174 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
14176 switch (output->mode) {
14177 case DRX_I2S_MODE_MASTER:
14178 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
14180 case DRX_I2S_MODE_SLAVE:
14181 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
14188 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
14190 switch (output->format) {
14191 case DRX_I2S_FORMAT_WS_ADVANCED:
14192 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
14194 case DRX_I2S_FORMAT_WS_WITH_DATA:
14195 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
14201 /* I2S word length */
14202 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
14204 switch (output->word_length) {
14205 case DRX_I2S_WORDLENGTH_16:
14206 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
14208 case DRX_I2S_WORDLENGTH_32:
14209 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
14216 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
14217 switch (output->polarity) {
14218 case DRX_I2S_POLARITY_LEFT:
14219 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
14221 case DRX_I2S_POLARITY_RIGHT:
14222 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
14228 /* I2S output enabled */
14229 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
14230 if (output->output_enable == true)
14231 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
14233 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
14238 w_i2s_freq = 6144 * 48000 * nrbits / ( 32 * frequency )
14240 16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
14241 32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
14243 if ((output->frequency > AUD_I2S_FREQUENCY_MAX) ||
14244 output->frequency < AUD_I2S_FREQUENCY_MIN) {
14248 w_i2s_freq = (6144UL * 48000UL) + (output->frequency >> 1);
14249 w_i2s_freq /= output->frequency;
14251 if (output->word_length == DRX_I2S_WORDLENGTH_16)
14254 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_I2S_CONFIG2__A, w_i2s_config, 0);
14256 pr_err("error %d\n", rc);
14259 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, (u16)w_i2s_freq, 0);
14261 pr_err("error %d\n", rc);
14265 /* configure I2S output pads for master or slave mode */
14266 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
14268 pr_err("error %d\n", rc);
14272 if (output->mode == DRX_I2S_MODE_MASTER) {
14273 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
14274 SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
14275 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
14276 SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
14277 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
14278 SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
14280 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
14281 SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
14282 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
14283 SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
14284 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
14285 SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
14288 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_DA_CFG__A, w_i2s_pads_data_da, 0);
14290 pr_err("error %d\n", rc);
14293 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_CL_CFG__A, w_i2s_pads_data_cl, 0);
14295 pr_err("error %d\n", rc);
14298 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_WS_CFG__A, w_i2s_pads_data_ws, 0);
14300 pr_err("error %d\n", rc);
14304 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
14306 pr_err("error %d\n", rc);
14310 /* all done, store config in data structure */
14311 ext_attr->aud_data.i2sdata = *output;
14318 /*============================================================================*/
14320 * \brief Get the Automatic Standard Select (ASS)
14321 * and Automatic Sound Change (ASC)
14322 * \param demod instance of demodulator
14323 * \param pointer to pDRXAudAutoSound_t
14328 aud_ctrl_get_cfg_auto_sound(struct drx_demod_instance *demod,
14329 enum drx_cfg_aud_auto_sound *auto_sound)
14331 struct drxj_data *ext_attr = NULL;
14335 if (auto_sound == NULL)
14338 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14341 if (ext_attr->aud_data.audio_is_active == false) {
14342 rc = power_up_aud(demod, true);
14344 pr_err("error %d\n", rc);
14347 ext_attr->aud_data.audio_is_active = true;
14350 rc = aud_get_modus(demod, &r_modus);
14352 pr_err("error %d\n", rc);
14356 switch (r_modus & (AUD_DEM_WR_MODUS_MOD_ASS__M |
14357 AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M)) {
14358 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14359 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14361 DRX_AUD_AUTO_SOUND_OFF;
14363 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14365 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
14367 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14369 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
14380 /*============================================================================*/
14382 * \brief Set the Automatic Standard Select (ASS)
14383 * and Automatic Sound Change (ASC)
14384 * \param demod instance of demodulator
14385 * \param pointer to pDRXAudAutoSound_t
14390 aud_ctr_setl_cfg_auto_sound(struct drx_demod_instance *demod,
14391 enum drx_cfg_aud_auto_sound *auto_sound)
14393 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14394 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14399 if (auto_sound == NULL)
14402 dev_addr = demod->my_i2c_dev_addr;
14403 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14406 if (ext_attr->aud_data.audio_is_active == false) {
14407 rc = power_up_aud(demod, true);
14409 pr_err("error %d\n", rc);
14412 ext_attr->aud_data.audio_is_active = true;
14415 rc = aud_get_modus(demod, &r_modus);
14417 pr_err("error %d\n", rc);
14422 /* clear ASS & ASC bits */
14423 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_ASS__M;
14424 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
14426 switch (*auto_sound) {
14427 case DRX_AUD_AUTO_SOUND_OFF:
14428 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
14429 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14431 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
14432 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14433 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
14435 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
14436 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14437 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14443 if (w_modus != r_modus) {
14444 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14446 pr_err("error %d\n", rc);
14450 /* copy to data structure */
14451 ext_attr->aud_data.auto_sound = *auto_sound;
14458 /*============================================================================*/
14460 * \brief Get the Automatic Standard Select thresholds
14461 * \param demod instance of demodulator
14462 * \param pointer to pDRXAudASSThres_t
14467 aud_ctrl_get_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14469 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14470 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14473 u16 thres_btsc = 0;
14474 u16 thres_nicam = 0;
14479 dev_addr = demod->my_i2c_dev_addr;
14480 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14483 if (ext_attr->aud_data.audio_is_active == false) {
14484 rc = power_up_aud(demod, true);
14486 pr_err("error %d\n", rc);
14489 ext_attr->aud_data.audio_is_active = true;
14492 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_A2_THRSHLD__A, &thres_a2, 0);
14494 pr_err("error %d\n", rc);
14497 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_BTSC_THRSHLD__A, &thres_btsc, 0);
14499 pr_err("error %d\n", rc);
14502 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_NICAM_THRSHLD__A, &thres_nicam, 0);
14504 pr_err("error %d\n", rc);
14508 thres->a2 = thres_a2;
14509 thres->btsc = thres_btsc;
14510 thres->nicam = thres_nicam;
14517 /*============================================================================*/
14519 * \brief Get the Automatic Standard Select thresholds
14520 * \param demod instance of demodulator
14521 * \param pointer to pDRXAudASSThres_t
14526 aud_ctrl_set_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14528 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14529 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14534 dev_addr = demod->my_i2c_dev_addr;
14535 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14538 if (ext_attr->aud_data.audio_is_active == false) {
14539 rc = power_up_aud(demod, true);
14541 pr_err("error %d\n", rc);
14544 ext_attr->aud_data.audio_is_active = true;
14547 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_A2_THRSHLD__A, thres->a2, 0);
14549 pr_err("error %d\n", rc);
14552 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc, 0);
14554 pr_err("error %d\n", rc);
14557 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam, 0);
14559 pr_err("error %d\n", rc);
14563 /* update DRXK data structure with hardware values */
14564 ext_attr->aud_data.ass_thresholds = *thres;
14571 /*============================================================================*/
14573 * \brief Get Audio Carrier settings
14574 * \param demod instance of demodulator
14575 * \param pointer to struct drx_aud_carrier ** \return int.
14579 aud_ctrl_get_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14581 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14582 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14600 if (carriers == NULL)
14603 dev_addr = demod->my_i2c_dev_addr;
14604 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14607 if (ext_attr->aud_data.audio_is_active == false) {
14608 rc = power_up_aud(demod, true);
14610 pr_err("error %d\n", rc);
14613 ext_attr->aud_data.audio_is_active = true;
14616 rc = aud_get_modus(demod, &w_modus);
14618 pr_err("error %d\n", rc);
14622 /* Behaviour of primary audio channel */
14623 switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_A__M)) {
14624 case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
14625 carriers->a.opt = DRX_NO_CARRIER_MUTE;
14627 case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
14628 carriers->a.opt = DRX_NO_CARRIER_NOISE;
14635 /* Behaviour of secondary audio channel */
14636 switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_B__M)) {
14637 case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
14638 carriers->b.opt = DRX_NO_CARRIER_MUTE;
14640 case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
14641 carriers->b.opt = DRX_NO_CARRIER_NOISE;
14648 /* frequency adjustment for primary & secondary audio channel */
14649 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_A_HI__A, &dco_a_hi, 0);
14651 pr_err("error %d\n", rc);
14654 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_A_LO__A, &dco_a_lo, 0);
14656 pr_err("error %d\n", rc);
14659 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_B_HI__A, &dco_b_hi, 0);
14661 pr_err("error %d\n", rc);
14664 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_B_LO__A, &dco_b_lo, 0);
14666 pr_err("error %d\n", rc);
14670 valA = (((u32) dco_a_hi) << 12) | ((u32) dco_a_lo & 0xFFF);
14671 valB = (((u32) dco_b_hi) << 12) | ((u32) dco_b_lo & 0xFFF);
14673 /* Multiply by 20250 * 1>>24 ~= 2 / 1657 */
14674 carriers->a.dco = DRX_S24TODRXFREQ(valA) * 2L / 1657L;
14675 carriers->b.dco = DRX_S24TODRXFREQ(valB) * 2L / 1657L;
14677 /* DC level of the incoming FM signal on the primary
14678 & seconday sound channel */
14679 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dc_lvl_a, 0);
14681 pr_err("error %d\n", rc);
14684 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dc_lvl_b, 0);
14686 pr_err("error %d\n", rc);
14690 /* offset (kHz) = (dcLvl / 322) */
14691 carriers->a.shift = (DRX_U16TODRXFREQ(dc_lvl_a) / 322L);
14692 carriers->b.shift = (DRX_U16TODRXFREQ(dc_lvl_b) / 322L);
14694 /* Carrier detetcion threshold for primary & secondary channel */
14695 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cm_thes_a, 0);
14697 pr_err("error %d\n", rc);
14700 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cm_thes_b, 0);
14702 pr_err("error %d\n", rc);
14706 carriers->a.thres = cm_thes_a;
14707 carriers->b.thres = cm_thes_b;
14714 /*============================================================================*/
14716 * \brief Set Audio Carrier settings
14717 * \param demod instance of demodulator
14718 * \param pointer to struct drx_aud_carrier ** \return int.
14722 aud_ctrl_set_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14724 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14725 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14736 if (carriers == NULL)
14739 dev_addr = demod->my_i2c_dev_addr;
14740 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14743 if (ext_attr->aud_data.audio_is_active == false) {
14744 rc = power_up_aud(demod, true);
14746 pr_err("error %d\n", rc);
14749 ext_attr->aud_data.audio_is_active = true;
14752 rc = aud_get_modus(demod, &r_modus);
14754 pr_err("error %d\n", rc);
14759 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_A__M;
14760 /* Behaviour of primary audio channel */
14761 switch (carriers->a.opt) {
14762 case DRX_NO_CARRIER_MUTE:
14763 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
14765 case DRX_NO_CARRIER_NOISE:
14766 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
14773 /* Behaviour of secondary audio channel */
14774 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_B__M;
14775 switch (carriers->b.opt) {
14776 case DRX_NO_CARRIER_MUTE:
14777 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
14779 case DRX_NO_CARRIER_NOISE:
14780 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
14787 /* now update the modus register */
14788 if (w_modus != r_modus) {
14789 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14791 pr_err("error %d\n", rc);
14796 /* frequency adjustment for primary & secondary audio channel */
14797 valA = (s32) ((carriers->a.dco) * 1657L / 2);
14798 valB = (s32) ((carriers->b.dco) * 1657L / 2);
14800 dco_a_hi = (u16) ((valA >> 12) & 0xFFF);
14801 dco_a_lo = (u16) (valA & 0xFFF);
14802 dco_b_hi = (u16) ((valB >> 12) & 0xFFF);
14803 dco_b_lo = (u16) (valB & 0xFFF);
14805 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_A_HI__A, dco_a_hi, 0);
14807 pr_err("error %d\n", rc);
14810 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_A_LO__A, dco_a_lo, 0);
14812 pr_err("error %d\n", rc);
14815 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_B_HI__A, dco_b_hi, 0);
14817 pr_err("error %d\n", rc);
14820 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_B_LO__A, dco_b_lo, 0);
14822 pr_err("error %d\n", rc);
14826 /* Carrier detetcion threshold for primary & secondary channel */
14827 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres, 0);
14829 pr_err("error %d\n", rc);
14832 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres, 0);
14834 pr_err("error %d\n", rc);
14838 /* update DRXK data structure */
14839 ext_attr->aud_data.carriers = *carriers;
14846 /*============================================================================*/
14848 * \brief Get I2S Source, I2S matrix and FM matrix
14849 * \param demod instance of demodulator
14850 * \param pointer to pDRXAudmixer_t
14855 aud_ctrl_get_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
14857 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14858 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14860 u16 src_i2s_matr = 0;
14866 dev_addr = demod->my_i2c_dev_addr;
14867 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14870 if (ext_attr->aud_data.audio_is_active == false) {
14871 rc = power_up_aud(demod, true);
14873 pr_err("error %d\n", rc);
14876 ext_attr->aud_data.audio_is_active = true;
14879 /* Source Selctor */
14880 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
14882 pr_err("error %d\n", rc);
14886 switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M) {
14887 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
14888 mixer->source_i2s = DRX_AUD_SRC_MONO;
14890 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
14891 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_AB;
14893 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
14894 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_A;
14896 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
14897 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_B;
14904 switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M) {
14905 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
14906 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_MONO;
14908 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
14909 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_STEREO;
14911 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
14912 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_A_MONO;
14914 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
14915 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_B_MONO;
14922 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
14924 pr_err("error %d\n", rc);
14927 switch (fm_matr & AUD_DEM_WR_FM_MATRIX__M) {
14928 case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
14929 mixer->matrix_fm = DRX_AUD_FM_MATRIX_NO_MATRIX;
14931 case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
14932 mixer->matrix_fm = DRX_AUD_FM_MATRIX_GERMAN;
14934 case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
14935 mixer->matrix_fm = DRX_AUD_FM_MATRIX_KOREAN;
14937 case AUD_DEM_WR_FM_MATRIX_SOUND_A:
14938 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_A;
14940 case AUD_DEM_WR_FM_MATRIX_SOUND_B:
14941 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_B;
14952 /*============================================================================*/
14954 * \brief Set I2S Source, I2S matrix and FM matrix
14955 * \param demod instance of demodulator
14956 * \param pointer to DRXAudmixer_t
14961 aud_ctrl_set_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
14963 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14964 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14966 u16 src_i2s_matr = 0;
14972 dev_addr = demod->my_i2c_dev_addr;
14973 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14976 if (ext_attr->aud_data.audio_is_active == false) {
14977 rc = power_up_aud(demod, true);
14979 pr_err("error %d\n", rc);
14982 ext_attr->aud_data.audio_is_active = true;
14985 /* Source Selctor */
14986 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
14988 pr_err("error %d\n", rc);
14991 src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
14993 switch (mixer->source_i2s) {
14994 case DRX_AUD_SRC_MONO:
14995 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
14997 case DRX_AUD_SRC_STEREO_OR_AB:
14998 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
15000 case DRX_AUD_SRC_STEREO_OR_A:
15001 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
15003 case DRX_AUD_SRC_STEREO_OR_B:
15004 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
15011 src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
15012 switch (mixer->matrix_i2s) {
15013 case DRX_AUD_I2S_MATRIX_MONO:
15014 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
15016 case DRX_AUD_I2S_MATRIX_STEREO:
15017 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO;
15019 case DRX_AUD_I2S_MATRIX_A_MONO:
15020 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
15022 case DRX_AUD_I2S_MATRIX_B_MONO:
15023 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
15028 /* write the result */
15029 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, src_i2s_matr, 0);
15031 pr_err("error %d\n", rc);
15036 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
15038 pr_err("error %d\n", rc);
15041 fm_matr &= (u16) ~AUD_DEM_WR_FM_MATRIX__M;
15042 switch (mixer->matrix_fm) {
15043 case DRX_AUD_FM_MATRIX_NO_MATRIX:
15044 fm_matr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
15046 case DRX_AUD_FM_MATRIX_GERMAN:
15047 fm_matr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
15049 case DRX_AUD_FM_MATRIX_KOREAN:
15050 fm_matr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
15052 case DRX_AUD_FM_MATRIX_SOUND_A:
15053 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
15055 case DRX_AUD_FM_MATRIX_SOUND_B:
15056 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
15062 /* Only write if ASS is off */
15063 if (ext_attr->aud_data.auto_sound == DRX_AUD_AUTO_SOUND_OFF) {
15064 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, fm_matr, 0);
15066 pr_err("error %d\n", rc);
15071 /* update the data structure with hardware state */
15072 ext_attr->aud_data.mixer = *mixer;
15079 /*============================================================================*/
15081 * \brief Set AV Sync settings
15082 * \param demod instance of demodulator
15083 * \param pointer to DRXICfgAVSync_t
15088 aud_ctrl_set_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15090 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15091 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15093 u16 w_aud_vid_sync = 0;
15095 if (av_sync == NULL)
15098 dev_addr = demod->my_i2c_dev_addr;
15099 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15102 if (ext_attr->aud_data.audio_is_active == false) {
15103 rc = power_up_aud(demod, true);
15105 pr_err("error %d\n", rc);
15108 ext_attr->aud_data.audio_is_active = true;
15111 /* audio/video synchronisation */
15112 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15114 pr_err("error %d\n", rc);
15118 w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_ON__M;
15120 if (*av_sync == DRX_AUD_AVSYNC_OFF)
15121 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
15123 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
15125 w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
15127 switch (*av_sync) {
15128 case DRX_AUD_AVSYNC_NTSC:
15129 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
15131 case DRX_AUD_AVSYNC_MONOCHROME:
15132 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
15134 case DRX_AUD_AVSYNC_PAL_SECAM:
15135 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
15137 case DRX_AUD_AVSYNC_OFF:
15144 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, w_aud_vid_sync, 0);
15146 pr_err("error %d\n", rc);
15154 /*============================================================================*/
15156 * \brief Get AV Sync settings
15157 * \param demod instance of demodulator
15158 * \param pointer to DRXICfgAVSync_t
15163 aud_ctrl_get_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15165 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15166 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15168 u16 w_aud_vid_sync = 0;
15170 if (av_sync == NULL)
15173 dev_addr = demod->my_i2c_dev_addr;
15174 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15177 if (ext_attr->aud_data.audio_is_active == false) {
15178 rc = power_up_aud(demod, true);
15180 pr_err("error %d\n", rc);
15183 ext_attr->aud_data.audio_is_active = true;
15186 /* audio/video synchronisation */
15187 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15189 pr_err("error %d\n", rc);
15193 if ((w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_ON__M) ==
15194 AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE) {
15195 *av_sync = DRX_AUD_AVSYNC_OFF;
15199 switch (w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M) {
15200 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
15201 *av_sync = DRX_AUD_AVSYNC_NTSC;
15203 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
15204 *av_sync = DRX_AUD_AVSYNC_MONOCHROME;
15206 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
15207 *av_sync = DRX_AUD_AVSYNC_PAL_SECAM;
15218 /*============================================================================*/
15220 * \brief Get deviation mode
15221 * \param demod instance of demodulator
15222 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15226 aud_ctrl_get_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15234 rc = aud_get_modus(demod, &r_modus);
15236 pr_err("error %d\n", rc);
15240 switch (r_modus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M) {
15241 case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
15242 *dev = DRX_AUD_DEVIATION_NORMAL;
15244 case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
15245 *dev = DRX_AUD_DEVIATION_HIGH;
15256 /*============================================================================*/
15258 * \brief Get deviation mode
15259 * \param demod instance of demodulator
15260 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15264 aud_ctrl_set_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15266 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15267 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15275 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15276 dev_addr = demod->my_i2c_dev_addr;
15278 rc = aud_get_modus(demod, &r_modus);
15280 pr_err("error %d\n", rc);
15286 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
15289 case DRX_AUD_DEVIATION_NORMAL:
15290 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
15292 case DRX_AUD_DEVIATION_HIGH:
15293 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
15299 /* now update the modus register */
15300 if (w_modus != r_modus) {
15301 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15303 pr_err("error %d\n", rc);
15307 /* store in drxk data struct */
15308 ext_attr->aud_data.deviation = *dev;
15315 /*============================================================================*/
15317 * \brief Get Prescaler settings
15318 * \param demod instance of demodulator
15319 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15323 aud_ctrl_get_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15325 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15326 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15328 u16 r_max_fm_deviation = 0;
15329 u16 r_nicam_prescaler = 0;
15334 dev_addr = demod->my_i2c_dev_addr;
15335 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15338 if (ext_attr->aud_data.audio_is_active == false) {
15339 rc = power_up_aud(demod, true);
15341 pr_err("error %d\n", rc);
15344 ext_attr->aud_data.audio_is_active = true;
15347 /* read register data */
15348 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, &r_nicam_prescaler, 0);
15350 pr_err("error %d\n", rc);
15353 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_FM_PRESC__A, &r_max_fm_deviation, 0);
15355 pr_err("error %d\n", rc);
15359 /* calculate max FM deviation */
15360 r_max_fm_deviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15361 if (r_max_fm_deviation > 0) {
15362 presc->fm_deviation = 3600UL + (r_max_fm_deviation >> 1);
15363 presc->fm_deviation /= r_max_fm_deviation;
15365 presc->fm_deviation = 380; /* kHz */
15368 /* calculate NICAM gain from pre-scaler */
15370 nicam_gain = 20 * ( log10( preScaler / 16) )
15371 = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
15373 because log1_times100() cannot return negative numbers
15374 = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
15376 for 0.1dB resolution:
15378 nicam_gain = 200 * ( log10( preScaler / 16) )
15379 = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
15380 = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
15383 r_nicam_prescaler >>= 8;
15384 if (r_nicam_prescaler <= 1)
15385 presc->nicam_gain = -241;
15387 presc->nicam_gain = (s16)(((s32)(log1_times100(10 * r_nicam_prescaler * r_nicam_prescaler)) - (s32)(log1_times100(10 * 16 * 16))));
15394 /*============================================================================*/
15396 * \brief Set Prescaler settings
15397 * \param demod instance of demodulator
15398 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15402 aud_ctrl_set_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15404 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15405 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15407 u16 w_max_fm_deviation = 0;
15408 u16 nicam_prescaler;
15413 dev_addr = demod->my_i2c_dev_addr;
15414 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15417 if (ext_attr->aud_data.audio_is_active == false) {
15418 rc = power_up_aud(demod, true);
15420 pr_err("error %d\n", rc);
15423 ext_attr->aud_data.audio_is_active = true;
15426 /* setting of max FM deviation */
15427 w_max_fm_deviation = (u16) (frac(3600UL, presc->fm_deviation, 0));
15428 w_max_fm_deviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15429 if (w_max_fm_deviation >= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION)
15430 w_max_fm_deviation = AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
15432 /* NICAM Prescaler */
15433 if ((presc->nicam_gain >= -241) && (presc->nicam_gain <= 180)) {
15436 prescaler = 16 * 10^( gd_b / 20 )
15438 minval of gd_b = -20*log( 16 ) = -24.1dB
15440 negative numbers not allowed for d_b2lin_times100, so
15442 prescaler = 16 * 10^( gd_b / 20 )
15443 = 10^( (gd_b / 20) + log10(16) )
15444 = 10^( (gd_b + 20log10(16)) / 20 )
15448 = 10^( G0.1dB + 200log10(16)) / 200 )
15451 nicam_prescaler = (u16)
15452 ((d_b2lin_times100(presc->nicam_gain + 241UL) + 50UL) / 100UL);
15455 if (nicam_prescaler > 127)
15456 nicam_prescaler = 127;
15458 /* shift before writing to register */
15459 nicam_prescaler <<= 8;
15463 /* end of setting NICAM Prescaler */
15465 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, nicam_prescaler, 0);
15467 pr_err("error %d\n", rc);
15470 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_FM_PRESC__A, w_max_fm_deviation, 0);
15472 pr_err("error %d\n", rc);
15476 ext_attr->aud_data.prescale = *presc;
15483 /*============================================================================*/
15486 * \param demod instance of demodulator
15487 * \param pointer to struct drx_aud_beep * \return int.
15490 static int aud_ctrl_beep(struct drx_demod_instance *demod, struct drx_aud_beep *beep)
15492 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15493 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15502 dev_addr = demod->my_i2c_dev_addr;
15503 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15506 if (ext_attr->aud_data.audio_is_active == false) {
15507 rc = power_up_aud(demod, true);
15509 pr_err("error %d\n", rc);
15512 ext_attr->aud_data.audio_is_active = true;
15515 if ((beep->volume > 0) || (beep->volume < -127))
15518 if (beep->frequency > 3000)
15521 volume = (u16) beep->volume + 127;
15522 the_beep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
15524 frequency = ((u32) beep->frequency) * 23 / 500;
15525 if (frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M)
15526 frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
15527 the_beep |= (u16) frequency;
15529 if (beep->mute == true)
15532 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_BEEPER__A, the_beep, 0);
15534 pr_err("error %d\n", rc);
15543 /*============================================================================*/
15545 * \brief Set an audio standard
15546 * \param demod instance of demodulator
15547 * \param pointer to enum drx_aud_standard * \return int.
15551 aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15553 struct i2c_device_addr *dev_addr = NULL;
15554 struct drxj_data *ext_attr = NULL;
15555 enum drx_standard current_standard = DRX_STANDARD_UNKNOWN;
15557 u16 w_standard = 0;
15561 bool mute_buffer = false;
15562 s16 volume_buffer = 0;
15565 if (standard == NULL)
15568 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15569 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15572 if (ext_attr->aud_data.audio_is_active == false) {
15573 rc = power_up_aud(demod, false);
15575 pr_err("error %d\n", rc);
15578 ext_attr->aud_data.audio_is_active = true;
15581 /* reset RDS data availability flag */
15582 ext_attr->aud_data.rds_data_present = false;
15584 /* we need to mute from here to avoid noise during standard switching */
15585 mute_buffer = ext_attr->aud_data.volume.mute;
15586 volume_buffer = ext_attr->aud_data.volume.volume;
15588 ext_attr->aud_data.volume.mute = true;
15589 /* restore data structure from DRX ExtAttr, call volume first to mute */
15590 rc = aud_ctrl_set_cfg_volume(demod, &ext_attr->aud_data.volume);
15592 pr_err("error %d\n", rc);
15595 rc = aud_ctrl_set_cfg_carrier(demod, &ext_attr->aud_data.carriers);
15597 pr_err("error %d\n", rc);
15600 rc = aud_ctrl_set_cfg_ass_thres(demod, &ext_attr->aud_data.ass_thresholds);
15602 pr_err("error %d\n", rc);
15605 rc = aud_ctr_setl_cfg_auto_sound(demod, &ext_attr->aud_data.auto_sound);
15607 pr_err("error %d\n", rc);
15610 rc = aud_ctrl_set_cfg_mixer(demod, &ext_attr->aud_data.mixer);
15612 pr_err("error %d\n", rc);
15615 rc = aud_ctrl_set_cfg_av_sync(demod, &ext_attr->aud_data.av_sync);
15617 pr_err("error %d\n", rc);
15620 rc = aud_ctrl_set_cfg_output_i2s(demod, &ext_attr->aud_data.i2sdata);
15622 pr_err("error %d\n", rc);
15626 /* get prescaler from presets */
15627 rc = aud_ctrl_set_cfg_prescale(demod, &ext_attr->aud_data.prescale);
15629 pr_err("error %d\n", rc);
15633 rc = aud_get_modus(demod, &r_modus);
15635 pr_err("error %d\n", rc);
15641 switch (*standard) {
15642 case DRX_AUD_STANDARD_AUTO:
15643 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15645 case DRX_AUD_STANDARD_BTSC:
15646 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
15647 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_MONO_AND_SAP)
15648 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
15650 case DRX_AUD_STANDARD_A2:
15651 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
15653 case DRX_AUD_STANDARD_EIAJ:
15654 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
15656 case DRX_AUD_STANDARD_FM_STEREO:
15657 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
15659 case DRX_AUD_STANDARD_BG_FM:
15660 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
15662 case DRX_AUD_STANDARD_D_K1:
15663 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
15665 case DRX_AUD_STANDARD_D_K2:
15666 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
15668 case DRX_AUD_STANDARD_D_K3:
15669 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
15671 case DRX_AUD_STANDARD_BG_NICAM_FM:
15672 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
15674 case DRX_AUD_STANDARD_L_NICAM_AM:
15675 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
15677 case DRX_AUD_STANDARD_I_NICAM_FM:
15678 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
15680 case DRX_AUD_STANDARD_D_K_NICAM_FM:
15681 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
15683 case DRX_AUD_STANDARD_UNKNOWN:
15684 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15690 if (*standard == DRX_AUD_STANDARD_AUTO) {
15691 /* we need the current standard here */
15692 current_standard = ext_attr->standard;
15694 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
15696 if ((current_standard == DRX_STANDARD_PAL_SECAM_L) || (current_standard == DRX_STANDARD_PAL_SECAM_LP))
15697 w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
15699 w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
15701 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
15702 if (current_standard == DRX_STANDARD_NTSC)
15703 w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
15705 w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
15709 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
15711 /* just get hardcoded deemphasis and activate here */
15712 if (ext_attr->aud_data.deemph == DRX_AUD_FM_DEEMPH_50US)
15713 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
15715 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
15717 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_BTSC__M;
15718 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_STEREO)
15719 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
15721 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
15723 if (w_modus != r_modus) {
15724 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15726 pr_err("error %d\n", rc);
15731 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_STANDARD_SEL__A, w_standard, 0);
15733 pr_err("error %d\n", rc);
15737 /**************************************************************************/
15738 /* NOT calling aud_ctrl_set_cfg_volume to avoid interfering standard */
15739 /* detection, need to keep things very minimal here, but keep audio */
15740 /* buffers intact */
15741 /**************************************************************************/
15742 ext_attr->aud_data.volume.mute = mute_buffer;
15743 if (ext_attr->aud_data.volume.mute == false) {
15744 w_volume |= (u16) ((volume_buffer + AUD_VOLUME_ZERO_DB) <<
15745 AUD_DSP_WR_VOLUME_VOL_MAIN__B);
15746 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
15748 pr_err("error %d\n", rc);
15753 /* write standard selected */
15754 ext_attr->aud_data.audio_standard = *standard;
15761 /*============================================================================*/
15763 * \brief Get the current audio standard
15764 * \param demod instance of demodulator
15765 * \param pointer to enum drx_aud_standard * \return int.
15769 aud_ctrl_get_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15771 struct i2c_device_addr *dev_addr = NULL;
15772 struct drxj_data *ext_attr = NULL;
15776 if (standard == NULL)
15779 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15780 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15783 if (ext_attr->aud_data.audio_is_active == false) {
15784 rc = power_up_aud(demod, true);
15786 pr_err("error %d\n", rc);
15789 ext_attr->aud_data.audio_is_active = true;
15792 *standard = DRX_AUD_STANDARD_UNKNOWN;
15794 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RD_STANDARD_RES__A, &r_data, 0);
15796 pr_err("error %d\n", rc);
15800 /* return OK if the detection is not ready yet */
15801 if (r_data >= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE) {
15802 *standard = DRX_AUD_STANDARD_NOT_READY;
15806 /* detection done, return correct standard */
15808 /* no standard detected */
15809 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
15810 *standard = DRX_AUD_STANDARD_UNKNOWN;
15812 /* standard is KOREA(A2) */
15813 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
15814 *standard = DRX_AUD_STANDARD_A2;
15816 /* standard is EIA-J (Japan) */
15817 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
15818 *standard = DRX_AUD_STANDARD_EIAJ;
15820 /* standard is BTSC-stereo */
15821 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
15822 *standard = DRX_AUD_STANDARD_BTSC;
15824 /* standard is BTSC-mono (SAP) */
15825 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
15826 *standard = DRX_AUD_STANDARD_BTSC;
15828 /* standard is FM radio */
15829 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
15830 *standard = DRX_AUD_STANDARD_FM_STEREO;
15832 /* standard is BG FM */
15833 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
15834 *standard = DRX_AUD_STANDARD_BG_FM;
15836 /* standard is DK-1 FM */
15837 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
15838 *standard = DRX_AUD_STANDARD_D_K1;
15840 /* standard is DK-2 FM */
15841 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
15842 *standard = DRX_AUD_STANDARD_D_K2;
15844 /* standard is DK-3 FM */
15845 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
15846 *standard = DRX_AUD_STANDARD_D_K3;
15848 /* standard is BG-NICAM FM */
15849 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
15850 *standard = DRX_AUD_STANDARD_BG_NICAM_FM;
15852 /* standard is L-NICAM AM */
15853 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
15854 *standard = DRX_AUD_STANDARD_L_NICAM_AM;
15856 /* standard is I-NICAM FM */
15857 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
15858 *standard = DRX_AUD_STANDARD_I_NICAM_FM;
15860 /* standard is DK-NICAM FM */
15861 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
15862 *standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
15865 *standard = DRX_AUD_STANDARD_UNKNOWN;
15874 /*============================================================================*/
15876 * \brief Retreive lock status in case of FM standard
15877 * \param demod instance of demodulator
15878 * \param pointer to lock status
15883 fm_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
15885 struct drx_aud_status status;
15888 /* Check detection of audio carriers */
15889 rc = aud_ctrl_get_carrier_detect_status(demod, &status);
15891 pr_err("error %d\n", rc);
15895 /* locked if either primary or secondary carrier is detected */
15896 if ((status.carrier_a == true) || (status.carrier_b == true))
15897 *lock_stat = DRX_LOCKED;
15899 *lock_stat = DRX_NOT_LOCKED;
15907 /*============================================================================*/
15909 * \brief retreive signal quality in case of FM standard
15910 * \param demod instance of demodulator
15911 * \param pointer to signal quality
15914 * Only the quality indicator field is will be supplied.
15915 * This will either be 0% or 100%, nothing in between.
15919 fm_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
15921 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
15924 rc = fm_lock_status(demod, &lock_status);
15926 pr_err("error %d\n", rc);
15929 if (lock_status == DRX_LOCKED)
15930 sig_quality->indicator = 100;
15932 sig_quality->indicator = 0;
15942 /*===========================================================================*/
15943 /*== END AUDIO DATAPATH FUNCTIONS ==*/
15944 /*===========================================================================*/
15946 /*============================================================================*/
15947 /*============================================================================*/
15948 /*== OOB DATAPATH FUNCTIONS ==*/
15949 /*============================================================================*/
15950 /*============================================================================*/
15951 #ifndef DRXJ_DIGITAL_ONLY
15953 * \fn int get_oob_lock_status ()
15954 * \brief Get OOB lock status.
15955 * \param dev_addr I2C address
15956 \ oob_lock OOB lock status.
15959 * Gets OOB lock status
15963 get_oob_lock_status(struct drx_demod_instance *demod,
15964 struct i2c_device_addr *dev_addr, enum drx_lock_status *oob_lock)
15966 struct drxjscu_cmd scu_cmd;
15969 u16 oob_lock_state;
15971 *oob_lock = DRX_NOT_LOCKED;
15973 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
15974 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
15975 scu_cmd.result_len = 2;
15976 scu_cmd.result = cmd_result;
15977 scu_cmd.parameter_len = 0;
15979 rc = scu_command(dev_addr, &scu_cmd);
15981 pr_err("error %d\n", rc);
15985 if (scu_cmd.result[1] < 0x4000) {
15986 /* 0x00 NOT LOCKED */
15987 *oob_lock = DRX_NOT_LOCKED;
15988 } else if (scu_cmd.result[1] < 0x8000) {
15989 /* 0x40 DEMOD LOCKED */
15990 *oob_lock = DRXJ_OOB_SYNC_LOCK;
15991 } else if (scu_cmd.result[1] < 0xC000) {
15992 /* 0x80 DEMOD + OOB LOCKED (system lock) */
15993 oob_lock_state = scu_cmd.result[1] & 0x00FF;
15995 if (oob_lock_state & 0x0008)
15996 *oob_lock = DRXJ_OOB_SYNC_LOCK;
15997 else if ((oob_lock_state & 0x0002) && (oob_lock_state & 0x0001))
15998 *oob_lock = DRXJ_OOB_AGC_LOCK;
16000 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
16001 *oob_lock = DRX_NEVER_LOCK;
16004 /* *oob_lock = scu_cmd.result[1]; */
16012 * \fn int get_oob_symbol_rate_offset ()
16013 * \brief Get OOB Symbol rate offset. Unit is [ppm]
16014 * \param dev_addr I2C address
16015 * \ Symbol Rate Offset OOB parameter.
16018 * Gets OOB frequency offset
16022 get_oob_symbol_rate_offset(struct i2c_device_addr *dev_addr, s32 *symbol_rate_offset)
16024 /* offset = -{(timing_offset/2^19)*(symbol_rate/12,656250MHz)}*10^6 [ppm] */
16025 /* offset = -{(timing_offset/2^19)*(symbol_rate/12656250)}*10^6 [ppm] */
16026 /* after reconfiguration: */
16027 /* offset = -{(timing_offset*symbol_rate)/(2^19*12656250)}*10^6 [ppm] */
16028 /* shift symbol rate left by 5 without lossing information */
16029 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
16030 /* shift 10^6 left by 6 without loosing information */
16031 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
16032 /* trim 12656250/15625 = 810 */
16033 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*810)} [ppm] */
16034 /* offset = -[(symbol_rate * 2^-5)*(timing_offset)/(2^8)]/810 [ppm] */
16036 s32 timing_offset = 0;
16037 u32 unsigned_timing_offset = 0;
16038 s32 division_factor = 810;
16040 u32 symbol_rate = 0;
16041 bool negative = false;
16043 *symbol_rate_offset = 0;
16044 /* read data rate */
16045 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data, 0);
16047 pr_err("error %d\n", rc);
16050 switch (data & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16051 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16052 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16053 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16054 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16055 symbol_rate = 1024000; /* bps */
16057 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16058 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16059 symbol_rate = 772000; /* bps */
16061 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16062 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16063 symbol_rate = 1544000; /* bps */
16069 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_CON_CTI_DTI_R__A, &data, 0);
16071 pr_err("error %d\n", rc);
16074 /* convert data to positive and keep information about sign */
16075 if ((data & 0x8000) == 0x8000) {
16076 if (data == 0x8000)
16077 unsigned_timing_offset = 32768;
16079 unsigned_timing_offset = 0x00007FFF & (u32) (-data);
16082 unsigned_timing_offset = (u32) data;
16084 symbol_rate = symbol_rate >> 5;
16085 unsigned_timing_offset = (unsigned_timing_offset * symbol_rate);
16086 unsigned_timing_offset = frac(unsigned_timing_offset, 256, FRAC_ROUND);
16087 unsigned_timing_offset = frac(unsigned_timing_offset,
16088 division_factor, FRAC_ROUND);
16090 timing_offset = (s32) unsigned_timing_offset;
16092 timing_offset = -(s32) unsigned_timing_offset;
16094 *symbol_rate_offset = timing_offset;
16102 * \fn int get_oob_freq_offset ()
16103 * \brief Get OOB lock status.
16104 * \param dev_addr I2C address
16105 * \ freq_offset OOB frequency offset.
16108 * Gets OOB frequency offset
16112 get_oob_freq_offset(struct drx_demod_instance *demod, s32 *freq_offset)
16114 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
16115 struct i2c_device_addr *dev_addr = NULL;
16119 u16 symbol_rate_reg = 0;
16120 u32 symbol_rate = 0;
16121 s32 coarse_freq_offset = 0;
16122 s32 fine_freq_offset = 0;
16124 s32 coarse_sign = 1;
16127 u32 temp_freq_offset = 0;
16129 /* check arguments */
16130 if ((demod == NULL) || (freq_offset == NULL))
16133 dev_addr = demod->my_i2c_dev_addr;
16134 common_attr = (struct drx_common_attr *) demod->my_common_attr;
16138 /* read sign (spectrum inversion) */
16139 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_IQM_FRQ_W__A, &rot, 0);
16141 pr_err("error %d\n", rc);
16145 /* read frequency offset */
16146 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_FRQ_OFFSET__A, &data, 0);
16148 pr_err("error %d\n", rc);
16151 /* find COARSE frequency offset */
16152 /* coarse_freq_offset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
16153 if (data & 0x8000) {
16154 data = (0xffff - data + 1);
16157 mult32(data, (common_attr->sys_clock_freq * 1000) / 6, &data64hi,
16159 temp_freq_offset = (((data64lo >> 21) & 0x7ff) | (data64hi << 11));
16161 /* get value in KHz */
16162 coarse_freq_offset = coarse_sign * frac(temp_freq_offset, 1000, FRAC_ROUND); /* KHz */
16163 /* read data rate */
16164 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbol_rate_reg, 0);
16166 pr_err("error %d\n", rc);
16169 switch (symbol_rate_reg & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16170 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16171 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16172 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16173 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16174 symbol_rate = 1024000;
16176 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16177 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16178 symbol_rate = 772000;
16180 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16181 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16182 symbol_rate = 1544000;
16188 /* find FINE frequency offset */
16189 /* fine_freq_offset = ( (CORRECTION_VALUE*symbol_rate) >> 18 ); */
16190 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_CON_CPH_FRQ_R__A, &data, 0);
16192 pr_err("error %d\n", rc);
16195 /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
16196 fine_freq_offset = (symbol_rate >> 5);
16197 if (data & 0x8000) {
16198 fine_freq_offset *= 0xffff - data + 1; /* Hz */
16201 fine_freq_offset *= data; /* Hz */
16203 /* Left to divide with 8192 (2^13) */
16204 fine_freq_offset = frac(fine_freq_offset, 8192, FRAC_ROUND);
16205 /* and to divide with 1000 to get KHz */
16206 fine_freq_offset = fine_sign * frac(fine_freq_offset, 1000, FRAC_ROUND); /* KHz */
16208 if ((rot & 0x8000) == 0x8000)
16209 *freq_offset = -(coarse_freq_offset + fine_freq_offset);
16211 *freq_offset = (coarse_freq_offset + fine_freq_offset);
16219 * \fn int get_oob_frequency ()
16220 * \brief Get OOB frequency (Unit:KHz).
16221 * \param dev_addr I2C address
16222 * \ frequency OOB frequency parameters.
16225 * Gets OOB frequency
16229 get_oob_frequency(struct drx_demod_instance *demod, s32 *frequency)
16231 struct i2c_device_addr *dev_addr = NULL;
16234 s32 freq_offset = 0;
16237 dev_addr = demod->my_i2c_dev_addr;
16239 *frequency = 0; /* KHz */
16241 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data, 0);
16243 pr_err("error %d\n", rc);
16247 freq = (s32) ((s32) data * 50 + 50000L);
16249 rc = get_oob_freq_offset(demod, &freq_offset);
16251 pr_err("error %d\n", rc);
16255 *frequency = freq + freq_offset;
16263 * \fn int get_oobmer ()
16264 * \brief Get OOB MER.
16265 * \param dev_addr I2C address
16266 \ MER OOB parameter in dB.
16269 * Gets OOB MER. Table for MER is in Programming guide.
16272 static int get_oobmer(struct i2c_device_addr *dev_addr, u32 *mer)
16279 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_EQU_MER_MER_R__A, &data, 0);
16281 pr_err("error %d\n", rc);
16285 case 0: /* fall through */
16322 case 13: /* fall through */
16326 case 15: /* fall through */
16330 case 17: /* fall through */
16334 case 19: /* fall through */
16338 case 21: /* fall through */
16342 case 23: /* fall through */
16343 case 24: /* fall through */
16347 case 26: /* fall through */
16348 case 27: /* fall through */
16352 case 29: /* fall through */
16353 case 30: /* fall through */
16354 case 31: /* fall through */
16358 case 33: /* fall through */
16359 case 34: /* fall through */
16360 case 35: /* fall through */
16364 case 37: /* fall through */
16365 case 38: /* fall through */
16366 case 39: /* fall through */
16370 case 41: /* fall through */
16371 case 42: /* fall through */
16372 case 43: /* fall through */
16373 case 44: /* fall through */
16377 case 46: /* fall through */
16378 case 47: /* fall through */
16379 case 48: /* fall through */
16380 case 49: /* fall through */
16381 case 50: /* fall through */
16384 case 51: /* fall through */
16385 case 52: /* fall through */
16386 case 53: /* fall through */
16387 case 54: /* fall through */
16388 case 55: /* fall through */
16389 case 56: /* fall through */
16393 case 58: /* fall through */
16394 case 59: /* fall through */
16395 case 60: /* fall through */
16396 case 61: /* fall through */
16397 case 62: /* fall through */
16409 #endif /*#ifndef DRXJ_DIGITAL_ONLY */
16412 * \fn int set_orx_nsu_aox()
16413 * \brief Configure OrxNsuAox for OOB
16414 * \param demod instance of demodulator.
16418 static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
16420 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
16424 /* Configure NSU_AOX */
16425 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
16427 pr_err("error %d\n", rc);
16431 data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON));
16433 data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
16434 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
16436 pr_err("error %d\n", rc);
16446 * \fn int ctrl_set_oob()
16447 * \brief Set OOB channel to be used.
16448 * \param demod instance of demodulator
16449 * \param oob_param OOB parameters for channel setting.
16450 * \frequency should be in KHz
16453 * Accepts only. Returns error otherwise.
16454 * Demapper value is written after scu_command START
16455 * because START command causes COMM_EXEC transition
16456 * from 0 to 1 which causes all registers to be
16457 * overwritten with initial value
16461 /* Nyquist filter impulse response */
16462 #define IMPULSE_COSINE_ALPHA_0_3 {-3, -4, -1, 6, 10, 7, -5, -20, -25, -10, 29, 79, 123, 140} /*sqrt raised-cosine filter with alpha=0.3 */
16463 #define IMPULSE_COSINE_ALPHA_0_5 { 2, 0, -2, -2, 2, 5, 2, -10, -20, -14, 20, 74, 125, 145} /*sqrt raised-cosine filter with alpha=0.5 */
16464 #define IMPULSE_COSINE_ALPHA_RO_0_5 { 0, 0, 1, 2, 3, 0, -7, -15, -16, 0, 34, 77, 114, 128} /*full raised-cosine filter with alpha=0.5 (receiver only) */
16466 /* Coefficients for the nyquist fitler (total: 27 taps) */
16467 #define NYQFILTERLEN 27
16469 static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
16471 #ifndef DRXJ_DIGITAL_ONLY
16473 s32 freq = 0; /* KHz */
16474 struct i2c_device_addr *dev_addr = NULL;
16475 struct drxj_data *ext_attr = NULL;
16477 bool mirror_freq_spect_oob = false;
16478 u16 trk_filter_value = 0;
16479 struct drxjscu_cmd scu_cmd;
16480 u16 set_param_parameters[3];
16481 u16 cmd_result[2] = { 0, 0 };
16482 s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
16483 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
16484 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
16485 IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
16486 IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
16488 u8 mode_val[4] = { 2, 2, 0, 1 };
16489 u8 pfi_coeffs[4][6] = {
16490 {DRXJ_16TO8(-92), DRXJ_16TO8(-108), DRXJ_16TO8(100)}, /* TARGET_MODE = 0: PFI_A = -23/32; PFI_B = -54/32; PFI_C = 25/32; fg = 0.5 MHz (Att=26dB) */
16491 {DRXJ_16TO8(-64), DRXJ_16TO8(-80), DRXJ_16TO8(80)}, /* TARGET_MODE = 1: PFI_A = -16/32; PFI_B = -40/32; PFI_C = 20/32; fg = 1.0 MHz (Att=28dB) */
16492 {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)}, /* TARGET_MODE = 2, 3: PFI_A = -20/32; PFI_B = -49/32; PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
16493 {DRXJ_16TO8(-80), DRXJ_16TO8(-98), DRXJ_16TO8(92)} /* TARGET_MODE = 2, 3: PFI_A = -20/32; PFI_B = -49/32; PFI_C = 23/32; fg = 0.8 MHz (Att=25dB) */
16497 dev_addr = demod->my_i2c_dev_addr;
16498 ext_attr = (struct drxj_data *) demod->my_ext_attr;
16499 mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
16501 /* Check parameters */
16502 if (oob_param == NULL) {
16503 /* power off oob module */
16504 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16505 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
16506 scu_cmd.parameter_len = 0;
16507 scu_cmd.result_len = 1;
16508 scu_cmd.result = cmd_result;
16509 rc = scu_command(dev_addr, &scu_cmd);
16511 pr_err("error %d\n", rc);
16514 rc = set_orx_nsu_aox(demod, false);
16516 pr_err("error %d\n", rc);
16519 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
16521 pr_err("error %d\n", rc);
16525 ext_attr->oob_power_on = false;
16529 freq = oob_param->frequency;
16530 if ((freq < 70000) || (freq > 130000))
16532 freq = (freq - 50000) / 50;
16537 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
16539 index = (u16) ((freq - 400) / 200);
16540 remainder = (u16) ((freq - 400) % 200);
16542 trk_filtercfg[index] - (trk_filtercfg[index] -
16543 trk_filtercfg[index +
16544 1]) / 10 * remainder /
16551 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
16553 pr_err("error %d\n", rc);
16556 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16557 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
16558 scu_cmd.parameter_len = 0;
16559 scu_cmd.result_len = 1;
16560 scu_cmd.result = cmd_result;
16561 rc = scu_command(dev_addr, &scu_cmd);
16563 pr_err("error %d\n", rc);
16569 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16570 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
16571 scu_cmd.parameter_len = 0;
16572 scu_cmd.result_len = 1;
16573 scu_cmd.result = cmd_result;
16574 rc = scu_command(dev_addr, &scu_cmd);
16576 pr_err("error %d\n", rc);
16582 /* set frequency, spectrum inversion and data rate */
16583 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16584 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
16585 scu_cmd.parameter_len = 3;
16586 /* 1-data rate;2-frequency */
16587 switch (oob_param->standard) {
16588 case DRX_OOB_MODE_A:
16590 /* signal is transmitted inverted */
16591 ((oob_param->spectrum_inverted == true) &
16592 /* and tuner is not mirroring the signal */
16593 (!mirror_freq_spect_oob)) |
16595 /* signal is transmitted noninverted */
16596 ((oob_param->spectrum_inverted == false) &
16597 /* and tuner is mirroring the signal */
16598 (mirror_freq_spect_oob))
16600 set_param_parameters[0] =
16601 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
16603 set_param_parameters[0] =
16604 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
16606 case DRX_OOB_MODE_B_GRADE_A:
16608 /* signal is transmitted inverted */
16609 ((oob_param->spectrum_inverted == true) &
16610 /* and tuner is not mirroring the signal */
16611 (!mirror_freq_spect_oob)) |
16613 /* signal is transmitted noninverted */
16614 ((oob_param->spectrum_inverted == false) &
16615 /* and tuner is mirroring the signal */
16616 (mirror_freq_spect_oob))
16618 set_param_parameters[0] =
16619 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
16621 set_param_parameters[0] =
16622 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
16624 case DRX_OOB_MODE_B_GRADE_B:
16627 /* signal is transmitted inverted */
16628 ((oob_param->spectrum_inverted == true) &
16629 /* and tuner is not mirroring the signal */
16630 (!mirror_freq_spect_oob)) |
16632 /* signal is transmitted noninverted */
16633 ((oob_param->spectrum_inverted == false) &
16634 /* and tuner is mirroring the signal */
16635 (mirror_freq_spect_oob))
16637 set_param_parameters[0] =
16638 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
16640 set_param_parameters[0] =
16641 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
16644 set_param_parameters[1] = (u16) (freq & 0xFFFF);
16645 set_param_parameters[2] = trk_filter_value;
16646 scu_cmd.parameter = set_param_parameters;
16647 scu_cmd.result_len = 1;
16648 scu_cmd.result = cmd_result;
16649 mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
16650 rc = scu_command(dev_addr, &scu_cmd);
16652 pr_err("error %d\n", rc);
16656 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
16658 pr_err("error %d\n", rc);
16660 } /* Write magic word to enable pdr reg write */
16661 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_OOB_CRX_CFG__A, OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B, 0);
16663 pr_err("error %d\n", rc);
16666 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_OOB_DRX_CFG__A, OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B, 0);
16668 pr_err("error %d\n", rc);
16671 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
16673 pr_err("error %d\n", rc);
16675 } /* Write magic word to disable pdr reg write */
16677 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
16679 pr_err("error %d\n", rc);
16682 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
16684 pr_err("error %d\n", rc);
16687 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
16689 pr_err("error %d\n", rc);
16694 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
16696 pr_err("error %d\n", rc);
16701 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
16703 pr_err("error %d\n", rc);
16707 /* initialization for target mode */
16708 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
16710 pr_err("error %d\n", rc);
16713 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
16715 pr_err("error %d\n", rc);
16719 /* Reset bits for timing and freq. recovery */
16720 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
16722 pr_err("error %d\n", rc);
16725 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
16727 pr_err("error %d\n", rc);
16730 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
16732 pr_err("error %d\n", rc);
16735 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
16737 pr_err("error %d\n", rc);
16741 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
16742 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
16744 pr_err("error %d\n", rc);
16747 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
16749 pr_err("error %d\n", rc);
16752 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
16754 pr_err("error %d\n", rc);
16757 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
16759 pr_err("error %d\n", rc);
16762 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
16764 pr_err("error %d\n", rc);
16768 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
16769 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
16771 pr_err("error %d\n", rc);
16774 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
16776 pr_err("error %d\n", rc);
16779 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
16781 pr_err("error %d\n", rc);
16784 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
16786 pr_err("error %d\n", rc);
16789 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
16791 pr_err("error %d\n", rc);
16795 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
16796 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
16798 pr_err("error %d\n", rc);
16801 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
16803 pr_err("error %d\n", rc);
16806 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
16808 pr_err("error %d\n", rc);
16811 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
16813 pr_err("error %d\n", rc);
16816 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
16818 pr_err("error %d\n", rc);
16822 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
16823 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
16825 pr_err("error %d\n", rc);
16828 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
16830 pr_err("error %d\n", rc);
16833 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
16835 pr_err("error %d\n", rc);
16838 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
16840 pr_err("error %d\n", rc);
16843 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
16845 pr_err("error %d\n", rc);
16849 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
16850 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
16852 pr_err("error %d\n", rc);
16855 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
16857 pr_err("error %d\n", rc);
16860 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
16862 pr_err("error %d\n", rc);
16865 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
16867 pr_err("error %d\n", rc);
16870 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
16872 pr_err("error %d\n", rc);
16876 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
16877 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
16879 pr_err("error %d\n", rc);
16882 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
16884 pr_err("error %d\n", rc);
16887 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
16889 pr_err("error %d\n", rc);
16892 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
16894 pr_err("error %d\n", rc);
16897 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
16899 pr_err("error %d\n", rc);
16903 /* PRE-Filter coefficients (PFI) */
16904 rc = DRXJ_DAP.write_block_func(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
16906 pr_err("error %d\n", rc);
16909 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
16911 pr_err("error %d\n", rc);
16915 /* NYQUIST-Filter coefficients (NYQ) */
16916 for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
16917 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
16919 pr_err("error %d\n", rc);
16922 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
16924 pr_err("error %d\n", rc);
16928 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
16930 pr_err("error %d\n", rc);
16933 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
16935 pr_err("error %d\n", rc);
16941 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16942 | SCU_RAM_COMMAND_CMD_DEMOD_START;
16943 scu_cmd.parameter_len = 0;
16944 scu_cmd.result_len = 1;
16945 scu_cmd.result = cmd_result;
16946 rc = scu_command(dev_addr, &scu_cmd);
16948 pr_err("error %d\n", rc);
16952 rc = set_orx_nsu_aox(demod, true);
16954 pr_err("error %d\n", rc);
16957 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
16959 pr_err("error %d\n", rc);
16963 ext_attr->oob_power_on = true;
16972 * \fn int ctrl_get_oob()
16973 * \brief Set modulation standard to be used.
16974 * \param demod instance of demodulator
16975 * \param oob_status OOB status parameters.
16979 ctrl_get_oob(struct drx_demod_instance *demod, struct drxoob_status *oob_status)
16981 #ifndef DRXJ_DIGITAL_ONLY
16983 struct i2c_device_addr *dev_addr = NULL;
16984 struct drxj_data *ext_attr = NULL;
16987 dev_addr = demod->my_i2c_dev_addr;
16988 ext_attr = (struct drxj_data *) demod->my_ext_attr;
16990 /* check arguments */
16991 if (oob_status == NULL)
16994 if (!ext_attr->oob_power_on)
16997 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_DDC_OFO_SET_W__A, &data, 0);
16999 pr_err("error %d\n", rc);
17002 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &data, 0);
17004 pr_err("error %d\n", rc);
17007 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_AAG_THR_W__A, &data, 0);
17009 pr_err("error %d\n", rc);
17012 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_DGN_KI__A, &data, 0);
17014 pr_err("error %d\n", rc);
17017 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
17019 pr_err("error %d\n", rc);
17023 rc = get_oob_lock_status(demod, dev_addr, &oob_status->lock);
17025 pr_err("error %d\n", rc);
17028 rc = get_oob_frequency(demod, &oob_status->frequency);
17030 pr_err("error %d\n", rc);
17033 rc = get_oobmer(dev_addr, &oob_status->mer);
17035 pr_err("error %d\n", rc);
17038 rc = get_oob_symbol_rate_offset(dev_addr, &oob_status->symbol_rate_offset);
17040 pr_err("error %d\n", rc);
17051 * \fn int ctrl_set_cfg_oob_pre_saw()
17052 * \brief Configure PreSAW treshold value
17053 * \param cfg_data Pointer to configuration parameter
17054 * \return Error code
17056 #ifndef DRXJ_DIGITAL_ONLY
17058 ctrl_set_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17060 struct i2c_device_addr *dev_addr = NULL;
17061 struct drxj_data *ext_attr = NULL;
17064 if (cfg_data == NULL)
17067 dev_addr = demod->my_i2c_dev_addr;
17068 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17070 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STHR_W__A, *cfg_data, 0);
17072 pr_err("error %d\n", rc);
17075 ext_attr->oob_pre_saw = *cfg_data;
17083 * \fn int ctrl_get_cfg_oob_pre_saw()
17084 * \brief Configure PreSAW treshold value
17085 * \param cfg_data Pointer to configuration parameter
17086 * \return Error code
17088 #ifndef DRXJ_DIGITAL_ONLY
17090 ctrl_get_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17092 struct drxj_data *ext_attr = NULL;
17094 if (cfg_data == NULL)
17097 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17099 *cfg_data = ext_attr->oob_pre_saw;
17106 * \fn int ctrl_set_cfg_oob_lo_power()
17107 * \brief Configure LO Power value
17108 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17110 #ifndef DRXJ_DIGITAL_ONLY
17112 ctrl_set_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17114 struct i2c_device_addr *dev_addr = NULL;
17115 struct drxj_data *ext_attr = NULL;
17118 if (cfg_data == NULL)
17121 dev_addr = demod->my_i2c_dev_addr;
17122 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17124 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_LOPOW_W__A, *cfg_data, 0);
17126 pr_err("error %d\n", rc);
17129 ext_attr->oob_lo_pow = *cfg_data;
17137 * \fn int ctrl_get_cfg_oob_lo_power()
17138 * \brief Configure LO Power value
17139 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17141 #ifndef DRXJ_DIGITAL_ONLY
17143 ctrl_get_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17145 struct drxj_data *ext_attr = NULL;
17147 if (cfg_data == NULL)
17150 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17152 *cfg_data = ext_attr->oob_lo_pow;
17157 /*============================================================================*/
17158 /*== END OOB DATAPATH FUNCTIONS ==*/
17159 /*============================================================================*/
17161 /*=============================================================================
17162 ===== MC command related functions ==========================================
17163 ===========================================================================*/
17165 /*=============================================================================
17166 ===== ctrl_set_channel() ==========================================================
17167 ===========================================================================*/
17169 * \fn int ctrl_set_channel()
17170 * \brief Select a new transmission channel.
17171 * \param demod instance of demod.
17172 * \param channel Pointer to channel data.
17175 * In case the tuner module is not used and in case of NTSC/FM the pogrammer
17176 * must tune the tuner to the centre frequency of the NTSC/FM channel.
17180 ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17183 s32 tuner_set_freq = 0;
17184 s32 tuner_get_freq = 0;
17185 s32 tuner_freq_offset = 0;
17186 s32 intermediate_freq = 0;
17187 struct drxj_data *ext_attr = NULL;
17188 struct i2c_device_addr *dev_addr = NULL;
17189 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17190 u32 tuner_mode = 0;
17191 struct drx_common_attr *common_attr = NULL;
17192 bool bridge_closed = false;
17193 #ifndef DRXJ_VSB_ONLY
17194 u32 min_symbol_rate = 0;
17195 u32 max_symbol_rate = 0;
17196 int bandwidth_temp = 0;
17199 /*== check arguments ======================================================*/
17200 if ((demod == NULL) || (channel == NULL))
17203 common_attr = (struct drx_common_attr *) demod->my_common_attr;
17204 dev_addr = demod->my_i2c_dev_addr;
17205 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17206 standard = ext_attr->standard;
17208 /* check valid standards */
17209 switch (standard) {
17210 case DRX_STANDARD_8VSB:
17211 #ifndef DRXJ_VSB_ONLY
17212 case DRX_STANDARD_ITU_A:
17213 case DRX_STANDARD_ITU_B:
17214 case DRX_STANDARD_ITU_C:
17215 #endif /* DRXJ_VSB_ONLY */
17216 #ifndef DRXJ_DIGITAL_ONLY
17217 case DRX_STANDARD_NTSC:
17218 case DRX_STANDARD_FM:
17219 case DRX_STANDARD_PAL_SECAM_BG:
17220 case DRX_STANDARD_PAL_SECAM_DK:
17221 case DRX_STANDARD_PAL_SECAM_I:
17222 case DRX_STANDARD_PAL_SECAM_L:
17223 case DRX_STANDARD_PAL_SECAM_LP:
17224 #endif /* DRXJ_DIGITAL_ONLY */
17226 case DRX_STANDARD_UNKNOWN:
17231 /* check bandwidth QAM annex B, NTSC and 8VSB */
17232 if ((standard == DRX_STANDARD_ITU_B) ||
17233 (standard == DRX_STANDARD_8VSB) ||
17234 (standard == DRX_STANDARD_NTSC)) {
17235 switch (channel->bandwidth) {
17236 case DRX_BANDWIDTH_6MHZ:
17237 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
17238 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17240 case DRX_BANDWIDTH_8MHZ: /* fall through */
17241 case DRX_BANDWIDTH_7MHZ: /* fall through */
17246 #ifndef DRXJ_DIGITAL_ONLY
17247 if (standard == DRX_STANDARD_PAL_SECAM_BG) {
17248 switch (channel->bandwidth) {
17249 case DRX_BANDWIDTH_7MHZ: /* fall through */
17250 case DRX_BANDWIDTH_8MHZ:
17253 case DRX_BANDWIDTH_6MHZ: /* fall through */
17254 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
17259 /* check bandwidth PAL/SECAM */
17260 if ((standard == DRX_STANDARD_PAL_SECAM_BG) ||
17261 (standard == DRX_STANDARD_PAL_SECAM_DK) ||
17262 (standard == DRX_STANDARD_PAL_SECAM_I) ||
17263 (standard == DRX_STANDARD_PAL_SECAM_L) ||
17264 (standard == DRX_STANDARD_PAL_SECAM_LP)) {
17265 switch (channel->bandwidth) {
17266 case DRX_BANDWIDTH_8MHZ:
17267 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
17268 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17270 case DRX_BANDWIDTH_6MHZ: /* fall through */
17271 case DRX_BANDWIDTH_7MHZ: /* fall through */
17278 /* For QAM annex A and annex C:
17279 -check symbolrate and constellation
17280 -derive bandwidth from symbolrate (input bandwidth is ignored)
17282 #ifndef DRXJ_VSB_ONLY
17283 if ((standard == DRX_STANDARD_ITU_A) ||
17284 (standard == DRX_STANDARD_ITU_C)) {
17285 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
17286 int bw_rolloff_factor = 0;
17288 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
17289 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
17290 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
17291 /* config SMA_TX pin to SAW switch mode */
17292 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
17294 pr_err("error %d\n", rc);
17298 if (channel->symbolrate < min_symbol_rate ||
17299 channel->symbolrate > max_symbol_rate) {
17303 switch (channel->constellation) {
17304 case DRX_CONSTELLATION_QAM16: /* fall through */
17305 case DRX_CONSTELLATION_QAM32: /* fall through */
17306 case DRX_CONSTELLATION_QAM64: /* fall through */
17307 case DRX_CONSTELLATION_QAM128: /* fall through */
17308 case DRX_CONSTELLATION_QAM256:
17309 bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
17310 bandwidth = bandwidth_temp / 100;
17312 if ((bandwidth_temp % 100) >= 50)
17315 if (bandwidth <= 6100000) {
17316 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17317 } else if ((bandwidth > 6100000)
17318 && (bandwidth <= 7100000)) {
17319 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
17320 } else if (bandwidth > 7100000) {
17321 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17329 /* For QAM annex B:
17330 -check constellation
17332 if (standard == DRX_STANDARD_ITU_B) {
17333 switch (channel->constellation) {
17334 case DRX_CONSTELLATION_AUTO:
17335 case DRX_CONSTELLATION_QAM256:
17336 case DRX_CONSTELLATION_QAM64:
17342 switch (channel->interleavemode) {
17343 case DRX_INTERLEAVEMODE_I128_J1:
17344 case DRX_INTERLEAVEMODE_I128_J1_V2:
17345 case DRX_INTERLEAVEMODE_I128_J2:
17346 case DRX_INTERLEAVEMODE_I64_J2:
17347 case DRX_INTERLEAVEMODE_I128_J3:
17348 case DRX_INTERLEAVEMODE_I32_J4:
17349 case DRX_INTERLEAVEMODE_I128_J4:
17350 case DRX_INTERLEAVEMODE_I16_J8:
17351 case DRX_INTERLEAVEMODE_I128_J5:
17352 case DRX_INTERLEAVEMODE_I8_J16:
17353 case DRX_INTERLEAVEMODE_I128_J6:
17354 case DRX_INTERLEAVEMODE_I128_J7:
17355 case DRX_INTERLEAVEMODE_I128_J8:
17356 case DRX_INTERLEAVEMODE_I12_J17:
17357 case DRX_INTERLEAVEMODE_I5_J4:
17358 case DRX_INTERLEAVEMODE_B52_M240:
17359 case DRX_INTERLEAVEMODE_B52_M720:
17360 case DRX_INTERLEAVEMODE_UNKNOWN:
17361 case DRX_INTERLEAVEMODE_AUTO:
17368 if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
17369 /* SAW SW, user UIO is used for switchable SAW */
17370 struct drxuio_data uio1 = { DRX_UIO1, false };
17372 switch (channel->bandwidth) {
17373 case DRX_BANDWIDTH_8MHZ:
17376 case DRX_BANDWIDTH_7MHZ:
17377 uio1.value = false;
17379 case DRX_BANDWIDTH_6MHZ:
17380 uio1.value = false;
17382 case DRX_BANDWIDTH_UNKNOWN:
17387 rc = ctrl_uio_write(demod, &uio1);
17389 pr_err("error %d\n", rc);
17393 #endif /* DRXJ_VSB_ONLY */
17394 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
17396 pr_err("error %d\n", rc);
17399 /*== Tune, fast mode ======================================================*/
17400 if (demod->my_tuner != NULL) {
17401 /* Determine tuner mode and freq to tune to ... */
17402 switch (standard) {
17403 #ifndef DRXJ_DIGITAL_ONLY
17404 case DRX_STANDARD_NTSC: /* fallthrough */
17405 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17406 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17407 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
17408 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
17409 case DRX_STANDARD_PAL_SECAM_LP:
17410 /* expecting center frequency, not picture carrier so no
17412 tuner_mode |= TUNER_MODE_ANALOG;
17413 tuner_set_freq = channel->frequency;
17415 case DRX_STANDARD_FM:
17416 /* center frequency (equals sound carrier) as input,
17417 tune to edge of SAW */
17418 tuner_mode |= TUNER_MODE_ANALOG;
17420 channel->frequency + DRXJ_FM_CARRIER_FREQ_OFFSET;
17423 case DRX_STANDARD_8VSB: /* fallthrough */
17424 #ifndef DRXJ_VSB_ONLY
17425 case DRX_STANDARD_ITU_A: /* fallthrough */
17426 case DRX_STANDARD_ITU_B: /* fallthrough */
17427 case DRX_STANDARD_ITU_C:
17429 tuner_mode |= TUNER_MODE_DIGITAL;
17430 tuner_set_freq = channel->frequency;
17432 case DRX_STANDARD_UNKNOWN:
17435 } /* switch(standard) */
17437 tuner_mode |= TUNER_MODE_SWITCH;
17438 switch (channel->bandwidth) {
17439 case DRX_BANDWIDTH_8MHZ:
17440 tuner_mode |= TUNER_MODE_8MHZ;
17442 case DRX_BANDWIDTH_7MHZ:
17443 tuner_mode |= TUNER_MODE_7MHZ;
17445 case DRX_BANDWIDTH_6MHZ:
17446 tuner_mode |= TUNER_MODE_6MHZ;
17449 /* TODO: for FM which bandwidth to use ?
17450 also check offset from centre frequency ?
17451 For now using 6MHz.
17453 tuner_mode |= TUNER_MODE_6MHZ;
17455 /* return (-EINVAL); */
17458 /* store bandwidth for GetChannel() */
17459 ext_attr->curr_bandwidth = channel->bandwidth;
17460 ext_attr->curr_symbol_rate = channel->symbolrate;
17461 ext_attr->frequency = tuner_set_freq;
17462 if (common_attr->tuner_port_nr == 1) {
17463 /* close tuner bridge */
17464 bridge_closed = true;
17465 rc = ctrl_i2c_bridge(demod, &bridge_closed);
17467 pr_err("error %d\n", rc);
17470 /* set tuner frequency */
17473 rc = drxbsp_tuner_set_frequency(demod->my_tuner, tuner_mode, tuner_set_freq);
17475 pr_err("error %d\n", rc);
17478 if (common_attr->tuner_port_nr == 1) {
17479 /* open tuner bridge */
17480 bridge_closed = false;
17481 rc = ctrl_i2c_bridge(demod, &bridge_closed);
17483 pr_err("error %d\n", rc);
17488 /* Get actual frequency set by tuner and compute offset */
17489 rc = drxbsp_tuner_get_frequency(demod->my_tuner, 0, &tuner_get_freq, &intermediate_freq);
17491 pr_err("error %d\n", rc);
17494 tuner_freq_offset = tuner_get_freq - tuner_set_freq;
17495 common_attr->intermediate_freq = intermediate_freq;
17497 /* no tuner instance defined, use fixed intermediate frequency */
17498 tuner_freq_offset = 0;
17499 intermediate_freq = demod->my_common_attr->intermediate_freq;
17500 } /* if ( demod->my_tuner != NULL ) */
17502 /*== Setup demod for specific standard ====================================*/
17503 switch (standard) {
17504 case DRX_STANDARD_8VSB:
17505 if (channel->mirror == DRX_MIRROR_AUTO)
17506 ext_attr->mirror = DRX_MIRROR_NO;
17508 ext_attr->mirror = channel->mirror;
17509 rc = set_vsb(demod);
17511 pr_err("error %d\n", rc);
17514 rc = set_frequency(demod, channel, tuner_freq_offset);
17516 pr_err("error %d\n", rc);
17520 #ifndef DRXJ_DIGITAL_ONLY
17521 case DRX_STANDARD_NTSC: /* fallthrough */
17522 case DRX_STANDARD_FM: /* fallthrough */
17523 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17524 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17525 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
17526 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
17527 case DRX_STANDARD_PAL_SECAM_LP:
17528 if (channel->mirror == DRX_MIRROR_AUTO)
17529 ext_attr->mirror = DRX_MIRROR_NO;
17531 ext_attr->mirror = channel->mirror;
17532 rc = set_atv_channel(demod, tuner_freq_offset, channel, standard);
17534 pr_err("error %d\n", rc);
17539 #ifndef DRXJ_VSB_ONLY
17540 case DRX_STANDARD_ITU_A: /* fallthrough */
17541 case DRX_STANDARD_ITU_B: /* fallthrough */
17542 case DRX_STANDARD_ITU_C:
17543 rc = set_qam_channel(demod, channel, tuner_freq_offset);
17545 pr_err("error %d\n", rc);
17550 case DRX_STANDARD_UNKNOWN:
17555 /*== Re-tune, slow mode ===================================================*/
17556 if (demod->my_tuner != NULL) {
17557 /* tune to slow mode */
17558 tuner_mode &= ~TUNER_MODE_SWITCH;
17559 tuner_mode |= TUNER_MODE_LOCK;
17561 if (common_attr->tuner_port_nr == 1) {
17562 /* close tuner bridge */
17563 bridge_closed = true;
17564 rc = ctrl_i2c_bridge(demod, &bridge_closed);
17566 pr_err("error %d\n", rc);
17571 /* set tuner frequency */
17572 rc = drxbsp_tuner_set_frequency(demod->my_tuner, tuner_mode, tuner_set_freq);
17574 pr_err("error %d\n", rc);
17577 if (common_attr->tuner_port_nr == 1) {
17578 /* open tuner bridge */
17579 bridge_closed = false;
17580 rc = ctrl_i2c_bridge(demod, &bridge_closed);
17582 pr_err("error %d\n", rc);
17588 /* if ( demod->my_tuner !=NULL ) */
17589 /* flag the packet error counter reset */
17590 ext_attr->reset_pkt_err_acc = true;
17597 /*=============================================================================
17598 ===== ctrl_get_channel() ==========================================================
17599 ===========================================================================*/
17601 * \fn int ctrl_get_channel()
17602 * \brief Retreive parameters of current transmission channel.
17603 * \param demod Pointer to demod instance.
17604 * \param channel Pointer to channel data.
17608 ctrl_get_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17610 struct i2c_device_addr *dev_addr = NULL;
17611 struct drxj_data *ext_attr = NULL;
17613 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17614 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17615 struct drx_common_attr *common_attr = NULL;
17616 s32 intermediate_freq = 0;
17617 s32 ctl_freq_offset = 0;
17618 u32 iqm_rc_rate_lo = 0;
17619 u32 adc_frequency = 0;
17620 #ifndef DRXJ_VSB_ONLY
17621 int bandwidth_temp = 0;
17625 /* check arguments */
17626 if ((demod == NULL) || (channel == NULL))
17629 dev_addr = demod->my_i2c_dev_addr;
17630 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17631 standard = ext_attr->standard;
17632 common_attr = (struct drx_common_attr *) demod->my_common_attr;
17634 /* initialize channel fields */
17635 channel->mirror = DRX_MIRROR_UNKNOWN;
17636 channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
17637 channel->priority = DRX_PRIORITY_UNKNOWN;
17638 channel->coderate = DRX_CODERATE_UNKNOWN;
17639 channel->guard = DRX_GUARD_UNKNOWN;
17640 channel->fftmode = DRX_FFTMODE_UNKNOWN;
17641 channel->classification = DRX_CLASSIFICATION_UNKNOWN;
17642 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
17643 channel->constellation = DRX_CONSTELLATION_UNKNOWN;
17644 channel->symbolrate = 0;
17645 channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
17646 channel->carrier = DRX_CARRIER_UNKNOWN;
17647 channel->framemode = DRX_FRAMEMODE_UNKNOWN;
17648 /* channel->interleaver = DRX_INTERLEAVER_UNKNOWN;*/
17649 channel->ldpc = DRX_LDPC_UNKNOWN;
17651 if (demod->my_tuner != NULL) {
17652 s32 tuner_freq_offset = 0;
17653 bool tuner_mirror = common_attr->mirror_freq_spect ? false : true;
17655 /* Get frequency from tuner */
17656 rc = drxbsp_tuner_get_frequency(demod->my_tuner, 0, &(channel->frequency), &intermediate_freq);
17658 pr_err("error %d\n", rc);
17661 tuner_freq_offset = channel->frequency - ext_attr->frequency;
17662 if (tuner_mirror) {
17663 /* positive image */
17664 channel->frequency += tuner_freq_offset;
17666 /* negative image */
17667 channel->frequency -= tuner_freq_offset;
17670 /* Handle sound carrier offset in RF domain */
17671 if (standard == DRX_STANDARD_FM)
17672 channel->frequency -= DRXJ_FM_CARRIER_FREQ_OFFSET;
17674 intermediate_freq = common_attr->intermediate_freq;
17677 /* check lock status */
17678 rc = ctrl_lock_status(demod, &lock_status);
17680 pr_err("error %d\n", rc);
17683 if ((lock_status == DRX_LOCKED) || (lock_status == DRXJ_DEMOD_LOCK)) {
17684 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &iqm_rc_rate_lo, 0);
17686 pr_err("error %d\n", rc);
17689 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
17691 channel->symbolrate =
17692 frac28(adc_frequency, (iqm_rc_rate_lo + (1 << 23))) >> 7;
17694 switch (standard) {
17695 case DRX_STANDARD_8VSB:
17696 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17697 /* get the channel frequency */
17698 rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17700 pr_err("error %d\n", rc);
17703 channel->frequency -= ctl_freq_offset;
17704 /* get the channel constellation */
17705 channel->constellation = DRX_CONSTELLATION_AUTO;
17707 #ifndef DRXJ_VSB_ONLY
17708 case DRX_STANDARD_ITU_A:
17709 case DRX_STANDARD_ITU_B:
17710 case DRX_STANDARD_ITU_C:
17712 /* get the channel frequency */
17713 rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17715 pr_err("error %d\n", rc);
17718 channel->frequency -= ctl_freq_offset;
17720 if (standard == DRX_STANDARD_ITU_B) {
17721 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17725 u32 roll_off = 113; /* default annex C */
17727 if (standard == DRX_STANDARD_ITU_A)
17731 channel->symbolrate * roll_off;
17732 bandwidth = bandwidth_temp / 100;
17734 if ((bandwidth_temp % 100) >= 50)
17737 if (bandwidth <= 6000000) {
17738 channel->bandwidth =
17739 DRX_BANDWIDTH_6MHZ;
17740 } else if ((bandwidth > 6000000)
17741 && (bandwidth <= 7000000)) {
17742 channel->bandwidth =
17743 DRX_BANDWIDTH_7MHZ;
17744 } else if (bandwidth > 7000000) {
17745 channel->bandwidth =
17746 DRX_BANDWIDTH_8MHZ;
17748 } /* if (standard == DRX_STANDARD_ITU_B) */
17751 struct drxjscu_cmd cmd_scu = { 0, 0, 0, NULL, NULL };
17752 u16 cmd_result[3] = { 0, 0, 0 };
17755 SCU_RAM_COMMAND_STANDARD_QAM |
17756 SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
17757 cmd_scu.parameter_len = 0;
17758 cmd_scu.result_len = 3;
17759 cmd_scu.parameter = NULL;
17760 cmd_scu.result = cmd_result;
17761 rc = scu_command(dev_addr, &cmd_scu);
17763 pr_err("error %d\n", rc);
17767 channel->interleavemode =
17768 (enum drx_interleave_mode) (cmd_scu.
17772 switch (ext_attr->constellation) {
17773 case DRX_CONSTELLATION_QAM256:
17774 channel->constellation =
17775 DRX_CONSTELLATION_QAM256;
17777 case DRX_CONSTELLATION_QAM128:
17778 channel->constellation =
17779 DRX_CONSTELLATION_QAM128;
17781 case DRX_CONSTELLATION_QAM64:
17782 channel->constellation =
17783 DRX_CONSTELLATION_QAM64;
17785 case DRX_CONSTELLATION_QAM32:
17786 channel->constellation =
17787 DRX_CONSTELLATION_QAM32;
17789 case DRX_CONSTELLATION_QAM16:
17790 channel->constellation =
17791 DRX_CONSTELLATION_QAM16;
17794 channel->constellation =
17795 DRX_CONSTELLATION_UNKNOWN;
17801 #ifndef DRXJ_DIGITAL_ONLY
17802 case DRX_STANDARD_NTSC: /* fall trough */
17803 case DRX_STANDARD_PAL_SECAM_BG:
17804 case DRX_STANDARD_PAL_SECAM_DK:
17805 case DRX_STANDARD_PAL_SECAM_I:
17806 case DRX_STANDARD_PAL_SECAM_L:
17807 case DRX_STANDARD_PAL_SECAM_LP:
17808 case DRX_STANDARD_FM:
17809 rc = get_atv_channel(demod, channel, standard);
17811 pr_err("error %d\n", rc);
17816 case DRX_STANDARD_UNKNOWN: /* fall trough */
17819 } /* switch ( standard ) */
17821 if (lock_status == DRX_LOCKED)
17822 channel->mirror = ext_attr->mirror;
17824 /* if ( lock_status == DRX_LOCKED ) */
17830 /*=============================================================================
17831 ===== SigQuality() ==========================================================
17832 ===========================================================================*/
17835 mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
17839 if (mer < min_mer) {
17841 } else if (mer < threshold_mer) {
17842 if ((threshold_mer - min_mer) != 0)
17843 indicator = 25 * (mer - min_mer) / (threshold_mer - min_mer);
17844 } else if (mer < max_mer) {
17845 if ((max_mer - threshold_mer) != 0)
17846 indicator = 25 + 75 * (mer - threshold_mer) / (max_mer - threshold_mer);
17857 * \fn int ctrl_sig_quality()
17858 * \brief Retreive signal quality form device.
17859 * \param devmod Pointer to demodulator instance.
17860 * \param sig_quality Pointer to signal quality data.
17862 * \retval 0 sig_quality contains valid data.
17863 * \retval -EINVAL sig_quality is NULL.
17864 * \retval -EIO Erroneous data, sig_quality contains invalid data.
17868 ctrl_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
17870 struct i2c_device_addr *dev_addr = NULL;
17871 struct drxj_data *ext_attr = NULL;
17873 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17874 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17877 u16 threshold_mer = 0;
17879 /* Check arguments */
17880 if ((sig_quality == NULL) || (demod == NULL))
17883 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17884 standard = ext_attr->standard;
17886 /* get basic information */
17887 dev_addr = demod->my_i2c_dev_addr;
17888 rc = ctrl_lock_status(demod, &lock_status);
17890 pr_err("error %d\n", rc);
17893 switch (standard) {
17894 case DRX_STANDARD_8VSB:
17895 #ifdef DRXJ_SIGNAL_ACCUM_ERR
17896 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
17898 pr_err("error %d\n", rc);
17902 rc = get_vsb_post_rs_pck_err(dev_addr, &sig_quality->packet_error);
17904 pr_err("error %d\n", rc);
17908 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
17909 sig_quality->post_viterbi_ber = 500000;
17910 sig_quality->MER = 20;
17911 sig_quality->pre_viterbi_ber = 0;
17913 /* PostViterbi is compute in steps of 10^(-6) */
17914 rc = get_vs_bpre_viterbi_ber(dev_addr, &sig_quality->pre_viterbi_ber);
17916 pr_err("error %d\n", rc);
17919 rc = get_vs_bpost_viterbi_ber(dev_addr, &sig_quality->post_viterbi_ber);
17921 pr_err("error %d\n", rc);
17924 rc = get_vsbmer(dev_addr, &sig_quality->MER);
17926 pr_err("error %d\n", rc);
17932 threshold_mer = 145;
17933 sig_quality->post_reed_solomon_ber = 0;
17934 sig_quality->scale_factor_ber = 1000000;
17935 sig_quality->indicator =
17936 mer2indicator(sig_quality->MER, min_mer, threshold_mer,
17939 #ifndef DRXJ_VSB_ONLY
17940 case DRX_STANDARD_ITU_A:
17941 case DRX_STANDARD_ITU_B:
17942 case DRX_STANDARD_ITU_C:
17943 rc = ctrl_get_qam_sig_quality(demod, sig_quality);
17945 pr_err("error %d\n", rc);
17948 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
17949 switch (ext_attr->constellation) {
17950 case DRX_CONSTELLATION_QAM256:
17951 sig_quality->MER = 210;
17953 case DRX_CONSTELLATION_QAM128:
17954 sig_quality->MER = 180;
17956 case DRX_CONSTELLATION_QAM64:
17957 sig_quality->MER = 150;
17959 case DRX_CONSTELLATION_QAM32:
17960 sig_quality->MER = 120;
17962 case DRX_CONSTELLATION_QAM16:
17963 sig_quality->MER = 90;
17966 sig_quality->MER = 0;
17971 switch (ext_attr->constellation) {
17972 case DRX_CONSTELLATION_QAM256:
17974 threshold_mer = 270;
17977 case DRX_CONSTELLATION_QAM64:
17979 threshold_mer = 210;
17982 case DRX_CONSTELLATION_QAM128:
17983 case DRX_CONSTELLATION_QAM32:
17984 case DRX_CONSTELLATION_QAM16:
17989 sig_quality->indicator =
17990 mer2indicator(sig_quality->MER, min_mer, threshold_mer,
17994 #ifndef DRXJ_DIGITAL_ONLY
17995 case DRX_STANDARD_PAL_SECAM_BG:
17996 case DRX_STANDARD_PAL_SECAM_DK:
17997 case DRX_STANDARD_PAL_SECAM_I:
17998 case DRX_STANDARD_PAL_SECAM_L:
17999 case DRX_STANDARD_PAL_SECAM_LP:
18000 case DRX_STANDARD_NTSC:
18001 rc = atv_sig_quality(demod, sig_quality);
18003 pr_err("error %d\n", rc);
18007 case DRX_STANDARD_FM:
18008 rc = fm_sig_quality(demod, sig_quality);
18010 pr_err("error %d\n", rc);
18024 /*============================================================================*/
18027 * \fn int ctrl_lock_status()
18028 * \brief Retreive lock status .
18029 * \param dev_addr Pointer to demodulator device address.
18030 * \param lock_stat Pointer to lock status structure.
18035 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
18037 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18038 struct drxj_data *ext_attr = NULL;
18039 struct i2c_device_addr *dev_addr = NULL;
18040 struct drxjscu_cmd cmd_scu = { /* command */ 0,
18041 /* parameter_len */ 0,
18042 /* result_len */ 0,
18043 /* *parameter */ NULL,
18047 u16 cmd_result[2] = { 0, 0 };
18048 u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
18050 /* check arguments */
18051 if ((demod == NULL) || (lock_stat == NULL))
18054 dev_addr = demod->my_i2c_dev_addr;
18055 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18056 standard = ext_attr->standard;
18058 *lock_stat = DRX_NOT_LOCKED;
18060 /* define the SCU command code */
18061 switch (standard) {
18062 case DRX_STANDARD_8VSB:
18063 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
18064 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18067 #ifndef DRXJ_VSB_ONLY
18068 case DRX_STANDARD_ITU_A:
18069 case DRX_STANDARD_ITU_B:
18070 case DRX_STANDARD_ITU_C:
18071 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
18072 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18075 #ifndef DRXJ_DIGITAL_ONLY
18076 case DRX_STANDARD_NTSC:
18077 case DRX_STANDARD_PAL_SECAM_BG:
18078 case DRX_STANDARD_PAL_SECAM_DK:
18079 case DRX_STANDARD_PAL_SECAM_I:
18080 case DRX_STANDARD_PAL_SECAM_L:
18081 case DRX_STANDARD_PAL_SECAM_LP:
18082 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
18083 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18085 case DRX_STANDARD_FM:
18086 return fm_lock_status(demod, lock_stat);
18088 case DRX_STANDARD_UNKNOWN: /* fallthrough */
18093 /* define the SCU command paramters and execute the command */
18094 cmd_scu.parameter_len = 0;
18095 cmd_scu.result_len = 2;
18096 cmd_scu.parameter = NULL;
18097 cmd_scu.result = cmd_result;
18098 rc = scu_command(dev_addr, &cmd_scu);
18100 pr_err("error %d\n", rc);
18104 /* set the lock status */
18105 if (cmd_scu.result[1] < demod_lock) {
18106 /* 0x0000 NOT LOCKED */
18107 *lock_stat = DRX_NOT_LOCKED;
18108 } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
18109 *lock_stat = DRXJ_DEMOD_LOCK;
18110 } else if (cmd_scu.result[1] <
18111 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
18112 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
18113 *lock_stat = DRX_LOCKED;
18115 /* 0xC000 NEVER LOCKED */
18116 /* (system will never be able to lock to the signal) */
18117 *lock_stat = DRX_NEVER_LOCK;
18125 /*============================================================================*/
18128 * \fn int ctrl_constel()
18129 * \brief Retreive a constellation point via I2C.
18130 * \param demod Pointer to demodulator instance.
18131 * \param complex_nr Pointer to the structure in which to store the
18132 constellation point.
18136 ctrl_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
18139 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18140 /**< active standard */
18142 /* check arguments */
18143 if ((demod == NULL) || (complex_nr == NULL))
18146 /* read device info */
18147 standard = ((struct drxj_data *) demod->my_ext_attr)->standard;
18149 /* Read constellation point */
18150 switch (standard) {
18151 case DRX_STANDARD_8VSB:
18152 rc = ctrl_get_vsb_constel(demod, complex_nr);
18154 pr_err("error %d\n", rc);
18158 #ifndef DRXJ_VSB_ONLY
18159 case DRX_STANDARD_ITU_A: /* fallthrough */
18160 case DRX_STANDARD_ITU_B: /* fallthrough */
18161 case DRX_STANDARD_ITU_C:
18162 rc = ctrl_get_qam_constel(demod, complex_nr);
18164 pr_err("error %d\n", rc);
18169 case DRX_STANDARD_UNKNOWN:
18179 /*============================================================================*/
18182 * \fn int ctrl_set_standard()
18183 * \brief Set modulation standard to be used.
18184 * \param standard Modulation standard.
18187 * Setup stuff for the desired demodulation standard.
18188 * Disable and power down the previous selected demodulation standard
18192 ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18194 struct drxj_data *ext_attr = NULL;
18196 enum drx_standard prev_standard;
18198 /* check arguments */
18199 if ((standard == NULL) || (demod == NULL))
18202 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18203 prev_standard = ext_attr->standard;
18206 Stop and power down previous standard
18208 switch (prev_standard) {
18209 #ifndef DRXJ_VSB_ONLY
18210 case DRX_STANDARD_ITU_A: /* fallthrough */
18211 case DRX_STANDARD_ITU_B: /* fallthrough */
18212 case DRX_STANDARD_ITU_C:
18213 rc = power_down_qam(demod, false);
18215 pr_err("error %d\n", rc);
18220 case DRX_STANDARD_8VSB:
18221 rc = power_down_vsb(demod, false);
18223 pr_err("error %d\n", rc);
18227 #ifndef DRXJ_DIGITAL_ONLY
18228 case DRX_STANDARD_NTSC: /* fallthrough */
18229 case DRX_STANDARD_FM: /* fallthrough */
18230 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18231 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18232 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18233 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18234 case DRX_STANDARD_PAL_SECAM_LP:
18235 rc = power_down_atv(demod, prev_standard, false);
18237 pr_err("error %d\n", rc);
18242 case DRX_STANDARD_UNKNOWN:
18245 case DRX_STANDARD_AUTO: /* fallthrough */
18251 Initialize channel independent registers
18252 Power up new standard
18254 ext_attr->standard = *standard;
18256 switch (*standard) {
18257 #ifndef DRXJ_VSB_ONLY
18258 case DRX_STANDARD_ITU_A: /* fallthrough */
18259 case DRX_STANDARD_ITU_B: /* fallthrough */
18260 case DRX_STANDARD_ITU_C:
18263 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18265 pr_err("error %d\n", rc);
18271 case DRX_STANDARD_8VSB:
18272 rc = set_vsb_leak_n_gain(demod);
18274 pr_err("error %d\n", rc);
18278 #ifndef DRXJ_DIGITAL_ONLY
18279 case DRX_STANDARD_NTSC: /* fallthrough */
18280 case DRX_STANDARD_FM: /* fallthrough */
18281 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18282 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18283 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18284 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18285 case DRX_STANDARD_PAL_SECAM_LP:
18286 rc = set_atv_standard(demod, standard);
18288 pr_err("error %d\n", rc);
18291 rc = power_up_atv(demod, *standard);
18293 pr_err("error %d\n", rc);
18299 ext_attr->standard = DRX_STANDARD_UNKNOWN;
18306 /* Don't know what the standard is now ... try again */
18307 ext_attr->standard = DRX_STANDARD_UNKNOWN;
18311 /*============================================================================*/
18314 * \fn int ctrl_get_standard()
18315 * \brief Get modulation standard currently used to demodulate.
18316 * \param standard Modulation standard.
18319 * Returns 8VSB, NTSC, QAM only.
18323 ctrl_get_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18325 struct drxj_data *ext_attr = NULL;
18327 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18329 /* check arguments */
18330 if (standard == NULL)
18333 *standard = ext_attr->standard;
18336 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18338 pr_err("error %d\n", rc);
18348 /*============================================================================*/
18351 * \fn int ctrl_get_cfg_symbol_clock_offset()
18352 * \brief Get frequency offsets of STR.
18353 * \param pointer to s32.
18358 ctrl_get_cfg_symbol_clock_offset(struct drx_demod_instance *demod, s32 *rate_offset)
18360 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18362 struct drxj_data *ext_attr = NULL;
18364 /* check arguments */
18365 if (rate_offset == NULL)
18368 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18369 standard = ext_attr->standard;
18371 switch (standard) {
18372 case DRX_STANDARD_8VSB: /* fallthrough */
18373 #ifndef DRXJ_VSB_ONLY
18374 case DRX_STANDARD_ITU_A: /* fallthrough */
18375 case DRX_STANDARD_ITU_B: /* fallthrough */
18376 case DRX_STANDARD_ITU_C:
18378 rc = get_str_freq_offset(demod, rate_offset);
18380 pr_err("error %d\n", rc);
18384 case DRX_STANDARD_NTSC:
18385 case DRX_STANDARD_UNKNOWN:
18395 /*============================================================================*/
18397 static void drxj_reset_mode(struct drxj_data *ext_attr)
18399 /* Initialize default AFE configuartion for QAM */
18400 if (ext_attr->has_lna) {
18401 /* IF AGC off, PGA active */
18402 #ifndef DRXJ_VSB_ONLY
18403 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
18404 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
18405 ext_attr->qam_pga_cfg = 140 + (11 * 13);
18407 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
18408 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
18409 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
18411 /* IF AGC on, PGA not active */
18412 #ifndef DRXJ_VSB_ONLY
18413 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
18414 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18415 ext_attr->qam_if_agc_cfg.min_output_level = 0;
18416 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
18417 ext_attr->qam_if_agc_cfg.speed = 3;
18418 ext_attr->qam_if_agc_cfg.top = 1297;
18419 ext_attr->qam_pga_cfg = 140;
18421 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
18422 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18423 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
18424 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
18425 ext_attr->vsb_if_agc_cfg.speed = 3;
18426 ext_attr->vsb_if_agc_cfg.top = 1024;
18427 ext_attr->vsb_pga_cfg = 140;
18429 /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
18430 /* mc has not used them */
18431 #ifndef DRXJ_VSB_ONLY
18432 ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
18433 ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18434 ext_attr->qam_rf_agc_cfg.min_output_level = 0;
18435 ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
18436 ext_attr->qam_rf_agc_cfg.speed = 3;
18437 ext_attr->qam_rf_agc_cfg.top = 9500;
18438 ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
18439 ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
18440 ext_attr->qam_pre_saw_cfg.reference = 0x07;
18441 ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
18443 /* Initialize default AFE configuartion for VSB */
18444 ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
18445 ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18446 ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
18447 ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
18448 ext_attr->vsb_rf_agc_cfg.speed = 3;
18449 ext_attr->vsb_rf_agc_cfg.top = 9500;
18450 ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
18451 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
18452 ext_attr->vsb_pre_saw_cfg.reference = 0x07;
18453 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
18455 #ifndef DRXJ_DIGITAL_ONLY
18456 /* Initialize default AFE configuartion for ATV */
18457 ext_attr->atv_rf_agc_cfg.standard = DRX_STANDARD_NTSC;
18458 ext_attr->atv_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18459 ext_attr->atv_rf_agc_cfg.top = 9500;
18460 ext_attr->atv_rf_agc_cfg.cut_off_current = 4000;
18461 ext_attr->atv_rf_agc_cfg.speed = 3;
18462 ext_attr->atv_if_agc_cfg.standard = DRX_STANDARD_NTSC;
18463 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18464 ext_attr->atv_if_agc_cfg.speed = 3;
18465 ext_attr->atv_if_agc_cfg.top = 2400;
18466 ext_attr->atv_pre_saw_cfg.reference = 0x0007;
18467 ext_attr->atv_pre_saw_cfg.use_pre_saw = true;
18468 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
18473 * \fn int ctrl_power_mode()
18474 * \brief Set the power mode of the device to the specified power mode
18475 * \param demod Pointer to demodulator instance.
18476 * \param mode Pointer to new power mode.
18478 * \retval 0 Success
18479 * \retval -EIO I2C error or other failure
18480 * \retval -EINVAL Invalid mode argument.
18485 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
18487 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
18488 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
18489 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
18491 u16 sio_cc_pwd_mode = 0;
18493 common_attr = (struct drx_common_attr *) demod->my_common_attr;
18494 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18495 dev_addr = demod->my_i2c_dev_addr;
18497 /* Check arguments */
18501 /* If already in requested power mode, do nothing */
18502 if (common_attr->current_power_mode == *mode)
18507 case DRXJ_POWER_DOWN_MAIN_PATH:
18508 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
18510 case DRXJ_POWER_DOWN_CORE:
18511 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
18513 case DRXJ_POWER_DOWN_PLL:
18514 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
18516 case DRX_POWER_DOWN:
18517 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
18520 /* Unknow sleep mode */
18525 /* Check if device needs to be powered up */
18526 if ((common_attr->current_power_mode != DRX_POWER_UP)) {
18527 rc = power_up_device(demod);
18529 pr_err("error %d\n", rc);
18534 if ((*mode == DRX_POWER_UP)) {
18535 /* Restore analog & pin configuartion */
18537 /* Initialize default AFE configuartion for VSB */
18538 drxj_reset_mode(ext_attr);
18540 /* Power down to requested mode */
18541 /* Backup some register settings */
18542 /* Set pins with possible pull-ups connected to them in input mode */
18543 /* Analog power down */
18544 /* ADC power down */
18545 /* Power down device */
18546 /* stop all comm_exec */
18548 Stop and power down previous standard
18551 switch (ext_attr->standard) {
18552 case DRX_STANDARD_ITU_A:
18553 case DRX_STANDARD_ITU_B:
18554 case DRX_STANDARD_ITU_C:
18555 rc = power_down_qam(demod, true);
18557 pr_err("error %d\n", rc);
18561 case DRX_STANDARD_8VSB:
18562 rc = power_down_vsb(demod, true);
18564 pr_err("error %d\n", rc);
18568 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18569 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18570 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18571 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18572 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
18573 case DRX_STANDARD_NTSC: /* fallthrough */
18574 case DRX_STANDARD_FM:
18575 rc = power_down_atv(demod, ext_attr->standard, true);
18577 pr_err("error %d\n", rc);
18581 case DRX_STANDARD_UNKNOWN:
18584 case DRX_STANDARD_AUTO: /* fallthrough */
18589 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
18590 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
18592 pr_err("error %d\n", rc);
18595 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
18597 pr_err("error %d\n", rc);
18601 /* Initialize HI, wakeup key especially before put IC to sleep */
18602 rc = init_hi(demod);
18604 pr_err("error %d\n", rc);
18608 ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
18609 rc = hi_cfg_command(demod);
18611 pr_err("error %d\n", rc);
18617 common_attr->current_power_mode = *mode;
18624 /*============================================================================*/
18627 * \fn int ctrl_version()
18628 * \brief Report version of microcode and if possible version of device
18629 * \param demod Pointer to demodulator instance.
18630 * \param version_list Pointer to pointer of linked list of versions.
18633 * Using static structures so no allocation of memory is needed.
18634 * Filling in all the fields each time, cause you don't know if they are
18635 * changed by the application.
18638 * Major version number will be last two digits of family number.
18639 * Minor number will be full respin number
18640 * Patch will be metal fix number+1
18642 * DRX3942J A2 => number: 42.1.2 text: "DRX3942J:A2"
18643 * DRX3933J B1 => number: 33.2.1 text: "DRX3933J:B1"
18647 ctrl_version(struct drx_demod_instance *demod, struct drx_version_list **version_list)
18649 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
18650 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
18651 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18653 u16 ucode_major_minor = 0; /* BCD Ma:Ma:Ma:Mi */
18654 u16 ucode_patch = 0; /* BCD Pa:Pa:Pa:Pa */
18664 static char ucode_name[] = "Microcode";
18665 static char device_name[] = "Device";
18667 dev_addr = demod->my_i2c_dev_addr;
18668 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18669 common_attr = (struct drx_common_attr *) demod->my_common_attr;
18671 /* Microcode version *************************************** */
18673 ext_attr->v_version[0].module_type = DRX_MODULE_MICROCODE;
18674 ext_attr->v_version[0].module_name = ucode_name;
18675 ext_attr->v_version[0].v_string = ext_attr->v_text[0];
18677 if (common_attr->is_opened == true) {
18678 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_VERSION_HI__A, &ucode_major_minor, 0);
18680 pr_err("error %d\n", rc);
18683 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_VERSION_LO__A, &ucode_patch, 0);
18685 pr_err("error %d\n", rc);
18689 /* Translate BCD to numbers and string */
18690 /* TODO: The most significant Ma and Pa will be ignored, check with spec */
18691 minor = (ucode_major_minor & 0xF);
18692 ucode_major_minor >>= 4;
18693 major = (ucode_major_minor & 0xF);
18694 ucode_major_minor >>= 4;
18695 major += (10 * (ucode_major_minor & 0xF));
18696 patch = (ucode_patch & 0xF);
18698 patch += (10 * (ucode_patch & 0xF));
18700 patch += (100 * (ucode_patch & 0xF));
18702 /* No microcode uploaded, No Rom existed, set version to 0.0.0 */
18707 ext_attr->v_version[0].v_major = major;
18708 ext_attr->v_version[0].v_minor = minor;
18709 ext_attr->v_version[0].v_patch = patch;
18711 if (major / 10 != 0) {
18712 ext_attr->v_version[0].v_string[idx++] =
18713 ((char)(major / 10)) + '0';
18716 ext_attr->v_version[0].v_string[idx++] = ((char)major) + '0';
18717 ext_attr->v_version[0].v_string[idx++] = '.';
18718 ext_attr->v_version[0].v_string[idx++] = ((char)minor) + '0';
18719 ext_attr->v_version[0].v_string[idx++] = '.';
18720 if (patch / 100 != 0) {
18721 ext_attr->v_version[0].v_string[idx++] =
18722 ((char)(patch / 100)) + '0';
18725 if (patch / 10 != 0) {
18726 ext_attr->v_version[0].v_string[idx++] =
18727 ((char)(patch / 10)) + '0';
18730 ext_attr->v_version[0].v_string[idx++] = ((char)patch) + '0';
18731 ext_attr->v_version[0].v_string[idx] = '\0';
18733 ext_attr->v_list_elements[0].version = &(ext_attr->v_version[0]);
18734 ext_attr->v_list_elements[0].next = &(ext_attr->v_list_elements[1]);
18736 /* Device version *************************************** */
18737 /* Check device id */
18738 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, &key, 0);
18740 pr_err("error %d\n", rc);
18743 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
18745 pr_err("error %d\n", rc);
18748 rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0);
18750 pr_err("error %d\n", rc);
18753 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
18755 pr_err("error %d\n", rc);
18758 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, key, 0);
18760 pr_err("error %d\n", rc);
18764 ext_attr->v_version[1].module_type = DRX_MODULE_DEVICE;
18765 ext_attr->v_version[1].module_name = device_name;
18766 ext_attr->v_version[1].v_string = ext_attr->v_text[1];
18767 ext_attr->v_version[1].v_string[0] = 'D';
18768 ext_attr->v_version[1].v_string[1] = 'R';
18769 ext_attr->v_version[1].v_string[2] = 'X';
18770 ext_attr->v_version[1].v_string[3] = '3';
18771 ext_attr->v_version[1].v_string[4] = '9';
18772 ext_attr->v_version[1].v_string[7] = 'J';
18773 ext_attr->v_version[1].v_string[8] = ':';
18774 ext_attr->v_version[1].v_string[11] = '\0';
18776 /* DRX39xxJ type Ax */
18777 /* TODO semantics of mfx and spin are unclear */
18778 subtype = (u16) ((jtag >> 12) & 0xFF);
18779 mfx = (u16) (jtag >> 29);
18780 ext_attr->v_version[1].v_minor = 1;
18782 ext_attr->v_version[1].v_patch = mfx + 2;
18784 ext_attr->v_version[1].v_patch = mfx + 1;
18785 ext_attr->v_version[1].v_string[6] = ((char)(subtype & 0xF)) + '0';
18786 ext_attr->v_version[1].v_major = (subtype & 0x0F);
18788 ext_attr->v_version[1].v_string[5] = ((char)(subtype & 0xF)) + '0';
18789 ext_attr->v_version[1].v_major += 10 * subtype;
18790 ext_attr->v_version[1].v_string[9] = 'A';
18792 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '2';
18794 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '1';
18796 ext_attr->v_list_elements[1].version = &(ext_attr->v_version[1]);
18797 ext_attr->v_list_elements[1].next = (struct drx_version_list *) (NULL);
18799 *version_list = &(ext_attr->v_list_elements[0]);
18804 *version_list = (struct drx_version_list *) (NULL);
18809 /*============================================================================*/
18812 * \fn int ctrl_probe_device()
18813 * \brief Probe device, check if it is present
18814 * \param demod Pointer to demodulator instance.
18816 * \retval 0 a drx39xxj device has been detected.
18817 * \retval -EIO no drx39xxj device detected.
18819 * This funtion can be caled before open() and after close().
18823 static int ctrl_probe_device(struct drx_demod_instance *demod)
18825 enum drx_power_mode org_power_mode = DRX_POWER_UP;
18826 int ret_status = 0;
18827 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18830 common_attr = (struct drx_common_attr *) demod->my_common_attr;
18832 if (common_attr->is_opened == false
18833 || common_attr->current_power_mode != DRX_POWER_UP) {
18834 struct i2c_device_addr *dev_addr = NULL;
18835 enum drx_power_mode power_mode = DRX_POWER_UP;
18838 dev_addr = demod->my_i2c_dev_addr;
18840 /* Remeber original power mode */
18841 org_power_mode = common_attr->current_power_mode;
18843 if (demod->my_common_attr->is_opened == false) {
18844 rc = power_up_device(demod);
18846 pr_err("error %d\n", rc);
18849 common_attr->current_power_mode = DRX_POWER_UP;
18851 /* Wake-up device, feedback from device */
18852 rc = ctrl_power_mode(demod, &power_mode);
18854 pr_err("error %d\n", rc);
18858 /* Initialize HI, wakeup key especially */
18859 rc = init_hi(demod);
18861 pr_err("error %d\n", rc);
18865 /* Check device id */
18866 rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0);
18868 pr_err("error %d\n", rc);
18871 jtag = (jtag >> 12) & 0xFFFF;
18873 case 0x3931: /* fallthrough */
18874 case 0x3932: /* fallthrough */
18875 case 0x3933: /* fallthrough */
18876 case 0x3934: /* fallthrough */
18877 case 0x3941: /* fallthrough */
18878 case 0x3942: /* fallthrough */
18879 case 0x3943: /* fallthrough */
18880 case 0x3944: /* fallthrough */
18881 case 0x3945: /* fallthrough */
18883 /* ok , do nothing */
18890 /* Device was not opened, return to orginal powermode,
18891 feedback from device */
18892 rc = ctrl_power_mode(demod, &org_power_mode);
18894 pr_err("error %d\n", rc);
18898 /* dummy read to make this function fail in case device
18899 suddenly disappears after a succesful drx_open */
18902 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18904 pr_err("error %d\n", rc);
18913 common_attr->current_power_mode = org_power_mode;
18917 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
18918 /*============================================================================*/
18921 * \fn int is_mc_block_audio()
18922 * \brief Check if MC block is Audio or not Audio.
18923 * \param addr Pointer to demodulator instance.
18924 * \param audioUpload true if MC block is Audio
18925 false if MC block not Audio
18928 bool is_mc_block_audio(u32 addr)
18930 if ((addr == AUD_XFP_PRAM_4K__A) || (addr == AUD_XDFP_PRAM_4K__A))
18936 /*============================================================================*/
18939 * \fn int ctrl_u_code_upload()
18940 * \brief Handle Audio or !Audio part of microcode upload.
18941 * \param demod Pointer to demodulator instance.
18942 * \param mc_info Pointer to information about microcode data.
18943 * \param action Either UCODE_UPLOAD or UCODE_VERIFY.
18944 * \param upload_audio_mc true if Audio MC need to be uploaded.
18945 false if !Audio MC need to be uploaded.
18949 ctrl_u_code_upload(struct drx_demod_instance *demod,
18950 struct drxu_code_info *mc_info,
18951 enum drxu_code_actionaction, bool upload_audio_mc)
18954 u16 mc_nr_of_blks = 0;
18955 u16 mc_magic_word = 0;
18956 u8 *mc_data = (u8 *)(NULL);
18957 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
18958 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
18961 dev_addr = demod->my_i2c_dev_addr;
18962 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18964 /* Check arguments */
18965 if (!mc_info || !mc_info->mc_data) {
18969 mc_data = mc_info->mc_data;
18972 mc_magic_word = u_code_read16(mc_data);
18973 mc_data += sizeof(u16);
18974 mc_nr_of_blks = u_code_read16(mc_data);
18975 mc_data += sizeof(u16);
18977 if ((mc_magic_word != DRXJ_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
18978 /* wrong endianess or wrong data ? */
18982 /* Process microcode blocks */
18983 for (i = 0; i < mc_nr_of_blks; i++) {
18984 struct drxu_code_block_hdr block_hdr;
18985 u16 mc_block_nr_bytes = 0;
18987 /* Process block header */
18988 block_hdr.addr = u_code_read32(mc_data);
18989 mc_data += sizeof(u32);
18990 block_hdr.size = u_code_read16(mc_data);
18991 mc_data += sizeof(u16);
18992 block_hdr.flags = u_code_read16(mc_data);
18993 mc_data += sizeof(u16);
18994 block_hdr.CRC = u_code_read16(mc_data);
18995 mc_data += sizeof(u16);
18997 /* Check block header on:
18999 - data larger then 64Kb
19000 - if CRC enabled check CRC
19002 if ((block_hdr.size == 0) ||
19003 (block_hdr.size > 0x7FFF) ||
19004 (((block_hdr.flags & DRXJ_UCODE_CRC_FLAG) != 0) &&
19005 (block_hdr.CRC != u_code_compute_crc(mc_data, block_hdr.size)))
19011 mc_block_nr_bytes = block_hdr.size * sizeof(u16);
19013 /* Perform the desired action */
19014 /* Check which part of MC need to be uploaded - Audio or not Audio */
19015 if (is_mc_block_audio(block_hdr.addr) == upload_audio_mc) {
19017 /*===================================================================*/
19020 /* Upload microcode */
19021 if (demod->my_access_funct->
19022 write_block_func(dev_addr,
19023 (dr_xaddr_t) block_hdr.
19024 addr, mc_block_nr_bytes,
19033 /*===================================================================*/
19038 [DRXJ_UCODE_MAX_BUF_SIZE];
19039 u32 bytes_to_compare = 0;
19040 u32 bytes_left_to_compare = 0;
19041 u32 curr_addr = (dr_xaddr_t) 0;
19042 u8 *curr_ptr = NULL;
19044 bytes_left_to_compare = mc_block_nr_bytes;
19045 curr_addr = block_hdr.addr;
19046 curr_ptr = mc_data;
19048 while (bytes_left_to_compare != 0) {
19049 if (bytes_left_to_compare > ((u32)DRXJ_UCODE_MAX_BUF_SIZE))
19050 bytes_to_compare = ((u32)DRXJ_UCODE_MAX_BUF_SIZE);
19052 bytes_to_compare = bytes_left_to_compare;
19054 if (demod->my_access_funct->
19055 read_block_func(dev_addr,
19067 drxbsp_hst_memcmp(curr_ptr,
19076 (bytes_to_compare / 2));
19078 &(curr_ptr[bytes_to_compare]);
19079 bytes_left_to_compare -=
19080 ((u32) bytes_to_compare);
19081 } /* while( bytes_to_compare > DRXJ_UCODE_MAX_BUF_SIZE ) */
19085 /*===================================================================*/
19090 } /* switch ( action ) */
19093 /* if( is_mc_block_audio( block_hdr.addr ) == upload_audio_mc ) */
19095 mc_data += mc_block_nr_bytes;
19096 } /* for( i = 0 ; i<mc_nr_of_blks ; i++ ) */
19098 if (!upload_audio_mc)
19099 ext_attr->flag_aud_mc_uploaded = false;
19103 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
19105 /*============================================================================*/
19106 /*== CTRL Set/Get Config related functions ===================================*/
19107 /*============================================================================*/
19109 /*===== SigStrength() =========================================================*/
19111 * \fn int ctrl_sig_strength()
19112 * \brief Retrieve signal strength.
19113 * \param devmod Pointer to demodulator instance.
19114 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
19116 * \retval 0 sig_strength contains valid data.
19117 * \retval -EINVAL sig_strength is NULL.
19118 * \retval -EIO Erroneous data, sig_strength contains invalid data.
19122 ctrl_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
19124 struct drxj_data *ext_attr = NULL;
19125 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
19128 /* Check arguments */
19129 if ((sig_strength == NULL) || (demod == NULL))
19132 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19133 standard = ext_attr->standard;
19136 /* Signal strength indication for each standard */
19137 switch (standard) {
19138 case DRX_STANDARD_8VSB: /* fallthrough */
19139 #ifndef DRXJ_VSB_ONLY
19140 case DRX_STANDARD_ITU_A: /* fallthrough */
19141 case DRX_STANDARD_ITU_B: /* fallthrough */
19142 case DRX_STANDARD_ITU_C:
19144 rc = get_sig_strength(demod, sig_strength);
19146 pr_err("error %d\n", rc);
19150 #ifndef DRXJ_DIGITAL_ONLY
19151 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19152 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19153 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19154 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19155 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19156 case DRX_STANDARD_NTSC: /* fallthrough */
19157 case DRX_STANDARD_FM:
19158 rc = get_atv_sig_strength(demod, sig_strength);
19160 pr_err("error %d\n", rc);
19165 case DRX_STANDARD_UNKNOWN: /* fallthrough */
19171 /* find out if signal strength is calculated in the same way for all standards */
19177 /*============================================================================*/
19179 * \fn int ctrl_get_cfg_oob_misc()
19180 * \brief Get current state information of OOB.
19181 * \param pointer to struct drxj_cfg_oob_misc.
19185 #ifndef DRXJ_DIGITAL_ONLY
19187 ctrl_get_cfg_oob_misc(struct drx_demod_instance *demod, struct drxj_cfg_oob_misc *misc)
19189 struct i2c_device_addr *dev_addr = NULL;
19194 u16 digital_agc_mant = 0U;
19195 u16 digital_agc_exp = 0U;
19197 /* check arguments */
19201 dev_addr = demod->my_i2c_dev_addr;
19204 /* check if the same registers are used for all standards (QAM/VSB/ATV) */
19205 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC, 0);
19207 pr_err("error %d\n", rc);
19210 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &misc->agc.RFAGC, 0);
19212 pr_err("error %d\n", rc);
19215 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
19217 pr_err("error %d\n", rc);
19221 digital_agc_mant = data & ORX_FWP_SRC_DGN_W_MANT__M;
19222 digital_agc_exp = (data & ORX_FWP_SRC_DGN_W_EXP__M)
19223 >> ORX_FWP_SRC_DGN_W_EXP__B;
19224 misc->agc.digital_agc = digital_agc_mant << digital_agc_exp;
19226 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_LOCK__A, &lock, 0);
19228 pr_err("error %d\n", rc);
19232 misc->ana_gain_lock = ((lock & 0x0001) ? true : false);
19233 misc->dig_gain_lock = ((lock & 0x0002) ? true : false);
19234 misc->freq_lock = ((lock & 0x0004) ? true : false);
19235 misc->phase_lock = ((lock & 0x0008) ? true : false);
19236 misc->sym_timing_lock = ((lock & 0x0010) ? true : false);
19237 misc->eq_lock = ((lock & 0x0020) ? true : false);
19239 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_STATE__A, &state, 0);
19241 pr_err("error %d\n", rc);
19244 misc->state = (state >> 8) & 0xff;
19253 * \fn int ctrl_get_cfg_vsb_misc()
19254 * \brief Get current state information of OOB.
19255 * \param pointer to struct drxj_cfg_oob_misc.
19260 ctrl_get_cfg_vsb_misc(struct drx_demod_instance *demod, struct drxj_cfg_vsb_misc *misc)
19262 struct i2c_device_addr *dev_addr = NULL;
19265 /* check arguments */
19269 dev_addr = demod->my_i2c_dev_addr;
19271 rc = get_vsb_symb_err(dev_addr, &misc->symb_error);
19273 pr_err("error %d\n", rc);
19282 /*============================================================================*/
19285 * \fn int ctrl_set_cfg_agc_if()
19286 * \brief Set IF AGC.
19287 * \param demod demod instance
19288 * \param agc_settings If agc configuration
19292 * Dispatch handling to standard specific function.
19296 ctrl_set_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19298 /* check arguments */
19299 if (agc_settings == NULL)
19302 switch (agc_settings->ctrl_mode) {
19303 case DRX_AGC_CTRL_AUTO: /* fallthrough */
19304 case DRX_AGC_CTRL_USER: /* fallthrough */
19305 case DRX_AGC_CTRL_OFF: /* fallthrough */
19312 switch (agc_settings->standard) {
19313 case DRX_STANDARD_8VSB: /* fallthrough */
19314 #ifndef DRXJ_VSB_ONLY
19315 case DRX_STANDARD_ITU_A: /* fallthrough */
19316 case DRX_STANDARD_ITU_B: /* fallthrough */
19317 case DRX_STANDARD_ITU_C:
19319 #ifndef DRXJ_DIGITAL_ONLY
19320 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19321 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19322 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19323 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19324 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19325 case DRX_STANDARD_NTSC: /* fallthrough */
19326 case DRX_STANDARD_FM:
19328 return set_agc_if(demod, agc_settings, true);
19329 case DRX_STANDARD_UNKNOWN:
19337 /*============================================================================*/
19340 * \fn int ctrl_get_cfg_agc_if()
19341 * \brief Retrieve IF AGC settings.
19342 * \param demod demod instance
19343 * \param agc_settings If agc configuration
19347 * Dispatch handling to standard specific function.
19351 ctrl_get_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19353 /* check arguments */
19354 if (agc_settings == NULL)
19358 switch (agc_settings->standard) {
19359 case DRX_STANDARD_8VSB: /* fallthrough */
19360 #ifndef DRXJ_VSB_ONLY
19361 case DRX_STANDARD_ITU_A: /* fallthrough */
19362 case DRX_STANDARD_ITU_B: /* fallthrough */
19363 case DRX_STANDARD_ITU_C:
19365 #ifndef DRXJ_DIGITAL_ONLY
19366 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19367 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19368 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19369 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19370 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19371 case DRX_STANDARD_NTSC: /* fallthrough */
19372 case DRX_STANDARD_FM:
19374 return get_agc_if(demod, agc_settings);
19375 case DRX_STANDARD_UNKNOWN:
19383 /*============================================================================*/
19386 * \fn int ctrl_set_cfg_agc_rf()
19387 * \brief Set RF AGC.
19388 * \param demod demod instance
19389 * \param agc_settings rf agc configuration
19393 * Dispatch handling to standard specific function.
19397 ctrl_set_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19399 /* check arguments */
19400 if (agc_settings == NULL)
19403 switch (agc_settings->ctrl_mode) {
19404 case DRX_AGC_CTRL_AUTO: /* fallthrough */
19405 case DRX_AGC_CTRL_USER: /* fallthrough */
19406 case DRX_AGC_CTRL_OFF:
19413 switch (agc_settings->standard) {
19414 case DRX_STANDARD_8VSB: /* fallthrough */
19415 #ifndef DRXJ_VSB_ONLY
19416 case DRX_STANDARD_ITU_A: /* fallthrough */
19417 case DRX_STANDARD_ITU_B: /* fallthrough */
19418 case DRX_STANDARD_ITU_C:
19420 #ifndef DRXJ_DIGITAL_ONLY
19421 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19422 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19423 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19424 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19425 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19426 case DRX_STANDARD_NTSC: /* fallthrough */
19427 case DRX_STANDARD_FM:
19429 return set_agc_rf(demod, agc_settings, true);
19430 case DRX_STANDARD_UNKNOWN:
19438 /*============================================================================*/
19441 * \fn int ctrl_get_cfg_agc_rf()
19442 * \brief Retrieve RF AGC settings.
19443 * \param demod demod instance
19444 * \param agc_settings Rf agc configuration
19448 * Dispatch handling to standard specific function.
19452 ctrl_get_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19454 /* check arguments */
19455 if (agc_settings == NULL)
19459 switch (agc_settings->standard) {
19460 case DRX_STANDARD_8VSB: /* fallthrough */
19461 #ifndef DRXJ_VSB_ONLY
19462 case DRX_STANDARD_ITU_A: /* fallthrough */
19463 case DRX_STANDARD_ITU_B: /* fallthrough */
19464 case DRX_STANDARD_ITU_C:
19466 #ifndef DRXJ_DIGITAL_ONLY
19467 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19468 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19469 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19470 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19471 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19472 case DRX_STANDARD_NTSC: /* fallthrough */
19473 case DRX_STANDARD_FM:
19475 return get_agc_rf(demod, agc_settings);
19476 case DRX_STANDARD_UNKNOWN:
19484 /*============================================================================*/
19487 * \fn int ctrl_get_cfg_agc_internal()
19488 * \brief Retrieve internal AGC value.
19489 * \param demod demod instance
19494 * Dispatch handling to standard specific function.
19498 ctrl_get_cfg_agc_internal(struct drx_demod_instance *demod, u16 *agc_internal)
19500 struct i2c_device_addr *dev_addr = NULL;
19502 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
19503 struct drxj_data *ext_attr = NULL;
19504 u16 iqm_cf_scale_sh = 0;
19505 u16 iqm_cf_power = 0;
19506 u16 iqm_cf_amp = 0;
19507 u16 iqm_cf_gain = 0;
19509 /* check arguments */
19510 if (agc_internal == NULL)
19512 dev_addr = demod->my_i2c_dev_addr;
19513 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19515 rc = ctrl_lock_status(demod, &lock_status);
19517 pr_err("error %d\n", rc);
19520 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
19526 switch (ext_attr->standard) {
19527 case DRX_STANDARD_8VSB:
19530 #ifndef DRXJ_VSB_ONLY
19531 case DRX_STANDARD_ITU_A:
19532 case DRX_STANDARD_ITU_B:
19533 case DRX_STANDARD_ITU_C:
19534 switch (ext_attr->constellation) {
19535 case DRX_CONSTELLATION_QAM256:
19536 case DRX_CONSTELLATION_QAM128:
19537 case DRX_CONSTELLATION_QAM32:
19538 case DRX_CONSTELLATION_QAM16:
19541 case DRX_CONSTELLATION_QAM64:
19553 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_POW__A, &iqm_cf_power, 0);
19555 pr_err("error %d\n", rc);
19558 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_SCALE_SH__A, &iqm_cf_scale_sh, 0);
19560 pr_err("error %d\n", rc);
19563 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_AMP__A, &iqm_cf_amp, 0);
19565 pr_err("error %d\n", rc);
19568 /* IQM_CF_PWR_CORRECTION_dB = 3;
19569 P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
19570 /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
19571 -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
19572 +6*7+10*log10(1+0.115/4); */
19573 /* PadcdB = P4dB +3 -6 +60; dBmV */
19574 *agc_internal = (u16) (log1_times100(iqm_cf_power)
19575 - 2 * log1_times100(iqm_cf_amp)
19576 - iqm_cf_gain - 120 * iqm_cf_scale_sh + 781);
19583 /*============================================================================*/
19586 * \fn int ctrl_set_cfg_pre_saw()
19587 * \brief Set Pre-saw reference.
19588 * \param demod demod instance
19593 * Dispatch handling to standard specific function.
19597 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19599 struct i2c_device_addr *dev_addr = NULL;
19600 struct drxj_data *ext_attr = NULL;
19603 dev_addr = demod->my_i2c_dev_addr;
19604 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19606 /* check arguments */
19607 if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
19612 /* Only if standard is currently active */
19613 if ((ext_attr->standard == pre_saw->standard) ||
19614 (DRXJ_ISQAMSTD(ext_attr->standard) &&
19615 DRXJ_ISQAMSTD(pre_saw->standard)) ||
19616 (DRXJ_ISATVSTD(ext_attr->standard) &&
19617 DRXJ_ISATVSTD(pre_saw->standard))) {
19618 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
19620 pr_err("error %d\n", rc);
19625 /* Store pre-saw settings */
19626 switch (pre_saw->standard) {
19627 case DRX_STANDARD_8VSB:
19628 ext_attr->vsb_pre_saw_cfg = *pre_saw;
19630 #ifndef DRXJ_VSB_ONLY
19631 case DRX_STANDARD_ITU_A: /* fallthrough */
19632 case DRX_STANDARD_ITU_B: /* fallthrough */
19633 case DRX_STANDARD_ITU_C:
19634 ext_attr->qam_pre_saw_cfg = *pre_saw;
19637 #ifndef DRXJ_DIGITAL_ONLY
19638 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19639 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19640 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19641 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19642 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19643 case DRX_STANDARD_NTSC: /* fallthrough */
19644 case DRX_STANDARD_FM:
19645 ext_attr->atv_pre_saw_cfg = *pre_saw;
19657 /*============================================================================*/
19660 * \fn int ctrl_set_cfg_afe_gain()
19661 * \brief Set AFE Gain.
19662 * \param demod demod instance
19667 * Dispatch handling to standard specific function.
19671 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19673 struct i2c_device_addr *dev_addr = NULL;
19674 struct drxj_data *ext_attr = NULL;
19678 /* check arguments */
19679 if (afe_gain == NULL)
19682 dev_addr = demod->my_i2c_dev_addr;
19683 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19685 switch (afe_gain->standard) {
19686 case DRX_STANDARD_8VSB: /* fallthrough */
19687 #ifndef DRXJ_VSB_ONLY
19688 case DRX_STANDARD_ITU_A: /* fallthrough */
19689 case DRX_STANDARD_ITU_B: /* fallthrough */
19690 case DRX_STANDARD_ITU_C:
19698 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
19699 So I (PJ) think interface requires choice between auto, user mode */
19701 if (afe_gain->gain >= 329)
19703 else if (afe_gain->gain <= 147)
19706 gain = (afe_gain->gain - 140 + 6) / 13;
19708 /* Only if standard is currently active */
19709 if (ext_attr->standard == afe_gain->standard) {
19710 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
19712 pr_err("error %d\n", rc);
19717 /* Store AFE Gain settings */
19718 switch (afe_gain->standard) {
19719 case DRX_STANDARD_8VSB:
19720 ext_attr->vsb_pga_cfg = gain * 13 + 140;
19722 #ifndef DRXJ_VSB_ONLY
19723 case DRX_STANDARD_ITU_A: /* fallthrough */
19724 case DRX_STANDARD_ITU_B: /* fallthrough */
19725 case DRX_STANDARD_ITU_C:
19726 ext_attr->qam_pga_cfg = gain * 13 + 140;
19738 /*============================================================================*/
19741 * \fn int ctrl_get_cfg_pre_saw()
19742 * \brief Get Pre-saw reference setting.
19743 * \param demod demod instance
19748 * Dispatch handling to standard specific function.
19752 ctrl_get_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19754 struct drxj_data *ext_attr = NULL;
19756 /* check arguments */
19757 if (pre_saw == NULL)
19760 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19762 switch (pre_saw->standard) {
19763 case DRX_STANDARD_8VSB:
19764 *pre_saw = ext_attr->vsb_pre_saw_cfg;
19766 #ifndef DRXJ_VSB_ONLY
19767 case DRX_STANDARD_ITU_A: /* fallthrough */
19768 case DRX_STANDARD_ITU_B: /* fallthrough */
19769 case DRX_STANDARD_ITU_C:
19770 *pre_saw = ext_attr->qam_pre_saw_cfg;
19773 #ifndef DRXJ_DIGITAL_ONLY
19774 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19775 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19776 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19777 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19778 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19779 case DRX_STANDARD_NTSC:
19780 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
19781 *pre_saw = ext_attr->atv_pre_saw_cfg;
19783 case DRX_STANDARD_FM:
19784 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_FM;
19785 *pre_saw = ext_attr->atv_pre_saw_cfg;
19795 /*============================================================================*/
19798 * \fn int ctrl_get_cfg_afe_gain()
19799 * \brief Get AFE Gain.
19800 * \param demod demod instance
19805 * Dispatch handling to standard specific function.
19809 ctrl_get_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19811 struct drxj_data *ext_attr = NULL;
19813 /* check arguments */
19814 if (afe_gain == NULL)
19817 ext_attr = demod->my_ext_attr;
19819 switch (afe_gain->standard) {
19820 case DRX_STANDARD_8VSB:
19821 afe_gain->gain = ext_attr->vsb_pga_cfg;
19823 #ifndef DRXJ_VSB_ONLY
19824 case DRX_STANDARD_ITU_A: /* fallthrough */
19825 case DRX_STANDARD_ITU_B: /* fallthrough */
19826 case DRX_STANDARD_ITU_C:
19827 afe_gain->gain = ext_attr->qam_pga_cfg;
19837 /*============================================================================*/
19840 * \fn int ctrl_get_fec_meas_seq_count()
19841 * \brief Get FEC measurement sequnce number.
19842 * \param demod demod instance
19847 * Dispatch handling to standard specific function.
19851 ctrl_get_fec_meas_seq_count(struct drx_demod_instance *demod, u16 *fec_meas_seq_count)
19854 /* check arguments */
19855 if (fec_meas_seq_count == NULL)
19858 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, fec_meas_seq_count, 0);
19860 pr_err("error %d\n", rc);
19869 /*============================================================================*/
19872 * \fn int ctrl_get_accum_cr_rs_cw_err()
19873 * \brief Get accumulative corrected RS codeword number.
19874 * \param demod demod instance
19879 * Dispatch handling to standard specific function.
19883 ctrl_get_accum_cr_rs_cw_err(struct drx_demod_instance *demod, u32 *accum_cr_rs_cw_err)
19886 if (accum_cr_rs_cw_err == NULL)
19889 rc = DRXJ_DAP.read_reg32func(demod->my_i2c_dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, accum_cr_rs_cw_err, 0);
19891 pr_err("error %d\n", rc);
19901 * \fn int ctrl_set_cfg()
19902 * \brief Set 'some' configuration of the device.
19903 * \param devmod Pointer to demodulator instance.
19904 * \param config Pointer to configuration parameters (type and data).
19908 static int ctrl_set_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
19912 if (config == NULL)
19917 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
19919 pr_err("error %d\n", rc);
19923 switch (config->cfg_type) {
19924 case DRX_CFG_MPEG_OUTPUT:
19925 return ctrl_set_cfg_mpeg_output(demod,
19926 (struct drx_cfg_mpeg_output *) config->
19928 case DRX_CFG_PINS_SAFE_MODE:
19929 return ctrl_set_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
19930 case DRXJ_CFG_AGC_RF:
19931 return ctrl_set_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
19932 case DRXJ_CFG_AGC_IF:
19933 return ctrl_set_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
19934 case DRXJ_CFG_PRE_SAW:
19935 return ctrl_set_cfg_pre_saw(demod,
19936 (struct drxj_cfg_pre_saw *) config->cfg_data);
19937 case DRXJ_CFG_AFE_GAIN:
19938 return ctrl_set_cfg_afe_gain(demod,
19939 (struct drxj_cfg_afe_gain *) config->cfg_data);
19940 case DRXJ_CFG_SMART_ANT:
19941 return ctrl_set_cfg_smart_ant(demod,
19942 (struct drxj_cfg_smart_ant *) (config->
19944 case DRXJ_CFG_RESET_PACKET_ERR:
19945 return ctrl_set_cfg_reset_pkt_err(demod);
19946 #ifndef DRXJ_DIGITAL_ONLY
19947 case DRXJ_CFG_OOB_PRE_SAW:
19948 return ctrl_set_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
19949 case DRXJ_CFG_OOB_LO_POW:
19950 return ctrl_set_cfg_oob_lo_power(demod,
19951 (enum drxj_cfg_oob_lo_power *) (config->
19953 case DRXJ_CFG_ATV_MISC:
19954 return ctrl_set_cfg_atv_misc(demod,
19955 (struct drxj_cfg_atv_misc *) config->cfg_data);
19956 case DRXJ_CFG_ATV_EQU_COEF:
19957 return ctrl_set_cfg_atv_equ_coef(demod,
19958 (struct drxj_cfg_atv_equ_coef *) config->
19960 case DRXJ_CFG_ATV_OUTPUT:
19961 return ctrl_set_cfg_atv_output(demod,
19962 (struct drxj_cfg_atv_output *) config->
19965 case DRXJ_CFG_MPEG_OUTPUT_MISC:
19966 return ctrl_set_cfg_mpeg_output_misc(demod,
19967 (struct drxj_cfg_mpeg_output_misc *)
19969 #ifndef DRXJ_EXCLUDE_AUDIO
19970 case DRX_CFG_AUD_VOLUME:
19971 return aud_ctrl_set_cfg_volume(demod,
19972 (struct drx_cfg_aud_volume *) config->
19974 case DRX_CFG_I2S_OUTPUT:
19975 return aud_ctrl_set_cfg_output_i2s(demod,
19976 (struct drx_cfg_i2s_output *) config->
19978 case DRX_CFG_AUD_AUTOSOUND:
19979 return aud_ctr_setl_cfg_auto_sound(demod, (enum drx_cfg_aud_auto_sound *)
19981 case DRX_CFG_AUD_ASS_THRES:
19982 return aud_ctrl_set_cfg_ass_thres(demod, (struct drx_cfg_aud_ass_thres *)
19984 case DRX_CFG_AUD_CARRIER:
19985 return aud_ctrl_set_cfg_carrier(demod,
19986 (struct drx_cfg_aud_carriers *) config->
19988 case DRX_CFG_AUD_DEVIATION:
19989 return aud_ctrl_set_cfg_dev(demod,
19990 (enum drx_cfg_aud_deviation *) config->
19992 case DRX_CFG_AUD_PRESCALE:
19993 return aud_ctrl_set_cfg_prescale(demod,
19994 (struct drx_cfg_aud_prescale *) config->
19996 case DRX_CFG_AUD_MIXER:
19997 return aud_ctrl_set_cfg_mixer(demod,
19998 (struct drx_cfg_aud_mixer *) config->cfg_data);
19999 case DRX_CFG_AUD_AVSYNC:
20000 return aud_ctrl_set_cfg_av_sync(demod,
20001 (enum drx_cfg_aud_av_sync *) config->
20014 /*============================================================================*/
20017 * \fn int ctrl_get_cfg()
20018 * \brief Get 'some' configuration of the device.
20019 * \param devmod Pointer to demodulator instance.
20020 * \param config Pointer to configuration parameters (type and data).
20024 static int ctrl_get_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
20028 if (config == NULL)
20033 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
20035 pr_err("error %d\n", rc);
20040 switch (config->cfg_type) {
20041 case DRX_CFG_MPEG_OUTPUT:
20042 return ctrl_get_cfg_mpeg_output(demod,
20043 (struct drx_cfg_mpeg_output *) config->
20045 case DRX_CFG_PINS_SAFE_MODE:
20046 return ctrl_get_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
20047 case DRXJ_CFG_AGC_RF:
20048 return ctrl_get_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
20049 case DRXJ_CFG_AGC_IF:
20050 return ctrl_get_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
20051 case DRXJ_CFG_AGC_INTERNAL:
20052 return ctrl_get_cfg_agc_internal(demod, (u16 *)config->cfg_data);
20053 case DRXJ_CFG_PRE_SAW:
20054 return ctrl_get_cfg_pre_saw(demod,
20055 (struct drxj_cfg_pre_saw *) config->cfg_data);
20056 case DRXJ_CFG_AFE_GAIN:
20057 return ctrl_get_cfg_afe_gain(demod,
20058 (struct drxj_cfg_afe_gain *) config->cfg_data);
20059 case DRXJ_CFG_ACCUM_CR_RS_CW_ERR:
20060 return ctrl_get_accum_cr_rs_cw_err(demod, (u32 *)config->cfg_data);
20061 case DRXJ_CFG_FEC_MERS_SEQ_COUNT:
20062 return ctrl_get_fec_meas_seq_count(demod, (u16 *)config->cfg_data);
20063 case DRXJ_CFG_VSB_MISC:
20064 return ctrl_get_cfg_vsb_misc(demod,
20065 (struct drxj_cfg_vsb_misc *) config->cfg_data);
20066 case DRXJ_CFG_SYMBOL_CLK_OFFSET:
20067 return ctrl_get_cfg_symbol_clock_offset(demod,
20068 (s32 *)config->cfg_data);
20069 #ifndef DRXJ_DIGITAL_ONLY
20070 case DRXJ_CFG_OOB_MISC:
20071 return ctrl_get_cfg_oob_misc(demod,
20072 (struct drxj_cfg_oob_misc *) config->cfg_data);
20073 case DRXJ_CFG_OOB_PRE_SAW:
20074 return ctrl_get_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
20075 case DRXJ_CFG_OOB_LO_POW:
20076 return ctrl_get_cfg_oob_lo_power(demod,
20077 (enum drxj_cfg_oob_lo_power *) (config->
20079 case DRXJ_CFG_ATV_EQU_COEF:
20080 return ctrl_get_cfg_atv_equ_coef(demod,
20081 (struct drxj_cfg_atv_equ_coef *) config->
20083 case DRXJ_CFG_ATV_MISC:
20084 return ctrl_get_cfg_atv_misc(demod,
20085 (struct drxj_cfg_atv_misc *) config->cfg_data);
20086 case DRXJ_CFG_ATV_OUTPUT:
20087 return ctrl_get_cfg_atv_output(demod,
20088 (struct drxj_cfg_atv_output *) config->
20090 case DRXJ_CFG_ATV_AGC_STATUS:
20091 return ctrl_get_cfg_atv_agc_status(demod,
20092 (struct drxj_cfg_atv_agc_status *) config->
20095 case DRXJ_CFG_MPEG_OUTPUT_MISC:
20096 return ctrl_get_cfg_mpeg_output_misc(demod,
20097 (struct drxj_cfg_mpeg_output_misc *)
20099 case DRXJ_CFG_HW_CFG:
20100 return ctrl_get_cfg_hw_cfg(demod,
20101 (struct drxj_cfg_hw_cfg *) config->cfg_data);
20102 #ifndef DRXJ_EXCLUDE_AUDIO
20103 case DRX_CFG_AUD_VOLUME:
20104 return aud_ctrl_get_cfg_volume(demod,
20105 (struct drx_cfg_aud_volume *) config->
20107 case DRX_CFG_I2S_OUTPUT:
20108 return aud_ctrl_get_cfg_output_i2s(demod,
20109 (struct drx_cfg_i2s_output *) config->
20112 case DRX_CFG_AUD_RDS:
20113 return aud_ctrl_get_cfg_rds(demod,
20114 (struct drx_cfg_aud_rds *) config->cfg_data);
20115 case DRX_CFG_AUD_AUTOSOUND:
20116 return aud_ctrl_get_cfg_auto_sound(demod,
20117 (enum drx_cfg_aud_auto_sound *) config->
20119 case DRX_CFG_AUD_ASS_THRES:
20120 return aud_ctrl_get_cfg_ass_thres(demod,
20121 (struct drx_cfg_aud_ass_thres *) config->
20123 case DRX_CFG_AUD_CARRIER:
20124 return aud_ctrl_get_cfg_carrier(demod,
20125 (struct drx_cfg_aud_carriers *) config->
20127 case DRX_CFG_AUD_DEVIATION:
20128 return aud_ctrl_get_cfg_dev(demod,
20129 (enum drx_cfg_aud_deviation *) config->
20131 case DRX_CFG_AUD_PRESCALE:
20132 return aud_ctrl_get_cfg_prescale(demod,
20133 (struct drx_cfg_aud_prescale *) config->
20135 case DRX_CFG_AUD_MIXER:
20136 return aud_ctrl_get_cfg_mixer(demod,
20137 (struct drx_cfg_aud_mixer *) config->cfg_data);
20138 case DRX_CFG_AUD_AVSYNC:
20139 return aud_ctrl_get_cfg_av_sync(demod,
20140 (enum drx_cfg_aud_av_sync *) config->
20153 /*=============================================================================
20154 ===== EXPORTED FUNCTIONS ====================================================*/
20158 * \brief Open the demod instance, configure device, configure drxdriver
20159 * \return Status_t Return status.
20161 * drxj_open() can be called with a NULL ucode image => no ucode upload.
20162 * This means that drxj_open() must NOT contain SCU commands or, in general,
20163 * rely on SCU or AUD ucode to be present.
20166 int drxj_open(struct drx_demod_instance *demod)
20168 struct i2c_device_addr *dev_addr = NULL;
20169 struct drxj_data *ext_attr = NULL;
20170 struct drx_common_attr *common_attr = NULL;
20171 u32 driver_version = 0;
20172 struct drxu_code_info ucode_info;
20173 struct drx_cfg_mpeg_output cfg_mpeg_output;
20176 /* Check arguments */
20177 if (demod->my_ext_attr == NULL)
20180 dev_addr = demod->my_i2c_dev_addr;
20181 ext_attr = (struct drxj_data *) demod->my_ext_attr;
20182 common_attr = (struct drx_common_attr *) demod->my_common_attr;
20184 rc = power_up_device(demod);
20186 pr_err("error %d\n", rc);
20189 common_attr->current_power_mode = DRX_POWER_UP;
20191 /* has to be in front of setIqmAf and setOrxNsuAox */
20192 rc = get_device_capabilities(demod);
20194 pr_err("error %d\n", rc);
20198 /* Soft reset of sys- and osc-clockdomain */
20199 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_SOFT_RST__A, (SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), 0);
20201 pr_err("error %d\n", rc);
20204 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
20206 pr_err("error %d\n", rc);
20209 rc = drxbsp_hst_sleep(1);
20211 pr_err("error %d\n", rc);
20215 /* TODO first make sure that everything keeps working before enabling this */
20216 /* PowerDownAnalogBlocks() */
20217 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, 0);
20219 pr_err("error %d\n", rc);
20223 rc = set_iqm_af(demod, false);
20225 pr_err("error %d\n", rc);
20228 rc = set_orx_nsu_aox(demod, false);
20230 pr_err("error %d\n", rc);
20234 rc = init_hi(demod);
20236 pr_err("error %d\n", rc);
20240 /* disable mpegoutput pins */
20241 cfg_mpeg_output.enable_mpeg_output = false;
20242 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
20244 pr_err("error %d\n", rc);
20247 /* Stop AUD Inform SetAudio it will need to do all setting */
20248 rc = power_down_aud(demod);
20250 pr_err("error %d\n", rc);
20254 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
20256 pr_err("error %d\n", rc);
20260 /* Upload microcode */
20261 if (common_attr->microcode_file != NULL) {
20262 /* Dirty trick to use common ucode upload & verify,
20263 pretend device is already open */
20264 common_attr->is_opened = true;
20265 ucode_info.mc_file = common_attr->microcode_file;
20267 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20268 /* Upload microcode without audio part */
20269 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_UPLOAD, false);
20271 pr_err("error %d\n", rc);
20275 rc = drx_ctrl(demod, DRX_CTRL_LOAD_UCODE, &ucode_info);
20277 pr_err("error %d\n", rc);
20280 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20281 if (common_attr->verify_microcode == true) {
20282 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20283 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_VERIFY, false);
20285 pr_err("error %d\n", rc);
20289 rc = drx_ctrl(demod, DRX_CTRL_VERIFY_UCODE, &ucode_info);
20291 pr_err("error %d\n", rc);
20294 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20296 common_attr->is_opened = false;
20299 /* Run SCU for a little while to initialize microcode version numbers */
20300 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
20302 pr_err("error %d\n", rc);
20306 /* Open tuner instance */
20307 if (demod->my_tuner != NULL) {
20308 demod->my_tuner->my_common_attr->my_user_data = (void *)demod;
20310 if (common_attr->tuner_port_nr == 1) {
20311 bool bridge_closed = true;
20312 rc = ctrl_i2c_bridge(demod, &bridge_closed);
20314 pr_err("error %d\n", rc);
20319 rc = drxbsp_tuner_open(demod->my_tuner);
20321 pr_err("error %d\n", rc);
20325 if (common_attr->tuner_port_nr == 1) {
20326 bool bridge_closed = false;
20327 rc = ctrl_i2c_bridge(demod, &bridge_closed);
20329 pr_err("error %d\n", rc);
20333 common_attr->tuner_min_freq_rf =
20334 ((demod->my_tuner)->my_common_attr->min_freq_rf);
20335 common_attr->tuner_max_freq_rf =
20336 ((demod->my_tuner)->my_common_attr->max_freq_rf);
20339 /* Initialize scan timeout */
20340 common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
20341 common_attr->scan_desired_lock = DRX_LOCKED;
20343 drxj_reset_mode(ext_attr);
20344 ext_attr->standard = DRX_STANDARD_UNKNOWN;
20346 rc = smart_ant_init(demod);
20348 pr_err("error %d\n", rc);
20352 /* Stamp driver version number in SCU data RAM in BCD code
20353 Done to enable field application engineers to retreive drxdriver version
20354 via I2C from SCU RAM
20356 driver_version = (VERSION_MAJOR / 100) % 10;
20357 driver_version <<= 4;
20358 driver_version += (VERSION_MAJOR / 10) % 10;
20359 driver_version <<= 4;
20360 driver_version += (VERSION_MAJOR % 10);
20361 driver_version <<= 4;
20362 driver_version += (VERSION_MINOR % 10);
20363 driver_version <<= 4;
20364 driver_version += (VERSION_PATCH / 1000) % 10;
20365 driver_version <<= 4;
20366 driver_version += (VERSION_PATCH / 100) % 10;
20367 driver_version <<= 4;
20368 driver_version += (VERSION_PATCH / 10) % 10;
20369 driver_version <<= 4;
20370 driver_version += (VERSION_PATCH % 10);
20371 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
20373 pr_err("error %d\n", rc);
20376 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
20378 pr_err("error %d\n", rc);
20382 /* refresh the audio data structure with default */
20383 ext_attr->aud_data = drxj_default_aud_data_g;
20387 common_attr->is_opened = false;
20391 /*============================================================================*/
20394 * \brief Close the demod instance, power down the device
20395 * \return Status_t Return status.
20398 int drxj_close(struct drx_demod_instance *demod)
20400 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
20401 struct drx_common_attr *common_attr = demod->my_common_attr;
20403 enum drx_power_mode power_mode = DRX_POWER_UP;
20406 rc = ctrl_power_mode(demod, &power_mode);
20408 pr_err("error %d\n", rc);
20412 if (demod->my_tuner != NULL) {
20413 /* Check if bridge is used */
20414 if (common_attr->tuner_port_nr == 1) {
20415 bool bridge_closed = true;
20416 rc = ctrl_i2c_bridge(demod, &bridge_closed);
20418 pr_err("error %d\n", rc);
20422 rc = drxbsp_tuner_close(demod->my_tuner);
20424 pr_err("error %d\n", rc);
20427 if (common_attr->tuner_port_nr == 1) {
20428 bool bridge_closed = false;
20429 rc = ctrl_i2c_bridge(demod, &bridge_closed);
20431 pr_err("error %d\n", rc);
20437 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
20439 pr_err("error %d\n", rc);
20442 power_mode = DRX_POWER_DOWN;
20443 rc = ctrl_power_mode(demod, &power_mode);
20445 pr_err("error %d\n", rc);
20454 /*============================================================================*/
20457 * \brief DRXJ specific control function
20458 * \return Status_t Return status.
20461 drxj_ctrl(struct drx_demod_instance *demod, u32 ctrl, void *ctrl_data)
20464 /*======================================================================*/
20465 case DRX_CTRL_SET_CHANNEL:
20467 return ctrl_set_channel(demod, (struct drx_channel *)ctrl_data);
20470 /*======================================================================*/
20471 case DRX_CTRL_GET_CHANNEL:
20473 return ctrl_get_channel(demod, (struct drx_channel *)ctrl_data);
20476 /*======================================================================*/
20477 case DRX_CTRL_SIG_QUALITY:
20479 return ctrl_sig_quality(demod,
20480 (struct drx_sig_quality *) ctrl_data);
20483 /*======================================================================*/
20484 case DRX_CTRL_SIG_STRENGTH:
20486 return ctrl_sig_strength(demod, (u16 *)ctrl_data);
20489 /*======================================================================*/
20490 case DRX_CTRL_CONSTEL:
20492 return ctrl_constel(demod, (struct drx_complex *)ctrl_data);
20495 /*======================================================================*/
20496 case DRX_CTRL_SET_CFG:
20498 return ctrl_set_cfg(demod, (struct drx_cfg *)ctrl_data);
20501 /*======================================================================*/
20502 case DRX_CTRL_GET_CFG:
20504 return ctrl_get_cfg(demod, (struct drx_cfg *)ctrl_data);
20507 /*======================================================================*/
20508 case DRX_CTRL_I2C_BRIDGE:
20510 return ctrl_i2c_bridge(demod, (bool *)ctrl_data);
20513 /*======================================================================*/
20514 case DRX_CTRL_LOCK_STATUS:
20516 return ctrl_lock_status(demod,
20517 (enum drx_lock_status *)ctrl_data);
20520 /*======================================================================*/
20521 case DRX_CTRL_SET_STANDARD:
20523 return ctrl_set_standard(demod,
20524 (enum drx_standard *)ctrl_data);
20527 /*======================================================================*/
20528 case DRX_CTRL_GET_STANDARD:
20530 return ctrl_get_standard(demod,
20531 (enum drx_standard *)ctrl_data);
20534 /*======================================================================*/
20535 case DRX_CTRL_POWER_MODE:
20537 return ctrl_power_mode(demod, (enum drx_power_mode *)ctrl_data);
20540 /*======================================================================*/
20541 case DRX_CTRL_VERSION:
20543 return ctrl_version(demod,
20544 (struct drx_version_list **)ctrl_data);
20547 /*======================================================================*/
20548 case DRX_CTRL_PROBE_DEVICE:
20550 return ctrl_probe_device(demod);
20553 /*======================================================================*/
20554 case DRX_CTRL_SET_OOB:
20556 return ctrl_set_oob(demod, (struct drxoob *)ctrl_data);
20559 /*======================================================================*/
20560 case DRX_CTRL_GET_OOB:
20562 return ctrl_get_oob(demod, (struct drxoob_status *)ctrl_data);
20565 /*======================================================================*/
20566 case DRX_CTRL_SET_UIO_CFG:
20568 return ctrl_set_uio_cfg(demod, (struct drxuio_cfg *)ctrl_data);
20571 /*======================================================================*/
20572 case DRX_CTRL_GET_UIO_CFG:
20574 return ctrl_getuio_cfg(demod, (struct drxuio_cfg *)ctrl_data);
20577 /*======================================================================*/
20578 case DRX_CTRL_UIO_READ:
20580 return ctrl_uio_read(demod, (struct drxuio_data *)ctrl_data);
20583 /*======================================================================*/
20584 case DRX_CTRL_UIO_WRITE:
20586 return ctrl_uio_write(demod, (struct drxuio_data *)ctrl_data);
20589 /*======================================================================*/
20590 case DRX_CTRL_AUD_SET_STANDARD:
20592 return aud_ctrl_set_standard(demod,
20593 (enum drx_aud_standard *) ctrl_data);
20596 /*======================================================================*/
20597 case DRX_CTRL_AUD_GET_STANDARD:
20599 return aud_ctrl_get_standard(demod,
20600 (enum drx_aud_standard *) ctrl_data);
20603 /*======================================================================*/
20604 case DRX_CTRL_AUD_GET_STATUS:
20606 return aud_ctrl_get_status(demod,
20607 (struct drx_aud_status *) ctrl_data);
20610 /*======================================================================*/
20611 case DRX_CTRL_AUD_BEEP:
20613 return aud_ctrl_beep(demod, (struct drx_aud_beep *)ctrl_data);
20617 /*======================================================================*/
20618 case DRX_CTRL_I2C_READWRITE:
20620 return ctrl_i2c_write_read(demod,
20621 (struct drxi2c_data *) ctrl_data);
20624 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20625 case DRX_CTRL_LOAD_UCODE:
20627 return ctrl_u_code_upload(demod,
20628 (p_drxu_code_info_t) ctrl_data,
20629 UCODE_UPLOAD, false);
20632 case DRX_CTRL_VERIFY_UCODE:
20634 return ctrl_u_code_upload(demod,
20635 (p_drxu_code_info_t) ctrl_data,
20636 UCODE_VERIFY, false);
20639 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20640 case DRX_CTRL_VALIDATE_UCODE:
20642 return ctrl_validate_u_code(demod);
20652 * Microcode related functions
20656 * drx_u_code_compute_crc - Compute CRC of block of microcode data.
20657 * @block_data: Pointer to microcode data.
20658 * @nr_words: Size of microcode block (number of 16 bits words).
20660 * returns The computed CRC residue.
20662 static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
20669 while (i < nr_words) {
20670 crc_word |= (u32)be16_to_cpu(*(u32 *)(block_data));
20671 for (j = 0; j < 16; j++) {
20674 crc_word ^= 0x80050000UL;
20675 carry = crc_word & 0x80000000UL;
20678 block_data += (sizeof(u16));
20680 return (u16)(crc_word >> 16);
20684 * drx_check_firmware - checks if the loaded firmware is valid
20686 * @demod: demod structure
20687 * @mc_data: pointer to the start of the firmware
20688 * @size: firmware size
20690 static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
20693 struct drxu_code_block_hdr block_hdr;
20695 unsigned count = 2 * sizeof(u16);
20696 u32 mc_dev_type, mc_version, mc_base_version;
20697 u16 mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data + sizeof(u16)));
20700 * Scan microcode blocks first for version info
20701 * and firmware check
20704 /* Clear version block */
20705 DRX_ATTR_MCRECORD(demod).aux_type = 0;
20706 DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
20707 DRX_ATTR_MCRECORD(demod).mc_version = 0;
20708 DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
20710 for (i = 0; i < mc_nr_of_blks; i++) {
20711 if (count + 3 * sizeof(u16) + sizeof(u32) > size)
20714 /* Process block header */
20715 block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data + count));
20716 count += sizeof(u32);
20717 block_hdr.size = be16_to_cpu(*(u32 *)(mc_data + count));
20718 count += sizeof(u16);
20719 block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data + count));
20720 count += sizeof(u16);
20721 block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data + count));
20722 count += sizeof(u16);
20724 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
20725 count, block_hdr.addr, block_hdr.size, block_hdr.flags,
20728 if (block_hdr.flags & 0x8) {
20729 u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
20732 if (block_hdr.addr + sizeof(u16) > size)
20735 auxtype = be16_to_cpu(*(u32 *)(auxblk));
20737 /* Aux block. Check type */
20738 if (DRX_ISMCVERTYPE(auxtype)) {
20739 if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
20742 auxblk += sizeof(u16);
20743 mc_dev_type = be32_to_cpu(*(u32 *)(auxblk));
20744 auxblk += sizeof(u32);
20745 mc_version = be32_to_cpu(*(u32 *)(auxblk));
20746 auxblk += sizeof(u32);
20747 mc_base_version = be32_to_cpu(*(u32 *)(auxblk));
20749 DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
20750 DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
20751 DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
20752 DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
20754 pr_info("Firmware dev %x, ver %x, base ver %x\n",
20755 mc_dev_type, mc_version, mc_base_version);
20758 } else if (count + block_hdr.size * sizeof(u16) > size)
20761 count += block_hdr.size * sizeof(u16);
20765 pr_err("Firmware is truncated at pos %u/%u\n", count, size);
20770 * drx_ctrl_u_code - Handle microcode upload or verify.
20771 * @dev_addr: Address of device.
20772 * @mc_info: Pointer to information about microcode data.
20773 * @action: Either UCODE_UPLOAD or UCODE_VERIFY
20775 * This function returns:
20777 * - In case of UCODE_UPLOAD: code is successfully uploaded.
20778 * - In case of UCODE_VERIFY: image on device is equal to
20779 * image provided to this control function.
20781 * - In case of UCODE_UPLOAD: I2C error.
20782 * - In case of UCODE_VERIFY: I2C error or image on device
20783 * is not equal to image provided to this control function.
20785 * - Invalid arguments.
20786 * - Provided image is corrupt
20788 static int drx_ctrl_u_code(struct drx_demod_instance *demod,
20789 struct drxu_code_info *mc_info,
20790 enum drxu_code_action action)
20792 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
20795 u16 mc_nr_of_blks = 0;
20796 u16 mc_magic_word = 0;
20797 const u8 *mc_data_init = NULL;
20798 u8 *mc_data = NULL;
20800 char *mc_file = mc_info->mc_file;
20802 /* Check arguments */
20803 if (!mc_info || !mc_file)
20806 if (!demod->firmware) {
20807 const struct firmware *fw = NULL;
20809 rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
20811 pr_err("Couldn't read firmware %s\n", mc_file);
20814 demod->firmware = fw;
20816 if (demod->firmware->size < 2 * sizeof(u16)) {
20818 pr_err("Firmware is too short!\n");
20822 pr_info("Firmware %s, size %zu\n",
20823 mc_file, demod->firmware->size);
20826 mc_data_init = demod->firmware->data;
20827 size = demod->firmware->size;
20829 mc_data = (void *)mc_data_init;
20831 mc_magic_word = be16_to_cpu(*(u32 *)(mc_data));
20832 mc_data += sizeof(u16);
20833 mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data));
20834 mc_data += sizeof(u16);
20836 if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
20838 pr_err("Firmware magic word doesn't match\n");
20842 if (action == UCODE_UPLOAD) {
20843 rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
20847 /* After scanning, validate the microcode.
20848 It is also valid if no validation control exists.
20850 rc = drx_ctrl(demod, DRX_CTRL_VALIDATE_UCODE, NULL);
20851 if (rc != 0 && rc != -ENOTSUPP) {
20852 pr_err("Validate ucode not supported\n");
20855 pr_info("Uploading firmware %s\n", mc_file);
20856 } else if (action == UCODE_VERIFY) {
20857 pr_info("Verifying if firmware upload was ok.\n");
20860 /* Process microcode blocks */
20861 for (i = 0; i < mc_nr_of_blks; i++) {
20862 struct drxu_code_block_hdr block_hdr;
20863 u16 mc_block_nr_bytes = 0;
20865 /* Process block header */
20866 block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data));
20867 mc_data += sizeof(u32);
20868 block_hdr.size = be16_to_cpu(*(u32 *)(mc_data));
20869 mc_data += sizeof(u16);
20870 block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data));
20871 mc_data += sizeof(u16);
20872 block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data));
20873 mc_data += sizeof(u16);
20875 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
20876 (unsigned)(mc_data - mc_data_init), block_hdr.addr,
20877 block_hdr.size, block_hdr.flags, block_hdr.CRC);
20879 /* Check block header on:
20880 - data larger than 64Kb
20881 - if CRC enabled check CRC
20883 if ((block_hdr.size > 0x7FFF) ||
20884 (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
20885 (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
20889 pr_err("firmware CRC is wrong\n");
20893 if (!block_hdr.size)
20896 mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
20898 /* Perform the desired action */
20900 case UCODE_UPLOAD: /* Upload microcode */
20901 if (demod->my_access_funct->write_block_func(dev_addr,
20904 mc_data, 0x0000)) {
20906 pr_err("error writing firmware at pos %u\n",
20907 (unsigned)(mc_data - mc_data_init));
20911 case UCODE_VERIFY: { /* Verify uploaded microcode */
20913 u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
20914 u32 bytes_to_comp = 0;
20915 u32 bytes_left = mc_block_nr_bytes;
20916 u32 curr_addr = block_hdr.addr;
20917 u8 *curr_ptr = mc_data;
20919 while (bytes_left != 0) {
20920 if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
20921 bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
20923 bytes_to_comp = bytes_left;
20925 if (demod->my_access_funct->
20926 read_block_func(dev_addr,
20928 (u16)bytes_to_comp,
20929 (u8 *)mc_data_buffer,
20931 pr_err("error reading firmware at pos %u\n",
20932 (unsigned)(mc_data - mc_data_init));
20936 result =drxbsp_hst_memcmp(curr_ptr,
20941 pr_err("error verifying firmware at pos %u\n",
20942 (unsigned)(mc_data - mc_data_init));
20946 curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
20947 curr_ptr =&(curr_ptr[bytes_to_comp]);
20948 bytes_left -=((u32) bytes_to_comp);
20957 mc_data += mc_block_nr_bytes;
20963 release_firmware(demod->firmware);
20964 demod->firmware = NULL;
20969 /*============================================================================*/
20972 * drx_ctrl_version - Build list of version information.
20973 * @demod: A pointer to a demodulator instance.
20974 * @version_list: Pointer to linked list of versions.
20976 * This function returns:
20977 * 0: Version information stored in version_list
20978 * -EINVAL: Invalid arguments.
20980 static int drx_ctrl_version(struct drx_demod_instance *demod,
20981 struct drx_version_list **version_list)
20983 static char drx_driver_core_module_name[] = "Core driver";
20984 static char drx_driver_core_version_text[] =
20985 DRX_VERSIONSTRING(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
20987 static struct drx_version drx_driver_core_version;
20988 static struct drx_version_list drx_driver_core_version_list;
20990 struct drx_version_list *demod_version_list = NULL;
20991 int return_status = -EIO;
20993 /* Check arguments */
20994 if (version_list == NULL)
20997 /* Get version info list from demod */
20998 return_status = (*(demod->my_demod_funct->ctrl_func)) (demod,
21001 &demod_version_list);
21003 /* Always fill in the information of the driver SW . */
21004 drx_driver_core_version.module_type = DRX_MODULE_DRIVERCORE;
21005 drx_driver_core_version.module_name = drx_driver_core_module_name;
21006 drx_driver_core_version.v_major = VERSION_MAJOR;
21007 drx_driver_core_version.v_minor = VERSION_MINOR;
21008 drx_driver_core_version.v_patch = VERSION_PATCH;
21009 drx_driver_core_version.v_string = drx_driver_core_version_text;
21011 drx_driver_core_version_list.version = &drx_driver_core_version;
21012 drx_driver_core_version_list.next = (struct drx_version_list *) (NULL);
21014 if ((return_status == 0) && (demod_version_list != NULL)) {
21015 /* Append versioninfo from driver to versioninfo from demod */
21016 /* Return version info in "bottom-up" order. This way, multiple
21017 devices can be handled without using malloc. */
21018 struct drx_version_list *current_list_element = demod_version_list;
21019 while (current_list_element->next != NULL)
21020 current_list_element = current_list_element->next;
21021 current_list_element->next = &drx_driver_core_version_list;
21023 *version_list = demod_version_list;
21025 /* Just return versioninfo from driver */
21026 *version_list = &drx_driver_core_version_list;
21033 * Exported functions
21037 * drx_open - Open a demodulator instance.
21038 * @demod: A pointer to a demodulator instance.
21040 * This function returns:
21041 * 0: Opened demod instance with succes.
21042 * -EIO: Driver not initialized or unable to initialize
21044 * -EINVAL: Demod instance has invalid content.
21048 int drx_open(struct drx_demod_instance *demod)
21052 if ((demod == NULL) ||
21053 (demod->my_demod_funct == NULL) ||
21054 (demod->my_common_attr == NULL) ||
21055 (demod->my_ext_attr == NULL) ||
21056 (demod->my_i2c_dev_addr == NULL) ||
21057 (demod->my_common_attr->is_opened)) {
21061 status = (*(demod->my_demod_funct->open_func)) (demod);
21064 demod->my_common_attr->is_opened = true;
21069 /*============================================================================*/
21072 * drx_close - Close device
21073 * @demod: A pointer to a demodulator instance.
21075 * Free resources occupied by device instance.
21076 * Put device into sleep mode.
21078 * This function returns:
21079 * 0: Closed demod instance with succes.
21080 * -EIO: Driver not initialized or error during close
21082 * -EINVAL: Demod instance has invalid content.
21084 int drx_close(struct drx_demod_instance *demod)
21088 if ((demod == NULL) ||
21089 (demod->my_demod_funct == NULL) ||
21090 (demod->my_common_attr == NULL) ||
21091 (demod->my_ext_attr == NULL) ||
21092 (demod->my_i2c_dev_addr == NULL) ||
21093 (!demod->my_common_attr->is_opened)) {
21097 status = (*(demod->my_demod_funct->close_func)) (demod);
21099 DRX_ATTR_ISOPENED(demod) = false;
21104 * drx_ctrl - Control the device.
21105 * @demod: A pointer to a demodulator instance.
21106 * @ctrl: Reference to desired control function.
21107 * @ctrl_data: Pointer to data structure for control function.
21109 * Data needed or returned by the control function is stored in ctrl_data.
21111 * This function returns:
21112 * 0: Control function completed successfully.
21113 * -EIO: Driver not initialized or error during control demod.
21114 * -EINVAL: Demod instance or ctrl_data has invalid content.
21115 * -ENOTSUPP: Specified control function is not available.
21118 int drx_ctrl(struct drx_demod_instance *demod, u32 ctrl, void *ctrl_data)
21122 if ((demod == NULL) ||
21123 (demod->my_demod_funct == NULL) ||
21124 (demod->my_common_attr == NULL) ||
21125 (demod->my_ext_attr == NULL) || (demod->my_i2c_dev_addr == NULL)
21130 if (((!demod->my_common_attr->is_opened) &&
21131 (ctrl != DRX_CTRL_PROBE_DEVICE) && (ctrl != DRX_CTRL_VERSION))
21136 if ((DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode) &&
21137 (ctrl != DRX_CTRL_POWER_MODE) &&
21138 (ctrl != DRX_CTRL_PROBE_DEVICE) &&
21139 (ctrl != DRX_CTRL_NOP) && (ctrl != DRX_CTRL_VERSION)
21145 /* Fixed control functions */
21147 /*======================================================================*/
21153 /*======================================================================*/
21154 case DRX_CTRL_VERSION:
21155 return drx_ctrl_version(demod, (struct drx_version_list **)ctrl_data);
21158 /*======================================================================*/
21164 /* Virtual functions */
21165 /* First try calling function from derived class */
21166 status = (*(demod->my_demod_funct->ctrl_func)) (demod, ctrl, ctrl_data);
21167 if (status == -ENOTSUPP) {
21168 /* Now try calling a the base class function */
21170 /*===================================================================*/
21171 case DRX_CTRL_LOAD_UCODE:
21172 return drx_ctrl_u_code(demod,
21173 (struct drxu_code_info *)ctrl_data,
21177 /*===================================================================*/
21178 case DRX_CTRL_VERIFY_UCODE:
21180 return drx_ctrl_u_code(demod,
21181 (struct drxu_code_info *)ctrl_data,
21186 /*===================================================================*/
21188 pr_err("control %d not supported\n", ctrl);