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__
43 /*============================================================================*/
44 /*=== DEFINES ================================================================*/
45 /*============================================================================*/
48 * \brief Maximum u32 value.
51 #define MAX_U32 ((u32) (0xFFFFFFFFL))
54 /* Customer configurable hardware settings, etc */
55 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
56 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
59 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
60 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
63 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
64 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
67 #ifndef OOB_CRX_DRIVE_STRENGTH
68 #define OOB_CRX_DRIVE_STRENGTH 0x02
71 #ifndef OOB_DRX_DRIVE_STRENGTH
72 #define OOB_DRX_DRIVE_STRENGTH 0x02
74 /**** START DJCOMBO patches to DRXJ registermap constants *********************/
75 /**** registermap 200706071303 from drxj **************************************/
76 #define ATV_TOP_CR_AMP_TH_FM 0x0
77 #define ATV_TOP_CR_AMP_TH_L 0xA
78 #define ATV_TOP_CR_AMP_TH_LP 0xA
79 #define ATV_TOP_CR_AMP_TH_BG 0x8
80 #define ATV_TOP_CR_AMP_TH_DK 0x8
81 #define ATV_TOP_CR_AMP_TH_I 0x8
82 #define ATV_TOP_CR_CONT_CR_D_MN 0x18
83 #define ATV_TOP_CR_CONT_CR_D_FM 0x0
84 #define ATV_TOP_CR_CONT_CR_D_L 0x20
85 #define ATV_TOP_CR_CONT_CR_D_LP 0x20
86 #define ATV_TOP_CR_CONT_CR_D_BG 0x18
87 #define ATV_TOP_CR_CONT_CR_D_DK 0x18
88 #define ATV_TOP_CR_CONT_CR_D_I 0x18
89 #define ATV_TOP_CR_CONT_CR_I_MN 0x80
90 #define ATV_TOP_CR_CONT_CR_I_FM 0x0
91 #define ATV_TOP_CR_CONT_CR_I_L 0x80
92 #define ATV_TOP_CR_CONT_CR_I_LP 0x80
93 #define ATV_TOP_CR_CONT_CR_I_BG 0x80
94 #define ATV_TOP_CR_CONT_CR_I_DK 0x80
95 #define ATV_TOP_CR_CONT_CR_I_I 0x80
96 #define ATV_TOP_CR_CONT_CR_P_MN 0x4
97 #define ATV_TOP_CR_CONT_CR_P_FM 0x0
98 #define ATV_TOP_CR_CONT_CR_P_L 0x4
99 #define ATV_TOP_CR_CONT_CR_P_LP 0x4
100 #define ATV_TOP_CR_CONT_CR_P_BG 0x4
101 #define ATV_TOP_CR_CONT_CR_P_DK 0x4
102 #define ATV_TOP_CR_CONT_CR_P_I 0x4
103 #define ATV_TOP_CR_OVM_TH_MN 0xA0
104 #define ATV_TOP_CR_OVM_TH_FM 0x0
105 #define ATV_TOP_CR_OVM_TH_L 0xA0
106 #define ATV_TOP_CR_OVM_TH_LP 0xA0
107 #define ATV_TOP_CR_OVM_TH_BG 0xA0
108 #define ATV_TOP_CR_OVM_TH_DK 0xA0
109 #define ATV_TOP_CR_OVM_TH_I 0xA0
110 #define ATV_TOP_EQU0_EQU_C0_FM 0x0
111 #define ATV_TOP_EQU0_EQU_C0_L 0x3
112 #define ATV_TOP_EQU0_EQU_C0_LP 0x3
113 #define ATV_TOP_EQU0_EQU_C0_BG 0x7
114 #define ATV_TOP_EQU0_EQU_C0_DK 0x0
115 #define ATV_TOP_EQU0_EQU_C0_I 0x3
116 #define ATV_TOP_EQU1_EQU_C1_FM 0x0
117 #define ATV_TOP_EQU1_EQU_C1_L 0x1F6
118 #define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
119 #define ATV_TOP_EQU1_EQU_C1_BG 0x197
120 #define ATV_TOP_EQU1_EQU_C1_DK 0x198
121 #define ATV_TOP_EQU1_EQU_C1_I 0x1F6
122 #define ATV_TOP_EQU2_EQU_C2_FM 0x0
123 #define ATV_TOP_EQU2_EQU_C2_L 0x28
124 #define ATV_TOP_EQU2_EQU_C2_LP 0x28
125 #define ATV_TOP_EQU2_EQU_C2_BG 0xC5
126 #define ATV_TOP_EQU2_EQU_C2_DK 0xB0
127 #define ATV_TOP_EQU2_EQU_C2_I 0x28
128 #define ATV_TOP_EQU3_EQU_C3_FM 0x0
129 #define ATV_TOP_EQU3_EQU_C3_L 0x192
130 #define ATV_TOP_EQU3_EQU_C3_LP 0x192
131 #define ATV_TOP_EQU3_EQU_C3_BG 0x12E
132 #define ATV_TOP_EQU3_EQU_C3_DK 0x18E
133 #define ATV_TOP_EQU3_EQU_C3_I 0x192
134 #define ATV_TOP_STD_MODE_MN 0x0
135 #define ATV_TOP_STD_MODE_FM 0x1
136 #define ATV_TOP_STD_MODE_L 0x0
137 #define ATV_TOP_STD_MODE_LP 0x0
138 #define ATV_TOP_STD_MODE_BG 0x0
139 #define ATV_TOP_STD_MODE_DK 0x0
140 #define ATV_TOP_STD_MODE_I 0x0
141 #define ATV_TOP_STD_VID_POL_MN 0x0
142 #define ATV_TOP_STD_VID_POL_FM 0x0
143 #define ATV_TOP_STD_VID_POL_L 0x2
144 #define ATV_TOP_STD_VID_POL_LP 0x2
145 #define ATV_TOP_STD_VID_POL_BG 0x0
146 #define ATV_TOP_STD_VID_POL_DK 0x0
147 #define ATV_TOP_STD_VID_POL_I 0x0
148 #define ATV_TOP_VID_AMP_MN 0x380
149 #define ATV_TOP_VID_AMP_FM 0x0
150 #define ATV_TOP_VID_AMP_L 0xF50
151 #define ATV_TOP_VID_AMP_LP 0xF50
152 #define ATV_TOP_VID_AMP_BG 0x380
153 #define ATV_TOP_VID_AMP_DK 0x394
154 #define ATV_TOP_VID_AMP_I 0x3D8
155 #define IQM_CF_OUT_ENA_OFDM__M 0x4
156 #define IQM_FS_ADJ_SEL_B_QAM 0x1
157 #define IQM_FS_ADJ_SEL_B_OFF 0x0
158 #define IQM_FS_ADJ_SEL_B_VSB 0x2
159 #define IQM_RC_ADJ_SEL_B_OFF 0x0
160 #define IQM_RC_ADJ_SEL_B_QAM 0x1
161 #define IQM_RC_ADJ_SEL_B_VSB 0x2
162 /**** END DJCOMBO patches to DRXJ registermap *********************************/
164 #include "drx_driver_version.h"
166 /* #define DRX_DEBUG */
171 /*-----------------------------------------------------------------------------
173 ----------------------------------------------------------------------------*/
175 /*-----------------------------------------------------------------------------
177 ----------------------------------------------------------------------------*/
178 #ifndef DRXJ_WAKE_UP_KEY
179 #define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
183 * \def DRXJ_DEF_I2C_ADDR
184 * \brief Default I2C addres of a demodulator instance.
186 #define DRXJ_DEF_I2C_ADDR (0x52)
189 * \def DRXJ_DEF_DEMOD_DEV_ID
190 * \brief Default device identifier of a demodultor instance.
192 #define DRXJ_DEF_DEMOD_DEV_ID (1)
195 * \def DRXJ_SCAN_TIMEOUT
196 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
198 #define DRXJ_SCAN_TIMEOUT 1000
202 * \brief Name of structure containing all data access protocol functions.
204 #define DRXJ_DAP drx_dap_drxj_funct_g
208 * \brief HI timing delay for I2C timing (in nano seconds)
210 * Used to compute HI_CFG_DIV
212 #define HI_I2C_DELAY 42
215 * \def HI_I2C_BRIDGE_DELAY
216 * \brief HI timing delay for I2C timing (in nano seconds)
218 * Used to compute HI_CFG_BDL
220 #define HI_I2C_BRIDGE_DELAY 750
223 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
225 #define VSB_TOP_MEASUREMENT_PERIOD 64
226 #define SYMBOLS_PER_SEGMENT 832
229 * \brief bit rate and segment rate constants used for SER and BER.
231 /* values taken from the QAM microcode */
232 #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
233 #define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
234 #define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
235 #define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
236 #define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
237 #define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
238 #define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
239 #define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
241 * \brief Min supported symbolrates.
243 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
244 #define DRXJ_QAM_SYMBOLRATE_MIN (520000)
248 * \brief Max supported symbolrates.
250 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
251 #define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
255 * \def DRXJ_QAM_MAX_WAITTIME
256 * \brief Maximal wait time for QAM auto constellation in ms
258 #ifndef DRXJ_QAM_MAX_WAITTIME
259 #define DRXJ_QAM_MAX_WAITTIME 900
262 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
263 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
266 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
267 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
271 * \def SCU status and results
274 #define DRX_SCU_READY 0
275 #define DRXJ_MAX_WAITTIME 100 /* ms */
276 #define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
277 #define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
280 * \def DRX_AUD_MAX_DEVIATION
281 * \brief Needed for calculation of prescale feature in AUD
283 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
284 #define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
288 * \brief Needed for calculation of NICAM prescale feature in AUD
290 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
291 #define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
295 * \brief Needed for calculation of NICAM prescale feature in AUD
297 #ifndef DRXJ_AUD_MAX_WAITTIME
298 #define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
301 /* ATV config changed flags */
302 #define DRXJ_ATV_CHANGED_COEF (0x00000001UL)
303 #define DRXJ_ATV_CHANGED_PEAK_FLT (0x00000008UL)
304 #define DRXJ_ATV_CHANGED_NOISE_FLT (0x00000010UL)
305 #define DRXJ_ATV_CHANGED_OUTPUT (0x00000020UL)
306 #define DRXJ_ATV_CHANGED_SIF_ATT (0x00000040UL)
309 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
310 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
312 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
313 /*============================================================================*/
314 /*=== MICROCODE RELATED DEFINES ==============================================*/
315 /*============================================================================*/
318 * \def DRXJ_UCODE_MAGIC_WORD
319 * \brief Magic word for checking correct Endianess of microcode data.
323 #ifndef DRXJ_UCODE_MAGIC_WORD
324 #define DRXJ_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L'))
328 * \def DRXJ_UCODE_CRC_FLAG
329 * \brief CRC flag in ucode header, flags field.
333 #ifndef DRXJ_UCODE_CRC_FLAG
334 #define DRXJ_UCODE_CRC_FLAG (0x0001)
338 * \def DRXJ_UCODE_COMPRESSION_FLAG
339 * \brief Compression flag in ucode header, flags field.
343 #ifndef DRXJ_UCODE_COMPRESSION_FLAG
344 #define DRXJ_UCODE_COMPRESSION_FLAG (0x0002)
348 * \def DRXJ_UCODE_MAX_BUF_SIZE
349 * \brief Maximum size of buffer used to verify the microcode.Must be an even number.
353 #ifndef DRXJ_UCODE_MAX_BUF_SIZE
354 #define DRXJ_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
356 #if DRXJ_UCODE_MAX_BUF_SIZE & 1
357 #error DRXJ_UCODE_MAX_BUF_SIZE must be an even number
360 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
362 /* Pin safe mode macro */
363 #define DRXJ_PIN_SAFE_MODE 0x0000
364 /*============================================================================*/
365 /*=== GLOBAL VARIABLEs =======================================================*/
366 /*============================================================================*/
371 * \brief Temporary register definitions.
372 * (register definitions that are not yet available in register master)
375 /******************************************************************************/
376 /* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
377 /* RAM adresses directly. This must be READ ONLY to avoid problems. */
378 /* Writing to the interface adresses is more than only writing the RAM */
380 /******************************************************************************/
382 * \brief RAM location of MODUS registers
384 #define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
385 #define AUD_DEM_RAM_MODUS_HI__M 0xF000
387 #define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
388 #define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
391 * \brief RAM location of I2S config registers
393 #define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
394 #define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
397 * \brief RAM location of DCO config registers
399 #define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
400 #define AUD_DEM_RAM_DCO_B_LO__A 0x1020462
401 #define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
402 #define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
405 * \brief RAM location of Threshold registers
407 #define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
408 #define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
409 #define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
412 * \brief RAM location of Carrier Threshold registers
414 #define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
415 #define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
418 * \brief FM Matrix register fix
420 #ifdef AUD_DEM_WR_FM_MATRIX__A
421 #undef AUD_DEM_WR_FM_MATRIX__A
423 #define AUD_DEM_WR_FM_MATRIX__A 0x105006F
425 /*============================================================================*/
427 * \brief Defines required for audio
429 #define AUD_VOLUME_ZERO_DB 115
430 #define AUD_VOLUME_DB_MIN -60
431 #define AUD_VOLUME_DB_MAX 12
432 #define AUD_CARRIER_STRENGTH_QP_0DB 0x4000
433 #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 421
434 #define AUD_MAX_AVC_REF_LEVEL 15
435 #define AUD_I2S_FREQUENCY_MAX 48000UL
436 #define AUD_I2S_FREQUENCY_MIN 12000UL
437 #define AUD_RDS_ARRAY_SIZE 18
440 * \brief Needed for calculation of prescale feature in AUD
442 #ifndef DRX_AUD_MAX_FM_DEVIATION
443 #define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
447 * \brief Needed for calculation of NICAM prescale feature in AUD
449 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
450 #define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
453 /*============================================================================*/
454 /* Values for I2S Master/Slave pin configurations */
455 #define SIO_PDR_I2S_CL_CFG_MODE__MASTER 0x0004
456 #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER 0x0008
457 #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE 0x0004
458 #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE 0x0000
460 #define SIO_PDR_I2S_DA_CFG_MODE__MASTER 0x0003
461 #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER 0x0008
462 #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE 0x0003
463 #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE 0x0008
465 #define SIO_PDR_I2S_WS_CFG_MODE__MASTER 0x0004
466 #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER 0x0008
467 #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE 0x0004
468 #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE 0x0000
470 /*============================================================================*/
471 /*=== REGISTER ACCESS MACROS =================================================*/
472 /*============================================================================*/
475 * This macro is used to create byte arrays for block writes.
476 * Block writes speed up I2C traffic between host and demod.
477 * The macro takes care of the required byte order in a 16 bits word.
478 * x -> lowbyte(x), highbyte(x)
480 #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
481 ((u8)((((u16)x)>>8)&0xFF))
483 * This macro is used to convert byte array to 16 bit register value for block read.
484 * Block read speed up I2C traffic between host and demod.
485 * The macro takes care of the required byte order in a 16 bits word.
487 #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
489 /*============================================================================*/
490 /*=== MISC DEFINES ===========================================================*/
491 /*============================================================================*/
493 /*============================================================================*/
494 /*=== HI COMMAND RELATED DEFINES =============================================*/
495 /*============================================================================*/
498 * \brief General maximum number of retries for ucode command interfaces
500 #define DRXJ_MAX_RETRIES (100)
502 /*============================================================================*/
503 /*=== STANDARD RELATED MACROS ================================================*/
504 /*============================================================================*/
506 #define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
507 (std == DRX_STANDARD_PAL_SECAM_DK) || \
508 (std == DRX_STANDARD_PAL_SECAM_I) || \
509 (std == DRX_STANDARD_PAL_SECAM_L) || \
510 (std == DRX_STANDARD_PAL_SECAM_LP) || \
511 (std == DRX_STANDARD_NTSC) || \
512 (std == DRX_STANDARD_FM))
514 #define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
515 (std == DRX_STANDARD_ITU_B) || \
516 (std == DRX_STANDARD_ITU_C) || \
517 (std == DRX_STANDARD_ITU_D))
519 /*-----------------------------------------------------------------------------
521 ----------------------------------------------------------------------------*/
523 * DRXJ DAP structures
526 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
529 u8 *data, u32 flags);
531 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
534 u8 wdata, u8 *rdata);
536 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
539 u16 wdata, u16 *rdata);
541 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
544 u32 wdata, u32 *rdata);
546 static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
548 u8 *data, u32 flags);
550 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
552 u16 *data, u32 flags);
554 static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
556 u32 *data, u32 flags);
558 static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
561 u8 *data, u32 flags);
563 static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
567 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
569 u16 data, u32 flags);
571 static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
573 u32 data, u32 flags);
575 /* The version structure of this protocol implementation */
576 char drx_dap_drxj_module_name[] = "DRXJ Data Access Protocol";
577 char drx_dap_drxj_version_text[] = "0.0.0";
579 struct drx_version drx_dap_drxj_version = {
580 DRX_MODULE_DAP, /**< type identifier of the module */
581 drx_dap_drxj_module_name, /**< name or description of module */
583 0, /**< major version number */
584 0, /**< minor version number */
585 0, /**< patch version number */
586 drx_dap_drxj_version_text /**< version as text string */
589 /* The structure containing the protocol interface */
590 struct drx_access_func drx_dap_drxj_funct_g = {
591 &drx_dap_drxj_version,
592 drxj_dap_write_block, /* Supported */
593 drxj_dap_read_block, /* Supported */
594 drxj_dap_write_reg8, /* Not supported */
595 drxj_dap_read_reg8, /* Not supported */
596 drxj_dap_read_modify_write_reg8, /* Not supported */
597 drxj_dap_write_reg16, /* Supported */
598 drxj_dap_read_reg16, /* Supported */
599 drxj_dap_read_modify_write_reg16, /* Supported */
600 drxj_dap_write_reg32, /* Supported */
601 drxj_dap_read_reg32, /* Supported */
602 drxj_dap_read_modify_write_reg32, /* Not supported */
607 * /brief The driver functions of the drxj
609 struct drx_demod_func drxj_functions_g = {
616 struct drxj_data drxj_data_g = {
617 false, /* has_lna : true if LNA (aka PGA) present */
618 false, /* has_oob : true if OOB supported */
619 false, /* has_ntsc: true if NTSC supported */
620 false, /* has_btsc: true if BTSC supported */
621 false, /* has_smatx: true if SMA_TX pin is available */
622 false, /* has_smarx: true if SMA_RX pin is available */
623 false, /* has_gpio : true if GPIO pin is available */
624 false, /* has_irqn : true if IRQN pin is available */
625 0, /* mfx A1/A2/A... */
628 false, /* tuner mirrors RF signal */
629 /* standard/channel settings */
630 DRX_STANDARD_UNKNOWN, /* current standard */
631 DRX_CONSTELLATION_AUTO, /* constellation */
632 0, /* frequency in KHz */
633 DRX_BANDWIDTH_UNKNOWN, /* curr_bandwidth */
634 DRX_MIRROR_NO, /* mirror */
636 /* signal quality information: */
637 /* default values taken from the QAM Programming guide */
638 /* fec_bits_desired should not be less than 4000000 */
639 4000000, /* fec_bits_desired */
641 4, /* qam_vd_prescale */
642 0xFFFF, /* qamVDPeriod */
643 204 * 8, /* fec_rs_plen annex A */
644 1, /* fec_rs_prescale */
645 FEC_RS_MEASUREMENT_PERIOD, /* fec_rs_period */
646 true, /* reset_pkt_err_acc */
647 0, /* pkt_err_acc_start */
649 /* HI configuration */
650 0, /* hi_cfg_timing_div */
651 0, /* hi_cfg_bridge_delay */
652 0, /* hi_cfg_wake_up_key */
654 0, /* HICfgTimeout */
655 /* UIO configuartion */
656 DRX_UIO_MODE_DISABLE, /* uio_sma_rx_mode */
657 DRX_UIO_MODE_DISABLE, /* uio_sma_tx_mode */
658 DRX_UIO_MODE_DISABLE, /* uioASELMode */
659 DRX_UIO_MODE_DISABLE, /* uio_irqn_mode */
661 0UL, /* iqm_fs_rate_ofs */
662 false, /* pos_image */
664 0UL, /* iqm_rc_rate_ofs */
665 /* AUD information */
666 /* false, * flagSetAUDdone */
667 /* false, * detectedRDS */
668 /* true, * flagASDRequest */
669 /* false, * flagHDevClear */
670 /* false, * flagHDevSet */
671 /* (u16) 0xFFF, * rdsLastCount */
673 /*#ifdef DRXJ_SPLIT_UCODE_UPLOAD
674 false, * flag_aud_mc_uploaded */
675 /*#endif * DRXJ_SPLIT_UCODE_UPLOAD */
676 /* ATV configuartion */
677 0UL, /* flags cfg changes */
678 /* shadow of ATV_TOP_EQU0__A */
680 ATV_TOP_EQU0_EQU_C0_FM,
681 ATV_TOP_EQU0_EQU_C0_L,
682 ATV_TOP_EQU0_EQU_C0_LP,
683 ATV_TOP_EQU0_EQU_C0_BG,
684 ATV_TOP_EQU0_EQU_C0_DK,
685 ATV_TOP_EQU0_EQU_C0_I},
686 /* shadow of ATV_TOP_EQU1__A */
688 ATV_TOP_EQU1_EQU_C1_FM,
689 ATV_TOP_EQU1_EQU_C1_L,
690 ATV_TOP_EQU1_EQU_C1_LP,
691 ATV_TOP_EQU1_EQU_C1_BG,
692 ATV_TOP_EQU1_EQU_C1_DK,
693 ATV_TOP_EQU1_EQU_C1_I},
694 /* shadow of ATV_TOP_EQU2__A */
696 ATV_TOP_EQU2_EQU_C2_FM,
697 ATV_TOP_EQU2_EQU_C2_L,
698 ATV_TOP_EQU2_EQU_C2_LP,
699 ATV_TOP_EQU2_EQU_C2_BG,
700 ATV_TOP_EQU2_EQU_C2_DK,
701 ATV_TOP_EQU2_EQU_C2_I},
702 /* shadow of ATV_TOP_EQU3__A */
704 ATV_TOP_EQU3_EQU_C3_FM,
705 ATV_TOP_EQU3_EQU_C3_L,
706 ATV_TOP_EQU3_EQU_C3_LP,
707 ATV_TOP_EQU3_EQU_C3_BG,
708 ATV_TOP_EQU3_EQU_C3_DK,
709 ATV_TOP_EQU3_EQU_C3_I},
710 false, /* flag: true=bypass */
711 ATV_TOP_VID_PEAK__PRE, /* shadow of ATV_TOP_VID_PEAK__A */
712 ATV_TOP_NOISE_TH__PRE, /* shadow of ATV_TOP_NOISE_TH__A */
713 true, /* flag CVBS ouput enable */
714 false, /* flag SIF ouput enable */
715 DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
716 { /* qam_rf_agc_cfg */
717 DRX_STANDARD_ITU_B, /* standard */
718 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
719 0, /* output_level */
720 0, /* min_output_level */
721 0xFFFF, /* max_output_level */
726 { /* qam_if_agc_cfg */
727 DRX_STANDARD_ITU_B, /* standard */
728 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
729 0, /* output_level */
730 0, /* min_output_level */
731 0xFFFF, /* max_output_level */
733 0x0000, /* top (don't care) */
734 0x0000 /* c.o.c. (don't care) */
736 { /* vsb_rf_agc_cfg */
737 DRX_STANDARD_8VSB, /* standard */
738 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
739 0, /* output_level */
740 0, /* min_output_level */
741 0xFFFF, /* max_output_level */
743 0x0000, /* top (don't care) */
744 0x0000 /* c.o.c. (don't care) */
746 { /* vsb_if_agc_cfg */
747 DRX_STANDARD_8VSB, /* standard */
748 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
749 0, /* output_level */
750 0, /* min_output_level */
751 0xFFFF, /* max_output_level */
753 0x0000, /* top (don't care) */
754 0x0000 /* c.o.c. (don't care) */
758 { /* qam_pre_saw_cfg */
759 DRX_STANDARD_ITU_B, /* standard */
761 false /* use_pre_saw */
763 { /* vsb_pre_saw_cfg */
764 DRX_STANDARD_8VSB, /* standard */
766 false /* use_pre_saw */
769 /* Version information */
772 "01234567890", /* human readable version microcode */
773 "01234567890" /* human readable version device specific code */
776 { /* struct drx_version for microcode */
784 { /* struct drx_version for device specific code */
794 { /* struct drx_version_list for microcode */
795 (struct drx_version *) (NULL),
796 (struct drx_version_list *) (NULL)
798 { /* struct drx_version_list for device specific code */
799 (struct drx_version *) (NULL),
800 (struct drx_version_list *) (NULL)
804 false, /* smart_ant_inverted */
805 /* Tracking filter setting for OOB */
815 false, /* oob_power_on */
816 0, /* mpeg_ts_static_bitrate */
817 false, /* disable_te_ihandling */
818 false, /* bit_reverse_mpeg_outout */
819 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO, /* mpeg_output_clock_rate */
820 DRXJ_MPEG_START_WIDTH_1CLKCYC, /* mpeg_start_width */
822 /* Pre SAW & Agc configuration for ATV */
824 DRX_STANDARD_NTSC, /* standard */
826 true /* use_pre_saw */
829 DRX_STANDARD_NTSC, /* standard */
830 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
831 0, /* output_level */
832 0, /* min_output_level (d.c.) */
833 0, /* max_output_level (d.c.) */
836 4000 /* cut-off current */
839 DRX_STANDARD_NTSC, /* standard */
840 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
841 0, /* output_level */
842 0, /* min_output_level (d.c.) */
843 0, /* max_output_level (d.c.) */
846 0 /* c.o.c. (d.c.) */
848 140, /* ATV PGA config */
849 0, /* curr_symbol_rate */
851 false, /* pdr_safe_mode */
852 SIO_PDR_GPIO_CFG__PRE, /* pdr_safe_restore_val_gpio */
853 SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
854 SIO_PDR_SMA_RX_CFG__PRE, /* pdr_safe_restore_val_sma_rx */
855 SIO_PDR_SMA_TX_CFG__PRE, /* pdr_safe_restore_val_sma_tx */
858 DRXJ_OOB_LO_POW_MINUS10DB, /* oob_lo_pow */
860 false /* aud_data, only first member */
865 * \var drxj_default_addr_g
866 * \brief Default I2C address and device identifier.
868 struct i2c_device_addr drxj_default_addr_g = {
869 DRXJ_DEF_I2C_ADDR, /* i2c address */
870 DRXJ_DEF_DEMOD_DEV_ID /* device id */
874 * \var drxj_default_comm_attr_g
875 * \brief Default common attributes of a drxj demodulator instance.
877 struct drx_common_attr drxj_default_comm_attr_g = {
878 (u8 *)NULL, /* ucode ptr */
879 true, /* ucode verify switch */
880 {0}, /* version record */
882 44000, /* IF in kHz in case no tuner instance is used */
883 (151875 - 0), /* system clock frequency in kHz */
884 0, /* oscillator frequency kHz */
885 0, /* oscillator deviation in ppm, signed */
886 false, /* If true mirror frequency spectrum */
888 /* MPEG output configuration */
889 true, /* If true, enable MPEG ouput */
890 false, /* If true, insert RS byte */
891 true, /* If true, parallel out otherwise serial */
892 false, /* If true, invert DATA signals */
893 false, /* If true, invert ERR signal */
894 false, /* If true, invert STR signals */
895 false, /* If true, invert VAL signals */
896 false, /* If true, invert CLK signals */
897 true, /* If true, static MPEG clockrate will
898 be used, otherwise clockrate will
899 adapt to the bitrate of the TS */
900 19392658UL, /* Maximum bitrate in b/s in case
901 static clockrate is selected */
902 DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
904 /* Initilisations below can be ommited, they require no user input and
905 are initialy 0, NULL or false. The compiler will initialize them to these
906 values when ommited. */
907 false, /* is_opened */
910 NULL, /* no scan params yet */
911 0, /* current scan index */
912 0, /* next scan frequency */
913 false, /* scan ready flag */
914 0, /* max channels to scan */
915 0, /* nr of channels scanned */
916 NULL, /* default scan function */
917 NULL, /* default context pointer */
918 0, /* millisec to wait for demod lock */
919 DRXJ_DEMOD_LOCK, /* desired lock */
922 /* Power management */
926 1, /* nr of I2C port to wich tuner is */
927 0L, /* minimum RF input frequency, in kHz */
928 0L, /* maximum RF input frequency, in kHz */
929 false, /* Rf Agc Polarity */
930 false, /* If Agc Polarity */
931 false, /* tuner slow mode */
933 { /* current channel (all 0) */
934 0UL /* channel.frequency */
936 DRX_STANDARD_UNKNOWN, /* current standard */
937 DRX_STANDARD_UNKNOWN, /* previous standard */
938 DRX_STANDARD_UNKNOWN, /* di_cache_standard */
939 false, /* use_bootloader */
940 0UL, /* capabilities */
945 * \var drxj_default_demod_g
946 * \brief Default drxj demodulator instance.
948 struct drx_demod_instance drxj_default_demod_g = {
949 &drxj_functions_g, /* demod functions */
950 &DRXJ_DAP, /* data access protocol functions */
951 NULL, /* tuner instance */
952 &drxj_default_addr_g, /* i2c address & device id */
953 &drxj_default_comm_attr_g, /* demod common attributes */
954 &drxj_data_g /* demod device specific attributes */
958 * \brief Default audio data structure for DRK demodulator instance.
960 * This structure is DRXK specific.
963 struct drx_aud_data drxj_default_aud_data_g = {
964 false, /* audio_is_active */
965 DRX_AUD_STANDARD_AUTO, /* audio_standard */
969 false, /* output_enable */
970 48000, /* frequency */
971 DRX_I2S_MODE_MASTER, /* mode */
972 DRX_I2S_WORDLENGTH_32, /* word_length */
973 DRX_I2S_POLARITY_RIGHT, /* polarity */
974 DRX_I2S_FORMAT_WS_WITH_DATA /* format */
980 DRX_AUD_AVC_OFF, /* avc_mode */
981 0, /* avc_ref_level */
982 DRX_AUD_AVC_MAX_GAIN_12DB, /* avc_max_gain */
983 DRX_AUD_AVC_MAX_ATTEN_24DB, /* avc_max_atten */
984 0, /* strength_left */
985 0 /* strength_right */
987 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
999 DRX_NO_CARRIER_NOISE, /* opt */
1006 DRX_NO_CARRIER_MUTE, /* opt */
1014 DRX_AUD_SRC_STEREO_OR_A, /* source_i2s */
1015 DRX_AUD_I2S_MATRIX_STEREO, /* matrix_i2s */
1016 DRX_AUD_FM_MATRIX_SOUND_A /* matrix_fm */
1018 DRX_AUD_DEVIATION_NORMAL, /* deviation */
1019 DRX_AUD_AVSYNC_OFF, /* av_sync */
1023 DRX_AUD_MAX_FM_DEVIATION, /* fm_deviation */
1024 DRX_AUD_MAX_NICAM_PRESCALE /* nicam_gain */
1026 DRX_AUD_FM_DEEMPH_75US, /* deemph */
1027 DRX_BTSC_STEREO, /* btsc_detect */
1028 0, /* rds_data_counter */
1029 false /* rds_data_present */
1032 /*-----------------------------------------------------------------------------
1034 ----------------------------------------------------------------------------*/
1035 struct drxjeq_stat {
1043 struct drxj_hi_cmd {
1053 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1054 /*============================================================================*/
1055 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
1056 /*============================================================================*/
1058 struct drxu_code_block_hdr {
1061 u16 flags; /* bit[15..2]=reserved,
1062 bit[1]= compression on/off
1063 bit[0]= CRC on/off */
1066 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1068 /*-----------------------------------------------------------------------------
1070 ----------------------------------------------------------------------------*/
1071 /* Some prototypes */
1073 hi_command(struct i2c_device_addr *dev_addr,
1074 const struct drxj_hi_cmd *cmd, u16 *result);
1077 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
1080 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
1082 static int power_down_aud(struct drx_demod_instance *demod);
1084 #ifndef DRXJ_DIGITAL_ONLY
1085 static int power_up_aud(struct drx_demod_instance *demod, bool set_standard);
1089 aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard);
1092 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1095 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
1097 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1099 ctrl_u_code_upload(struct drx_demod_instance *demod,
1100 struct drxu_code_info *mc_info,
1101 enum drxu_code_actionaction, bool audio_mc_upload);
1102 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1104 /*============================================================================*/
1105 /*============================================================================*/
1106 /*== HELPER FUNCTIONS ==*/
1107 /*============================================================================*/
1108 /*============================================================================*/
1111 * \fn void mult32(u32 a, u32 b, u32 *h, u32 *l)
1112 * \brief 32bitsx32bits signed multiplication
1113 * \param a 32 bits multiplicant, typecast from signed to unisgned
1114 * \param b 32 bits multiplier, typecast from signed to unisgned
1115 * \param h pointer to high part 64 bits result, typecast from signed to unisgned
1116 * \param l pointer to low part 64 bits result
1118 * For the 2n+n addition a + b:
1119 * if a >= 0, then h += 0 (sign extension = 0)
1120 * but if a < 0, then h += 2^n-1 ==> h -= 1.
1122 * Also, if a + b < 2^n, then a + b >= a && a + b >= b
1123 * but if a + b >= 2^n, then R = a + b - 2^n,
1124 * and because a < 2^n && b < 2*n ==> R < a && R < b.
1125 * Therefore, to detect overflow, simply compare the addition result with
1126 * one of the operands; if the result is smaller, overflow has occurred and
1127 * h must be incremented.
1129 * Booth multiplication uses additions and subtractions to reduce the number
1130 * of iterations. This is done by taking three subsequent bits abc and calculating
1131 * the following multiplication factor: -2a + b + c. This factor is multiplied
1132 * by the second operand and added to the result. Next, the first operand is
1133 * shifted two bits (hence one of the three bits is reused) and the process
1134 * repeated. The last iteration has only two bits left, but we simply add
1135 * a zero to the end.
1138 * 1 * a = 0 * 4a + 1 * a
1139 * 2 * a = 1 * 4a - 2 * a
1140 * 3 * a = 1 * 4a - 1 * a
1141 * -1 * a = 0 * 4a - 1 * a
1142 * -5 * a = -1 * 4a - 1 * a
1146 * Note that the function is type size independent. Any unsigned integer type
1147 * can be substituted for booth_t.
1151 #define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof(u32) * 8 - 1))) != 0)
1153 static void mult32(u32 a, u32 b, u32 *h, u32 *l)
1158 /* n/2 iterations; shift operand a left two bits after each iteration. */
1159 /* This automatically appends a zero to the operand for the last iteration. */
1160 for (i = 0; i < sizeof(a) * 8; i += 2, a = a << 2) {
1161 /* Shift result left two bits */
1162 *h = (*h << 2) + (*l >> (sizeof(*l) * 8 - 2));
1165 /* Take the first three bits of operand a for the Booth conversion: */
1166 /* 0, 7: do nothing */
1169 /* 4 : subtract 2b */
1170 /* 5, 6: subtract b */
1171 switch (a >> (sizeof(a) * 8 - 3)) {
1174 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1178 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1182 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1190 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1200 /*============================================================================*/
1203 * \fn u32 frac28(u32 N, u32 D)
1204 * \brief Compute: (1<<28)*N/D
1207 * \return (1<<28)*N/D
1208 * This function is used to avoid floating-point calculations as they may
1209 * not be present on the target platform.
1211 * frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1212 * fraction used for setting the Frequency Shifter registers.
1213 * N and D can hold numbers up to width: 28-bits.
1214 * The 4 bits integer part and the 28 bits fractional part are calculated.
1216 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1218 * N: 0...(1<<28)-1 = 268435454
1222 static u32 frac28(u32 N, u32 D)
1228 R0 = (N % D) << 4; /* 32-28 == 4 shifts possible at max */
1229 Q1 = N / D; /* integer part, only the 4 least significant bits
1230 will be visible in the result */
1232 /* division using radix 16, 7 nibbles in the result */
1233 for (i = 0; i < 7; i++) {
1234 Q1 = (Q1 << 4) | R0 / D;
1245 * \fn u32 log1_times100( u32 x)
1246 * \brief Compute: 100*log10(x)
1248 * \return 100*log10(x)
1251 * = 100*(log2(x)/log2(10)))
1252 * = (100*(2^15)*log2(x))/((2^15)*log2(10))
1253 * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1254 * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1255 * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1257 * where y = 2^k and 1<= (x/y) < 2
1260 static u32 log1_times100(u32 x)
1262 static const u8 scale = 15;
1263 static const u8 index_width = 5;
1265 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1266 0 <= n < ((1<<INDEXWIDTH)+1)
1269 static const u32 log2lut[] = {
1271 290941, /* 290941.300628 */
1272 573196, /* 573196.476418 */
1273 847269, /* 847269.179851 */
1274 1113620, /* 1113620.489452 */
1275 1372674, /* 1372673.576986 */
1276 1624818, /* 1624817.752104 */
1277 1870412, /* 1870411.981536 */
1278 2109788, /* 2109787.962654 */
1279 2343253, /* 2343252.817465 */
1280 2571091, /* 2571091.461923 */
1281 2793569, /* 2793568.696416 */
1282 3010931, /* 3010931.055901 */
1283 3223408, /* 3223408.452106 */
1284 3431216, /* 3431215.635215 */
1285 3634553, /* 3634553.498355 */
1286 3833610, /* 3833610.244726 */
1287 4028562, /* 4028562.434393 */
1288 4219576, /* 4219575.925308 */
1289 4406807, /* 4406806.721144 */
1290 4590402, /* 4590401.736809 */
1291 4770499, /* 4770499.491025 */
1292 4947231, /* 4947230.734179 */
1293 5120719, /* 5120719.018555 */
1294 5291081, /* 5291081.217197 */
1295 5458428, /* 5458427.996830 */
1296 5622864, /* 5622864.249668 */
1297 5784489, /* 5784489.488298 */
1298 5943398, /* 5943398.207380 */
1299 6099680, /* 6099680.215452 */
1300 6253421, /* 6253420.939751 */
1301 6404702, /* 6404701.706649 */
1302 6553600, /* 6553600.000000 */
1314 /* Scale x (normalize) */
1315 /* computing y in log(x/y) = log(x) - log(y) */
1316 if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
1317 for (k = scale; k > 0; k--) {
1318 if (x & (((u32) 1) << scale))
1323 for (k = scale; k < 31; k++) {
1324 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
1330 Now x has binary point between bit[scale] and bit[scale-1]
1331 and 1.0 <= x < 2.0 */
1333 /* correction for divison: log(x) = log(x/y)+log(y) */
1334 y = k * ((((u32) 1) << scale) * 200);
1336 /* remove integer part */
1337 x &= ((((u32) 1) << scale) - 1);
1339 i = (u8) (x >> (scale - index_width));
1340 /* compute delta (x-a) */
1341 d = x & ((((u32) 1) << (scale - index_width)) - 1);
1342 /* compute log, multiplication ( d* (.. )) must be within range ! */
1344 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
1345 /* Conver to log10() */
1346 y /= 108853; /* (log2(10) << scale) */
1357 * \fn u32 frac_times1e6( u16 N, u32 D)
1358 * \brief Compute: (N/D) * 1000000.
1359 * \param N nominator 16-bits.
1360 * \param D denominator 32-bits.
1362 * \retval ((N/D) * 1000000), 32 bits
1366 static u32 frac_times1e6(u32 N, u32 D)
1372 frac = (N * 1000000) / D
1373 To let it fit in a 32 bits computation:
1374 frac = (N * (1000000 >> 4)) / (D >> 4)
1375 This would result in a problem in case D < 16 (div by 0).
1376 So we do it more elaborate as shown below.
1378 frac = (((u32) N) * (1000000 >> 4)) / D;
1380 remainder = (((u32) N) * (1000000 >> 4)) % D;
1382 frac += remainder / D;
1383 remainder = remainder % D;
1384 if ((remainder * 2) > D)
1390 /*============================================================================*/
1393 * \brief Compute: 100 * 10^( gd_b / 200 ).
1394 * \param u32 gd_b Gain in 0.1dB
1395 * \return u32 Gainfactor in 0.01 resolution
1398 static u32 d_b2lin_times100(u32 gd_b)
1401 u32 nr6d_b_steps = 0;
1403 u32 remainder_fac = 0;
1405 /* start with factors 2 (6.02dB) */
1406 nr6d_b_steps = gd_b * 1000UL / 60206UL;
1407 if (nr6d_b_steps > 17) {
1408 /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
1411 result = (1 << nr6d_b_steps);
1413 /* calculate remaining factor,
1414 poly approximation of 10^(gd_b/200):
1416 y = 1E-04x2 + 0.0106x + 1.0026
1418 max deviation < 0.005 for range x = [0 ... 60]
1420 remainder = ((gd_b * 1000UL) % 60206UL) / 1000UL;
1421 /* using 1e-4 for poly calculation */
1422 remainder_fac = 1 * remainder * remainder;
1423 remainder_fac += 106 * remainder;
1424 remainder_fac += 10026;
1426 /* multiply by remaining factor */
1427 result *= remainder_fac;
1429 /* conversion from 1e-4 to 1e-2 */
1430 return (result + 50) / 100;
1433 #ifndef DRXJ_DIGITAL_ONLY
1434 #define FRAC_FLOOR 0
1436 #define FRAC_ROUND 2
1438 * \fn u32 frac( u32 N, u32 D, u16 RC )
1439 * \brief Compute: N/D.
1440 * \param N nominator 32-bits.
1441 * \param D denominator 32-bits.
1442 * \param RC-result correction: 0-floor; 1-ceil; 2-round
1444 * \retval N/D, 32 bits
1448 static u32 frac(u32 N, u32 D, u16 RC)
1467 while (bit_cnt-- > 0) {
1469 remainder |= ((frac & 0x80000000) >> 31);
1471 if (remainder < D) {
1479 /* result correction if needed */
1480 if ((RC == FRAC_CEIL) && (remainder != 0)) {
1481 /* ceil the result */
1482 /*(remainder is not zero -> value behind decimal point exists) */
1485 if ((RC == FRAC_ROUND) && (remainder >= D >> 1)) {
1486 /* remainder is bigger from D/2 -> round the result */
1495 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1496 /*============================================================================*/
1499 * \fn u16 u_code_read16( u8 *addr)
1500 * \brief Read a 16 bits word, expect big endian data.
1501 * \return u16 The data read.
1503 static u16 u_code_read16(u8 *addr)
1505 /* Works fo any host processor */
1509 word = ((u16) addr[0]);
1511 word |= ((u16) addr[1]);
1516 /*============================================================================*/
1519 * \fn u32 u_code_read32( u8 *addr)
1520 * \brief Read a 32 bits word, expect big endian data.
1521 * \return u32 The data read.
1523 static u32 u_code_read32(u8 *addr)
1525 /* Works fo any host processor */
1529 word = ((u16) addr[0]);
1531 word |= ((u16) addr[1]);
1533 word |= ((u16) addr[2]);
1535 word |= ((u16) addr[3]);
1540 /*============================================================================*/
1543 * \fn u16 u_code_compute_crc (u8 *block_data, u16 nr_words)
1544 * \brief Compute CRC of block of microcode data.
1545 * \param block_data Pointer to microcode data.
1546 * \param nr_words Size of microcode block (number of 16 bits words).
1547 * \return u16 The computed CRC residu.
1549 static u16 u_code_compute_crc(u8 *block_data, u16 nr_words)
1556 while (i < nr_words) {
1557 crc_word |= (u32) u_code_read16(block_data);
1558 for (j = 0; j < 16; j++) {
1561 crc_word ^= 0x80050000UL;
1562 carry = crc_word & 0x80000000UL;
1565 block_data += (sizeof(u16));
1567 return (u16)(crc_word >> 16);
1569 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1572 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1573 * and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1576 static const u16 nicam_presc_table_val[43] = {
1577 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1578 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1579 18, 20, 23, 25, 28, 32, 36, 40, 45,
1580 51, 57, 64, 71, 80, 90, 101, 113, 127
1583 /*============================================================================*/
1584 /*== END HELPER FUNCTIONS ==*/
1585 /*============================================================================*/
1587 /*============================================================================*/
1588 /*============================================================================*/
1589 /*== DRXJ DAP FUNCTIONS ==*/
1590 /*============================================================================*/
1591 /*============================================================================*/
1594 This layer takes care of some device specific register access protocols:
1595 -conversion to short address format
1596 -access to audio block
1597 This layer is placed between the drx_dap_fasi and the rest of the drxj
1598 specific implementation. This layer can use address map knowledge whereas
1599 dap_fasi may not use memory map knowledge.
1601 * For audio currently only 16 bits read and write register access is
1602 supported. More is not needed. RMW and 32 or 8 bit access on audio
1603 registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1604 single/multi master) will be ignored.
1606 TODO: check ignoring single/multimaster is ok for AUD access ?
1609 #define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1610 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
1611 /*============================================================================*/
1614 * \fn bool is_handled_by_aud_tr_if( u32 addr )
1615 * \brief Check if this address is handled by the audio token ring interface.
1618 * \retval true Yes, handled by audio token ring interface
1619 * \retval false No, not handled by audio token ring interface
1623 bool is_handled_by_aud_tr_if(u32 addr)
1625 bool retval = false;
1627 if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1628 (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1629 (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1636 /*============================================================================*/
1638 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
1641 u8 *data, u32 flags)
1643 return drx_dap_fasi_funct_g.read_block_func(dev_addr,
1644 addr, datasize, data, flags);
1647 /*============================================================================*/
1649 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
1652 u8 wdata, u8 *rdata)
1654 return drx_dap_fasi_funct_g.read_modify_write_reg8func(dev_addr,
1656 raddr, wdata, rdata);
1659 /*============================================================================*/
1662 * \fn int drxj_dap_rm_write_reg16short
1663 * \brief Read modify write 16 bits audio register using short format only.
1665 * \param waddr Address to write to
1666 * \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1667 * \param wdata Data to write
1668 * \param rdata Buffer for data to read
1671 * \retval -EIO Timeout, I2C error, illegal bank
1673 * 16 bits register read modify write access using short addressing format only.
1674 * Requires knowledge of the registermap, thus device dependent.
1675 * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1679 /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1680 See comments drxj_dap_read_modify_write_reg16 */
1681 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
1682 static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1685 u16 wdata, u16 *rdata)
1693 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1694 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1695 SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1698 /* Write new data: triggers RMW */
1699 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr, waddr, wdata,
1704 rc = drx_dap_fasi_funct_g.read_reg16func(dev_addr, raddr, rdata,
1708 /* Reset RMW flag */
1709 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1710 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1718 /*============================================================================*/
1720 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1723 u16 wdata, u16 *rdata)
1725 /* TODO: correct short/long addressing format decision,
1726 now long format has higher prio then short because short also
1727 needs virt bnks (not impl yet) for certain audio registers */
1728 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1729 return drx_dap_fasi_funct_g.read_modify_write_reg16func(dev_addr,
1731 raddr, wdata, rdata);
1733 return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
1737 /*============================================================================*/
1739 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
1742 u32 wdata, u32 *rdata)
1744 return drx_dap_fasi_funct_g.read_modify_write_reg32func(dev_addr,
1746 raddr, wdata, rdata);
1749 /*============================================================================*/
1751 static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
1753 u8 *data, u32 flags)
1755 return drx_dap_fasi_funct_g.read_reg8func(dev_addr, addr, data, flags);
1758 /*============================================================================*/
1761 * \fn int drxj_dap_read_aud_reg16
1762 * \brief Read 16 bits audio register
1768 * \retval -EIO Timeout, I2C error, illegal bank
1770 * 16 bits register read access via audio token ring interface.
1773 static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1774 u32 addr, u16 *data)
1776 u32 start_timer = 0;
1777 u32 current_timer = 0;
1778 u32 delta_timer = 0;
1782 /* No read possible for bank 3, return with error */
1783 if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1786 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1788 /* Force reset write bit */
1789 addr &= (~write_bit);
1792 start_timer = drxbsp_hst_clock();
1794 /* RMW to aud TR IF until request is granted or timeout */
1795 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1797 SIO_HI_RA_RAM_S0_RMWBUF__A,
1798 0x0000, &tr_status);
1803 current_timer = drxbsp_hst_clock();
1804 delta_timer = current_timer - start_timer;
1805 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1810 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1811 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1812 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1813 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1814 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1816 /* Wait for read ready status or timeout */
1818 start_timer = drxbsp_hst_clock();
1820 while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1821 AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1822 stat = drxj_dap_read_reg16(dev_addr,
1824 &tr_status, 0x0000);
1828 current_timer = drxbsp_hst_clock();
1829 delta_timer = current_timer - start_timer;
1830 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1834 } /* while ( ... ) */
1839 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1840 AUD_TOP_TR_RD_REG__A,
1841 SIO_HI_RA_RAM_S0_RMWBUF__A,
1846 /*============================================================================*/
1848 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1850 u16 *data, u32 flags)
1855 if ((dev_addr == NULL) || (data == NULL))
1858 if (is_handled_by_aud_tr_if(addr))
1859 stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
1861 stat = drx_dap_fasi_funct_g.read_reg16func(dev_addr,
1867 /*============================================================================*/
1869 static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
1871 u32 *data, u32 flags)
1873 return drx_dap_fasi_funct_g.read_reg32func(dev_addr, addr, data, flags);
1876 /*============================================================================*/
1878 static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
1881 u8 *data, u32 flags)
1883 return drx_dap_fasi_funct_g.write_block_func(dev_addr,
1884 addr, datasize, data, flags);
1887 /*============================================================================*/
1889 static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
1893 return drx_dap_fasi_funct_g.write_reg8func(dev_addr, addr, data, flags);
1896 /*============================================================================*/
1899 * \fn int drxj_dap_write_aud_reg16
1900 * \brief Write 16 bits audio register
1906 * \retval -EIO Timeout, I2C error, illegal bank
1908 * 16 bits register write access via audio token ring interface.
1911 static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
1916 /* No write possible for bank 2, return with error */
1917 if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
1920 u32 start_timer = 0;
1921 u32 current_timer = 0;
1922 u32 delta_timer = 0;
1924 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1926 /* Force write bit */
1928 start_timer = drxbsp_hst_clock();
1930 /* RMW to aud TR IF until request is granted or timeout */
1931 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1933 SIO_HI_RA_RAM_S0_RMWBUF__A,
1938 current_timer = drxbsp_hst_clock();
1939 delta_timer = current_timer - start_timer;
1940 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1945 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1946 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1947 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1948 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1950 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
1955 /*============================================================================*/
1957 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
1959 u16 data, u32 flags)
1964 if (dev_addr == NULL)
1967 if (is_handled_by_aud_tr_if(addr))
1968 stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
1970 stat = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1976 /*============================================================================*/
1978 static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
1980 u32 data, u32 flags)
1982 return drx_dap_fasi_funct_g.write_reg32func(dev_addr, addr, data, flags);
1985 /*============================================================================*/
1987 /* Free data ram in SIO HI */
1988 #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
1989 #define SIO_HI_RA_RAM_USR_END__A 0x420060
1991 #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
1992 #define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
1993 #define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
1994 #define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
1997 * \fn int drxj_dap_atomic_read_write_block()
1998 * \brief Basic access routine for atomic read or write access
1999 * \param dev_addr pointer to i2c dev address
2000 * \param addr destination/source address
2001 * \param datasize size of data buffer in bytes
2002 * \param data pointer to data buffer
2005 * \retval -EIO Timeout, I2C error, illegal bank
2009 int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2012 u8 *data, bool read_flag)
2014 struct drxj_hi_cmd hi_cmd;
2020 /* Parameter check */
2021 if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
2024 /* Set up HI parameters to read or write n bytes */
2025 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2027 (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2028 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2030 (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2031 hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2033 hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2035 hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
2036 hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2037 DRXDAP_FASI_ADDR2BANK(addr));
2038 hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
2041 /* write data to buffer */
2042 for (i = 0; i < (datasize / 2); i++) {
2044 word = ((u16) data[2 * i]);
2045 word += (((u16) data[(2 * i) + 1]) << 8);
2046 drxj_dap_write_reg16(dev_addr,
2047 (DRXJ_HI_ATOMIC_BUF_START + i),
2052 rc = hi_command(dev_addr, &hi_cmd, &dummy);
2054 pr_err("error %d\n", rc);
2059 /* read data from buffer */
2060 for (i = 0; i < (datasize / 2); i++) {
2061 drxj_dap_read_reg16(dev_addr,
2062 (DRXJ_HI_ATOMIC_BUF_START + i),
2064 data[2 * i] = (u8) (word & 0xFF);
2065 data[(2 * i) + 1] = (u8) (word >> 8);
2076 /*============================================================================*/
2079 * \fn int drxj_dap_atomic_read_reg32()
2080 * \brief Atomic read of 32 bits words
2083 int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2085 u32 *data, u32 flags)
2087 u8 buf[sizeof(*data)];
2094 rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
2095 sizeof(*data), buf, true);
2100 word = (u32) buf[3];
2102 word |= (u32) buf[2];
2104 word |= (u32) buf[1];
2106 word |= (u32) buf[0];
2113 /*============================================================================*/
2115 /*============================================================================*/
2116 /*== END DRXJ DAP FUNCTIONS ==*/
2117 /*============================================================================*/
2119 /*============================================================================*/
2120 /*============================================================================*/
2121 /*== HOST INTERFACE FUNCTIONS ==*/
2122 /*============================================================================*/
2123 /*============================================================================*/
2126 * \fn int hi_cfg_command()
2127 * \brief Configure HI with settings stored in the demod structure.
2128 * \param demod Demodulator.
2131 * This routine was created because to much orthogonal settings have
2132 * been put into one HI API function (configure). Especially the I2C bridge
2133 * enable/disable should not need re-configuration of the HI.
2136 static int hi_cfg_command(const struct drx_demod_instance *demod)
2138 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2139 struct drxj_hi_cmd hi_cmd;
2143 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2145 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2146 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2147 hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2148 hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2149 hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2150 hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2151 hi_cmd.param6 = ext_attr->hi_cfg_transmit;
2153 rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
2155 pr_err("error %d\n", rc);
2159 /* Reset power down flag (set one call only) */
2160 ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2169 * \fn int hi_command()
2170 * \brief Configure HI with settings stored in the demod structure.
2171 * \param dev_addr I2C address.
2172 * \param cmd HI command.
2173 * \param result HI command result.
2176 * Sends command to HI
2180 hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
2184 bool powerdown_cmd = false;
2187 /* Write parameters */
2190 case SIO_HI_RA_RAM_CMD_CONFIG:
2191 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2192 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
2194 pr_err("error %d\n", rc);
2197 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
2199 pr_err("error %d\n", rc);
2202 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
2204 pr_err("error %d\n", rc);
2207 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
2209 pr_err("error %d\n", rc);
2213 case SIO_HI_RA_RAM_CMD_BRDCTRL:
2214 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
2216 pr_err("error %d\n", rc);
2219 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
2221 pr_err("error %d\n", rc);
2225 case SIO_HI_RA_RAM_CMD_NULL:
2235 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
2237 pr_err("error %d\n", rc);
2241 if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
2242 drxbsp_hst_sleep(1);
2244 /* Detect power down to ommit reading result */
2245 powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2247 param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2248 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2249 if (!powerdown_cmd) {
2250 /* Wait until command rdy */
2253 if (nr_retries > DRXJ_MAX_RETRIES) {
2254 pr_err("timeout\n");
2258 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
2260 pr_err("error %d\n", rc);
2263 } while (wait_cmd != 0);
2266 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
2268 pr_err("error %d\n", rc);
2273 /* if ( powerdown_cmd == true ) */
2280 * \fn int init_hi( const struct drx_demod_instance *demod )
2281 * \brief Initialise and configurate HI.
2282 * \param demod pointer to demod data.
2283 * \return int Return status.
2284 * \retval 0 Success.
2285 * \retval -EIO Failure.
2287 * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2288 * Need to store configuration in driver because of the way I2C
2289 * bridging is controlled.
2292 static int init_hi(const struct drx_demod_instance *demod)
2294 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2295 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2296 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2299 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2300 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2301 dev_addr = demod->my_i2c_dev_addr;
2303 /* PATCH for bug 5003, HI ucode v3.1.0 */
2304 rc = DRXJ_DAP.write_reg16func(dev_addr, 0x4301D7, 0x801, 0);
2306 pr_err("error %d\n", rc);
2310 /* Timing div, 250ns/Psys */
2311 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2312 ext_attr->hi_cfg_timing_div =
2313 (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
2315 if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
2316 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2317 /* Bridge delay, uses oscilator clock */
2318 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2319 /* SDA brdige delay */
2320 ext_attr->hi_cfg_bridge_delay =
2321 (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
2324 if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
2325 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2326 /* SCL bridge delay, same as SDA for now */
2327 ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
2328 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2329 /* Wakeup key, setting the read flag (as suggest in the documentation) does
2330 not always result into a working solution (barebones worked VI2C failed).
2331 Not setting the bit works in all cases . */
2332 ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
2333 /* port/bridge/power down ctrl */
2334 ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2335 /* transit mode time out delay and watch dog divider */
2336 ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
2338 rc = hi_cfg_command(demod);
2340 pr_err("error %d\n", rc);
2350 /*============================================================================*/
2351 /*== END HOST INTERFACE FUNCTIONS ==*/
2352 /*============================================================================*/
2354 /*============================================================================*/
2355 /*============================================================================*/
2356 /*== AUXILIARY FUNCTIONS ==*/
2357 /*============================================================================*/
2358 /*============================================================================*/
2361 * \fn int get_device_capabilities()
2362 * \brief Get and store device capabilities.
2363 * \param demod Pointer to demodulator instance.
2366 * \retval -EIO Failure
2368 * Depending on pulldowns on MDx pins the following internals are set:
2369 * * common_attr->osc_clock_freq
2370 * * ext_attr->has_lna
2371 * * ext_attr->has_ntsc
2372 * * ext_attr->has_btsc
2373 * * ext_attr->has_oob
2376 static int get_device_capabilities(struct drx_demod_instance *demod)
2378 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2379 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
2380 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2381 u16 sio_pdr_ohw_cfg = 0;
2382 u32 sio_top_jtagid_lo = 0;
2386 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2387 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2388 dev_addr = demod->my_i2c_dev_addr;
2390 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2392 pr_err("error %d\n", rc);
2395 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
2397 pr_err("error %d\n", rc);
2400 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2402 pr_err("error %d\n", rc);
2406 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2408 /* ignore (bypass ?) */
2412 common_attr->osc_clock_freq = 27000;
2416 common_attr->osc_clock_freq = 20250;
2420 common_attr->osc_clock_freq = 4000;
2427 Determine device capabilities
2428 Based on pinning v47
2430 rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
2432 pr_err("error %d\n", rc);
2435 ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
2437 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
2439 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2441 pr_err("error %d\n", rc);
2444 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
2446 pr_err("error %d\n", rc);
2449 bid = (bid >> 10) & 0xf;
2450 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2452 pr_err("error %d\n", rc);
2456 ext_attr->has_lna = true;
2457 ext_attr->has_ntsc = false;
2458 ext_attr->has_btsc = false;
2459 ext_attr->has_oob = false;
2460 ext_attr->has_smatx = true;
2461 ext_attr->has_smarx = false;
2462 ext_attr->has_gpio = false;
2463 ext_attr->has_irqn = false;
2466 ext_attr->has_lna = false;
2467 ext_attr->has_ntsc = false;
2468 ext_attr->has_btsc = false;
2469 ext_attr->has_oob = false;
2470 ext_attr->has_smatx = true;
2471 ext_attr->has_smarx = false;
2472 ext_attr->has_gpio = false;
2473 ext_attr->has_irqn = false;
2476 ext_attr->has_lna = true;
2477 ext_attr->has_ntsc = true;
2478 ext_attr->has_btsc = false;
2479 ext_attr->has_oob = false;
2480 ext_attr->has_smatx = true;
2481 ext_attr->has_smarx = true;
2482 ext_attr->has_gpio = true;
2483 ext_attr->has_irqn = false;
2486 ext_attr->has_lna = false;
2487 ext_attr->has_ntsc = true;
2488 ext_attr->has_btsc = false;
2489 ext_attr->has_oob = false;
2490 ext_attr->has_smatx = true;
2491 ext_attr->has_smarx = true;
2492 ext_attr->has_gpio = true;
2493 ext_attr->has_irqn = false;
2496 ext_attr->has_lna = true;
2497 ext_attr->has_ntsc = true;
2498 ext_attr->has_btsc = true;
2499 ext_attr->has_oob = false;
2500 ext_attr->has_smatx = true;
2501 ext_attr->has_smarx = true;
2502 ext_attr->has_gpio = true;
2503 ext_attr->has_irqn = false;
2506 ext_attr->has_lna = false;
2507 ext_attr->has_ntsc = true;
2508 ext_attr->has_btsc = true;
2509 ext_attr->has_oob = false;
2510 ext_attr->has_smatx = true;
2511 ext_attr->has_smarx = true;
2512 ext_attr->has_gpio = true;
2513 ext_attr->has_irqn = false;
2516 ext_attr->has_lna = true;
2517 ext_attr->has_ntsc = false;
2518 ext_attr->has_btsc = false;
2519 ext_attr->has_oob = true;
2520 ext_attr->has_smatx = true;
2521 ext_attr->has_smarx = true;
2522 ext_attr->has_gpio = true;
2523 ext_attr->has_irqn = true;
2526 ext_attr->has_lna = false;
2527 ext_attr->has_ntsc = true;
2528 ext_attr->has_btsc = true;
2529 ext_attr->has_oob = true;
2530 ext_attr->has_smatx = true;
2531 ext_attr->has_smarx = true;
2532 ext_attr->has_gpio = true;
2533 ext_attr->has_irqn = true;
2536 ext_attr->has_lna = true;
2537 ext_attr->has_ntsc = true;
2538 ext_attr->has_btsc = true;
2539 ext_attr->has_oob = true;
2540 ext_attr->has_smatx = true;
2541 ext_attr->has_smarx = true;
2542 ext_attr->has_gpio = true;
2543 ext_attr->has_irqn = true;
2546 ext_attr->has_lna = false;
2547 ext_attr->has_ntsc = true;
2548 ext_attr->has_btsc = true;
2549 ext_attr->has_oob = true;
2550 ext_attr->has_smatx = true;
2551 ext_attr->has_smarx = true;
2552 ext_attr->has_gpio = true;
2553 ext_attr->has_irqn = true;
2556 /* Unknown device variant */
2567 * \fn int power_up_device()
2568 * \brief Power up device.
2569 * \param demod Pointer to demodulator instance.
2572 * \retval -EIO Failure, I2C or max retries reached
2576 #ifndef DRXJ_MAX_RETRIES_POWERUP
2577 #define DRXJ_MAX_RETRIES_POWERUP 10
2580 static int power_up_device(struct drx_demod_instance *demod)
2582 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2584 u16 retry_count = 0;
2585 struct i2c_device_addr wake_up_addr;
2587 dev_addr = demod->my_i2c_dev_addr;
2588 wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2589 wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2590 wake_up_addr.user_data = dev_addr->user_data;
2592 * I2C access may fail in this case: no ack
2593 * dummy write must be used to wake uop device, dummy read must be used to
2594 * reset HI state machine (avoiding actual writes)
2598 drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
2599 (struct i2c_device_addr *)(NULL), 0,
2601 drxbsp_hst_sleep(10);
2603 } while ((drxbsp_i2c_write_read
2604 ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
2606 != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
2608 /* Need some recovery time .... */
2609 drxbsp_hst_sleep(10);
2611 if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
2617 /*----------------------------------------------------------------------------*/
2618 /* MPEG Output Configuration Functions - begin */
2619 /*----------------------------------------------------------------------------*/
2621 * \fn int ctrl_set_cfg_mpeg_output()
2622 * \brief Set MPEG output configuration of the device.
2623 * \param devmod Pointer to demodulator instance.
2624 * \param cfg_data Pointer to mpeg output configuaration.
2627 * Configure MPEG output parameters.
2631 ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
2633 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2634 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2635 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2637 u16 fec_oc_reg_mode = 0;
2638 u16 fec_oc_reg_ipr_mode = 0;
2639 u16 fec_oc_reg_ipr_invert = 0;
2640 u32 max_bit_rate = 0;
2643 u16 sio_pdr_md_cfg = 0;
2644 /* data mask for the output data byte */
2645 u16 invert_data_mask =
2646 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2647 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2648 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2649 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2651 /* check arguments */
2652 if ((demod == NULL) || (cfg_data == NULL))
2655 dev_addr = demod->my_i2c_dev_addr;
2656 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2657 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2659 if (cfg_data->enable_mpeg_output == true) {
2660 /* quick and dirty patch to set MPEG incase current std is not
2662 switch (ext_attr->standard) {
2663 case DRX_STANDARD_8VSB:
2664 case DRX_STANDARD_ITU_A:
2665 case DRX_STANDARD_ITU_B:
2666 case DRX_STANDARD_ITU_C:
2669 /* not an MPEG producing std, just store MPEG cfg */
2670 common_attr->mpeg_cfg.enable_mpeg_output =
2671 cfg_data->enable_mpeg_output;
2672 common_attr->mpeg_cfg.insert_rs_byte =
2673 cfg_data->insert_rs_byte;
2674 common_attr->mpeg_cfg.enable_parallel =
2675 cfg_data->enable_parallel;
2676 common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
2677 common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
2678 common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
2679 common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
2680 common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
2681 common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
2682 common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
2686 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
2688 pr_err("error %d\n", rc);
2691 switch (ext_attr->standard) {
2692 case DRX_STANDARD_8VSB:
2693 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
2695 pr_err("error %d\n", rc);
2697 } /* 2048 bytes fifo ram */
2698 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
2700 pr_err("error %d\n", rc);
2703 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
2705 pr_err("error %d\n", rc);
2708 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
2710 pr_err("error %d\n", rc);
2713 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
2715 pr_err("error %d\n", rc);
2718 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
2720 pr_err("error %d\n", rc);
2723 /* Low Water Mark for synchronization */
2724 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
2726 pr_err("error %d\n", rc);
2729 /* High Water Mark for synchronization */
2730 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
2732 pr_err("error %d\n", rc);
2736 case DRX_STANDARD_ITU_A:
2737 case DRX_STANDARD_ITU_C:
2738 switch (ext_attr->constellation) {
2739 case DRX_CONSTELLATION_QAM256:
2742 case DRX_CONSTELLATION_QAM128:
2745 case DRX_CONSTELLATION_QAM64:
2748 case DRX_CONSTELLATION_QAM32:
2751 case DRX_CONSTELLATION_QAM16:
2756 } /* ext_attr->constellation */
2757 /* max_bit_rate = symbol_rate * nr_bits * coef */
2758 /* coef = 188/204 */
2760 (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
2761 /* pass through b/c Annex A/c need following settings */
2762 case DRX_STANDARD_ITU_B:
2763 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
2765 pr_err("error %d\n", rc);
2768 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
2770 pr_err("error %d\n", rc);
2773 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
2775 pr_err("error %d\n", rc);
2778 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
2780 pr_err("error %d\n", rc);
2783 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
2785 pr_err("error %d\n", rc);
2788 if (cfg_data->static_clk == true) {
2789 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
2791 pr_err("error %d\n", rc);
2795 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
2797 pr_err("error %d\n", rc);
2801 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
2803 pr_err("error %d\n", rc);
2806 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
2808 pr_err("error %d\n", rc);
2814 } /* swtich (standard) */
2816 /* Check insertion of the Reed-Solomon parity bytes */
2817 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
2819 pr_err("error %d\n", rc);
2822 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
2824 pr_err("error %d\n", rc);
2827 if (cfg_data->insert_rs_byte == true) {
2828 /* enable parity symbol forward */
2829 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
2830 /* MVAL disable during parity bytes */
2831 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2832 switch (ext_attr->standard) {
2833 case DRX_STANDARD_8VSB:
2834 rcn_rate = 0x004854D3;
2836 case DRX_STANDARD_ITU_B:
2837 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2838 switch (ext_attr->constellation) {
2839 case DRX_CONSTELLATION_QAM256:
2840 rcn_rate = 0x008945E7;
2842 case DRX_CONSTELLATION_QAM64:
2843 rcn_rate = 0x005F64D4;
2849 case DRX_STANDARD_ITU_A:
2850 case DRX_STANDARD_ITU_C:
2851 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2855 (u32) (common_attr->sys_clock_freq / 8))) /
2860 } /* ext_attr->standard */
2861 } else { /* insert_rs_byte == false */
2863 /* disable parity symbol forward */
2864 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2865 /* MVAL enable during parity bytes */
2866 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2867 switch (ext_attr->standard) {
2868 case DRX_STANDARD_8VSB:
2869 rcn_rate = 0x0041605C;
2871 case DRX_STANDARD_ITU_B:
2872 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2873 switch (ext_attr->constellation) {
2874 case DRX_CONSTELLATION_QAM256:
2875 rcn_rate = 0x0082D6A0;
2877 case DRX_CONSTELLATION_QAM64:
2878 rcn_rate = 0x005AEC1A;
2884 case DRX_STANDARD_ITU_A:
2885 case DRX_STANDARD_ITU_C:
2886 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2890 (u32) (common_attr->sys_clock_freq / 8))) /
2895 } /* ext_attr->standard */
2898 if (cfg_data->enable_parallel == true) { /* MPEG data output is paralel -> clear ipr_mode[0] */
2899 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2900 } else { /* MPEG data output is serial -> set ipr_mode[0] */
2901 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
2904 /* Control slective inversion of output bits */
2905 if (cfg_data->invert_data == true)
2906 fec_oc_reg_ipr_invert |= invert_data_mask;
2908 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2910 if (cfg_data->invert_err == true)
2911 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2913 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2915 if (cfg_data->invert_str == true)
2916 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2918 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2920 if (cfg_data->invert_val == true)
2921 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2923 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2925 if (cfg_data->invert_clk == true)
2926 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
2928 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2930 if (cfg_data->static_clk == true) { /* Static mode */
2933 u16 fec_oc_dto_burst_len = 0;
2934 u16 fec_oc_dto_period = 0;
2936 fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
2938 switch (ext_attr->standard) {
2939 case DRX_STANDARD_8VSB:
2940 fec_oc_dto_period = 4;
2941 if (cfg_data->insert_rs_byte == true)
2942 fec_oc_dto_burst_len = 208;
2944 case DRX_STANDARD_ITU_A:
2946 u32 symbol_rate_th = 6400000;
2947 if (cfg_data->insert_rs_byte == true) {
2948 fec_oc_dto_burst_len = 204;
2949 symbol_rate_th = 5900000;
2951 if (ext_attr->curr_symbol_rate >=
2953 fec_oc_dto_period = 0;
2955 fec_oc_dto_period = 1;
2959 case DRX_STANDARD_ITU_B:
2960 fec_oc_dto_period = 1;
2961 if (cfg_data->insert_rs_byte == true)
2962 fec_oc_dto_burst_len = 128;
2964 case DRX_STANDARD_ITU_C:
2965 fec_oc_dto_period = 1;
2966 if (cfg_data->insert_rs_byte == true)
2967 fec_oc_dto_burst_len = 204;
2973 common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
2976 frac28(bit_rate, common_attr->sys_clock_freq * 1000);
2978 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
2980 pr_err("error %d\n", rc);
2983 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);
2985 pr_err("error %d\n", rc);
2988 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);
2990 pr_err("error %d\n", rc);
2993 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);
2995 pr_err("error %d\n", rc);
2998 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
3000 pr_err("error %d\n", rc);
3003 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3004 fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
3005 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
3007 pr_err("error %d\n", rc);
3010 } else { /* Dynamic mode */
3012 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
3014 pr_err("error %d\n", rc);
3017 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
3019 pr_err("error %d\n", rc);
3024 rc = DRXJ_DAP.write_reg32func(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
3026 pr_err("error %d\n", rc);
3030 /* Write appropriate registers with requested configuration */
3031 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
3033 pr_err("error %d\n", rc);
3036 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
3038 pr_err("error %d\n", rc);
3041 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
3043 pr_err("error %d\n", rc);
3047 /* enabling for both parallel and serial now */
3048 /* Write magic word to enable pdr reg write */
3049 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3051 pr_err("error %d\n", rc);
3054 /* Set MPEG TS pads to outputmode */
3055 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
3057 pr_err("error %d\n", rc);
3060 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
3062 pr_err("error %d\n", rc);
3065 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);
3067 pr_err("error %d\n", rc);
3070 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
3072 pr_err("error %d\n", rc);
3076 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3077 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
3078 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3080 pr_err("error %d\n", rc);
3083 if (cfg_data->enable_parallel == true) { /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
3085 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3086 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3087 SIO_PDR_MD0_CFG_MODE__B;
3088 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3090 pr_err("error %d\n", rc);
3093 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
3095 pr_err("error %d\n", rc);
3098 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
3100 pr_err("error %d\n", rc);
3103 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
3105 pr_err("error %d\n", rc);
3108 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
3110 pr_err("error %d\n", rc);
3113 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
3115 pr_err("error %d\n", rc);
3118 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
3120 pr_err("error %d\n", rc);
3123 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
3125 pr_err("error %d\n", rc);
3128 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3129 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3131 pr_err("error %d\n", rc);
3134 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3136 pr_err("error %d\n", rc);
3139 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3141 pr_err("error %d\n", rc);
3144 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3146 pr_err("error %d\n", rc);
3149 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3151 pr_err("error %d\n", rc);
3154 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3156 pr_err("error %d\n", rc);
3159 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3161 pr_err("error %d\n", rc);
3165 /* Enable Monitor Bus output over MPEG pads and ctl input */
3166 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3168 pr_err("error %d\n", rc);
3171 /* Write nomagic word to enable pdr reg write */
3172 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3174 pr_err("error %d\n", rc);
3178 /* Write magic word to enable pdr reg write */
3179 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3181 pr_err("error %d\n", rc);
3184 /* Set MPEG TS pads to inputmode */
3185 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
3187 pr_err("error %d\n", rc);
3190 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
3192 pr_err("error %d\n", rc);
3195 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
3197 pr_err("error %d\n", rc);
3200 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
3202 pr_err("error %d\n", rc);
3205 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
3207 pr_err("error %d\n", rc);
3210 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3212 pr_err("error %d\n", rc);
3215 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3217 pr_err("error %d\n", rc);
3220 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3222 pr_err("error %d\n", rc);
3225 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3227 pr_err("error %d\n", rc);
3230 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3232 pr_err("error %d\n", rc);
3235 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3237 pr_err("error %d\n", rc);
3240 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3242 pr_err("error %d\n", rc);
3245 /* Enable Monitor Bus output over MPEG pads and ctl input */
3246 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3248 pr_err("error %d\n", rc);
3251 /* Write nomagic word to enable pdr reg write */
3252 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3254 pr_err("error %d\n", rc);
3259 /* save values for restore after re-acquire */
3260 common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3261 common_attr->mpeg_cfg.insert_rs_byte = cfg_data->insert_rs_byte;
3262 common_attr->mpeg_cfg.enable_parallel = cfg_data->enable_parallel;
3263 common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
3264 common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
3265 common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
3266 common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
3267 common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
3268 common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
3269 common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
3276 /*----------------------------------------------------------------------------*/
3279 * \fn int ctrl_get_cfg_mpeg_output()
3280 * \brief Get MPEG output configuration of the device.
3281 * \param devmod Pointer to demodulator instance.
3282 * \param cfg_data Pointer to MPEG output configuaration struct.
3285 * Retrieve MPEG output configuartion.
3289 ctrl_get_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
3291 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3292 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
3293 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
3299 if (cfg_data == NULL)
3302 dev_addr = demod->my_i2c_dev_addr;
3303 common_attr = demod->my_common_attr;
3305 cfg_data->enable_mpeg_output = common_attr->mpeg_cfg.enable_mpeg_output;
3306 cfg_data->insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
3307 cfg_data->enable_parallel = common_attr->mpeg_cfg.enable_parallel;
3308 cfg_data->invert_data = common_attr->mpeg_cfg.invert_data;
3309 cfg_data->invert_err = common_attr->mpeg_cfg.invert_err;
3310 cfg_data->invert_str = common_attr->mpeg_cfg.invert_str;
3311 cfg_data->invert_val = common_attr->mpeg_cfg.invert_val;
3312 cfg_data->invert_clk = common_attr->mpeg_cfg.invert_clk;
3313 cfg_data->static_clk = common_attr->mpeg_cfg.static_clk;
3314 cfg_data->bitrate = 0;
3316 rc = ctrl_lock_status(demod, &lock_status);
3318 pr_err("error %d\n", rc);
3321 if ((lock_status == DRX_LOCKED)) {
3322 rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_RCN_DYN_RATE_LO__A, &rate_reg, 0);
3324 pr_err("error %d\n", rc);
3327 /* Frcn_rate = rate_reg * Fsys / 2 ^ 25 */
3328 mult32(rate_reg, common_attr->sys_clock_freq * 1000, &data64hi,
3330 cfg_data->bitrate = (data64hi << 7) | (data64lo >> 25);
3338 /*----------------------------------------------------------------------------*/
3339 /* MPEG Output Configuration Functions - end */
3340 /*----------------------------------------------------------------------------*/
3342 /*----------------------------------------------------------------------------*/
3343 /* miscellaneous configuartions - begin */
3344 /*----------------------------------------------------------------------------*/
3347 * \fn int set_mpegtei_handling()
3348 * \brief Activate MPEG TEI handling settings.
3349 * \param devmod Pointer to demodulator instance.
3352 * This routine should be called during a set channel of QAM/VSB
3355 static int set_mpegtei_handling(struct drx_demod_instance *demod)
3357 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3358 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3360 u16 fec_oc_dpr_mode = 0;
3361 u16 fec_oc_snc_mode = 0;
3362 u16 fec_oc_ems_mode = 0;
3364 dev_addr = demod->my_i2c_dev_addr;
3365 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3367 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
3369 pr_err("error %d\n", rc);
3372 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
3374 pr_err("error %d\n", rc);
3377 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
3379 pr_err("error %d\n", rc);
3383 /* reset to default, allow TEI bit to be changed */
3384 fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3385 fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3386 FEC_OC_SNC_MODE_CORR_DISABLE__M));
3387 fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
3389 if (ext_attr->disable_te_ihandling) {
3390 /* do not change TEI bit */
3391 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3392 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3393 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3394 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3397 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
3399 pr_err("error %d\n", rc);
3402 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
3404 pr_err("error %d\n", rc);
3407 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
3409 pr_err("error %d\n", rc);
3418 /*----------------------------------------------------------------------------*/
3420 * \fn int bit_reverse_mpeg_output()
3421 * \brief Set MPEG output bit-endian settings.
3422 * \param devmod Pointer to demodulator instance.
3425 * This routine should be called during a set channel of QAM/VSB
3428 static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
3430 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3431 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3433 u16 fec_oc_ipr_mode = 0;
3435 dev_addr = demod->my_i2c_dev_addr;
3436 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3438 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
3440 pr_err("error %d\n", rc);
3444 /* reset to default (normal bit order) */
3445 fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3447 if (ext_attr->bit_reverse_mpeg_outout)
3448 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3450 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
3452 pr_err("error %d\n", rc);
3461 /*----------------------------------------------------------------------------*/
3463 * \fn int set_mpeg_output_clock_rate()
3464 * \brief Set MPEG output clock rate.
3465 * \param devmod Pointer to demodulator instance.
3468 * This routine should be called during a set channel of QAM/VSB
3471 static int set_mpeg_output_clock_rate(struct drx_demod_instance *demod)
3473 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3474 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3477 dev_addr = demod->my_i2c_dev_addr;
3478 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3480 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3481 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_PERIOD__A, ext_attr->mpeg_output_clock_rate - 1, 0);
3483 pr_err("error %d\n", rc);
3493 /*----------------------------------------------------------------------------*/
3495 * \fn int set_mpeg_start_width()
3496 * \brief Set MPEG start width.
3497 * \param devmod Pointer to demodulator instance.
3500 * This routine should be called during a set channel of QAM/VSB
3503 static int set_mpeg_start_width(struct drx_demod_instance *demod)
3505 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3506 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3507 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
3509 u16 fec_oc_comm_mb = 0;
3511 dev_addr = demod->my_i2c_dev_addr;
3512 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3513 common_attr = demod->my_common_attr;
3515 if ((common_attr->mpeg_cfg.static_clk == true)
3516 && (common_attr->mpeg_cfg.enable_parallel == false)) {
3517 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
3519 pr_err("error %d\n", rc);
3522 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3523 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
3524 fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
3525 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
3527 pr_err("error %d\n", rc);
3537 /*----------------------------------------------------------------------------*/
3539 * \fn int ctrl_set_cfg_mpeg_output_misc()
3540 * \brief Set miscellaneous configuartions
3541 * \param devmod Pointer to demodulator instance.
3542 * \param cfg_data pDRXJCfgMisc_t
3545 * This routine can be used to set configuartion options that are DRXJ
3546 * specific and/or added to the requirements at a late stage.
3550 ctrl_set_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3551 struct drxj_cfg_mpeg_output_misc *cfg_data)
3553 struct drxj_data *ext_attr = NULL;
3556 if (cfg_data == NULL)
3559 ext_attr = demod->my_ext_attr;
3562 Set disable TEI bit handling flag.
3563 TEI must be left untouched by device in case of BER measurements using
3564 external equipment that is unable to ignore the TEI bit in the TS.
3565 Default will false (enable TEI bit handling).
3566 Reverse output bit order. Default is false (msb on MD7 (parallel) or out first (serial)).
3567 Set clock rate. Default is auto that is derived from symbol rate.
3568 The flags and values will also be used to set registers during a set channel.
3570 ext_attr->disable_te_ihandling = cfg_data->disable_tei_handling;
3571 ext_attr->bit_reverse_mpeg_outout = cfg_data->bit_reverse_mpeg_outout;
3572 ext_attr->mpeg_output_clock_rate = cfg_data->mpeg_output_clock_rate;
3573 ext_attr->mpeg_start_width = cfg_data->mpeg_start_width;
3574 /* Don't care what the active standard is, activate setting immediatly */
3575 rc = set_mpegtei_handling(demod);
3577 pr_err("error %d\n", rc);
3580 rc = bit_reverse_mpeg_output(demod);
3582 pr_err("error %d\n", rc);
3585 rc = set_mpeg_output_clock_rate(demod);
3587 pr_err("error %d\n", rc);
3590 rc = set_mpeg_start_width(demod);
3592 pr_err("error %d\n", rc);
3601 /*----------------------------------------------------------------------------*/
3604 * \fn int ctrl_get_cfg_mpeg_output_misc()
3605 * \brief Get miscellaneous configuartions.
3606 * \param devmod Pointer to demodulator instance.
3607 * \param cfg_data Pointer to DRXJCfgMisc_t.
3610 * This routine can be used to retreive the current setting of the configuartion
3611 * options that are DRXJ specific and/or added to the requirements at a
3616 ctrl_get_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3617 struct drxj_cfg_mpeg_output_misc *cfg_data)
3619 struct drxj_data *ext_attr = NULL;
3623 if (cfg_data == NULL)
3626 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3627 cfg_data->disable_tei_handling = ext_attr->disable_te_ihandling;
3628 cfg_data->bit_reverse_mpeg_outout = ext_attr->bit_reverse_mpeg_outout;
3629 cfg_data->mpeg_start_width = ext_attr->mpeg_start_width;
3630 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3631 cfg_data->mpeg_output_clock_rate = ext_attr->mpeg_output_clock_rate;
3633 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, FEC_OC_DTO_PERIOD__A, &data, 0);
3635 pr_err("error %d\n", rc);
3638 cfg_data->mpeg_output_clock_rate =
3639 (enum drxj_mpeg_output_clock_rate) (data + 1);
3647 /*----------------------------------------------------------------------------*/
3650 * \fn int ctrl_get_cfg_hw_cfg()
3651 * \brief Get HW configuartions.
3652 * \param devmod Pointer to demodulator instance.
3653 * \param cfg_data Pointer to Bool.
3656 * This routine can be used to retreive the current setting of the configuartion
3657 * options that are DRXJ specific and/or added to the requirements at a
3662 ctrl_get_cfg_hw_cfg(struct drx_demod_instance *demod, struct drxj_cfg_hw_cfg *cfg_data)
3667 if (cfg_data == NULL)
3670 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3672 pr_err("error %d\n", rc);
3675 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_OHW_CFG__A, &data, 0);
3677 pr_err("error %d\n", rc);
3680 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3682 pr_err("error %d\n", rc);
3686 cfg_data->i2c_speed = (enum drxji2c_speed) ((data >> 6) & 0x1);
3687 cfg_data->xtal_freq = (enum drxj_xtal_freq) (data & 0x3);
3694 /*----------------------------------------------------------------------------*/
3695 /* miscellaneous configuartions - end */
3696 /*----------------------------------------------------------------------------*/
3698 /*----------------------------------------------------------------------------*/
3699 /* UIO Configuration Functions - begin */
3700 /*----------------------------------------------------------------------------*/
3702 * \fn int ctrl_set_uio_cfg()
3703 * \brief Configure modus oprandi UIO.
3704 * \param demod Pointer to demodulator instance.
3705 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3708 static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3710 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3713 if ((uio_cfg == NULL) || (demod == NULL))
3716 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3718 /* Write magic word to enable pdr reg write */
3719 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3721 pr_err("error %d\n", rc);
3724 switch (uio_cfg->uio) {
3725 /*====================================================================*/
3727 /* DRX_UIO1: SMA_TX UIO-1 */
3728 if (!ext_attr->has_smatx)
3730 switch (uio_cfg->mode) {
3731 case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
3732 case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
3733 case DRX_UIO_MODE_READWRITE:
3734 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3736 case DRX_UIO_MODE_DISABLE:
3737 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3738 /* pad configuration register is set 0 - input mode */
3739 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
3741 pr_err("error %d\n", rc);
3747 } /* switch ( uio_cfg->mode ) */
3749 /*====================================================================*/
3751 /* DRX_UIO2: SMA_RX UIO-2 */
3752 if (!ext_attr->has_smarx)
3754 switch (uio_cfg->mode) {
3755 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3756 case DRX_UIO_MODE_READWRITE:
3757 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3759 case DRX_UIO_MODE_DISABLE:
3760 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3761 /* pad configuration register is set 0 - input mode */
3762 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
3764 pr_err("error %d\n", rc);
3771 } /* switch ( uio_cfg->mode ) */
3773 /*====================================================================*/
3775 /* DRX_UIO3: GPIO UIO-3 */
3776 if (!ext_attr->has_gpio)
3778 switch (uio_cfg->mode) {
3779 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3780 case DRX_UIO_MODE_READWRITE:
3781 ext_attr->uio_gpio_mode = uio_cfg->mode;
3783 case DRX_UIO_MODE_DISABLE:
3784 ext_attr->uio_gpio_mode = uio_cfg->mode;
3785 /* pad configuration register is set 0 - input mode */
3786 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
3788 pr_err("error %d\n", rc);
3795 } /* switch ( uio_cfg->mode ) */
3797 /*====================================================================*/
3799 /* DRX_UIO4: IRQN UIO-4 */
3800 if (!ext_attr->has_irqn)
3802 switch (uio_cfg->mode) {
3803 case DRX_UIO_MODE_READWRITE:
3804 ext_attr->uio_irqn_mode = uio_cfg->mode;
3806 case DRX_UIO_MODE_DISABLE:
3807 /* pad configuration register is set 0 - input mode */
3808 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
3810 pr_err("error %d\n", rc);
3813 ext_attr->uio_irqn_mode = uio_cfg->mode;
3815 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3819 } /* switch ( uio_cfg->mode ) */
3821 /*====================================================================*/
3824 } /* switch ( uio_cfg->uio ) */
3826 /* Write magic word to disable pdr reg write */
3827 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3829 pr_err("error %d\n", rc);
3838 /*============================================================================*/
3840 * \fn int ctrl_getuio_cfg()
3841 * \brief Get modus oprandi UIO.
3842 * \param demod Pointer to demodulator instance.
3843 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3846 static int ctrl_getuio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3849 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
3850 enum drxuio_mode *uio_mode[4] = { NULL };
3851 bool *uio_available[4] = { NULL };
3853 ext_attr = demod->my_ext_attr;
3855 uio_mode[DRX_UIO1] = &ext_attr->uio_sma_tx_mode;
3856 uio_mode[DRX_UIO2] = &ext_attr->uio_sma_rx_mode;
3857 uio_mode[DRX_UIO3] = &ext_attr->uio_gpio_mode;
3858 uio_mode[DRX_UIO4] = &ext_attr->uio_irqn_mode;
3860 uio_available[DRX_UIO1] = &ext_attr->has_smatx;
3861 uio_available[DRX_UIO2] = &ext_attr->has_smarx;
3862 uio_available[DRX_UIO3] = &ext_attr->has_gpio;
3863 uio_available[DRX_UIO4] = &ext_attr->has_irqn;
3865 if (uio_cfg == NULL)
3868 if ((uio_cfg->uio > DRX_UIO4) || (uio_cfg->uio < DRX_UIO1))
3871 if (!*uio_available[uio_cfg->uio])
3874 uio_cfg->mode = *uio_mode[uio_cfg->uio];
3880 * \fn int ctrl_uio_write()
3881 * \brief Write to a UIO.
3882 * \param demod Pointer to demodulator instance.
3883 * \param uio_data Pointer to data container for a certain UIO.
3887 ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
3889 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3891 u16 pin_cfg_value = 0;
3894 if ((uio_data == NULL) || (demod == NULL))
3897 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3899 /* Write magic word to enable pdr reg write */
3900 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3902 pr_err("error %d\n", rc);
3905 switch (uio_data->uio) {
3906 /*====================================================================*/
3908 /* DRX_UIO1: SMA_TX UIO-1 */
3909 if (!ext_attr->has_smatx)
3911 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3912 && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3916 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3917 pin_cfg_value |= 0x0113;
3918 /* io_pad_cfg_mode output mode is drive always */
3919 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3921 /* write to io pad configuration register - output mode */
3922 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
3924 pr_err("error %d\n", rc);
3928 /* use corresponding bit in io data output registar */
3929 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3931 pr_err("error %d\n", rc);
3934 if (!uio_data->value)
3935 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
3937 value |= 0x8000; /* write one to 15th bit - 1st UIO */
3939 /* write back to io data output register */
3940 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3942 pr_err("error %d\n", rc);
3946 /*======================================================================*/
3948 /* DRX_UIO2: SMA_RX UIO-2 */
3949 if (!ext_attr->has_smarx)
3951 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
3955 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3956 pin_cfg_value |= 0x0113;
3957 /* io_pad_cfg_mode output mode is drive always */
3958 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3960 /* write to io pad configuration register - output mode */
3961 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
3963 pr_err("error %d\n", rc);
3967 /* use corresponding bit in io data output registar */
3968 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3970 pr_err("error %d\n", rc);
3973 if (!uio_data->value)
3974 value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
3976 value |= 0x4000; /* write one to 14th bit - 2nd UIO */
3978 /* write back to io data output register */
3979 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3981 pr_err("error %d\n", rc);
3985 /*====================================================================*/
3987 /* DRX_UIO3: ASEL UIO-3 */
3988 if (!ext_attr->has_gpio)
3990 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
3994 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3995 pin_cfg_value |= 0x0113;
3996 /* io_pad_cfg_mode output mode is drive always */
3997 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3999 /* write to io pad configuration register - output mode */
4000 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
4002 pr_err("error %d\n", rc);
4006 /* use corresponding bit in io data output registar */
4007 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
4009 pr_err("error %d\n", rc);
4012 if (!uio_data->value)
4013 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
4015 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
4017 /* write back to io data output register */
4018 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
4020 pr_err("error %d\n", rc);
4024 /*=====================================================================*/
4026 /* DRX_UIO4: IRQN UIO-4 */
4027 if (!ext_attr->has_irqn)
4030 if (ext_attr->uio_irqn_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_IRQN_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_LO__A, &value, 0);
4049 pr_err("error %d\n", rc);
4052 if (uio_data->value == false)
4053 value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
4055 value |= 0x1000; /* write one to 12th bit - 4th UIO */
4057 /* write back to io data output register */
4058 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
4060 pr_err("error %d\n", rc);
4064 /*=====================================================================*/
4067 } /* switch ( uio_data->uio ) */
4069 /* Write magic word to disable pdr reg write */
4070 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4072 pr_err("error %d\n", rc);
4082 *\fn int ctrl_uio_read
4083 *\brief Read from a UIO.
4084 * \param demod Pointer to demodulator instance.
4085 * \param uio_data Pointer to data container for a certain UIO.
4088 static int ctrl_uio_read(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
4090 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
4092 u16 pin_cfg_value = 0;
4095 if ((uio_data == NULL) || (demod == NULL))
4098 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4100 /* Write magic word to enable pdr reg write */
4101 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4103 pr_err("error %d\n", rc);
4106 switch (uio_data->uio) {
4107 /*====================================================================*/
4109 /* DRX_UIO1: SMA_TX UIO-1 */
4110 if (!ext_attr->has_smatx)
4113 if (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
4117 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4118 pin_cfg_value |= 0x0110;
4119 /* io_pad_cfg_mode output mode is drive always */
4120 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4122 /* write to io pad configuration register - input mode */
4123 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
4125 pr_err("error %d\n", rc);
4129 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4131 pr_err("error %d\n", rc);
4134 if ((value & 0x8000) != 0) { /* check 15th bit - 1st UIO */
4135 uio_data->value = true;
4137 uio_data->value = false;
4140 /*======================================================================*/
4142 /* DRX_UIO2: SMA_RX UIO-2 */
4143 if (!ext_attr->has_smarx)
4146 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
4150 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4151 pin_cfg_value |= 0x0110;
4152 /* io_pad_cfg_mode output mode is drive always */
4153 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4155 /* write to io pad configuration register - input mode */
4156 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
4158 pr_err("error %d\n", rc);
4162 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4164 pr_err("error %d\n", rc);
4168 if ((value & 0x4000) != 0) /* check 14th bit - 2nd UIO */
4169 uio_data->value = true;
4171 uio_data->value = false;
4174 /*=====================================================================*/
4176 /* DRX_UIO3: GPIO UIO-3 */
4177 if (!ext_attr->has_gpio)
4180 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
4184 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4185 pin_cfg_value |= 0x0110;
4186 /* io_pad_cfg_mode output mode is drive always */
4187 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4189 /* write to io pad configuration register - input mode */
4190 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
4192 pr_err("error %d\n", rc);
4196 /* read io input data registar */
4197 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_HI__A, &value, 0);
4199 pr_err("error %d\n", rc);
4202 if ((value & 0x0004) != 0) { /* check 2nd bit - 3rd UIO */
4203 uio_data->value = true;
4205 uio_data->value = false;
4208 /*=====================================================================*/
4210 /* DRX_UIO4: IRQN UIO-4 */
4211 if (!ext_attr->has_irqn)
4214 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
4218 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4219 pin_cfg_value |= 0x0110;
4220 /* io_pad_cfg_mode output mode is drive always */
4221 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4223 /* write to io pad configuration register - input mode */
4224 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
4226 pr_err("error %d\n", rc);
4230 /* read io input data registar */
4231 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4233 pr_err("error %d\n", rc);
4236 if ((value & 0x1000) != 0) /* check 12th bit - 4th UIO */
4237 uio_data->value = true;
4239 uio_data->value = false;
4242 /*====================================================================*/
4245 } /* switch ( uio_data->uio ) */
4247 /* Write magic word to disable pdr reg write */
4248 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4250 pr_err("error %d\n", rc);
4259 /*---------------------------------------------------------------------------*/
4260 /* UIO Configuration Functions - end */
4261 /*---------------------------------------------------------------------------*/
4263 /*----------------------------------------------------------------------------*/
4264 /* I2C Bridge Functions - begin */
4265 /*----------------------------------------------------------------------------*/
4267 * \fn int ctrl_i2c_bridge()
4268 * \brief Open or close the I2C switch to tuner.
4269 * \param demod Pointer to demodulator instance.
4270 * \param bridge_closed Pointer to bool indication if bridge is closed not.
4275 ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
4277 struct drxj_hi_cmd hi_cmd;
4280 /* check arguments */
4281 if (bridge_closed == NULL)
4284 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
4285 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
4287 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
4289 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
4291 return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
4294 /*----------------------------------------------------------------------------*/
4295 /* I2C Bridge Functions - end */
4296 /*----------------------------------------------------------------------------*/
4298 /*----------------------------------------------------------------------------*/
4299 /* Smart antenna Functions - begin */
4300 /*----------------------------------------------------------------------------*/
4302 * \fn int smart_ant_init()
4303 * \brief Initialize Smart Antenna.
4304 * \param pointer to struct drx_demod_instance.
4308 static int smart_ant_init(struct drx_demod_instance *demod)
4310 struct drxj_data *ext_attr = NULL;
4311 struct i2c_device_addr *dev_addr = NULL;
4312 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
4316 dev_addr = demod->my_i2c_dev_addr;
4317 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4319 /* Write magic word to enable pdr reg write */
4320 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4322 pr_err("error %d\n", rc);
4325 /* init smart antenna */
4326 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
4328 pr_err("error %d\n", rc);
4331 if (ext_attr->smart_ant_inverted) {
4332 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);
4334 pr_err("error %d\n", rc);
4338 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);
4340 pr_err("error %d\n", rc);
4345 /* config SMA_TX pin to smart antenna mode */
4346 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
4348 pr_err("error %d\n", rc);
4351 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
4353 pr_err("error %d\n", rc);
4356 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
4358 pr_err("error %d\n", rc);
4362 /* Write magic word to disable pdr reg write */
4363 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4365 pr_err("error %d\n", rc);
4375 * \fn int ctrl_set_cfg_smart_ant()
4376 * \brief Set Smart Antenna.
4377 * \param pointer to struct drxj_cfg_smart_ant.
4382 ctrl_set_cfg_smart_ant(struct drx_demod_instance *demod, struct drxj_cfg_smart_ant *smart_ant)
4384 struct drxj_data *ext_attr = NULL;
4385 struct i2c_device_addr *dev_addr = NULL;
4389 static bool bit_inverted;
4391 dev_addr = demod->my_i2c_dev_addr;
4392 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4394 /* check arguments */
4395 if (smart_ant == NULL)
4398 if (bit_inverted != ext_attr->smart_ant_inverted
4399 || ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SMA) {
4400 rc = smart_ant_init(demod);
4402 pr_err("error %d\n", rc);
4405 bit_inverted = ext_attr->smart_ant_inverted;
4408 /* Write magic word to enable pdr reg write */
4409 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4411 pr_err("error %d\n", rc);
4415 switch (smart_ant->io) {
4416 case DRXJ_SMT_ANT_OUTPUT:
4417 /* enable Tx if Mode B (input) is supported */
4419 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4420 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
4422 start_time = drxbsp_hst_clock();
4424 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_SA_TX_STATUS__A, &data, 0);
4426 pr_err("error %d\n", rc);
4429 } while ((data & SIO_SA_TX_STATUS_BUSY__M) && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
4431 if (data & SIO_SA_TX_STATUS_BUSY__M)
4434 /* write to smart antenna configuration register */
4435 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);
4437 pr_err("error %d\n", rc);
4440 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);
4442 pr_err("error %d\n", rc);
4445 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);
4447 pr_err("error %d\n", rc);
4450 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA3__A, 0xff8d, 0);
4452 pr_err("error %d\n", rc);
4456 /* trigger the sending */
4457 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_LENGTH__A, 56, 0);
4459 pr_err("error %d\n", rc);
4464 case DRXJ_SMT_ANT_INPUT:
4465 /* disable Tx if Mode B (input) is supported */
4467 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4468 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
4473 /* Write magic word to enable pdr reg write */
4474 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4476 pr_err("error %d\n", rc);
4485 static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
4495 /* Wait until SCU command interface is ready to receive command */
4496 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4498 pr_err("error %d\n", rc);
4501 if (cur_cmd != DRX_SCU_READY)
4504 switch (cmd->parameter_len) {
4506 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
4508 pr_err("error %d\n", rc);
4512 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
4514 pr_err("error %d\n", rc);
4518 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
4520 pr_err("error %d\n", rc);
4524 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
4526 pr_err("error %d\n", rc);
4530 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
4532 pr_err("error %d\n", rc);
4539 /* this number of parameters is not supported */
4542 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
4544 pr_err("error %d\n", rc);
4548 /* Wait until SCU has processed command */
4549 start_time = drxbsp_hst_clock();
4551 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4553 pr_err("error %d\n", rc);
4556 } while (!(cur_cmd == DRX_SCU_READY)
4557 && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
4559 if (cur_cmd != DRX_SCU_READY)
4563 if ((cmd->result_len > 0) && (cmd->result != NULL)) {
4566 switch (cmd->result_len) {
4568 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
4570 pr_err("error %d\n", rc);
4574 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
4576 pr_err("error %d\n", rc);
4580 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
4582 pr_err("error %d\n", rc);
4586 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
4588 pr_err("error %d\n", rc);
4595 /* this number of parameters is not supported */
4599 /* Check if an error was reported by SCU */
4600 err = cmd->result[0];
4602 /* check a few fixed error codes */
4603 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4604 || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4605 || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4606 || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
4610 /* here it is assumed that negative means error, and positive no error */
4624 * \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4625 * \brief Basic access routine for SCU atomic read or write access
4626 * \param dev_addr pointer to i2c dev address
4627 * \param addr destination/source address
4628 * \param datasize size of data buffer in bytes
4629 * \param data pointer to data buffer
4632 * \retval -EIO Timeout, I2C error, illegal bank
4635 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4637 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 */
4638 u8 *data, bool read_flag)
4640 struct drxjscu_cmd scu_cmd;
4642 u16 set_param_parameters[15];
4645 /* Parameter check */
4646 if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
4649 set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4650 if (read_flag) { /* read */
4651 set_param_parameters[0] = ((~(0x0080)) & datasize);
4652 scu_cmd.parameter_len = 2;
4653 scu_cmd.result_len = datasize / 2 + 2;
4657 set_param_parameters[0] = 0x0080 | datasize;
4658 for (i = 0; i < (datasize / 2); i++) {
4659 set_param_parameters[i + 2] =
4660 (data[2 * i] | (data[(2 * i) + 1] << 8));
4662 scu_cmd.parameter_len = datasize / 2 + 2;
4663 scu_cmd.result_len = 1;
4667 SCU_RAM_COMMAND_STANDARD_TOP |
4668 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4669 scu_cmd.result = cmd_result;
4670 scu_cmd.parameter = set_param_parameters;
4671 rc = scu_command(dev_addr, &scu_cmd);
4673 pr_err("error %d\n", rc);
4679 /* read data from buffer */
4680 for (i = 0; i < (datasize / 2); i++) {
4681 data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4682 data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
4693 /*============================================================================*/
4696 * \fn int DRXJ_DAP_AtomicReadReg16()
4697 * \brief Atomic read of 16 bits words
4700 int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4702 u16 *data, u32 flags)
4711 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
4715 word = (u16) (buf[0] + (buf[1] << 8));
4722 /*============================================================================*/
4724 * \fn int drxj_dap_scu_atomic_write_reg16()
4725 * \brief Atomic read of 16 bits words
4728 int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4730 u16 data, u32 flags)
4735 buf[0] = (u8) (data & 0xff);
4736 buf[1] = (u8) ((data >> 8) & 0xff);
4738 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
4744 ctrl_i2c_write_read(struct drx_demod_instance *demod, struct drxi2c_data *i2c_data)
4749 /* -------------------------------------------------------------------------- */
4751 * \brief Measure result of ADC synchronisation
4752 * \param demod demod instance
4753 * \param count (returned) count
4756 * \retval -EIO Failure: I2C error
4759 static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
4761 struct i2c_device_addr *dev_addr = NULL;
4765 dev_addr = demod->my_i2c_dev_addr;
4767 /* Start measurement */
4768 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
4770 pr_err("error %d\n", rc);
4773 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
4775 pr_err("error %d\n", rc);
4779 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4780 rc = drxbsp_hst_sleep(1);
4782 pr_err("error %d\n", rc);
4787 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE0__A, &data, 0);
4789 pr_err("error %d\n", rc);
4793 *count = *count + 1;
4794 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE1__A, &data, 0);
4796 pr_err("error %d\n", rc);
4800 *count = *count + 1;
4801 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE2__A, &data, 0);
4803 pr_err("error %d\n", rc);
4807 *count = *count + 1;
4815 * \brief Synchronize analog and digital clock domains
4816 * \param demod demod instance
4819 * \retval -EIO Failure: I2C error or failure to synchronize
4821 * An IQM reset will also reset the results of this synchronization.
4822 * After an IQM reset this routine needs to be called again.
4826 static int adc_synchronization(struct drx_demod_instance *demod)
4828 struct i2c_device_addr *dev_addr = NULL;
4832 dev_addr = demod->my_i2c_dev_addr;
4834 rc = adc_sync_measurement(demod, &count);
4836 pr_err("error %d\n", rc);
4841 /* Try sampling on a diffrent edge */
4844 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
4846 pr_err("error %d\n", rc);
4850 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4851 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
4853 pr_err("error %d\n", rc);
4857 rc = adc_sync_measurement(demod, &count);
4859 pr_err("error %d\n", rc);
4864 /* TODO: implement fallback scenarios */
4874 * \brief Configure IQM AF registers
4875 * \param demod instance of demodulator.
4879 static int iqm_set_af(struct drx_demod_instance *demod, bool active)
4881 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
4886 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
4888 pr_err("error %d\n", rc);
4892 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));
4894 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);
4895 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
4897 pr_err("error %d\n", rc);
4906 /* -------------------------------------------------------------------------- */
4908 ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg);
4911 * \brief set configuration of pin-safe mode
4912 * \param demod instance of demodulator.
4913 * \param enable boolean; true: activate pin-safe mode, false: de-activate p.s.m.
4917 ctrl_set_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enable)
4919 struct drxj_data *ext_attr = NULL;
4920 struct i2c_device_addr *dev_addr = NULL;
4926 dev_addr = demod->my_i2c_dev_addr;
4927 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4929 /* Write magic word to enable pdr reg write */
4930 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4932 pr_err("error %d\n", rc);
4937 bool bridge_enabled = false;
4939 /* MPEG pins to input */
4940 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4942 pr_err("error %d\n", rc);
4945 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4947 pr_err("error %d\n", rc);
4950 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MCLK_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4952 pr_err("error %d\n", rc);
4955 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4957 pr_err("error %d\n", rc);
4960 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4962 pr_err("error %d\n", rc);
4965 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4967 pr_err("error %d\n", rc);
4970 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4972 pr_err("error %d\n", rc);
4975 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4977 pr_err("error %d\n", rc);
4980 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4982 pr_err("error %d\n", rc);
4985 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4987 pr_err("error %d\n", rc);
4990 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4992 pr_err("error %d\n", rc);
4995 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4997 pr_err("error %d\n", rc);
5001 /* PD_I2C_SDA2 Bridge off, Port2 Inactive
5002 PD_I2C_SCL2 Bridge off, Port2 Inactive */
5003 rc = ctrl_i2c_bridge(demod, &bridge_enabled);
5005 pr_err("error %d\n", rc);
5008 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5010 pr_err("error %d\n", rc);
5013 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5015 pr_err("error %d\n", rc);
5019 /* PD_GPIO Store and set to input
5020 PD_VSYNC Store and set to input
5021 PD_SMA_RX Store and set to input
5022 PD_SMA_TX Store and set to input */
5023 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, &ext_attr->pdr_safe_restore_val_gpio, 0);
5025 pr_err("error %d\n", rc);
5028 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, &ext_attr->pdr_safe_restore_val_v_sync, 0);
5030 pr_err("error %d\n", rc);
5033 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_rx, 0);
5035 pr_err("error %d\n", rc);
5038 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_tx, 0);
5040 pr_err("error %d\n", rc);
5043 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5045 pr_err("error %d\n", rc);
5048 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5050 pr_err("error %d\n", rc);
5053 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5055 pr_err("error %d\n", rc);
5058 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5060 pr_err("error %d\n", rc);
5064 /* PD_RF_AGC Analog DAC outputs, cannot be set to input or tristate!
5065 PD_IF_AGC Analog DAC outputs, cannot be set to input or tristate! */
5066 rc = iqm_set_af(demod, false);
5068 pr_err("error %d\n", rc);
5072 /* PD_CVBS Analog DAC output, standby mode
5073 PD_SIF Analog DAC output, standby mode */
5074 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);
5076 pr_err("error %d\n", rc);
5083 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5085 pr_err("error %d\n", rc);
5088 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5090 pr_err("error %d\n", rc);
5093 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_WS_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5095 pr_err("error %d\n", rc);
5099 /* No need to restore MPEG pins;
5100 is done in SetStandard/SetChannel */
5102 /* PD_I2C_SDA2 Port2 active
5103 PD_I2C_SCL2 Port2 active */
5104 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, SIO_PDR_I2C_SDA2_CFG__PRE, 0);
5106 pr_err("error %d\n", rc);
5109 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, SIO_PDR_I2C_SCL2_CFG__PRE, 0);
5111 pr_err("error %d\n", rc);
5118 PD_SMA_TX Restore */
5119 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, ext_attr->pdr_safe_restore_val_gpio, 0);
5121 pr_err("error %d\n", rc);
5124 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, ext_attr->pdr_safe_restore_val_v_sync, 0);
5126 pr_err("error %d\n", rc);
5129 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, ext_attr->pdr_safe_restore_val_sma_rx, 0);
5131 pr_err("error %d\n", rc);
5134 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, ext_attr->pdr_safe_restore_val_sma_tx, 0);
5136 pr_err("error %d\n", rc);
5140 /* PD_RF_AGC, PD_IF_AGC
5141 No need to restore; will be restored in SetStandard/SetChannel */
5144 No need to restore; will be restored in SetStandard/SetChannel */
5146 /* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
5147 Should be restored via DRX_CTRL_SET_AUD */
5150 /* Write magic word to disable pdr reg write */
5151 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
5153 pr_err("error %d\n", rc);
5156 ext_attr->pdr_safe_mode = *enable;
5164 /* -------------------------------------------------------------------------- */
5167 * \brief get configuration of pin-safe mode
5168 * \param demod instance of demodulator.
5169 * \param enable boolean indicating whether pin-safe mode is active
5173 ctrl_get_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enabled)
5175 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
5177 if (enabled == NULL)
5180 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5181 *enabled = ext_attr->pdr_safe_mode;
5187 * \brief Verifies whether microcode can be loaded.
5188 * \param demod Demodulator instance.
5191 static int ctrl_validate_u_code(struct drx_demod_instance *demod)
5193 u32 mc_dev, mc_patch;
5197 * Disallow microcode if:
5198 * - MC has version record AND
5199 * - device ID in version record is not 0 AND
5200 * - product ID in version record's device ID does not
5201 * match DRXJ1 product IDs - 0x393 or 0x394
5203 ver_type = DRX_ATTR_MCRECORD(demod).aux_type;
5204 mc_dev = DRX_ATTR_MCRECORD(demod).mc_dev_type;
5205 mc_patch = DRX_ATTR_MCRECORD(demod).mc_base_version;
5207 if (DRX_ISMCVERTYPE(ver_type)) {
5208 if ((mc_dev != 0) &&
5209 (((mc_dev >> 16) & 0xFFF) != 0x393) &&
5210 (((mc_dev >> 16) & 0xFFF) != 0x394)) {
5211 /* Microcode is marked for another device - error */
5213 } else if (mc_patch != 0) {
5214 /* Patch not allowed because there is no ROM */
5219 /* Everything else: OK */
5223 /*============================================================================*/
5224 /*== END AUXILIARY FUNCTIONS ==*/
5225 /*============================================================================*/
5227 /*============================================================================*/
5228 /*============================================================================*/
5229 /*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5230 /*============================================================================*/
5231 /*============================================================================*/
5233 * \fn int init_agc ()
5234 * \brief Initialize AGC for all standards.
5235 * \param demod instance of demodulator.
5236 * \param channel pointer to channel data.
5239 static int init_agc(struct drx_demod_instance *demod)
5241 struct i2c_device_addr *dev_addr = NULL;
5242 struct drx_common_attr *common_attr = NULL;
5243 struct drxj_data *ext_attr = NULL;
5244 struct drxj_cfg_agc *p_agc_rf_settings = NULL;
5245 struct drxj_cfg_agc *p_agc_if_settings = NULL;
5247 u16 ingain_tgt_max = 0;
5249 u16 sns_sum_max = 0;
5250 u16 clp_sum_max = 0;
5252 u16 ki_innergain_min = 0;
5255 u16 if_iaccu_hi_tgt_min = 0;
5257 u16 agc_ki_dgain = 0;
5259 u16 clp_ctrl_mode = 0;
5263 dev_addr = demod->my_i2c_dev_addr;
5264 common_attr = (struct drx_common_attr *) demod->my_common_attr;
5265 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5267 switch (ext_attr->standard) {
5268 case DRX_STANDARD_8VSB:
5270 clp_dir_to = (u16) (-9);
5272 sns_dir_to = (u16) (-9);
5273 ki_innergain_min = (u16) (-32768);
5276 if_iaccu_hi_tgt_min = 2047;
5278 ingain_tgt_max = 16383;
5280 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
5282 pr_err("error %d\n", rc);
5285 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
5287 pr_err("error %d\n", rc);
5290 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
5292 pr_err("error %d\n", rc);
5295 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
5297 pr_err("error %d\n", rc);
5300 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
5302 pr_err("error %d\n", rc);
5305 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
5307 pr_err("error %d\n", rc);
5310 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
5312 pr_err("error %d\n", rc);
5315 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
5317 pr_err("error %d\n", rc);
5320 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
5322 pr_err("error %d\n", rc);
5325 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
5327 pr_err("error %d\n", rc);
5330 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
5332 pr_err("error %d\n", rc);
5335 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
5337 pr_err("error %d\n", rc);
5340 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
5342 pr_err("error %d\n", rc);
5345 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
5346 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
5348 #ifndef DRXJ_VSB_ONLY
5349 case DRX_STANDARD_ITU_A:
5350 case DRX_STANDARD_ITU_C:
5351 case DRX_STANDARD_ITU_B:
5352 ingain_tgt_max = 5119;
5354 clp_dir_to = (u16) (-5);
5356 sns_dir_to = (u16) (-3);
5357 ki_innergain_min = 0;
5359 if_iaccu_hi_tgt_min = 2047;
5363 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
5365 pr_err("error %d\n", rc);
5368 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
5370 pr_err("error %d\n", rc);
5373 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
5375 pr_err("error %d\n", rc);
5378 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
5380 pr_err("error %d\n", rc);
5383 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
5385 pr_err("error %d\n", rc);
5388 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
5390 pr_err("error %d\n", rc);
5393 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
5395 pr_err("error %d\n", rc);
5398 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
5400 pr_err("error %d\n", rc);
5403 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
5405 pr_err("error %d\n", rc);
5408 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
5410 pr_err("error %d\n", rc);
5413 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
5414 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
5415 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5417 pr_err("error %d\n", rc);
5421 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
5423 pr_err("error %d\n", rc);
5427 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
5429 pr_err("error %d\n", rc);
5434 #ifndef DRXJ_DIGITAL_ONLY
5435 case DRX_STANDARD_FM:
5438 ki_innergain_min = (u16) (-32768);
5439 if_iaccu_hi_tgt_min = 2047;
5443 clp_dir_to = (u16) (-9);
5444 sns_dir_to = (u16) (-9);
5445 ingain_tgt_max = 9000;
5447 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5448 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5449 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5451 pr_err("error %d\n", rc);
5455 case DRX_STANDARD_NTSC:
5456 case DRX_STANDARD_PAL_SECAM_BG:
5457 case DRX_STANDARD_PAL_SECAM_DK:
5458 case DRX_STANDARD_PAL_SECAM_I:
5461 ki_innergain_min = (u16) (-32768);
5462 if_iaccu_hi_tgt_min = 2047;
5466 clp_dir_to = (u16) (-9);
5467 ingain_tgt_max = 9000;
5468 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5469 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5470 sns_dir_to = (u16) (-9);
5472 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5474 pr_err("error %d\n", rc);
5478 case DRX_STANDARD_PAL_SECAM_L:
5479 case DRX_STANDARD_PAL_SECAM_LP:
5482 ki_innergain_min = (u16) (-32768);
5483 if_iaccu_hi_tgt_min = 2047;
5487 clp_dir_to = (u16) (-9);
5488 sns_dir_to = (u16) (-9);
5489 ingain_tgt_max = 9000;
5491 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5492 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5493 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5495 pr_err("error %d\n", rc);
5504 /* for new AGC interface */
5505 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
5507 pr_err("error %d\n", rc);
5510 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
5512 pr_err("error %d\n", rc);
5514 } /* Gain fed from inner to outer AGC */
5515 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
5517 pr_err("error %d\n", rc);
5520 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
5522 pr_err("error %d\n", rc);
5525 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
5527 pr_err("error %d\n", rc);
5529 } /* set to p_agc_settings->top before */
5530 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
5532 pr_err("error %d\n", rc);
5535 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
5537 pr_err("error %d\n", rc);
5540 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
5542 pr_err("error %d\n", rc);
5545 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
5547 pr_err("error %d\n", rc);
5550 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
5552 pr_err("error %d\n", rc);
5555 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
5557 pr_err("error %d\n", rc);
5560 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
5562 pr_err("error %d\n", rc);
5565 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
5567 pr_err("error %d\n", rc);
5570 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
5572 pr_err("error %d\n", rc);
5575 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
5577 pr_err("error %d\n", rc);
5580 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
5582 pr_err("error %d\n", rc);
5585 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
5587 pr_err("error %d\n", rc);
5590 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
5592 pr_err("error %d\n", rc);
5595 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
5597 pr_err("error %d\n", rc);
5600 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
5602 pr_err("error %d\n", rc);
5605 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
5607 pr_err("error %d\n", rc);
5610 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
5612 pr_err("error %d\n", rc);
5615 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
5617 pr_err("error %d\n", rc);
5620 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
5622 pr_err("error %d\n", rc);
5625 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
5627 pr_err("error %d\n", rc);
5630 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
5632 pr_err("error %d\n", rc);
5636 agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
5637 if (common_attr->tuner_rf_agc_pol == true)
5638 agc_rf = 0x87ff - agc_rf;
5641 if (common_attr->tuner_if_agc_pol == true)
5642 agc_rf = 0x87ff - agc_rf;
5644 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
5646 pr_err("error %d\n", rc);
5649 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
5651 pr_err("error %d\n", rc);
5655 /* Set/restore Ki DGAIN factor */
5656 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5658 pr_err("error %d\n", rc);
5661 data &= ~SCU_RAM_AGC_KI_DGAIN__M;
5662 data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
5663 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5665 pr_err("error %d\n", rc);
5675 * \fn int set_frequency ()
5676 * \brief Set frequency shift.
5677 * \param demod instance of demodulator.
5678 * \param channel pointer to channel data.
5679 * \param tuner_freq_offset residual frequency from tuner.
5683 set_frequency(struct drx_demod_instance *demod,
5684 struct drx_channel *channel, s32 tuner_freq_offset)
5686 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5687 struct drxj_data *ext_attr = demod->my_ext_attr;
5689 s32 sampling_frequency = 0;
5690 s32 frequency_shift = 0;
5691 s32 if_freq_actual = 0;
5692 s32 rf_freq_residual = -1 * tuner_freq_offset;
5694 s32 intermediate_freq = 0;
5695 u32 iqm_fs_rate_ofs = 0;
5696 bool adc_flip = true;
5697 bool select_pos_image = false;
5700 bool image_to_select = true;
5701 s32 fm_frequency_shift = 0;
5703 rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
5704 tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
5706 Program frequency shifter
5707 No need to account for mirroring on RF
5709 switch (ext_attr->standard) {
5710 case DRX_STANDARD_ITU_A: /* fallthrough */
5711 case DRX_STANDARD_ITU_C: /* fallthrough */
5712 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
5713 case DRX_STANDARD_8VSB:
5714 select_pos_image = true;
5716 case DRX_STANDARD_FM:
5717 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
5718 Sound carrier is already 3Mhz above centre frequency due
5719 to tuner setting so now add an extra shift of 1MHz... */
5720 fm_frequency_shift = 1000;
5721 case DRX_STANDARD_ITU_B: /* fallthrough */
5722 case DRX_STANDARD_NTSC: /* fallthrough */
5723 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
5724 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
5725 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
5726 case DRX_STANDARD_PAL_SECAM_L:
5727 select_pos_image = false;
5732 intermediate_freq = demod->my_common_attr->intermediate_freq;
5733 sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
5735 if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
5737 if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
5738 if (if_freq_actual > sampling_frequency / 2) {
5740 adc_freq = sampling_frequency - if_freq_actual;
5743 /* adc doesn't mirror */
5744 adc_freq = if_freq_actual;
5748 frequency_shift = adc_freq;
5750 (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
5751 iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
5753 if (image_to_select)
5754 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
5756 /* Program frequency shifter with tuner offset compensation */
5757 /* frequency_shift += tuner_freq_offset; TODO */
5758 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
5760 pr_err("error %d\n", rc);
5763 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
5764 ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
5772 * \fn int get_sig_strength()
5773 * \brief Retrieve signal strength for VSB and QAM.
5774 * \param demod Pointer to demod instance
5775 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
5777 * \retval 0 sig_strength contains valid data.
5778 * \retval -EINVAL sig_strength is NULL.
5779 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5781 #define DRXJ_AGC_TOP 0x2800
5782 #define DRXJ_AGC_SNS 0x1600
5783 #define DRXJ_RFAGC_MAX 0x3fff
5784 #define DRXJ_RFAGC_MIN 0x800
5786 static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
5788 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5797 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
5799 pr_err("error %d\n", rc);
5802 if_gain &= IQM_AF_AGC_IF__M;
5803 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
5805 pr_err("error %d\n", rc);
5808 rf_gain &= IQM_AF_AGC_RF__M;
5810 if_agc_sns = DRXJ_AGC_SNS;
5811 if_agc_top = DRXJ_AGC_TOP;
5812 rf_agc_max = DRXJ_RFAGC_MAX;
5813 rf_agc_min = DRXJ_RFAGC_MIN;
5815 if (if_gain > if_agc_top) {
5816 if (rf_gain > rf_agc_max)
5817 *sig_strength = 100;
5818 else if (rf_gain > rf_agc_min) {
5819 if (rf_agc_max == rf_agc_min) {
5820 pr_err("error: rf_agc_max == rf_agc_min\n");
5824 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
5828 } else if (if_gain > if_agc_sns) {
5829 if (if_agc_top == if_agc_sns) {
5830 pr_err("error: if_agc_top == if_agc_sns\n");
5834 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
5837 pr_err("error: if_agc_sns is zero!\n");
5840 *sig_strength = (20 * if_gain / if_agc_sns);
5849 * \fn int get_acc_pkt_err()
5850 * \brief Retrieve signal strength for VSB and QAM.
5851 * \param demod Pointer to demod instance
5852 * \param packet_err Pointer to packet error
5854 * \retval 0 sig_strength contains valid data.
5855 * \retval -EINVAL sig_strength is NULL.
5856 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5858 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5859 static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
5863 static u16 last_pkt_err;
5865 struct drxj_data *ext_attr = NULL;
5866 struct i2c_device_addr *dev_addr = NULL;
5868 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5869 dev_addr = demod->my_i2c_dev_addr;
5871 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
5873 pr_err("error %d\n", rc);
5876 if (ext_attr->reset_pkt_err_acc) {
5877 last_pkt_err = data;
5879 ext_attr->reset_pkt_err_acc = false;
5882 if (data < last_pkt_err) {
5883 pkt_err += 0xffff - last_pkt_err;
5886 pkt_err += (data - last_pkt_err);
5888 *packet_err = pkt_err;
5889 last_pkt_err = data;
5898 * \fn int ResetAccPktErr()
5899 * \brief Reset Accumulating packet error count.
5900 * \param demod Pointer to demod instance
5903 * \retval -EIO Erroneous data.
5905 static int ctrl_set_cfg_reset_pkt_err(struct drx_demod_instance *demod)
5907 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5908 struct drxj_data *ext_attr = NULL;
5910 u16 packet_error = 0;
5912 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5913 ext_attr->reset_pkt_err_acc = true;
5914 /* call to reset counter */
5915 rc = get_acc_pkt_err(demod, &packet_error);
5917 pr_err("error %d\n", rc);
5928 * \fn static short get_str_freq_offset()
5929 * \brief Get symbol rate offset in QAM & 8VSB mode
5930 * \return Error code
5932 static int get_str_freq_offset(struct drx_demod_instance *demod, s32 *str_freq)
5935 u32 symbol_frequency_ratio = 0;
5936 u32 symbol_nom_frequency_ratio = 0;
5938 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5939 struct drxj_data *ext_attr = demod->my_ext_attr;
5941 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &symbol_frequency_ratio, 0);
5943 pr_err("error %d\n", rc);
5946 symbol_nom_frequency_ratio = ext_attr->iqm_rc_rate_ofs;
5948 if (symbol_frequency_ratio > symbol_nom_frequency_ratio)
5951 frac_times1e6((symbol_frequency_ratio -
5952 symbol_nom_frequency_ratio),
5953 (symbol_frequency_ratio + (1 << 23)));
5956 frac_times1e6((symbol_nom_frequency_ratio -
5957 symbol_frequency_ratio),
5958 (symbol_frequency_ratio + (1 << 23)));
5966 * \fn static short get_ctl_freq_offset
5967 * \brief Get the value of ctl_freq in QAM & ATSC mode
5968 * \return Error code
5970 static int get_ctl_freq_offset(struct drx_demod_instance *demod, s32 *ctl_freq)
5972 s32 sampling_frequency = 0;
5973 s32 current_frequency = 0;
5974 s32 nominal_frequency = 0;
5975 s32 carrier_frequency_shift = 0;
5979 struct drxj_data *ext_attr = NULL;
5980 struct drx_common_attr *common_attr = NULL;
5981 struct i2c_device_addr *dev_addr = NULL;
5984 dev_addr = demod->my_i2c_dev_addr;
5985 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5986 common_attr = (struct drx_common_attr *) demod->my_common_attr;
5988 sampling_frequency = common_attr->sys_clock_freq / 3;
5990 /* both registers are sign extended */
5991 nominal_frequency = ext_attr->iqm_fs_rate_ofs;
5992 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, (u32 *)¤t_frequency, 0);
5994 pr_err("error %d\n", rc);
5998 if (ext_attr->pos_image) {
5999 /* negative image */
6000 carrier_frequency_shift = nominal_frequency - current_frequency;
6002 /* positive image */
6003 carrier_frequency_shift = current_frequency - nominal_frequency;
6006 /* carrier Frequency Shift In Hz */
6007 if (carrier_frequency_shift < 0) {
6009 carrier_frequency_shift *= sign;
6012 /* *ctl_freq = carrier_frequency_shift * 50.625e6 / (1 << 28); */
6013 mult32(carrier_frequency_shift, sampling_frequency, &data64hi, &data64lo);
6015 (s32) ((((data64lo >> 28) & 0xf) | (data64hi << 4)) * sign);
6022 /*============================================================================*/
6025 * \fn int set_agc_rf ()
6026 * \brief Configure RF AGC
6027 * \param demod instance of demodulator.
6028 * \param agc_settings AGC configuration structure
6032 set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
6034 struct i2c_device_addr *dev_addr = NULL;
6035 struct drxj_data *ext_attr = NULL;
6036 struct drxj_cfg_agc *p_agc_settings = NULL;
6037 struct drx_common_attr *common_attr = NULL;
6039 drx_write_reg16func_t scu_wr16 = NULL;
6040 drx_read_reg16func_t scu_rr16 = NULL;
6042 common_attr = (struct drx_common_attr *) demod->my_common_attr;
6043 dev_addr = demod->my_i2c_dev_addr;
6044 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6047 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
6048 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
6050 scu_rr16 = DRXJ_DAP.read_reg16func;
6051 scu_wr16 = DRXJ_DAP.write_reg16func;
6054 /* Configure AGC only if standard is currently active */
6055 if ((ext_attr->standard == agc_settings->standard) ||
6056 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6057 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6058 (DRXJ_ISATVSTD(ext_attr->standard) &&
6059 DRXJ_ISATVSTD(agc_settings->standard))) {
6062 switch (agc_settings->ctrl_mode) {
6063 case DRX_AGC_CTRL_AUTO:
6065 /* Enable RF AGC DAC */
6066 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6068 pr_err("error %d\n", rc);
6071 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
6072 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6074 pr_err("error %d\n", rc);
6078 /* Enable SCU RF AGC loop */
6079 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6081 pr_err("error %d\n", rc);
6084 data &= ~SCU_RAM_AGC_KI_RF__M;
6085 if (ext_attr->standard == DRX_STANDARD_8VSB)
6086 data |= (2 << SCU_RAM_AGC_KI_RF__B);
6087 else if (DRXJ_ISQAMSTD(ext_attr->standard))
6088 data |= (5 << SCU_RAM_AGC_KI_RF__B);
6090 data |= (4 << SCU_RAM_AGC_KI_RF__B);
6092 if (common_attr->tuner_rf_agc_pol)
6093 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
6095 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
6096 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6098 pr_err("error %d\n", rc);
6102 /* Set speed ( using complementary reduction value ) */
6103 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
6105 pr_err("error %d\n", rc);
6108 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
6109 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);
6111 pr_err("error %d\n", rc);
6115 if (agc_settings->standard == DRX_STANDARD_8VSB)
6116 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
6117 else if (DRXJ_ISQAMSTD(agc_settings->standard))
6118 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
6119 else if (DRXJ_ISATVSTD(agc_settings->standard))
6120 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
6124 /* Set TOP, only if IF-AGC is in AUTO mode */
6125 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
6126 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
6128 pr_err("error %d\n", rc);
6131 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
6133 pr_err("error %d\n", rc);
6138 /* Cut-Off current */
6139 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
6141 pr_err("error %d\n", rc);
6145 case DRX_AGC_CTRL_USER:
6147 /* Enable RF AGC DAC */
6148 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6150 pr_err("error %d\n", rc);
6153 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
6154 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6156 pr_err("error %d\n", rc);
6160 /* Disable SCU RF AGC loop */
6161 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6163 pr_err("error %d\n", rc);
6166 data &= ~SCU_RAM_AGC_KI_RF__M;
6167 if (common_attr->tuner_rf_agc_pol)
6168 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
6170 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
6171 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6173 pr_err("error %d\n", rc);
6177 /* Write value to output pin */
6178 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
6180 pr_err("error %d\n", rc);
6184 case DRX_AGC_CTRL_OFF:
6186 /* Disable RF AGC DAC */
6187 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6189 pr_err("error %d\n", rc);
6192 data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
6193 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6195 pr_err("error %d\n", rc);
6199 /* Disable SCU RF AGC loop */
6200 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6202 pr_err("error %d\n", rc);
6205 data &= ~SCU_RAM_AGC_KI_RF__M;
6206 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6208 pr_err("error %d\n", rc);
6214 } /* switch ( agcsettings->ctrl_mode ) */
6217 /* Store rf agc settings */
6218 switch (agc_settings->standard) {
6219 case DRX_STANDARD_8VSB:
6220 ext_attr->vsb_rf_agc_cfg = *agc_settings;
6222 #ifndef DRXJ_VSB_ONLY
6223 case DRX_STANDARD_ITU_A:
6224 case DRX_STANDARD_ITU_B:
6225 case DRX_STANDARD_ITU_C:
6226 ext_attr->qam_rf_agc_cfg = *agc_settings;
6229 #ifndef DRXJ_DIGITAL_ONLY
6230 case DRX_STANDARD_PAL_SECAM_BG:
6231 case DRX_STANDARD_PAL_SECAM_DK:
6232 case DRX_STANDARD_PAL_SECAM_I:
6233 case DRX_STANDARD_PAL_SECAM_L:
6234 case DRX_STANDARD_PAL_SECAM_LP:
6235 case DRX_STANDARD_NTSC:
6236 case DRX_STANDARD_FM:
6237 ext_attr->atv_rf_agc_cfg = *agc_settings;
6250 * \fn int get_agc_rf ()
6251 * \brief get configuration of RF AGC
6252 * \param demod instance of demodulator.
6253 * \param agc_settings AGC configuration structure
6257 get_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6259 struct i2c_device_addr *dev_addr = NULL;
6260 struct drxj_data *ext_attr = NULL;
6261 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6264 dev_addr = demod->my_i2c_dev_addr;
6265 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6267 /* Return stored AGC settings */
6268 standard = agc_settings->standard;
6269 switch (agc_settings->standard) {
6270 case DRX_STANDARD_8VSB:
6271 *agc_settings = ext_attr->vsb_rf_agc_cfg;
6273 #ifndef DRXJ_VSB_ONLY
6274 case DRX_STANDARD_ITU_A:
6275 case DRX_STANDARD_ITU_B:
6276 case DRX_STANDARD_ITU_C:
6277 *agc_settings = ext_attr->qam_rf_agc_cfg;
6280 #ifndef DRXJ_DIGITAL_ONLY
6281 case DRX_STANDARD_PAL_SECAM_BG:
6282 case DRX_STANDARD_PAL_SECAM_DK:
6283 case DRX_STANDARD_PAL_SECAM_I:
6284 case DRX_STANDARD_PAL_SECAM_L:
6285 case DRX_STANDARD_PAL_SECAM_LP:
6286 case DRX_STANDARD_NTSC:
6287 case DRX_STANDARD_FM:
6288 *agc_settings = ext_attr->atv_rf_agc_cfg;
6294 agc_settings->standard = standard;
6296 /* Get AGC output only if standard is currently active. */
6297 if ((ext_attr->standard == agc_settings->standard) ||
6298 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6299 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6300 (DRXJ_ISATVSTD(ext_attr->standard) &&
6301 DRXJ_ISATVSTD(agc_settings->standard))) {
6302 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, &(agc_settings->output_level), 0);
6304 pr_err("error %d\n", rc);
6315 * \fn int set_agc_if ()
6316 * \brief Configure If AGC
6317 * \param demod instance of demodulator.
6318 * \param agc_settings AGC configuration structure
6322 set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
6324 struct i2c_device_addr *dev_addr = NULL;
6325 struct drxj_data *ext_attr = NULL;
6326 struct drxj_cfg_agc *p_agc_settings = NULL;
6327 struct drx_common_attr *common_attr = NULL;
6328 drx_write_reg16func_t scu_wr16 = NULL;
6329 drx_read_reg16func_t scu_rr16 = NULL;
6332 common_attr = (struct drx_common_attr *) demod->my_common_attr;
6333 dev_addr = demod->my_i2c_dev_addr;
6334 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6337 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
6338 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
6340 scu_rr16 = DRXJ_DAP.read_reg16func;
6341 scu_wr16 = DRXJ_DAP.write_reg16func;
6344 /* Configure AGC only if standard is currently active */
6345 if ((ext_attr->standard == agc_settings->standard) ||
6346 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6347 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6348 (DRXJ_ISATVSTD(ext_attr->standard) &&
6349 DRXJ_ISATVSTD(agc_settings->standard))) {
6352 switch (agc_settings->ctrl_mode) {
6353 case DRX_AGC_CTRL_AUTO:
6354 /* Enable IF AGC DAC */
6355 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6357 pr_err("error %d\n", rc);
6360 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
6361 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6363 pr_err("error %d\n", rc);
6367 /* Enable SCU IF AGC loop */
6368 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6370 pr_err("error %d\n", rc);
6373 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6374 data &= ~SCU_RAM_AGC_KI_IF__M;
6375 if (ext_attr->standard == DRX_STANDARD_8VSB)
6376 data |= (3 << SCU_RAM_AGC_KI_IF__B);
6377 else if (DRXJ_ISQAMSTD(ext_attr->standard))
6378 data |= (6 << SCU_RAM_AGC_KI_IF__B);
6380 data |= (5 << SCU_RAM_AGC_KI_IF__B);
6382 if (common_attr->tuner_if_agc_pol)
6383 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
6385 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
6386 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6388 pr_err("error %d\n", rc);
6392 /* Set speed (using complementary reduction value) */
6393 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
6395 pr_err("error %d\n", rc);
6398 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
6399 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);
6401 pr_err("error %d\n", rc);
6405 if (agc_settings->standard == DRX_STANDARD_8VSB)
6406 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
6407 else if (DRXJ_ISQAMSTD(agc_settings->standard))
6408 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
6409 else if (DRXJ_ISATVSTD(agc_settings->standard))
6410 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
6415 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
6416 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
6418 pr_err("error %d\n", rc);
6421 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
6423 pr_err("error %d\n", rc);
6427 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
6429 pr_err("error %d\n", rc);
6432 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
6434 pr_err("error %d\n", rc);
6440 case DRX_AGC_CTRL_USER:
6442 /* Enable IF AGC DAC */
6443 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6445 pr_err("error %d\n", rc);
6448 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
6449 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6451 pr_err("error %d\n", rc);
6455 /* Disable SCU IF AGC loop */
6456 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6458 pr_err("error %d\n", rc);
6461 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6462 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6463 if (common_attr->tuner_if_agc_pol)
6464 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
6466 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
6467 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6469 pr_err("error %d\n", rc);
6473 /* Write value to output pin */
6474 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
6476 pr_err("error %d\n", rc);
6481 case DRX_AGC_CTRL_OFF:
6483 /* Disable If AGC DAC */
6484 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6486 pr_err("error %d\n", rc);
6489 data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
6490 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6492 pr_err("error %d\n", rc);
6496 /* Disable SCU IF AGC loop */
6497 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6499 pr_err("error %d\n", rc);
6502 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6503 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6504 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6506 pr_err("error %d\n", rc);
6512 } /* switch ( agcsettings->ctrl_mode ) */
6514 /* always set the top to support configurations without if-loop */
6515 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
6517 pr_err("error %d\n", rc);
6522 /* Store if agc settings */
6523 switch (agc_settings->standard) {
6524 case DRX_STANDARD_8VSB:
6525 ext_attr->vsb_if_agc_cfg = *agc_settings;
6527 #ifndef DRXJ_VSB_ONLY
6528 case DRX_STANDARD_ITU_A:
6529 case DRX_STANDARD_ITU_B:
6530 case DRX_STANDARD_ITU_C:
6531 ext_attr->qam_if_agc_cfg = *agc_settings;
6534 #ifndef DRXJ_DIGITAL_ONLY
6535 case DRX_STANDARD_PAL_SECAM_BG:
6536 case DRX_STANDARD_PAL_SECAM_DK:
6537 case DRX_STANDARD_PAL_SECAM_I:
6538 case DRX_STANDARD_PAL_SECAM_L:
6539 case DRX_STANDARD_PAL_SECAM_LP:
6540 case DRX_STANDARD_NTSC:
6541 case DRX_STANDARD_FM:
6542 ext_attr->atv_if_agc_cfg = *agc_settings;
6555 * \fn int get_agc_if ()
6556 * \brief get configuration of If AGC
6557 * \param demod instance of demodulator.
6558 * \param agc_settings AGC configuration structure
6562 get_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6564 struct i2c_device_addr *dev_addr = NULL;
6565 struct drxj_data *ext_attr = NULL;
6566 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6569 dev_addr = demod->my_i2c_dev_addr;
6570 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6572 /* Return stored ATV AGC settings */
6573 standard = agc_settings->standard;
6574 switch (agc_settings->standard) {
6575 case DRX_STANDARD_8VSB:
6576 *agc_settings = ext_attr->vsb_if_agc_cfg;
6578 #ifndef DRXJ_VSB_ONLY
6579 case DRX_STANDARD_ITU_A:
6580 case DRX_STANDARD_ITU_B:
6581 case DRX_STANDARD_ITU_C:
6582 *agc_settings = ext_attr->qam_if_agc_cfg;
6585 #ifndef DRXJ_DIGITAL_ONLY
6586 case DRX_STANDARD_PAL_SECAM_BG:
6587 case DRX_STANDARD_PAL_SECAM_DK:
6588 case DRX_STANDARD_PAL_SECAM_I:
6589 case DRX_STANDARD_PAL_SECAM_L:
6590 case DRX_STANDARD_PAL_SECAM_LP:
6591 case DRX_STANDARD_NTSC:
6592 case DRX_STANDARD_FM:
6593 *agc_settings = ext_attr->atv_if_agc_cfg;
6599 agc_settings->standard = standard;
6601 /* Get AGC output only if standard is currently active */
6602 if ((ext_attr->standard == agc_settings->standard) ||
6603 (DRXJ_ISQAMSTD(ext_attr->standard) &&
6604 DRXJ_ISQAMSTD(agc_settings->standard)) ||
6605 (DRXJ_ISATVSTD(ext_attr->standard) &&
6606 DRXJ_ISATVSTD(agc_settings->standard))) {
6607 /* read output level */
6608 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, &(agc_settings->output_level), 0);
6610 pr_err("error %d\n", rc);
6621 * \fn int set_iqm_af ()
6622 * \brief Configure IQM AF registers
6623 * \param demod instance of demodulator.
6627 static int set_iqm_af(struct drx_demod_instance *demod, bool active)
6630 struct i2c_device_addr *dev_addr = NULL;
6633 dev_addr = demod->my_i2c_dev_addr;
6636 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6638 pr_err("error %d\n", rc);
6642 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));
6644 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);
6645 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6647 pr_err("error %d\n", rc);
6656 /*============================================================================*/
6657 /*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
6658 /*============================================================================*/
6660 /*============================================================================*/
6661 /*============================================================================*/
6662 /*== 8VSB DATAPATH FUNCTIONS ==*/
6663 /*============================================================================*/
6664 /*============================================================================*/
6667 * \fn int power_down_vsb ()
6668 * \brief Powr down QAM related blocks.
6669 * \param demod instance of demodulator.
6670 * \param channel pointer to channel data.
6673 static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
6675 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6676 struct drxjscu_cmd cmd_scu = { /* command */ 0,
6677 /* parameter_len */ 0,
6679 /* *parameter */ NULL,
6682 struct drx_cfg_mpeg_output cfg_mpeg_output;
6688 reset of FEC and VSB HW
6690 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
6691 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6692 cmd_scu.parameter_len = 0;
6693 cmd_scu.result_len = 1;
6694 cmd_scu.parameter = NULL;
6695 cmd_scu.result = &cmd_result;
6696 rc = scu_command(dev_addr, &cmd_scu);
6698 pr_err("error %d\n", rc);
6702 /* stop all comm_exec */
6703 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
6705 pr_err("error %d\n", rc);
6708 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
6710 pr_err("error %d\n", rc);
6714 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
6716 pr_err("error %d\n", rc);
6719 rc = set_iqm_af(demod, false);
6721 pr_err("error %d\n", rc);
6725 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
6727 pr_err("error %d\n", rc);
6730 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
6732 pr_err("error %d\n", rc);
6735 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
6737 pr_err("error %d\n", rc);
6740 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
6742 pr_err("error %d\n", rc);
6745 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
6747 pr_err("error %d\n", rc);
6752 cfg_mpeg_output.enable_mpeg_output = false;
6753 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6755 pr_err("error %d\n", rc);
6765 * \fn int set_vsb_leak_n_gain ()
6766 * \brief Set ATSC demod.
6767 * \param demod instance of demodulator.
6770 static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
6772 struct i2c_device_addr *dev_addr = NULL;
6775 const u8 vsb_ffe_leak_gain_ram0[] = {
6776 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
6777 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
6778 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
6779 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
6780 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
6781 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
6782 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
6783 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
6784 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
6785 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
6786 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
6787 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
6788 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
6789 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
6790 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
6791 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
6792 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
6793 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
6794 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
6795 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
6796 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
6797 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
6798 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
6799 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
6800 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
6801 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
6802 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
6803 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
6804 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
6805 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
6806 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
6807 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
6808 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
6809 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
6810 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
6811 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
6812 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
6813 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
6814 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
6815 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
6816 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
6817 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
6818 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
6819 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
6820 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
6821 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
6822 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
6823 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
6824 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
6825 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
6826 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
6827 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
6828 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
6829 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
6830 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
6831 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
6832 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
6833 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
6834 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
6835 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
6836 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
6837 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
6838 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
6839 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
6840 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
6841 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
6842 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
6843 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
6844 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
6845 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
6846 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
6847 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
6848 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
6849 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
6850 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
6851 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
6852 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
6853 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
6854 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
6855 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
6856 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
6857 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
6858 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
6859 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
6860 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
6861 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
6862 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
6863 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
6864 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
6865 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
6866 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
6867 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
6868 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
6869 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
6870 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
6871 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
6872 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
6873 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
6874 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
6875 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
6876 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
6877 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
6878 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
6879 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
6880 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
6881 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
6882 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
6883 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
6884 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
6885 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
6886 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
6887 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
6888 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
6889 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
6890 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
6891 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
6892 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
6893 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
6894 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
6895 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
6896 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
6897 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
6898 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
6899 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
6900 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
6901 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
6902 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
6903 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
6906 const u8 vsb_ffe_leak_gain_ram1[] = {
6907 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
6908 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
6909 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
6910 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
6911 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
6912 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
6913 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
6914 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
6915 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
6916 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
6917 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
6918 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
6919 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
6920 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
6921 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
6922 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
6923 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
6924 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
6925 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
6926 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
6927 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
6928 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
6929 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
6930 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
6931 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
6932 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
6933 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
6934 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
6935 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
6936 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
6937 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
6938 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
6939 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
6940 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
6941 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
6942 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
6943 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
6944 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
6945 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
6946 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
6947 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
6948 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
6949 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
6950 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
6951 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
6952 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
6953 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
6954 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
6955 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
6956 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
6957 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
6958 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
6959 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
6960 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
6963 dev_addr = demod->my_i2c_dev_addr;
6964 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);
6966 pr_err("error %d\n", rc);
6969 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);
6971 pr_err("error %d\n", rc);
6982 * \brief Set 8VSB demod.
6983 * \param demod instance of demodulator.
6987 static int set_vsb(struct drx_demod_instance *demod)
6989 struct i2c_device_addr *dev_addr = NULL;
6991 struct drx_common_attr *common_attr = NULL;
6992 struct drxjscu_cmd cmd_scu;
6993 struct drxj_data *ext_attr = NULL;
6996 const u8 vsb_taps_re[] = {
6997 DRXJ_16TO8(-2), /* re0 */
6998 DRXJ_16TO8(4), /* re1 */
6999 DRXJ_16TO8(1), /* re2 */
7000 DRXJ_16TO8(-4), /* re3 */
7001 DRXJ_16TO8(1), /* re4 */
7002 DRXJ_16TO8(4), /* re5 */
7003 DRXJ_16TO8(-3), /* re6 */
7004 DRXJ_16TO8(-3), /* re7 */
7005 DRXJ_16TO8(6), /* re8 */
7006 DRXJ_16TO8(1), /* re9 */
7007 DRXJ_16TO8(-9), /* re10 */
7008 DRXJ_16TO8(3), /* re11 */
7009 DRXJ_16TO8(12), /* re12 */
7010 DRXJ_16TO8(-9), /* re13 */
7011 DRXJ_16TO8(-15), /* re14 */
7012 DRXJ_16TO8(17), /* re15 */
7013 DRXJ_16TO8(19), /* re16 */
7014 DRXJ_16TO8(-29), /* re17 */
7015 DRXJ_16TO8(-22), /* re18 */
7016 DRXJ_16TO8(45), /* re19 */
7017 DRXJ_16TO8(25), /* re20 */
7018 DRXJ_16TO8(-70), /* re21 */
7019 DRXJ_16TO8(-28), /* re22 */
7020 DRXJ_16TO8(111), /* re23 */
7021 DRXJ_16TO8(30), /* re24 */
7022 DRXJ_16TO8(-201), /* re25 */
7023 DRXJ_16TO8(-31), /* re26 */
7024 DRXJ_16TO8(629) /* re27 */
7027 dev_addr = demod->my_i2c_dev_addr;
7028 common_attr = (struct drx_common_attr *) demod->my_common_attr;
7029 ext_attr = (struct drxj_data *) demod->my_ext_attr;
7031 /* stop all comm_exec */
7032 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
7034 pr_err("error %d\n", rc);
7037 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
7039 pr_err("error %d\n", rc);
7042 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
7044 pr_err("error %d\n", rc);
7047 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
7049 pr_err("error %d\n", rc);
7052 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
7054 pr_err("error %d\n", rc);
7057 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
7059 pr_err("error %d\n", rc);
7062 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
7064 pr_err("error %d\n", rc);
7068 /* reset demodulator */
7069 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7070 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
7071 cmd_scu.parameter_len = 0;
7072 cmd_scu.result_len = 1;
7073 cmd_scu.parameter = NULL;
7074 cmd_scu.result = &cmd_result;
7075 rc = scu_command(dev_addr, &cmd_scu);
7077 pr_err("error %d\n", rc);
7081 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
7083 pr_err("error %d\n", rc);
7086 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
7088 pr_err("error %d\n", rc);
7091 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
7093 pr_err("error %d\n", rc);
7096 ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
7097 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
7099 pr_err("error %d\n", rc);
7102 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
7104 pr_err("error %d\n", rc);
7107 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
7109 pr_err("error %d\n", rc);
7113 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
7115 pr_err("error %d\n", rc);
7118 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, 28, 0);
7120 pr_err("error %d\n", rc);
7123 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
7125 pr_err("error %d\n", rc);
7128 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
7130 pr_err("error %d\n", rc);
7133 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
7135 pr_err("error %d\n", rc);
7138 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
7140 pr_err("error %d\n", rc);
7143 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE__A, 1393, 0);
7145 pr_err("error %d\n", rc);
7148 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
7150 pr_err("error %d\n", rc);
7153 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
7155 pr_err("error %d\n", rc);
7159 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
7161 pr_err("error %d\n", rc);
7164 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
7166 pr_err("error %d\n", rc);
7170 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
7172 pr_err("error %d\n", rc);
7174 } /* set higher threshold */
7175 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
7177 pr_err("error %d\n", rc);
7179 } /* burst detection on */
7180 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
7182 pr_err("error %d\n", rc);
7184 } /* drop thresholds by 1 dB */
7185 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
7187 pr_err("error %d\n", rc);
7189 } /* drop thresholds by 2 dB */
7190 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
7192 pr_err("error %d\n", rc);
7195 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
7197 pr_err("error %d\n", rc);
7201 /* Initialize the FEC Subsystem */
7202 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
7204 pr_err("error %d\n", rc);
7208 u16 fec_oc_snc_mode = 0;
7209 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
7211 pr_err("error %d\n", rc);
7214 /* output data even when not locked */
7215 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
7217 pr_err("error %d\n", rc);
7223 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
7225 pr_err("error %d\n", rc);
7228 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
7230 pr_err("error %d\n", rc);
7233 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
7235 pr_err("error %d\n", rc);
7238 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
7240 pr_err("error %d\n", rc);
7243 /* no transparent, no A&C framing; parity is set in mpegoutput */
7245 u16 fec_oc_reg_mode = 0;
7246 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
7248 pr_err("error %d\n", rc);
7251 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);
7253 pr_err("error %d\n", rc);
7258 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
7260 pr_err("error %d\n", rc);
7262 } /* timeout counter for restarting */
7263 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
7265 pr_err("error %d\n", rc);
7268 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MODE__A, 0, 0);
7270 pr_err("error %d\n", rc);
7272 } /* bypass disabled */
7273 /* initialize RS packet error measurement parameters */
7274 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
7276 pr_err("error %d\n", rc);
7279 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
7281 pr_err("error %d\n", rc);
7285 /* init measurement period of MER/SER */
7286 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
7288 pr_err("error %d\n", rc);
7291 rc = DRXJ_DAP.write_reg32func(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
7293 pr_err("error %d\n", rc);
7296 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
7298 pr_err("error %d\n", rc);
7301 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
7303 pr_err("error %d\n", rc);
7307 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
7309 pr_err("error %d\n", rc);
7312 /* B-Input to ADC, PGA+filter in standby */
7313 if (!ext_attr->has_lna) {
7314 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
7316 pr_err("error %d\n", rc);
7321 /* turn on IQMAF. It has to be in front of setAgc**() */
7322 rc = set_iqm_af(demod, true);
7324 pr_err("error %d\n", rc);
7327 rc = adc_synchronization(demod);
7329 pr_err("error %d\n", rc);
7333 rc = init_agc(demod);
7335 pr_err("error %d\n", rc);
7338 rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
7340 pr_err("error %d\n", rc);
7343 rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
7345 pr_err("error %d\n", rc);
7349 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
7351 struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
7353 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
7354 rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
7356 pr_err("error %d\n", rc);
7360 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
7362 pr_err("error %d\n", rc);
7366 /* Mpeg output has to be in front of FEC active */
7367 rc = set_mpegtei_handling(demod);
7369 pr_err("error %d\n", rc);
7372 rc = bit_reverse_mpeg_output(demod);
7374 pr_err("error %d\n", rc);
7377 rc = set_mpeg_start_width(demod);
7379 pr_err("error %d\n", rc);
7383 /* TODO: move to set_standard after hardware reset value problem is solved */
7384 /* Configure initial MPEG output */
7385 struct drx_cfg_mpeg_output cfg_mpeg_output;
7386 cfg_mpeg_output.enable_mpeg_output = true;
7387 cfg_mpeg_output.insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
7388 cfg_mpeg_output.enable_parallel =
7389 common_attr->mpeg_cfg.enable_parallel;
7390 cfg_mpeg_output.invert_data = common_attr->mpeg_cfg.invert_data;
7391 cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
7392 cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
7393 cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
7394 cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
7395 cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
7396 cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
7397 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
7399 pr_err("error %d\n", rc);
7404 /* TBD: what parameters should be set */
7405 cmd_param = 0x00; /* Default mode AGC on, etc */
7406 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7407 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
7408 cmd_scu.parameter_len = 1;
7409 cmd_scu.result_len = 1;
7410 cmd_scu.parameter = &cmd_param;
7411 cmd_scu.result = &cmd_result;
7412 rc = scu_command(dev_addr, &cmd_scu);
7414 pr_err("error %d\n", rc);
7418 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
7420 pr_err("error %d\n", rc);
7423 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
7425 pr_err("error %d\n", rc);
7428 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
7430 pr_err("error %d\n", rc);
7433 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
7435 pr_err("error %d\n", rc);
7438 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
7440 pr_err("error %d\n", rc);
7443 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
7445 pr_err("error %d\n", rc);
7448 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
7450 pr_err("error %d\n", rc);
7453 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
7455 pr_err("error %d\n", rc);
7459 /* start demodulator */
7460 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7461 | SCU_RAM_COMMAND_CMD_DEMOD_START;
7462 cmd_scu.parameter_len = 0;
7463 cmd_scu.result_len = 1;
7464 cmd_scu.parameter = NULL;
7465 cmd_scu.result = &cmd_result;
7466 rc = scu_command(dev_addr, &cmd_scu);
7468 pr_err("error %d\n", rc);
7472 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
7474 pr_err("error %d\n", rc);
7477 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
7479 pr_err("error %d\n", rc);
7482 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
7484 pr_err("error %d\n", rc);
7494 * \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
7495 * \brief Get the values of packet error in 8VSB mode
7496 * \return Error code
7498 static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *pck_errs)
7504 u16 packet_errors_mant = 0;
7505 u16 packet_errors_exp = 0;
7507 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
7509 pr_err("error %d\n", rc);
7512 packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
7513 packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
7514 >> FEC_RS_NR_FAILURES_EXP__B;
7515 period = FEC_RS_MEASUREMENT_PERIOD;
7516 prescale = FEC_RS_MEASUREMENT_PRESCALE;
7517 /* packet error rate = (error packet number) per second */
7518 /* 77.3 us is time for per packet */
7519 if (period * prescale == 0) {
7520 pr_err("error: period and/or prescale is zero!\n");
7524 (u16) frac_times1e6(packet_errors_mant * (1 << packet_errors_exp),
7525 (period * prescale * 77));
7533 * \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
7534 * \brief Get the values of ber in VSB mode
7535 * \return Error code
7537 static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7543 u16 bit_errors_mant = 0;
7544 u16 bit_errors_exp = 0;
7546 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
7548 pr_err("error %d\n", rc);
7551 period = FEC_RS_MEASUREMENT_PERIOD;
7552 prescale = FEC_RS_MEASUREMENT_PRESCALE;
7554 bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
7555 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
7556 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
7558 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
7561 if (period * prescale == 0) {
7562 pr_err("error: period and/or prescale is zero!\n");
7566 frac_times1e6(bit_errors_mant <<
7568 2) ? (bit_errors_exp - 3) : bit_errors_exp),
7569 period * prescale * 207 *
7570 ((bit_errors_exp > 2) ? 1 : 8));
7579 * \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7580 * \brief Get the values of ber in VSB mode
7581 * \return Error code
7583 static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7588 rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
7590 pr_err("error %d\n", rc);
7595 VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT);
7603 * \fn static short get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ber)
7604 * \brief Get the values of ber in VSB mode
7605 * \return Error code
7607 static int get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ser)
7613 u16 symb_errors_mant = 0;
7614 u16 symb_errors_exp = 0;
7616 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &data, 0);
7618 pr_err("error %d\n", rc);
7621 period = FEC_RS_MEASUREMENT_PERIOD;
7622 prescale = FEC_RS_MEASUREMENT_PRESCALE;
7624 symb_errors_mant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M;
7625 symb_errors_exp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M)
7626 >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B;
7628 if (period * prescale == 0) {
7629 pr_err("error: period and/or prescale is zero!\n");
7632 *ser = (u32) frac_times1e6((symb_errors_mant << symb_errors_exp) * 1000,
7633 (period * prescale * 77318));
7641 * \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7642 * \brief Get the values of MER
7643 * \return Error code
7645 static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7650 rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
7652 pr_err("error %d\n", rc);
7656 (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
7663 /*============================================================================*/
7665 * \fn int ctrl_get_vsb_constel()
7666 * \brief Retreive a VSB constellation point via I2C.
7667 * \param demod Pointer to demodulator instance.
7668 * \param complex_nr Pointer to the structure in which to store the
7669 constellation point.
7673 ctrl_get_vsb_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
7675 struct i2c_device_addr *dev_addr = NULL;
7677 /**< device address */
7678 u16 vsb_top_comm_mb = 0; /**< VSB SL MB configuration */
7679 u16 vsb_top_comm_mb_init = 0; /**< VSB SL MB intial configuration */
7680 u16 re = 0; /**< constellation Re part */
7683 /* read device info */
7684 dev_addr = demod->my_i2c_dev_addr;
7687 /* Monitor bus grabbing is an open external interface issue */
7688 /* Needs to be checked when external interface PG is updated */
7690 /* Configure MB (Monitor bus) */
7691 rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_COMM_MB__A, &vsb_top_comm_mb_init, 0);
7693 pr_err("error %d\n", rc);
7696 /* set observe flag & MB mux */
7697 vsb_top_comm_mb = (vsb_top_comm_mb_init |
7698 VSB_TOP_COMM_MB_OBS_OBS_ON |
7699 VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2);
7700 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb, 0);
7702 pr_err("error %d\n", rc);
7706 /* Enable MB grabber in the FEC OC */
7707 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M, 0);
7709 pr_err("error %d\n", rc);
7713 /* Disable MB grabber in the FEC OC */
7714 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, 0x0, 0);
7716 pr_err("error %d\n", rc);
7721 rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_OCR_GRAB_RD1__A, &data, 0);
7723 pr_err("error %d\n", rc);
7726 re = (u16) (((data >> 10) & 0x300) | ((data >> 2) & 0xff));
7729 complex_nr->re = re;
7732 /* Restore MB (Monitor bus) */
7733 rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb_init, 0);
7735 pr_err("error %d\n", rc);
7744 /*============================================================================*/
7745 /*== END 8VSB DATAPATH FUNCTIONS ==*/
7746 /*============================================================================*/
7748 /*============================================================================*/
7749 /*============================================================================*/
7750 /*== QAM DATAPATH FUNCTIONS ==*/
7751 /*============================================================================*/
7752 /*============================================================================*/
7755 * \fn int power_down_qam ()
7756 * \brief Powr down QAM related blocks.
7757 * \param demod instance of demodulator.
7758 * \param channel pointer to channel data.
7761 static int power_down_qam(struct drx_demod_instance *demod, bool primary)
7763 struct drxjscu_cmd cmd_scu = { /* command */ 0,
7764 /* parameter_len */ 0,
7766 /* *parameter */ NULL,
7770 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7771 struct drx_cfg_mpeg_output cfg_mpeg_output;
7776 resets IQM, QAM and FEC HW blocks
7778 /* stop all comm_exec */
7779 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
7781 pr_err("error %d\n", rc);
7784 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
7786 pr_err("error %d\n", rc);
7790 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
7791 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
7792 cmd_scu.parameter_len = 0;
7793 cmd_scu.result_len = 1;
7794 cmd_scu.parameter = NULL;
7795 cmd_scu.result = &cmd_result;
7796 rc = scu_command(dev_addr, &cmd_scu);
7798 pr_err("error %d\n", rc);
7803 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
7805 pr_err("error %d\n", rc);
7808 rc = set_iqm_af(demod, false);
7810 pr_err("error %d\n", rc);
7814 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
7816 pr_err("error %d\n", rc);
7819 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
7821 pr_err("error %d\n", rc);
7824 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
7826 pr_err("error %d\n", rc);
7829 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
7831 pr_err("error %d\n", rc);
7834 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
7836 pr_err("error %d\n", rc);
7841 cfg_mpeg_output.enable_mpeg_output = false;
7842 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
7844 pr_err("error %d\n", rc);
7853 /*============================================================================*/
7856 * \fn int set_qam_measurement ()
7857 * \brief Setup of the QAM Measuremnt intervals for signal quality
7858 * \param demod instance of demod.
7859 * \param constellation current constellation.
7863 * Take into account that for certain settings the errorcounters can overflow.
7864 * The implementation does not check this.
7866 * TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
7867 * constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
7871 #ifndef DRXJ_VSB_ONLY
7873 set_qam_measurement(struct drx_demod_instance *demod,
7874 enum drx_modulation constellation, u32 symbol_rate)
7876 struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */
7877 struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specif data */
7879 u32 fec_bits_desired = 0; /* BER accounting period */
7880 u16 fec_rs_plen = 0; /* defines RS BER measurement period */
7881 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
7882 u32 fec_rs_period = 0; /* Value for corresponding I2C register */
7883 u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
7884 u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
7885 u32 qam_vd_period = 0; /* Value for corresponding I2C register */
7886 u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
7887 u16 fec_vd_plen = 0; /* no of trellis symbols: VD SER measur period */
7888 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
7890 dev_addr = demod->my_i2c_dev_addr;
7891 ext_attr = (struct drxj_data *) demod->my_ext_attr;
7893 fec_bits_desired = ext_attr->fec_bits_desired;
7894 fec_rs_prescale = ext_attr->fec_rs_prescale;
7896 switch (constellation) {
7897 case DRX_CONSTELLATION_QAM16:
7898 fec_bits_desired = 4 * symbol_rate;
7900 case DRX_CONSTELLATION_QAM32:
7901 fec_bits_desired = 5 * symbol_rate;
7903 case DRX_CONSTELLATION_QAM64:
7904 fec_bits_desired = 6 * symbol_rate;
7906 case DRX_CONSTELLATION_QAM128:
7907 fec_bits_desired = 7 * symbol_rate;
7909 case DRX_CONSTELLATION_QAM256:
7910 fec_bits_desired = 8 * symbol_rate;
7916 /* Parameters for Reed-Solomon Decoder */
7917 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
7918 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
7919 /* result is within 32 bit arithmetic -> */
7920 /* no need for mult or frac functions */
7922 /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
7923 switch (ext_attr->standard) {
7924 case DRX_STANDARD_ITU_A:
7925 case DRX_STANDARD_ITU_C:
7926 fec_rs_plen = 204 * 8;
7928 case DRX_STANDARD_ITU_B:
7929 fec_rs_plen = 128 * 7;
7935 ext_attr->fec_rs_plen = fec_rs_plen; /* for getSigQual */
7936 fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage */
7937 if (fec_rs_bit_cnt == 0) {
7938 pr_err("error: fec_rs_bit_cnt is zero!\n");
7941 fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1; /* ceil */
7942 if (ext_attr->standard != DRX_STANDARD_ITU_B)
7943 fec_oc_snc_fail_period = fec_rs_period;
7945 /* limit to max 16 bit value (I2C register width) if needed */
7946 if (fec_rs_period > 0xFFFF)
7947 fec_rs_period = 0xFFFF;
7949 /* write corresponding registers */
7950 switch (ext_attr->standard) {
7951 case DRX_STANDARD_ITU_A:
7952 case DRX_STANDARD_ITU_C:
7954 case DRX_STANDARD_ITU_B:
7955 switch (constellation) {
7956 case DRX_CONSTELLATION_QAM64:
7957 fec_rs_period = 31581;
7958 fec_oc_snc_fail_period = 17932;
7960 case DRX_CONSTELLATION_QAM256:
7961 fec_rs_period = 45446;
7962 fec_oc_snc_fail_period = 25805;
7972 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
7974 pr_err("error %d\n", rc);
7977 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
7979 pr_err("error %d\n", rc);
7982 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
7984 pr_err("error %d\n", rc);
7987 ext_attr->fec_rs_period = (u16) fec_rs_period;
7988 ext_attr->fec_rs_prescale = fec_rs_prescale;
7989 rc = DRXJ_DAP.write_reg32func(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
7991 pr_err("error %d\n", rc);
7994 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
7996 pr_err("error %d\n", rc);
7999 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
8001 pr_err("error %d\n", rc);
8005 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8006 /* Parameters for Viterbi Decoder */
8007 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
8008 /* (qamvd_prescale*plen*(qam_constellation+1))) */
8009 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
8010 /* result is within 32 bit arithmetic -> */
8011 /* no need for mult or frac functions */
8013 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
8014 fec_vd_plen = ext_attr->fec_vd_plen;
8015 qam_vd_prescale = ext_attr->qam_vd_prescale;
8016 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
8018 switch (constellation) {
8019 case DRX_CONSTELLATION_QAM64:
8020 /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
8022 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
8023 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
8025 case DRX_CONSTELLATION_QAM256:
8026 /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
8028 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
8029 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
8034 if (qam_vd_period == 0) {
8035 pr_err("error: qam_vd_period is zero!\n");
8038 qam_vd_period = fec_bits_desired / qam_vd_period;
8039 /* limit to max 16 bit value (I2C register width) if needed */
8040 if (qam_vd_period > 0xFFFF)
8041 qam_vd_period = 0xFFFF;
8043 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
8044 qam_vd_bit_cnt *= qam_vd_period;
8046 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
8048 pr_err("error %d\n", rc);
8051 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
8053 pr_err("error %d\n", rc);
8056 ext_attr->qam_vd_period = (u16) qam_vd_period;
8057 ext_attr->qam_vd_prescale = qam_vd_prescale;
8065 /*============================================================================*/
8068 * \fn int set_qam16 ()
8069 * \brief QAM16 specific setup
8070 * \param demod instance of demod.
8073 static int set_qam16(struct drx_demod_instance *demod)
8075 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8077 const u8 qam_dq_qual_fun[] = {
8078 DRXJ_16TO8(2), /* fun0 */
8079 DRXJ_16TO8(2), /* fun1 */
8080 DRXJ_16TO8(2), /* fun2 */
8081 DRXJ_16TO8(2), /* fun3 */
8082 DRXJ_16TO8(3), /* fun4 */
8083 DRXJ_16TO8(3), /* fun5 */
8085 const u8 qam_eq_cma_rad[] = {
8086 DRXJ_16TO8(13517), /* RAD0 */
8087 DRXJ_16TO8(13517), /* RAD1 */
8088 DRXJ_16TO8(13517), /* RAD2 */
8089 DRXJ_16TO8(13517), /* RAD3 */
8090 DRXJ_16TO8(13517), /* RAD4 */
8091 DRXJ_16TO8(13517), /* RAD5 */
8094 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8096 pr_err("error %d\n", rc);
8099 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);
8101 pr_err("error %d\n", rc);
8105 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
8107 pr_err("error %d\n", rc);
8110 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
8112 pr_err("error %d\n", rc);
8115 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
8117 pr_err("error %d\n", rc);
8120 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
8122 pr_err("error %d\n", rc);
8125 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
8127 pr_err("error %d\n", rc);
8130 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
8132 pr_err("error %d\n", rc);
8136 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8138 pr_err("error %d\n", rc);
8141 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
8143 pr_err("error %d\n", rc);
8146 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8148 pr_err("error %d\n", rc);
8152 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
8154 pr_err("error %d\n", rc);
8157 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
8159 pr_err("error %d\n", rc);
8162 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
8164 pr_err("error %d\n", rc);
8167 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
8169 pr_err("error %d\n", rc);
8172 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
8174 pr_err("error %d\n", rc);
8177 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
8179 pr_err("error %d\n", rc);
8182 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
8184 pr_err("error %d\n", rc);
8188 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8190 pr_err("error %d\n", rc);
8193 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8195 pr_err("error %d\n", rc);
8198 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8200 pr_err("error %d\n", rc);
8203 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
8205 pr_err("error %d\n", rc);
8208 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8210 pr_err("error %d\n", rc);
8213 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8215 pr_err("error %d\n", rc);
8218 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
8220 pr_err("error %d\n", rc);
8223 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
8225 pr_err("error %d\n", rc);
8228 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8230 pr_err("error %d\n", rc);
8233 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8235 pr_err("error %d\n", rc);
8238 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8240 pr_err("error %d\n", rc);
8243 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8245 pr_err("error %d\n", rc);
8248 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8250 pr_err("error %d\n", rc);
8253 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8255 pr_err("error %d\n", rc);
8258 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8260 pr_err("error %d\n", rc);
8263 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8265 pr_err("error %d\n", rc);
8268 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
8270 pr_err("error %d\n", rc);
8273 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8275 pr_err("error %d\n", rc);
8278 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8280 pr_err("error %d\n", rc);
8283 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
8285 pr_err("error %d\n", rc);
8289 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
8291 pr_err("error %d\n", rc);
8300 /*============================================================================*/
8303 * \fn int set_qam32 ()
8304 * \brief QAM32 specific setup
8305 * \param demod instance of demod.
8308 static int set_qam32(struct drx_demod_instance *demod)
8310 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8312 const u8 qam_dq_qual_fun[] = {
8313 DRXJ_16TO8(3), /* fun0 */
8314 DRXJ_16TO8(3), /* fun1 */
8315 DRXJ_16TO8(3), /* fun2 */
8316 DRXJ_16TO8(3), /* fun3 */
8317 DRXJ_16TO8(4), /* fun4 */
8318 DRXJ_16TO8(4), /* fun5 */
8320 const u8 qam_eq_cma_rad[] = {
8321 DRXJ_16TO8(6707), /* RAD0 */
8322 DRXJ_16TO8(6707), /* RAD1 */
8323 DRXJ_16TO8(6707), /* RAD2 */
8324 DRXJ_16TO8(6707), /* RAD3 */
8325 DRXJ_16TO8(6707), /* RAD4 */
8326 DRXJ_16TO8(6707), /* RAD5 */
8329 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8331 pr_err("error %d\n", rc);
8334 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);
8336 pr_err("error %d\n", rc);
8340 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
8342 pr_err("error %d\n", rc);
8345 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
8347 pr_err("error %d\n", rc);
8350 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8352 pr_err("error %d\n", rc);
8355 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
8357 pr_err("error %d\n", rc);
8360 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8362 pr_err("error %d\n", rc);
8365 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
8367 pr_err("error %d\n", rc);
8371 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8373 pr_err("error %d\n", rc);
8376 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
8378 pr_err("error %d\n", rc);
8381 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8383 pr_err("error %d\n", rc);
8387 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
8389 pr_err("error %d\n", rc);
8392 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
8394 pr_err("error %d\n", rc);
8397 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
8399 pr_err("error %d\n", rc);
8402 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
8404 pr_err("error %d\n", rc);
8407 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
8409 pr_err("error %d\n", rc);
8412 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
8414 pr_err("error %d\n", rc);
8417 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
8419 pr_err("error %d\n", rc);
8423 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8425 pr_err("error %d\n", rc);
8428 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8430 pr_err("error %d\n", rc);
8433 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8435 pr_err("error %d\n", rc);
8438 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
8440 pr_err("error %d\n", rc);
8443 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8445 pr_err("error %d\n", rc);
8448 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8450 pr_err("error %d\n", rc);
8453 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
8455 pr_err("error %d\n", rc);
8458 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
8460 pr_err("error %d\n", rc);
8463 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8465 pr_err("error %d\n", rc);
8468 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8470 pr_err("error %d\n", rc);
8473 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8475 pr_err("error %d\n", rc);
8478 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8480 pr_err("error %d\n", rc);
8483 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8485 pr_err("error %d\n", rc);
8488 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8490 pr_err("error %d\n", rc);
8493 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8495 pr_err("error %d\n", rc);
8498 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8500 pr_err("error %d\n", rc);
8503 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
8505 pr_err("error %d\n", rc);
8508 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8510 pr_err("error %d\n", rc);
8513 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8515 pr_err("error %d\n", rc);
8518 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
8520 pr_err("error %d\n", rc);
8524 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
8526 pr_err("error %d\n", rc);
8535 /*============================================================================*/
8538 * \fn int set_qam64 ()
8539 * \brief QAM64 specific setup
8540 * \param demod instance of demod.
8543 static int set_qam64(struct drx_demod_instance *demod)
8545 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8547 const u8 qam_dq_qual_fun[] = { /* this is hw reset value. no necessary to re-write */
8548 DRXJ_16TO8(4), /* fun0 */
8549 DRXJ_16TO8(4), /* fun1 */
8550 DRXJ_16TO8(4), /* fun2 */
8551 DRXJ_16TO8(4), /* fun3 */
8552 DRXJ_16TO8(6), /* fun4 */
8553 DRXJ_16TO8(6), /* fun5 */
8555 const u8 qam_eq_cma_rad[] = {
8556 DRXJ_16TO8(13336), /* RAD0 */
8557 DRXJ_16TO8(12618), /* RAD1 */
8558 DRXJ_16TO8(11988), /* RAD2 */
8559 DRXJ_16TO8(13809), /* RAD3 */
8560 DRXJ_16TO8(13809), /* RAD4 */
8561 DRXJ_16TO8(15609), /* RAD5 */
8564 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8566 pr_err("error %d\n", rc);
8569 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);
8571 pr_err("error %d\n", rc);
8575 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
8577 pr_err("error %d\n", rc);
8580 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
8582 pr_err("error %d\n", rc);
8585 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8587 pr_err("error %d\n", rc);
8590 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
8592 pr_err("error %d\n", rc);
8595 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8597 pr_err("error %d\n", rc);
8600 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
8602 pr_err("error %d\n", rc);
8606 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8608 pr_err("error %d\n", rc);
8611 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
8613 pr_err("error %d\n", rc);
8616 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8618 pr_err("error %d\n", rc);
8622 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
8624 pr_err("error %d\n", rc);
8627 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
8629 pr_err("error %d\n", rc);
8632 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
8634 pr_err("error %d\n", rc);
8637 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
8639 pr_err("error %d\n", rc);
8642 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
8644 pr_err("error %d\n", rc);
8647 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
8649 pr_err("error %d\n", rc);
8652 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
8654 pr_err("error %d\n", rc);
8658 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8660 pr_err("error %d\n", rc);
8663 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8665 pr_err("error %d\n", rc);
8668 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8670 pr_err("error %d\n", rc);
8673 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
8675 pr_err("error %d\n", rc);
8678 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8680 pr_err("error %d\n", rc);
8683 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8685 pr_err("error %d\n", rc);
8688 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
8690 pr_err("error %d\n", rc);
8693 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
8695 pr_err("error %d\n", rc);
8698 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8700 pr_err("error %d\n", rc);
8703 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8705 pr_err("error %d\n", rc);
8708 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8710 pr_err("error %d\n", rc);
8713 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8715 pr_err("error %d\n", rc);
8718 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8720 pr_err("error %d\n", rc);
8723 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8725 pr_err("error %d\n", rc);
8728 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8730 pr_err("error %d\n", rc);
8733 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
8735 pr_err("error %d\n", rc);
8738 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
8740 pr_err("error %d\n", rc);
8743 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8745 pr_err("error %d\n", rc);
8748 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8750 pr_err("error %d\n", rc);
8753 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
8755 pr_err("error %d\n", rc);
8759 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
8761 pr_err("error %d\n", rc);
8770 /*============================================================================*/
8773 * \fn int set_qam128 ()
8774 * \brief QAM128 specific setup
8775 * \param demod: instance of demod.
8778 static int set_qam128(struct drx_demod_instance *demod)
8780 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8782 const u8 qam_dq_qual_fun[] = {
8783 DRXJ_16TO8(6), /* fun0 */
8784 DRXJ_16TO8(6), /* fun1 */
8785 DRXJ_16TO8(6), /* fun2 */
8786 DRXJ_16TO8(6), /* fun3 */
8787 DRXJ_16TO8(9), /* fun4 */
8788 DRXJ_16TO8(9), /* fun5 */
8790 const u8 qam_eq_cma_rad[] = {
8791 DRXJ_16TO8(6164), /* RAD0 */
8792 DRXJ_16TO8(6598), /* RAD1 */
8793 DRXJ_16TO8(6394), /* RAD2 */
8794 DRXJ_16TO8(6409), /* RAD3 */
8795 DRXJ_16TO8(6656), /* RAD4 */
8796 DRXJ_16TO8(7238), /* RAD5 */
8799 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8801 pr_err("error %d\n", rc);
8804 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);
8806 pr_err("error %d\n", rc);
8810 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
8812 pr_err("error %d\n", rc);
8815 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
8817 pr_err("error %d\n", rc);
8820 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8822 pr_err("error %d\n", rc);
8825 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
8827 pr_err("error %d\n", rc);
8830 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8832 pr_err("error %d\n", rc);
8835 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
8837 pr_err("error %d\n", rc);
8841 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8843 pr_err("error %d\n", rc);
8846 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
8848 pr_err("error %d\n", rc);
8851 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8853 pr_err("error %d\n", rc);
8857 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
8859 pr_err("error %d\n", rc);
8862 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
8864 pr_err("error %d\n", rc);
8867 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
8869 pr_err("error %d\n", rc);
8872 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
8874 pr_err("error %d\n", rc);
8877 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
8879 pr_err("error %d\n", rc);
8882 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
8884 pr_err("error %d\n", rc);
8887 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
8889 pr_err("error %d\n", rc);
8893 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8895 pr_err("error %d\n", rc);
8898 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8900 pr_err("error %d\n", rc);
8903 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8905 pr_err("error %d\n", rc);
8908 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
8910 pr_err("error %d\n", rc);
8913 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8915 pr_err("error %d\n", rc);
8918 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8920 pr_err("error %d\n", rc);
8923 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
8925 pr_err("error %d\n", rc);
8928 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
8930 pr_err("error %d\n", rc);
8933 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8935 pr_err("error %d\n", rc);
8938 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8940 pr_err("error %d\n", rc);
8943 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8945 pr_err("error %d\n", rc);
8948 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8950 pr_err("error %d\n", rc);
8953 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8955 pr_err("error %d\n", rc);
8958 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8960 pr_err("error %d\n", rc);
8963 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8965 pr_err("error %d\n", rc);
8968 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8970 pr_err("error %d\n", rc);
8973 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
8975 pr_err("error %d\n", rc);
8978 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8980 pr_err("error %d\n", rc);
8983 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8985 pr_err("error %d\n", rc);
8988 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
8990 pr_err("error %d\n", rc);
8994 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
8996 pr_err("error %d\n", rc);
9005 /*============================================================================*/
9008 * \fn int set_qam256 ()
9009 * \brief QAM256 specific setup
9010 * \param demod: instance of demod.
9013 static int set_qam256(struct drx_demod_instance *demod)
9015 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9017 const u8 qam_dq_qual_fun[] = {
9018 DRXJ_16TO8(8), /* fun0 */
9019 DRXJ_16TO8(8), /* fun1 */
9020 DRXJ_16TO8(8), /* fun2 */
9021 DRXJ_16TO8(8), /* fun3 */
9022 DRXJ_16TO8(12), /* fun4 */
9023 DRXJ_16TO8(12), /* fun5 */
9025 const u8 qam_eq_cma_rad[] = {
9026 DRXJ_16TO8(12345), /* RAD0 */
9027 DRXJ_16TO8(12345), /* RAD1 */
9028 DRXJ_16TO8(13626), /* RAD2 */
9029 DRXJ_16TO8(12931), /* RAD3 */
9030 DRXJ_16TO8(14719), /* RAD4 */
9031 DRXJ_16TO8(15356), /* RAD5 */
9034 rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9036 pr_err("error %d\n", rc);
9039 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);
9041 pr_err("error %d\n", rc);
9045 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
9047 pr_err("error %d\n", rc);
9050 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9052 pr_err("error %d\n", rc);
9055 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9057 pr_err("error %d\n", rc);
9060 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
9062 pr_err("error %d\n", rc);
9065 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9067 pr_err("error %d\n", rc);
9070 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
9072 pr_err("error %d\n", rc);
9076 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9078 pr_err("error %d\n", rc);
9081 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
9083 pr_err("error %d\n", rc);
9086 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9088 pr_err("error %d\n", rc);
9092 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
9094 pr_err("error %d\n", rc);
9097 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
9099 pr_err("error %d\n", rc);
9102 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
9104 pr_err("error %d\n", rc);
9107 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
9109 pr_err("error %d\n", rc);
9112 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
9114 pr_err("error %d\n", rc);
9117 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
9119 pr_err("error %d\n", rc);
9122 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
9124 pr_err("error %d\n", rc);
9128 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9130 pr_err("error %d\n", rc);
9133 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9135 pr_err("error %d\n", rc);
9138 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9140 pr_err("error %d\n", rc);
9143 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
9145 pr_err("error %d\n", rc);
9148 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9150 pr_err("error %d\n", rc);
9153 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9155 pr_err("error %d\n", rc);
9158 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
9160 pr_err("error %d\n", rc);
9163 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9165 pr_err("error %d\n", rc);
9168 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9170 pr_err("error %d\n", rc);
9173 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9175 pr_err("error %d\n", rc);
9178 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9180 pr_err("error %d\n", rc);
9183 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9185 pr_err("error %d\n", rc);
9188 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9190 pr_err("error %d\n", rc);
9193 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9195 pr_err("error %d\n", rc);
9198 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9200 pr_err("error %d\n", rc);
9203 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
9205 pr_err("error %d\n", rc);
9208 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
9210 pr_err("error %d\n", rc);
9213 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9215 pr_err("error %d\n", rc);
9218 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9220 pr_err("error %d\n", rc);
9223 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9225 pr_err("error %d\n", rc);
9229 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
9231 pr_err("error %d\n", rc);
9240 /*============================================================================*/
9241 #define QAM_SET_OP_ALL 0x1
9242 #define QAM_SET_OP_CONSTELLATION 0x2
9243 #define QAM_SET_OP_SPECTRUM 0X4
9246 * \fn int set_qam ()
9247 * \brief Set QAM demod.
9248 * \param demod: instance of demod.
9249 * \param channel: pointer to channel data.
9253 set_qam(struct drx_demod_instance *demod,
9254 struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
9256 struct i2c_device_addr *dev_addr = NULL;
9257 struct drxj_data *ext_attr = NULL;
9258 struct drx_common_attr *common_attr = NULL;
9260 u32 adc_frequency = 0;
9261 u32 iqm_rc_rate = 0;
9263 u16 lc_symbol_freq = 0;
9264 u16 iqm_rc_stretch = 0;
9265 u16 set_env_parameters = 0;
9266 u16 set_param_parameters[2] = { 0 };
9267 struct drxjscu_cmd cmd_scu = { /* command */ 0,
9268 /* parameter_len */ 0,
9270 /* parameter */ NULL,
9273 const u8 qam_a_taps[] = {
9274 DRXJ_16TO8(-1), /* re0 */
9275 DRXJ_16TO8(1), /* re1 */
9276 DRXJ_16TO8(1), /* re2 */
9277 DRXJ_16TO8(-1), /* re3 */
9278 DRXJ_16TO8(-1), /* re4 */
9279 DRXJ_16TO8(2), /* re5 */
9280 DRXJ_16TO8(1), /* re6 */
9281 DRXJ_16TO8(-2), /* re7 */
9282 DRXJ_16TO8(0), /* re8 */
9283 DRXJ_16TO8(3), /* re9 */
9284 DRXJ_16TO8(-1), /* re10 */
9285 DRXJ_16TO8(-3), /* re11 */
9286 DRXJ_16TO8(4), /* re12 */
9287 DRXJ_16TO8(1), /* re13 */
9288 DRXJ_16TO8(-8), /* re14 */
9289 DRXJ_16TO8(4), /* re15 */
9290 DRXJ_16TO8(13), /* re16 */
9291 DRXJ_16TO8(-13), /* re17 */
9292 DRXJ_16TO8(-19), /* re18 */
9293 DRXJ_16TO8(28), /* re19 */
9294 DRXJ_16TO8(25), /* re20 */
9295 DRXJ_16TO8(-53), /* re21 */
9296 DRXJ_16TO8(-31), /* re22 */
9297 DRXJ_16TO8(96), /* re23 */
9298 DRXJ_16TO8(37), /* re24 */
9299 DRXJ_16TO8(-190), /* re25 */
9300 DRXJ_16TO8(-40), /* re26 */
9301 DRXJ_16TO8(619) /* re27 */
9303 const u8 qam_b64_taps[] = {
9304 DRXJ_16TO8(0), /* re0 */
9305 DRXJ_16TO8(-2), /* re1 */
9306 DRXJ_16TO8(1), /* re2 */
9307 DRXJ_16TO8(2), /* re3 */
9308 DRXJ_16TO8(-2), /* re4 */
9309 DRXJ_16TO8(0), /* re5 */
9310 DRXJ_16TO8(4), /* re6 */
9311 DRXJ_16TO8(-2), /* re7 */
9312 DRXJ_16TO8(-4), /* re8 */
9313 DRXJ_16TO8(4), /* re9 */
9314 DRXJ_16TO8(3), /* re10 */
9315 DRXJ_16TO8(-6), /* re11 */
9316 DRXJ_16TO8(0), /* re12 */
9317 DRXJ_16TO8(6), /* re13 */
9318 DRXJ_16TO8(-5), /* re14 */
9319 DRXJ_16TO8(-3), /* re15 */
9320 DRXJ_16TO8(11), /* re16 */
9321 DRXJ_16TO8(-4), /* re17 */
9322 DRXJ_16TO8(-19), /* re18 */
9323 DRXJ_16TO8(19), /* re19 */
9324 DRXJ_16TO8(28), /* re20 */
9325 DRXJ_16TO8(-45), /* re21 */
9326 DRXJ_16TO8(-36), /* re22 */
9327 DRXJ_16TO8(90), /* re23 */
9328 DRXJ_16TO8(42), /* re24 */
9329 DRXJ_16TO8(-185), /* re25 */
9330 DRXJ_16TO8(-46), /* re26 */
9331 DRXJ_16TO8(614) /* re27 */
9333 const u8 qam_b256_taps[] = {
9334 DRXJ_16TO8(-2), /* re0 */
9335 DRXJ_16TO8(4), /* re1 */
9336 DRXJ_16TO8(1), /* re2 */
9337 DRXJ_16TO8(-4), /* re3 */
9338 DRXJ_16TO8(0), /* re4 */
9339 DRXJ_16TO8(4), /* re5 */
9340 DRXJ_16TO8(-2), /* re6 */
9341 DRXJ_16TO8(-4), /* re7 */
9342 DRXJ_16TO8(5), /* re8 */
9343 DRXJ_16TO8(2), /* re9 */
9344 DRXJ_16TO8(-8), /* re10 */
9345 DRXJ_16TO8(2), /* re11 */
9346 DRXJ_16TO8(11), /* re12 */
9347 DRXJ_16TO8(-8), /* re13 */
9348 DRXJ_16TO8(-15), /* re14 */
9349 DRXJ_16TO8(16), /* re15 */
9350 DRXJ_16TO8(19), /* re16 */
9351 DRXJ_16TO8(-27), /* re17 */
9352 DRXJ_16TO8(-22), /* re18 */
9353 DRXJ_16TO8(44), /* re19 */
9354 DRXJ_16TO8(26), /* re20 */
9355 DRXJ_16TO8(-69), /* re21 */
9356 DRXJ_16TO8(-28), /* re22 */
9357 DRXJ_16TO8(110), /* re23 */
9358 DRXJ_16TO8(31), /* re24 */
9359 DRXJ_16TO8(-201), /* re25 */
9360 DRXJ_16TO8(-32), /* re26 */
9361 DRXJ_16TO8(628) /* re27 */
9363 const u8 qam_c_taps[] = {
9364 DRXJ_16TO8(-3), /* re0 */
9365 DRXJ_16TO8(3), /* re1 */
9366 DRXJ_16TO8(2), /* re2 */
9367 DRXJ_16TO8(-4), /* re3 */
9368 DRXJ_16TO8(0), /* re4 */
9369 DRXJ_16TO8(4), /* re5 */
9370 DRXJ_16TO8(-1), /* re6 */
9371 DRXJ_16TO8(-4), /* re7 */
9372 DRXJ_16TO8(3), /* re8 */
9373 DRXJ_16TO8(3), /* re9 */
9374 DRXJ_16TO8(-5), /* re10 */
9375 DRXJ_16TO8(0), /* re11 */
9376 DRXJ_16TO8(9), /* re12 */
9377 DRXJ_16TO8(-4), /* re13 */
9378 DRXJ_16TO8(-12), /* re14 */
9379 DRXJ_16TO8(10), /* re15 */
9380 DRXJ_16TO8(16), /* re16 */
9381 DRXJ_16TO8(-21), /* re17 */
9382 DRXJ_16TO8(-20), /* re18 */
9383 DRXJ_16TO8(37), /* re19 */
9384 DRXJ_16TO8(25), /* re20 */
9385 DRXJ_16TO8(-62), /* re21 */
9386 DRXJ_16TO8(-28), /* re22 */
9387 DRXJ_16TO8(105), /* re23 */
9388 DRXJ_16TO8(31), /* re24 */
9389 DRXJ_16TO8(-197), /* re25 */
9390 DRXJ_16TO8(-33), /* re26 */
9391 DRXJ_16TO8(626) /* re27 */
9394 dev_addr = demod->my_i2c_dev_addr;
9395 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9396 common_attr = (struct drx_common_attr *) demod->my_common_attr;
9398 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9399 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9400 switch (channel->constellation) {
9401 case DRX_CONSTELLATION_QAM256:
9402 iqm_rc_rate = 0x00AE3562;
9404 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
9405 channel->symbolrate = 5360537;
9406 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
9408 case DRX_CONSTELLATION_QAM64:
9409 iqm_rc_rate = 0x00C05A0E;
9410 lc_symbol_freq = 409;
9411 channel->symbolrate = 5056941;
9412 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
9418 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
9419 if (channel->symbolrate == 0) {
9420 pr_err("error: channel symbolrate is zero!\n");
9424 (adc_frequency / channel->symbolrate) * (1 << 21) +
9426 ((adc_frequency % channel->symbolrate),
9427 channel->symbolrate) >> 7) - (1 << 23);
9430 (channel->symbolrate +
9431 (adc_frequency >> 13),
9432 adc_frequency) >> 16);
9433 if (lc_symbol_freq > 511)
9434 lc_symbol_freq = 511;
9436 iqm_rc_stretch = 21;
9439 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
9440 set_env_parameters = QAM_TOP_ANNEX_A; /* annex */
9441 set_param_parameters[0] = channel->constellation; /* constellation */
9442 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
9443 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9444 set_env_parameters = QAM_TOP_ANNEX_B; /* annex */
9445 set_param_parameters[0] = channel->constellation; /* constellation */
9446 set_param_parameters[1] = channel->interleavemode; /* interleave mode */
9447 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9448 set_env_parameters = QAM_TOP_ANNEX_C; /* annex */
9449 set_param_parameters[0] = channel->constellation; /* constellation */
9450 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
9456 if (op & QAM_SET_OP_ALL) {
9458 STEP 1: reset demodulator
9459 resets IQM, QAM and FEC HW blocks
9460 resets SCU variables
9462 /* stop all comm_exec */
9463 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9465 pr_err("error %d\n", rc);
9468 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
9470 pr_err("error %d\n", rc);
9473 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9475 pr_err("error %d\n", rc);
9478 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9480 pr_err("error %d\n", rc);
9483 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9485 pr_err("error %d\n", rc);
9488 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9490 pr_err("error %d\n", rc);
9493 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9495 pr_err("error %d\n", rc);
9499 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9500 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
9501 cmd_scu.parameter_len = 0;
9502 cmd_scu.result_len = 1;
9503 cmd_scu.parameter = NULL;
9504 cmd_scu.result = &cmd_result;
9505 rc = scu_command(dev_addr, &cmd_scu);
9507 pr_err("error %d\n", rc);
9512 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9514 STEP 2: configure demodulator
9516 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
9518 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9519 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
9520 cmd_scu.parameter_len = 1;
9521 cmd_scu.result_len = 1;
9522 cmd_scu.parameter = &set_env_parameters;
9523 cmd_scu.result = &cmd_result;
9524 rc = scu_command(dev_addr, &cmd_scu);
9526 pr_err("error %d\n", rc);
9530 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9531 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
9532 cmd_scu.parameter_len = 2;
9533 cmd_scu.result_len = 1;
9534 cmd_scu.parameter = set_param_parameters;
9535 cmd_scu.result = &cmd_result;
9536 rc = scu_command(dev_addr, &cmd_scu);
9538 pr_err("error %d\n", rc);
9541 /* set symbol rate */
9542 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
9544 pr_err("error %d\n", rc);
9547 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
9548 rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
9550 pr_err("error %d\n", rc);
9554 /* STEP 3: enable the system in a mode where the ADC provides valid signal
9555 setup constellation independent registers */
9556 /* from qam_cmd.py script (qam_driver_b) */
9557 /* TODO: remove re-writes of HW reset values */
9558 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
9559 rc = set_frequency(demod, channel, tuner_freq_offset);
9561 pr_err("error %d\n", rc);
9566 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9568 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
9570 pr_err("error %d\n", rc);
9573 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
9575 pr_err("error %d\n", rc);
9580 if (op & QAM_SET_OP_ALL) {
9581 if (!ext_attr->has_lna) {
9582 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
9584 pr_err("error %d\n", rc);
9588 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
9590 pr_err("error %d\n", rc);
9593 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
9595 pr_err("error %d\n", rc);
9598 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
9600 pr_err("error %d\n", rc);
9604 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
9606 pr_err("error %d\n", rc);
9608 } /* scu temporary shut down agc */
9610 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
9612 pr_err("error %d\n", rc);
9615 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
9617 pr_err("error %d\n", rc);
9620 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
9622 pr_err("error %d\n", rc);
9625 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
9627 pr_err("error %d\n", rc);
9630 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PDREF__A, 4, 0);
9632 pr_err("error %d\n", rc);
9635 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
9637 pr_err("error %d\n", rc);
9640 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
9642 pr_err("error %d\n", rc);
9646 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
9648 pr_err("error %d\n", rc);
9651 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
9653 pr_err("error %d\n", rc);
9655 } /*! reset default val ! */
9657 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
9659 pr_err("error %d\n", rc);
9661 } /*! reset default val ! */
9662 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9663 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
9665 pr_err("error %d\n", rc);
9667 } /*! reset default val ! */
9668 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
9670 pr_err("error %d\n", rc);
9672 } /*! reset default val ! */
9673 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9675 pr_err("error %d\n", rc);
9677 } /*! reset default val ! */
9679 switch (channel->constellation) {
9680 case DRX_CONSTELLATION_QAM16:
9681 case DRX_CONSTELLATION_QAM64:
9682 case DRX_CONSTELLATION_QAM256:
9683 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9685 pr_err("error %d\n", rc);
9688 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
9690 pr_err("error %d\n", rc);
9693 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9695 pr_err("error %d\n", rc);
9697 } /*! reset default val ! */
9699 case DRX_CONSTELLATION_QAM32:
9700 case DRX_CONSTELLATION_QAM128:
9701 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9703 pr_err("error %d\n", rc);
9706 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
9708 pr_err("error %d\n", rc);
9711 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
9713 pr_err("error %d\n", rc);
9722 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
9724 pr_err("error %d\n", rc);
9726 } /*! reset default val ! */
9727 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
9729 pr_err("error %d\n", rc);
9732 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
9734 pr_err("error %d\n", rc);
9737 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
9739 pr_err("error %d\n", rc);
9742 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_MODE__A, 7, 0);
9744 pr_err("error %d\n", rc);
9747 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
9749 pr_err("error %d\n", rc);
9752 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
9754 pr_err("error %d\n", rc);
9757 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
9759 pr_err("error %d\n", rc);
9762 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
9764 pr_err("error %d\n", rc);
9767 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
9769 pr_err("error %d\n", rc);
9772 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
9774 pr_err("error %d\n", rc);
9777 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
9779 pr_err("error %d\n", rc);
9782 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
9784 pr_err("error %d\n", rc);
9787 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
9789 pr_err("error %d\n", rc);
9792 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
9794 pr_err("error %d\n", rc);
9797 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
9799 pr_err("error %d\n", rc);
9802 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
9804 pr_err("error %d\n", rc);
9807 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
9809 pr_err("error %d\n", rc);
9812 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
9814 pr_err("error %d\n", rc);
9817 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
9819 pr_err("error %d\n", rc);
9823 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
9825 pr_err("error %d\n", rc);
9828 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
9830 pr_err("error %d\n", rc);
9833 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
9835 pr_err("error %d\n", rc);
9838 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
9840 pr_err("error %d\n", rc);
9843 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
9845 pr_err("error %d\n", rc);
9849 /* No more resets of the IQM, current standard correctly set =>
9850 now AGCs can be configured. */
9851 /* turn on IQMAF. It has to be in front of setAgc**() */
9852 rc = set_iqm_af(demod, true);
9854 pr_err("error %d\n", rc);
9857 rc = adc_synchronization(demod);
9859 pr_err("error %d\n", rc);
9863 rc = init_agc(demod);
9865 pr_err("error %d\n", rc);
9868 rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
9870 pr_err("error %d\n", rc);
9873 rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
9875 pr_err("error %d\n", rc);
9879 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
9881 struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
9883 qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
9884 rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
9886 pr_err("error %d\n", rc);
9890 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
9892 pr_err("error %d\n", rc);
9897 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9898 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
9899 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9901 pr_err("error %d\n", rc);
9904 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9906 pr_err("error %d\n", rc);
9909 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9910 switch (channel->constellation) {
9911 case DRX_CONSTELLATION_QAM64:
9912 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9914 pr_err("error %d\n", rc);
9917 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9919 pr_err("error %d\n", rc);
9923 case DRX_CONSTELLATION_QAM256:
9924 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9926 pr_err("error %d\n", rc);
9929 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9931 pr_err("error %d\n", rc);
9938 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9939 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_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_c_taps), ((u8 *)qam_c_taps), 0);
9946 pr_err("error %d\n", rc);
9951 /* SETP 4: constellation specific setup */
9952 switch (channel->constellation) {
9953 case DRX_CONSTELLATION_QAM16:
9954 rc = set_qam16(demod);
9956 pr_err("error %d\n", rc);
9960 case DRX_CONSTELLATION_QAM32:
9961 rc = set_qam32(demod);
9963 pr_err("error %d\n", rc);
9967 case DRX_CONSTELLATION_QAM64:
9968 rc = set_qam64(demod);
9970 pr_err("error %d\n", rc);
9974 case DRX_CONSTELLATION_QAM128:
9975 rc = set_qam128(demod);
9977 pr_err("error %d\n", rc);
9981 case DRX_CONSTELLATION_QAM256:
9982 rc = set_qam256(demod);
9984 pr_err("error %d\n", rc);
9993 if ((op & QAM_SET_OP_ALL)) {
9994 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
9996 pr_err("error %d\n", rc);
10000 /* Mpeg output has to be in front of FEC active */
10001 rc = set_mpegtei_handling(demod);
10003 pr_err("error %d\n", rc);
10006 rc = bit_reverse_mpeg_output(demod);
10008 pr_err("error %d\n", rc);
10011 rc = set_mpeg_start_width(demod);
10013 pr_err("error %d\n", rc);
10017 /* TODO: move to set_standard after hardware reset value problem is solved */
10018 /* Configure initial MPEG output */
10019 struct drx_cfg_mpeg_output cfg_mpeg_output;
10021 cfg_mpeg_output.enable_mpeg_output = true;
10022 cfg_mpeg_output.insert_rs_byte =
10023 common_attr->mpeg_cfg.insert_rs_byte;
10024 cfg_mpeg_output.enable_parallel =
10025 common_attr->mpeg_cfg.enable_parallel;
10026 cfg_mpeg_output.invert_data =
10027 common_attr->mpeg_cfg.invert_data;
10028 cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
10029 cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
10030 cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
10031 cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
10032 cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
10033 cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
10034 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
10036 pr_err("error %d\n", rc);
10042 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
10044 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
10045 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10046 SCU_RAM_COMMAND_CMD_DEMOD_START;
10047 cmd_scu.parameter_len = 0;
10048 cmd_scu.result_len = 1;
10049 cmd_scu.parameter = NULL;
10050 cmd_scu.result = &cmd_result;
10051 rc = scu_command(dev_addr, &cmd_scu);
10053 pr_err("error %d\n", rc);
10058 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
10060 pr_err("error %d\n", rc);
10063 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
10065 pr_err("error %d\n", rc);
10068 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
10070 pr_err("error %d\n", rc);
10079 /*============================================================================*/
10081 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality);
10082 static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
10085 u32 iqm_fs_rate_ofs = 0;
10086 u32 iqm_fs_rate_lo = 0;
10087 u16 qam_ctl_ena = 0;
10093 struct i2c_device_addr *dev_addr = NULL;
10094 struct drxj_data *ext_attr = NULL;
10096 dev_addr = demod->my_i2c_dev_addr;
10097 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10099 /* Silence the controlling of lc, equ, and the acquisition state machine */
10100 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10102 pr_err("error %d\n", rc);
10105 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);
10107 pr_err("error %d\n", rc);
10111 /* freeze the frequency control loop */
10112 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CF__A, 0, 0);
10114 pr_err("error %d\n", rc);
10117 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CF1__A, 0, 0);
10119 pr_err("error %d\n", rc);
10123 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
10125 pr_err("error %d\n", rc);
10128 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
10130 pr_err("error %d\n", rc);
10133 ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
10134 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
10135 iqm_fs_rate_ofs -= 2 * ofsofs;
10137 /* freeze dq/fq updating */
10138 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_MODE__A, &data, 0);
10140 pr_err("error %d\n", rc);
10143 data = (data & 0xfff9);
10144 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10146 pr_err("error %d\n", rc);
10149 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10151 pr_err("error %d\n", rc);
10155 /* lc_cp / _ci / _ca */
10156 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CI__A, 0, 0);
10158 pr_err("error %d\n", rc);
10161 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_EP__A, 0, 0);
10163 pr_err("error %d\n", rc);
10166 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
10168 pr_err("error %d\n", rc);
10172 /* flip the spec */
10173 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
10175 pr_err("error %d\n", rc);
10178 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
10179 ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
10181 /* freeze dq/fq updating */
10182 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_MODE__A, &data, 0);
10184 pr_err("error %d\n", rc);
10188 data = (data & 0xfff9);
10189 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10191 pr_err("error %d\n", rc);
10194 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10196 pr_err("error %d\n", rc);
10200 for (i = 0; i < 28; i++) {
10201 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
10203 pr_err("error %d\n", rc);
10206 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
10208 pr_err("error %d\n", rc);
10213 for (i = 0; i < 24; i++) {
10214 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
10216 pr_err("error %d\n", rc);
10219 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
10221 pr_err("error %d\n", rc);
10227 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10229 pr_err("error %d\n", rc);
10232 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10234 pr_err("error %d\n", rc);
10238 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
10240 pr_err("error %d\n", rc);
10245 while ((fsm_state != 4) && (i++ < 100)) {
10246 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
10248 pr_err("error %d\n", rc);
10252 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
10254 pr_err("error %d\n", rc);
10264 #define NO_LOCK 0x0
10265 #define DEMOD_LOCKED 0x1
10266 #define SYNC_FLIPPED 0x2
10267 #define SPEC_MIRRORED 0x4
10269 * \fn int qam64auto ()
10270 * \brief auto do sync pattern switching and mirroring.
10271 * \param demod: instance of demod.
10272 * \param channel: pointer to channel data.
10273 * \param tuner_freq_offset: tuner frequency offset.
10274 * \param lock_status: pointer to lock status.
10278 qam64auto(struct drx_demod_instance *demod,
10279 struct drx_channel *channel,
10280 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
10282 struct drx_sig_quality sig_quality;
10283 struct drxj_data *ext_attr = NULL;
10285 u32 state = NO_LOCK;
10286 u32 start_time = 0;
10287 u32 d_locked_time = 0;
10288 u32 timeout_ofs = 0;
10291 /* external attributes for storing aquired channel constellation */
10292 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10293 *lock_status = DRX_NOT_LOCKED;
10294 start_time = drxbsp_hst_clock();
10297 rc = ctrl_lock_status(demod, lock_status);
10299 pr_err("error %d\n", rc);
10305 if (*lock_status == DRXJ_DEMOD_LOCK) {
10306 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10308 pr_err("error %d\n", rc);
10311 if (sig_quality.MER > 208) {
10312 state = DEMOD_LOCKED;
10313 /* some delay to see if fec_lock possible TODO find the right value */
10314 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
10315 d_locked_time = drxbsp_hst_clock();
10320 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
10321 ((drxbsp_hst_clock() - d_locked_time) >
10322 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10323 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10325 pr_err("error %d\n", rc);
10328 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
10330 pr_err("error %d\n", rc);
10333 state = SYNC_FLIPPED;
10334 drxbsp_hst_sleep(10);
10338 if (*lock_status == DRXJ_DEMOD_LOCK) {
10339 if (channel->mirror == DRX_MIRROR_AUTO) {
10340 /* flip sync pattern back */
10341 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10343 pr_err("error %d\n", rc);
10346 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
10348 pr_err("error %d\n", rc);
10351 /* flip spectrum */
10352 ext_attr->mirror = DRX_MIRROR_YES;
10353 rc = qam_flip_spec(demod, channel);
10355 pr_err("error %d\n", rc);
10358 state = SPEC_MIRRORED;
10359 /* reset timer TODO: still need 500ms? */
10360 start_time = d_locked_time =
10361 drxbsp_hst_clock();
10363 } else { /* no need to wait lock */
10366 drxbsp_hst_clock() -
10367 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
10371 case SPEC_MIRRORED:
10372 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
10373 ((drxbsp_hst_clock() - d_locked_time) >
10374 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10375 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10377 pr_err("error %d\n", rc);
10380 if (sig_quality.MER > 208) {
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 | 0x1, 0);
10388 pr_err("error %d\n", rc);
10391 /* no need to wait lock */
10393 drxbsp_hst_clock() -
10394 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
10401 drxbsp_hst_sleep(10);
10403 ((*lock_status != DRX_LOCKED) &&
10404 (*lock_status != DRX_NEVER_LOCK) &&
10405 ((drxbsp_hst_clock() - start_time) <
10406 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
10408 /* Returning control to apllication ... */
10416 * \fn int qam256auto ()
10417 * \brief auto do sync pattern switching and mirroring.
10418 * \param demod: instance of demod.
10419 * \param channel: pointer to channel data.
10420 * \param tuner_freq_offset: tuner frequency offset.
10421 * \param lock_status: pointer to lock status.
10425 qam256auto(struct drx_demod_instance *demod,
10426 struct drx_channel *channel,
10427 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
10429 struct drx_sig_quality sig_quality;
10430 struct drxj_data *ext_attr = NULL;
10432 u32 state = NO_LOCK;
10433 u32 start_time = 0;
10434 u32 d_locked_time = 0;
10435 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
10437 /* external attributes for storing aquired channel constellation */
10438 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10439 *lock_status = DRX_NOT_LOCKED;
10440 start_time = drxbsp_hst_clock();
10443 rc = ctrl_lock_status(demod, lock_status);
10445 pr_err("error %d\n", rc);
10450 if (*lock_status == DRXJ_DEMOD_LOCK) {
10451 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10453 pr_err("error %d\n", rc);
10456 if (sig_quality.MER > 268) {
10457 state = DEMOD_LOCKED;
10458 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
10459 d_locked_time = drxbsp_hst_clock();
10464 if (*lock_status == DRXJ_DEMOD_LOCK) {
10465 if ((channel->mirror == DRX_MIRROR_AUTO) &&
10466 ((drxbsp_hst_clock() - d_locked_time) >
10467 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10468 ext_attr->mirror = DRX_MIRROR_YES;
10469 rc = qam_flip_spec(demod, channel);
10471 pr_err("error %d\n", rc);
10474 state = SPEC_MIRRORED;
10475 /* reset timer TODO: still need 300ms? */
10476 start_time = drxbsp_hst_clock();
10477 timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
10481 case SPEC_MIRRORED:
10486 drxbsp_hst_sleep(10);
10488 ((*lock_status < DRX_LOCKED) &&
10489 (*lock_status != DRX_NEVER_LOCK) &&
10490 ((drxbsp_hst_clock() - start_time) <
10491 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
10499 * \fn int set_qam_channel ()
10500 * \brief Set QAM channel according to the requested constellation.
10501 * \param demod: instance of demod.
10502 * \param channel: pointer to channel data.
10506 set_qam_channel(struct drx_demod_instance *demod,
10507 struct drx_channel *channel, s32 tuner_freq_offset)
10509 struct drxj_data *ext_attr = NULL;
10511 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
10512 bool auto_flag = false;
10514 /* external attributes for storing aquired channel constellation */
10515 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10517 /* set QAM channel constellation */
10518 switch (channel->constellation) {
10519 case DRX_CONSTELLATION_QAM16:
10520 case DRX_CONSTELLATION_QAM32:
10521 case DRX_CONSTELLATION_QAM64:
10522 case DRX_CONSTELLATION_QAM128:
10523 case DRX_CONSTELLATION_QAM256:
10524 ext_attr->constellation = channel->constellation;
10525 if (channel->mirror == DRX_MIRROR_AUTO)
10526 ext_attr->mirror = DRX_MIRROR_NO;
10528 ext_attr->mirror = channel->mirror;
10529 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
10531 pr_err("error %d\n", rc);
10535 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
10536 (channel->constellation == DRX_CONSTELLATION_QAM64)) {
10537 rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10539 pr_err("error %d\n", rc);
10544 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
10545 (channel->mirror == DRX_MIRROR_AUTO) &&
10546 (channel->constellation == DRX_CONSTELLATION_QAM256)) {
10547 rc = qam256auto(demod, channel, tuner_freq_offset, &lock_status);
10549 pr_err("error %d\n", rc);
10554 case DRX_CONSTELLATION_AUTO: /* for channel scan */
10555 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
10557 /* try to lock default QAM constellation: QAM64 */
10558 channel->constellation = DRX_CONSTELLATION_QAM256;
10559 ext_attr->constellation = DRX_CONSTELLATION_QAM256;
10560 if (channel->mirror == DRX_MIRROR_AUTO)
10561 ext_attr->mirror = DRX_MIRROR_NO;
10563 ext_attr->mirror = channel->mirror;
10564 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
10566 pr_err("error %d\n", rc);
10569 rc = qam256auto(demod, channel, tuner_freq_offset, &lock_status);
10571 pr_err("error %d\n", rc);
10575 if (lock_status < DRX_LOCKED) {
10576 /* QAM254 not locked -> try to lock QAM64 constellation */
10577 channel->constellation =
10578 DRX_CONSTELLATION_QAM64;
10579 ext_attr->constellation =
10580 DRX_CONSTELLATION_QAM64;
10581 if (channel->mirror == DRX_MIRROR_AUTO)
10582 ext_attr->mirror = DRX_MIRROR_NO;
10584 ext_attr->mirror = channel->mirror;
10586 u16 qam_ctl_ena = 0;
10587 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10589 pr_err("error %d\n", rc);
10592 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);
10594 pr_err("error %d\n", rc);
10597 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2, 0);
10599 pr_err("error %d\n", rc);
10601 } /* force to rate hunting */
10603 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_CONSTELLATION);
10605 pr_err("error %d\n", rc);
10608 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena, 0);
10610 pr_err("error %d\n", rc);
10614 rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10616 pr_err("error %d\n", rc);
10620 channel->constellation = DRX_CONSTELLATION_AUTO;
10621 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
10622 channel->constellation = DRX_CONSTELLATION_QAM64;
10623 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
10626 if (channel->mirror == DRX_MIRROR_AUTO)
10627 ext_attr->mirror = DRX_MIRROR_NO;
10629 ext_attr->mirror = channel->mirror;
10631 u16 qam_ctl_ena = 0;
10632 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10634 pr_err("error %d\n", rc);
10637 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);
10639 pr_err("error %d\n", rc);
10642 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2, 0);
10644 pr_err("error %d\n", rc);
10646 } /* force to rate hunting */
10648 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_CONSTELLATION);
10650 pr_err("error %d\n", rc);
10653 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena, 0);
10655 pr_err("error %d\n", rc);
10659 rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10661 pr_err("error %d\n", rc);
10664 channel->constellation = DRX_CONSTELLATION_AUTO;
10666 channel->constellation = DRX_CONSTELLATION_AUTO;
10676 /* restore starting value */
10678 channel->constellation = DRX_CONSTELLATION_AUTO;
10682 /*============================================================================*/
10685 * \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
10686 * \brief Get RS error count in QAM mode (used for post RS BER calculation)
10687 * \return Error code
10689 * precondition: measurement period & measurement prescale must be set
10693 get_qamrs_err_count(struct i2c_device_addr *dev_addr, struct drxjrs_errors *rs_errors)
10696 u16 nr_bit_errors = 0,
10697 nr_symbol_errors = 0,
10698 nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
10700 /* check arguments */
10701 if (dev_addr == NULL)
10704 /* all reported errors are received in the */
10705 /* most recently finished measurment period */
10706 /* no of pre RS bit errors */
10707 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
10709 pr_err("error %d\n", rc);
10712 /* no of symbol errors */
10713 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
10715 pr_err("error %d\n", rc);
10718 /* no of packet errors */
10719 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
10721 pr_err("error %d\n", rc);
10724 /* no of failures to decode */
10725 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
10727 pr_err("error %d\n", rc);
10730 /* no of post RS bit erros */
10731 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
10733 pr_err("error %d\n", rc);
10737 /* These register values are fetched in non-atomic fashion */
10738 /* It is possible that the read values contain unrelated information */
10740 rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
10741 rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
10742 rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
10743 rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
10744 rs_errors->nr_snc_par_fail_count =
10745 nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
10752 /*============================================================================*/
10755 * \fn int ctrl_get_qam_sig_quality()
10756 * \brief Retreive QAM signal quality from device.
10757 * \param devmod Pointer to demodulator instance.
10758 * \param sig_quality Pointer to signal quality data.
10760 * \retval 0 sig_quality contains valid data.
10761 * \retval -EINVAL sig_quality is NULL.
10762 * \retval -EIO Erroneous data, sig_quality contains invalid data.
10764 * Pre-condition: Device must be started and in lock.
10767 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
10769 struct i2c_device_addr *dev_addr = NULL;
10770 struct drxj_data *ext_attr = NULL;
10772 enum drx_modulation constellation = DRX_CONSTELLATION_UNKNOWN;
10773 struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
10775 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
10776 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
10777 u32 pkt_errs = 0; /* no of packet errors in RS */
10778 u16 qam_sl_err_power = 0; /* accumulated error between raw and sliced symbols */
10779 u16 qsym_err_vd = 0; /* quadrature symbol errors in QAM_VD */
10780 u16 fec_oc_period = 0; /* SNC sync failure measurement period */
10781 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
10782 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
10783 /* calculation constants */
10784 u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
10785 u32 qam_sl_sig_power = 0; /* used for MER, depends of QAM constellation */
10786 /* intermediate results */
10787 u32 e = 0; /* exponent value used for QAM BER/SER */
10788 u32 m = 0; /* mantisa value used for QAM BER/SER */
10789 u32 ber_cnt = 0; /* BER count */
10790 /* signal quality info */
10791 u32 qam_sl_mer = 0; /* QAM MER */
10792 u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
10793 u32 qam_post_rs_ber = 0; /* Post RedSolomon BER */
10794 u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
10795 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
10796 u16 qam_vd_period = 0; /* Viterbi Measurement period */
10797 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
10799 /* get device basic information */
10800 dev_addr = demod->my_i2c_dev_addr;
10801 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10802 constellation = ext_attr->constellation;
10804 /* read the physical registers */
10805 /* Get the RS error data */
10806 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
10808 pr_err("error %d\n", rc);
10811 /* get the register value needed for MER */
10812 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
10814 pr_err("error %d\n", rc);
10817 /* get the register value needed for post RS BER */
10818 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
10820 pr_err("error %d\n", rc);
10824 /* get constants needed for signal quality calculation */
10825 fec_rs_period = ext_attr->fec_rs_period;
10826 fec_rs_prescale = ext_attr->fec_rs_prescale;
10827 rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
10828 qam_vd_period = ext_attr->qam_vd_period;
10829 qam_vd_prescale = ext_attr->qam_vd_prescale;
10830 vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
10832 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
10833 switch (constellation) {
10834 case DRX_CONSTELLATION_QAM16:
10835 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
10837 case DRX_CONSTELLATION_QAM32:
10838 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
10840 case DRX_CONSTELLATION_QAM64:
10841 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
10843 case DRX_CONSTELLATION_QAM128:
10844 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
10846 case DRX_CONSTELLATION_QAM256:
10847 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
10853 /* ------------------------------ */
10854 /* MER Calculation */
10855 /* ------------------------------ */
10856 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
10858 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
10859 if (qam_sl_err_power == 0)
10862 qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
10864 /* ----------------------------------------- */
10865 /* Pre Viterbi Symbol Error Rate Calculation */
10866 /* ----------------------------------------- */
10867 /* pre viterbi SER is good if it is bellow 0.025 */
10869 /* get the register value */
10870 /* no of quadrature symbol errors */
10871 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
10873 pr_err("error %d\n", rc);
10876 /* Extract the Exponent and the Mantisa */
10877 /* of number of quadrature symbol errors */
10878 e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
10879 QAM_VD_NR_QSYM_ERRORS_EXP__B;
10880 m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
10881 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
10883 if ((m << e) >> 3 > 549752)
10884 qam_vd_ser = 500000;
10886 qam_vd_ser = frac_times1e6(m << ((e > 2) ? (e - 3) : e), vd_bit_cnt * ((e > 2) ? 1 : 8) / 8);
10888 /* --------------------------------------- */
10889 /* pre and post RedSolomon BER Calculation */
10890 /* --------------------------------------- */
10891 /* pre RS BER is good if it is below 3.5e-4 */
10893 /* get the register values */
10894 pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
10895 pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
10897 /* Extract the Exponent and the Mantisa of the */
10898 /* pre Reed-Solomon bit error count */
10899 e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
10900 FEC_RS_NR_BIT_ERRORS_EXP__B;
10901 m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
10902 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
10906 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
10907 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
10908 qam_pre_rs_ber = 500000;
10910 qam_pre_rs_ber = frac_times1e6(m, rs_bit_cnt >> e);
10912 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
10913 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
10915 => c = (1000000*100*11.17)/1504 =
10916 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
10917 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
10918 *100 and /100 is for more precision.
10919 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
10921 Precision errors still possible.
10923 e = post_bit_err_rs * 742686;
10924 m = fec_oc_period * 100;
10925 if (fec_oc_period == 0)
10926 qam_post_rs_ber = 0xFFFFFFFF;
10928 qam_post_rs_ber = e / m;
10930 /* fill signal quality data structure */
10931 sig_quality->MER = ((u16) qam_sl_mer);
10932 if (ext_attr->standard == DRX_STANDARD_ITU_B)
10933 sig_quality->pre_viterbi_ber = qam_vd_ser;
10935 sig_quality->pre_viterbi_ber = qam_pre_rs_ber;
10936 sig_quality->post_viterbi_ber = qam_pre_rs_ber;
10937 sig_quality->post_reed_solomon_ber = qam_post_rs_ber;
10938 sig_quality->scale_factor_ber = ((u32) 1000000);
10939 #ifdef DRXJ_SIGNAL_ACCUM_ERR
10940 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
10942 pr_err("error %d\n", rc);
10946 sig_quality->packet_error = ((u16) pkt_errs);
10955 * \fn int ctrl_get_qam_constel()
10956 * \brief Retreive a QAM constellation point via I2C.
10957 * \param demod Pointer to demodulator instance.
10958 * \param complex_nr Pointer to the structure in which to store the
10959 constellation point.
10963 ctrl_get_qam_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
10965 struct i2c_device_addr *dev_addr = NULL;
10968 u16 fec_oc_ocr_mode = 0;
10969 /**< FEC OCR grabber configuration */
10970 u16 qam_sl_comm_mb = 0;/**< QAM SL MB configuration */
10971 u16 qam_sl_comm_mb_init = 0;
10972 /**< QAM SL MB intial configuration */
10973 u16 im = 0; /**< constellation Im part */
10974 u16 re = 0; /**< constellation Re part */
10975 /**< device address */
10977 /* read device info */
10978 dev_addr = demod->my_i2c_dev_addr;
10981 /* Monitor bus grabbing is an open external interface issue */
10982 /* Needs to be checked when external interface PG is updated */
10984 /* Configure MB (Monitor bus) */
10985 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_SL_COMM_MB__A, &qam_sl_comm_mb_init, 0);
10987 pr_err("error %d\n", rc);
10990 /* set observe flag & MB mux */
10991 qam_sl_comm_mb = qam_sl_comm_mb_init & (~(QAM_SL_COMM_MB_OBS__M +
10992 QAM_SL_COMM_MB_MUX_OBS__M));
10993 qam_sl_comm_mb |= (QAM_SL_COMM_MB_OBS_ON +
10994 QAM_SL_COMM_MB_MUX_OBS_CONST_CORR);
10995 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb, 0);
10997 pr_err("error %d\n", rc);
11001 /* Enable MB grabber in the FEC OC */
11002 fec_oc_ocr_mode = (/* output select: observe bus */
11003 (FEC_OC_OCR_MODE_MB_SELECT__M &
11004 (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B)) |
11005 /* grabber enable: on */
11006 (FEC_OC_OCR_MODE_GRAB_ENABLE__M &
11007 (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B)) |
11008 /* grabber select: observe bus */
11009 (FEC_OC_OCR_MODE_GRAB_SELECT__M &
11010 (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B)) |
11011 /* grabber mode: continuous */
11012 (FEC_OC_OCR_MODE_GRAB_COUNTED__M &
11013 (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B)));
11014 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, fec_oc_ocr_mode, 0);
11016 pr_err("error %d\n", rc);
11020 /* Disable MB grabber in the FEC OC */
11021 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, 0x00, 0);
11023 pr_err("error %d\n", rc);
11028 rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_OCR_GRAB_RD0__A, &data, 0);
11030 pr_err("error %d\n", rc);
11033 re = (u16) (data & FEC_OC_OCR_GRAB_RD0__M);
11034 im = (u16) ((data >> 16) & FEC_OC_OCR_GRAB_RD1__M);
11037 /* interpret data (re & im) according to the Monitor bus mapping ?? */
11039 /* sign extension, 10th bit is sign bit */
11040 if ((re & 0x0200) == 0x0200)
11042 if ((im & 0x0200) == 0x0200)
11044 complex_nr->re = ((s16) re);
11045 complex_nr->im = ((s16) im);
11047 /* Restore MB (Monitor bus) */
11048 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb_init, 0);
11050 pr_err("error %d\n", rc);
11058 #endif /* #ifndef DRXJ_VSB_ONLY */
11060 /*============================================================================*/
11061 /*== END QAM DATAPATH FUNCTIONS ==*/
11062 /*============================================================================*/
11064 /*============================================================================*/
11065 /*============================================================================*/
11066 /*== ATV DATAPATH FUNCTIONS ==*/
11067 /*============================================================================*/
11068 /*============================================================================*/
11071 Implementation notes.
11075 Four AGCs are used for NTSC:
11076 (1) RF (used to attenuate the input signal in case of to much power)
11077 (2) IF (used to attenuate the input signal in case of to much power)
11078 (3) Video AGC (used to amplify the output signal in case input to low)
11079 (4) SIF AGC (used to amplify the output signal in case input to low)
11081 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
11082 that the coupling between Video AGC and the RF and IF AGCs also works in
11083 favor of the SIF AGC.
11085 Three AGCs are used for FM:
11086 (1) RF (used to attenuate the input signal in case of to much power)
11087 (2) IF (used to attenuate the input signal in case of to much power)
11088 (3) SIF AGC (used to amplify the output signal in case input to low)
11090 The SIF AGC is now coupled to the RF/IF AGCs.
11091 The SIF AGC is needed for both SIF ouput and the internal SIF signal to
11094 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
11095 the ATV block. The AGC control algorithms are all implemented in
11100 (Shadow settings will not be used for now, they will be implemented
11101 later on because of the schedule)
11103 Several HW/SCU "settings" can be used for ATV. The standard selection
11104 will reset most of these settings. To avoid that the end user apllication
11105 has to perform these settings each time the ATV or FM standards is
11106 selected the driver will shadow these settings. This enables the end user
11107 to perform the settings only once after a drx_open(). The driver must
11108 write the shadow settings to HW/SCU incase:
11109 ( setstandard FM/ATV) ||
11110 ( settings have changed && FM/ATV standard is active)
11111 The shadow settings will be stored in the device specific data container.
11112 A set of flags will be defined to flag changes in shadow settings.
11113 A routine will be implemented to write all changed shadow settings to
11116 The "settings" will consist of: AGC settings, filter settings etc.
11118 Disadvantage of use of shadow settings:
11119 Direct changes in HW/SCU registers will not be reflected in the
11120 shadow settings and these changes will be overwritten during a next
11121 update. This can happen during evaluation. This will not be a problem
11122 for normal customer usage.
11124 /* -------------------------------------------------------------------------- */
11127 * \brief Get array index for atv coef (ext_attr->atvTopCoefX[index])
11129 * \param pointer to index
11133 static int atv_equ_coef_index(enum drx_standard standard, int *index)
11135 switch (standard) {
11136 case DRX_STANDARD_PAL_SECAM_BG:
11137 *index = (int)DRXJ_COEF_IDX_BG;
11139 case DRX_STANDARD_PAL_SECAM_DK:
11140 *index = (int)DRXJ_COEF_IDX_DK;
11142 case DRX_STANDARD_PAL_SECAM_I:
11143 *index = (int)DRXJ_COEF_IDX_I;
11145 case DRX_STANDARD_PAL_SECAM_L:
11146 *index = (int)DRXJ_COEF_IDX_L;
11148 case DRX_STANDARD_PAL_SECAM_LP:
11149 *index = (int)DRXJ_COEF_IDX_LP;
11151 case DRX_STANDARD_NTSC:
11152 *index = (int)DRXJ_COEF_IDX_MN;
11154 case DRX_STANDARD_FM:
11155 *index = (int)DRXJ_COEF_IDX_FM;
11158 *index = (int)DRXJ_COEF_IDX_MN; /* still return a valid index */
11166 /* -------------------------------------------------------------------------- */
11168 * \fn int atv_update_config ()
11169 * \brief Flush changes in ATV shadow registers to physical registers.
11170 * \param demod instance of demodulator
11171 * \param force_update don't look at standard or change flags, flush all.
11176 atv_update_config(struct drx_demod_instance *demod, bool force_update)
11178 struct i2c_device_addr *dev_addr = NULL;
11179 struct drxj_data *ext_attr = NULL;
11182 dev_addr = demod->my_i2c_dev_addr;
11183 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11185 /* equalizer coefficients */
11186 if (force_update ||
11187 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_COEF) != 0)) {
11190 rc = atv_equ_coef_index(ext_attr->standard, &index);
11192 pr_err("error %d\n", rc);
11195 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU0__A, ext_attr->atv_top_equ0[index], 0);
11197 pr_err("error %d\n", rc);
11200 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU1__A, ext_attr->atv_top_equ1[index], 0);
11202 pr_err("error %d\n", rc);
11205 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU2__A, ext_attr->atv_top_equ2[index], 0);
11207 pr_err("error %d\n", rc);
11210 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU3__A, ext_attr->atv_top_equ3[index], 0);
11212 pr_err("error %d\n", rc);
11217 /* bypass fast carrier recovery */
11218 if (force_update) {
11221 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_RT_ROT_BP__A, &data, 0);
11223 pr_err("error %d\n", rc);
11226 data &= (~((u16) IQM_RT_ROT_BP_ROT_OFF__M));
11227 if (ext_attr->phase_correction_bypass)
11228 data |= IQM_RT_ROT_BP_ROT_OFF_OFF;
11230 data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE;
11231 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ROT_BP__A, data, 0);
11233 pr_err("error %d\n", rc);
11238 /* peak filter setting */
11239 if (force_update ||
11240 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0)) {
11241 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_PEAK__A, ext_attr->atv_top_vid_peak, 0);
11243 pr_err("error %d\n", rc);
11248 /* noise filter setting */
11249 if (force_update ||
11250 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0)) {
11251 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_NOISE_TH__A, ext_attr->atv_top_noise_th, 0);
11253 pr_err("error %d\n", rc);
11258 /* SIF attenuation */
11259 if (force_update ||
11260 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_SIF_ATT) != 0)) {
11261 u16 attenuation = 0;
11263 switch (ext_attr->sif_attenuation) {
11264 case DRXJ_SIF_ATTENUATION_0DB:
11265 attenuation = ATV_TOP_AF_SIF_ATT_0DB;
11267 case DRXJ_SIF_ATTENUATION_3DB:
11268 attenuation = ATV_TOP_AF_SIF_ATT_M3DB;
11270 case DRXJ_SIF_ATTENUATION_6DB:
11271 attenuation = ATV_TOP_AF_SIF_ATT_M6DB;
11273 case DRXJ_SIF_ATTENUATION_9DB:
11274 attenuation = ATV_TOP_AF_SIF_ATT_M9DB;
11280 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_AF_SIF_ATT__A, attenuation, 0);
11282 pr_err("error %d\n", rc);
11287 /* SIF & CVBS enable */
11288 if (force_update ||
11289 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_OUTPUT) != 0)) {
11292 rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_STDBY__A, &data, 0);
11294 pr_err("error %d\n", rc);
11297 if (ext_attr->enable_cvbs_output)
11298 data |= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE;
11300 data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE);
11302 if (ext_attr->enable_sif_output)
11303 data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY);
11305 data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY;
11306 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, data, 0);
11308 pr_err("error %d\n", rc);
11313 ext_attr->atv_cfg_changed_flags = 0;
11320 /* -------------------------------------------------------------------------- */
11322 * \fn int ctrl_set_cfg_atv_output()
11323 * \brief Configure ATV ouputs
11324 * \param demod instance of demodulator
11325 * \param output_cfg output configuaration
11330 ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11332 struct drxj_data *ext_attr = NULL;
11335 /* Check arguments */
11336 if (output_cfg == NULL)
11339 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11340 if (output_cfg->enable_sif_output) {
11341 switch (output_cfg->sif_attenuation) {
11342 case DRXJ_SIF_ATTENUATION_0DB: /* fallthrough */
11343 case DRXJ_SIF_ATTENUATION_3DB: /* fallthrough */
11344 case DRXJ_SIF_ATTENUATION_6DB: /* fallthrough */
11345 case DRXJ_SIF_ATTENUATION_9DB:
11353 if (ext_attr->sif_attenuation != output_cfg->sif_attenuation) {
11354 ext_attr->sif_attenuation = output_cfg->sif_attenuation;
11355 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_SIF_ATT;
11359 if (ext_attr->enable_cvbs_output != output_cfg->enable_cvbs_output) {
11360 ext_attr->enable_cvbs_output = output_cfg->enable_cvbs_output;
11361 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11364 if (ext_attr->enable_sif_output != output_cfg->enable_sif_output) {
11365 ext_attr->enable_sif_output = output_cfg->enable_sif_output;
11366 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11369 rc = atv_update_config(demod, false);
11371 pr_err("error %d\n", rc);
11380 /* -------------------------------------------------------------------------- */
11381 #ifndef DRXJ_DIGITAL_ONLY
11383 * \fn int ctrl_set_cfg_atv_equ_coef()
11384 * \brief Set ATV equalizer coefficients
11385 * \param demod instance of demodulator
11386 * \param coef the equalizer coefficients
11391 ctrl_set_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11393 struct drxj_data *ext_attr = NULL;
11397 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11399 /* current standard needs to be an ATV standard */
11400 if (!DRXJ_ISATVSTD(ext_attr->standard))
11403 /* Check arguments */
11404 if ((coef == NULL) ||
11405 (coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2)) ||
11406 (coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2)) ||
11407 (coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2)) ||
11408 (coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2)) ||
11409 (coef->coef0 < ((s16) ~(ATV_TOP_EQU0_EQU_C0__M >> 1))) ||
11410 (coef->coef1 < ((s16) ~(ATV_TOP_EQU1_EQU_C1__M >> 1))) ||
11411 (coef->coef2 < ((s16) ~(ATV_TOP_EQU2_EQU_C2__M >> 1))) ||
11412 (coef->coef3 < ((s16) ~(ATV_TOP_EQU3_EQU_C3__M >> 1)))) {
11416 rc = atv_equ_coef_index(ext_attr->standard, &index);
11418 pr_err("error %d\n", rc);
11421 ext_attr->atv_top_equ0[index] = coef->coef0;
11422 ext_attr->atv_top_equ1[index] = coef->coef1;
11423 ext_attr->atv_top_equ2[index] = coef->coef2;
11424 ext_attr->atv_top_equ3[index] = coef->coef3;
11425 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_COEF;
11427 rc = atv_update_config(demod, false);
11429 pr_err("error %d\n", rc);
11438 /* -------------------------------------------------------------------------- */
11440 * \fn int ctrl_get_cfg_atv_equ_coef()
11441 * \brief Get ATV equ coef settings
11442 * \param demod instance of demodulator
11443 * \param coef The ATV equ coefficients
11446 * The values are read from the shadow registers maintained by the drxdriver
11447 * If registers are manipulated outside of the drxdriver scope the reported
11448 * settings will not reflect these changes because of the use of shadow
11453 ctrl_get_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11455 struct drxj_data *ext_attr = NULL;
11459 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11461 /* current standard needs to be an ATV standard */
11462 if (!DRXJ_ISATVSTD(ext_attr->standard))
11465 /* Check arguments */
11469 rc = atv_equ_coef_index(ext_attr->standard, &index);
11471 pr_err("error %d\n", rc);
11474 coef->coef0 = ext_attr->atv_top_equ0[index];
11475 coef->coef1 = ext_attr->atv_top_equ1[index];
11476 coef->coef2 = ext_attr->atv_top_equ2[index];
11477 coef->coef3 = ext_attr->atv_top_equ3[index];
11484 /* -------------------------------------------------------------------------- */
11486 * \fn int ctrl_set_cfg_atv_misc()
11487 * \brief Set misc. settings for ATV.
11488 * \param demod instance of demodulator
11494 ctrl_set_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11496 struct drxj_data *ext_attr = NULL;
11499 /* Check arguments */
11500 if ((settings == NULL) ||
11501 ((settings->peak_filter) < (s16) (-8)) ||
11502 ((settings->peak_filter) > (s16) (15)) ||
11503 ((settings->noise_filter) > 15)) {
11507 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11509 if (settings->peak_filter != ext_attr->atv_top_vid_peak) {
11510 ext_attr->atv_top_vid_peak = settings->peak_filter;
11511 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_PEAK_FLT;
11514 if (settings->noise_filter != ext_attr->atv_top_noise_th) {
11515 ext_attr->atv_top_noise_th = settings->noise_filter;
11516 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_NOISE_FLT;
11519 rc = atv_update_config(demod, false);
11521 pr_err("error %d\n", rc);
11530 /* -------------------------------------------------------------------------- */
11532 * \fn int ctrl_get_cfg_atv_misc()
11533 * \brief Get misc settings of ATV.
11534 * \param demod instance of demodulator
11535 * \param settings misc. ATV settings
11538 * The values are read from the shadow registers maintained by the drxdriver
11539 * If registers are manipulated outside of the drxdriver scope the reported
11540 * settings will not reflect these changes because of the use of shadow
11544 ctrl_get_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11546 struct drxj_data *ext_attr = NULL;
11548 /* Check arguments */
11549 if (settings == NULL)
11552 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11554 settings->peak_filter = ext_attr->atv_top_vid_peak;
11555 settings->noise_filter = ext_attr->atv_top_noise_th;
11560 /* -------------------------------------------------------------------------- */
11562 /* -------------------------------------------------------------------------- */
11564 * \fn int ctrl_get_cfg_atv_output()
11566 * \param demod instance of demodulator
11567 * \param output_cfg output configuaration
11572 ctrl_get_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11577 /* Check arguments */
11578 if (output_cfg == NULL)
11581 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, ATV_TOP_STDBY__A, &data, 0);
11583 pr_err("error %d\n", rc);
11586 if (data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)
11587 output_cfg->enable_cvbs_output = true;
11589 output_cfg->enable_cvbs_output = false;
11591 if (data & ATV_TOP_STDBY_SIF_STDBY_STANDBY) {
11592 output_cfg->enable_sif_output = false;
11594 output_cfg->enable_sif_output = true;
11595 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, ATV_TOP_AF_SIF_ATT__A, &data, 0);
11597 pr_err("error %d\n", rc);
11600 output_cfg->sif_attenuation = (enum drxjsif_attenuation) data;
11608 /* -------------------------------------------------------------------------- */
11610 * \fn int ctrl_get_cfg_atv_agc_status()
11612 * \param demod instance of demodulator
11613 * \param agc_status agc status
11618 ctrl_get_cfg_atv_agc_status(struct drx_demod_instance *demod,
11619 struct drxj_cfg_atv_agc_status *agc_status)
11621 struct i2c_device_addr *dev_addr = NULL;
11626 /* Check arguments */
11627 if (agc_status == NULL)
11630 dev_addr = demod->my_i2c_dev_addr;
11633 RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
11634 = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
11636 IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
11638 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &data, 0);
11640 pr_err("error %d\n", rc);
11643 tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */
11644 agc_status->rf_agc_gain = (u16) (tmp / 1000); /* uA */
11646 if (tmp % 1000 >= 500)
11647 (agc_status->rf_agc_gain)++;
11650 IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
11651 = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
11653 IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
11655 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &data, 0);
11657 pr_err("error %d\n", rc);
11660 tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */
11661 agc_status->if_agc_gain = (u16) (tmp / 1000); /* uA */
11663 if (tmp % 1000 >= 500)
11664 (agc_status->if_agc_gain)++;
11667 videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
11668 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
11669 = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
11670 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
11671 = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
11674 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &data, 0);
11676 pr_err("error %d\n", rc);
11679 /* dividing by 32 inclusive rounding */
11681 if ((data & 1) != 0)
11684 agc_status->video_agc_gain = ((s16) data) - 75; /* 0.1 dB */
11687 audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
11688 = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
11689 = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
11690 = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
11691 = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
11694 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &data, 0);
11696 pr_err("error %d\n", rc);
11699 data &= SCU_RAM_ATV_SIF_GAIN__M;
11700 /* dividing by 2 inclusive rounding */
11701 if ((data & 1) != 0)
11704 agc_status->audio_agc_gain = ((s16) data) - 4; /* 0.1 dB */
11707 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
11709 pr_err("error %d\n", rc);
11712 agc_status->video_agc_loop_gain =
11713 ((data & SCU_RAM_AGC_KI_DGAIN__M) >> SCU_RAM_AGC_KI_DGAIN__B);
11714 agc_status->rf_agc_loop_gain =
11715 ((data & SCU_RAM_AGC_KI_RF__M) >> SCU_RAM_AGC_KI_RF__B);
11716 agc_status->if_agc_loop_gain =
11717 ((data & SCU_RAM_AGC_KI_IF__M) >> SCU_RAM_AGC_KI_IF__B);
11724 /* -------------------------------------------------------------------------- */
11727 * \fn int power_up_atv ()
11728 * \brief Power up ATV.
11729 * \param demod instance of demodulator
11730 * \param standard either NTSC or FM (sub strandard for ATV )
11733 * * Starts ATV and IQM
11734 * * AUdio already started during standard init for ATV.
11736 static int power_up_atv(struct drx_demod_instance *demod, enum drx_standard standard)
11738 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11742 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE, 0);
11744 pr_err("error %d\n", rc);
11747 /* turn on IQM_AF */
11748 rc = set_iqm_af(demod, true);
11750 pr_err("error %d\n", rc);
11753 rc = adc_synchronization(demod);
11755 pr_err("error %d\n", rc);
11759 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
11761 pr_err("error %d\n", rc);
11765 /* Audio, already done during set standard */
11771 #endif /* #ifndef DRXJ_DIGITAL_ONLY */
11773 /* -------------------------------------------------------------------------- */
11776 * \fn int power_down_atv ()
11777 * \brief Power down ATV.
11778 * \param demod instance of demodulator
11779 * \param standard either NTSC or FM (sub strandard for ATV )
11782 * Stops and thus resets ATV and IQM block
11783 * SIF and CVBS ADC are powered down
11784 * Calls audio power down
11787 power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
11789 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11790 struct drxjscu_cmd cmd_scu = { /* command */ 0,
11791 /* parameter_len */ 0,
11792 /* result_len */ 0,
11793 /* *parameter */ NULL,
11797 u16 cmd_result = 0;
11801 /* Stop ATV SCU (will reset ATV and IQM hardware */
11802 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
11803 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
11804 cmd_scu.parameter_len = 0;
11805 cmd_scu.result_len = 1;
11806 cmd_scu.parameter = NULL;
11807 cmd_scu.result = &cmd_result;
11808 rc = scu_command(dev_addr, &cmd_scu);
11810 pr_err("error %d\n", rc);
11813 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
11814 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);
11816 pr_err("error %d\n", rc);
11820 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
11822 pr_err("error %d\n", rc);
11826 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
11828 pr_err("error %d\n", rc);
11831 rc = set_iqm_af(demod, false);
11833 pr_err("error %d\n", rc);
11837 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
11839 pr_err("error %d\n", rc);
11842 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
11844 pr_err("error %d\n", rc);
11847 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
11849 pr_err("error %d\n", rc);
11852 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
11854 pr_err("error %d\n", rc);
11857 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
11859 pr_err("error %d\n", rc);
11863 rc = power_down_aud(demod);
11865 pr_err("error %d\n", rc);
11874 /* -------------------------------------------------------------------------- */
11876 * \fn int set_atv_standard ()
11877 * \brief Set up ATV demodulator.
11878 * \param demod instance of demodulator
11879 * \param standard either NTSC or FM (sub strandard for ATV )
11882 * Init all channel independent registers.
11883 * Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
11886 #ifndef DRXJ_DIGITAL_ONLY
11887 #define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */
11889 set_atv_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
11891 /* TODO: enable alternative for tap settings via external file
11894 #ifdef DRXJ_ATV_COEF_FILE
11895 #include DRXJ_ATV_COEF_FILE
11897 ... code defining fixed coef's ...
11900 Cutsomer must create file "customer_coefs.c.inc" containing
11901 modified copy off the constants below, and define the compiler
11902 switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
11904 Still to check if this will work; DRXJ_16TO8 macro may cause
11907 const u8 ntsc_taps_re[] = {
11908 DRXJ_16TO8(-12), /* re0 */
11909 DRXJ_16TO8(-9), /* re1 */
11910 DRXJ_16TO8(9), /* re2 */
11911 DRXJ_16TO8(19), /* re3 */
11912 DRXJ_16TO8(-4), /* re4 */
11913 DRXJ_16TO8(-24), /* re5 */
11914 DRXJ_16TO8(-6), /* re6 */
11915 DRXJ_16TO8(16), /* re7 */
11916 DRXJ_16TO8(6), /* re8 */
11917 DRXJ_16TO8(-16), /* re9 */
11918 DRXJ_16TO8(-5), /* re10 */
11919 DRXJ_16TO8(13), /* re11 */
11920 DRXJ_16TO8(-2), /* re12 */
11921 DRXJ_16TO8(-20), /* re13 */
11922 DRXJ_16TO8(4), /* re14 */
11923 DRXJ_16TO8(25), /* re15 */
11924 DRXJ_16TO8(-6), /* re16 */
11925 DRXJ_16TO8(-36), /* re17 */
11926 DRXJ_16TO8(2), /* re18 */
11927 DRXJ_16TO8(38), /* re19 */
11928 DRXJ_16TO8(-10), /* re20 */
11929 DRXJ_16TO8(-48), /* re21 */
11930 DRXJ_16TO8(35), /* re22 */
11931 DRXJ_16TO8(94), /* re23 */
11932 DRXJ_16TO8(-59), /* re24 */
11933 DRXJ_16TO8(-217), /* re25 */
11934 DRXJ_16TO8(50), /* re26 */
11935 DRXJ_16TO8(679) /* re27 */
11937 const u8 ntsc_taps_im[] = {
11938 DRXJ_16TO8(11), /* im0 */
11939 DRXJ_16TO8(1), /* im1 */
11940 DRXJ_16TO8(-10), /* im2 */
11941 DRXJ_16TO8(2), /* im3 */
11942 DRXJ_16TO8(24), /* im4 */
11943 DRXJ_16TO8(21), /* im5 */
11944 DRXJ_16TO8(1), /* im6 */
11945 DRXJ_16TO8(-4), /* im7 */
11946 DRXJ_16TO8(7), /* im8 */
11947 DRXJ_16TO8(14), /* im9 */
11948 DRXJ_16TO8(27), /* im10 */
11949 DRXJ_16TO8(42), /* im11 */
11950 DRXJ_16TO8(22), /* im12 */
11951 DRXJ_16TO8(-20), /* im13 */
11952 DRXJ_16TO8(2), /* im14 */
11953 DRXJ_16TO8(98), /* im15 */
11954 DRXJ_16TO8(122), /* im16 */
11955 DRXJ_16TO8(0), /* im17 */
11956 DRXJ_16TO8(-85), /* im18 */
11957 DRXJ_16TO8(51), /* im19 */
11958 DRXJ_16TO8(247), /* im20 */
11959 DRXJ_16TO8(192), /* im21 */
11960 DRXJ_16TO8(-55), /* im22 */
11961 DRXJ_16TO8(-95), /* im23 */
11962 DRXJ_16TO8(217), /* im24 */
11963 DRXJ_16TO8(544), /* im25 */
11964 DRXJ_16TO8(553), /* im26 */
11965 DRXJ_16TO8(302) /* im27 */
11967 const u8 bg_taps_re[] = {
11968 DRXJ_16TO8(-18), /* re0 */
11969 DRXJ_16TO8(18), /* re1 */
11970 DRXJ_16TO8(19), /* re2 */
11971 DRXJ_16TO8(-26), /* re3 */
11972 DRXJ_16TO8(-20), /* re4 */
11973 DRXJ_16TO8(36), /* re5 */
11974 DRXJ_16TO8(5), /* re6 */
11975 DRXJ_16TO8(-51), /* re7 */
11976 DRXJ_16TO8(15), /* re8 */
11977 DRXJ_16TO8(45), /* re9 */
11978 DRXJ_16TO8(-46), /* re10 */
11979 DRXJ_16TO8(-24), /* re11 */
11980 DRXJ_16TO8(71), /* re12 */
11981 DRXJ_16TO8(-17), /* re13 */
11982 DRXJ_16TO8(-83), /* re14 */
11983 DRXJ_16TO8(74), /* re15 */
11984 DRXJ_16TO8(75), /* re16 */
11985 DRXJ_16TO8(-134), /* re17 */
11986 DRXJ_16TO8(-40), /* re18 */
11987 DRXJ_16TO8(191), /* re19 */
11988 DRXJ_16TO8(-11), /* re20 */
11989 DRXJ_16TO8(-233), /* re21 */
11990 DRXJ_16TO8(74), /* re22 */
11991 DRXJ_16TO8(271), /* re23 */
11992 DRXJ_16TO8(-132), /* re24 */
11993 DRXJ_16TO8(-341), /* re25 */
11994 DRXJ_16TO8(172), /* re26 */
11995 DRXJ_16TO8(801) /* re27 */
11997 const u8 bg_taps_im[] = {
11998 DRXJ_16TO8(-24), /* im0 */
11999 DRXJ_16TO8(-10), /* im1 */
12000 DRXJ_16TO8(9), /* im2 */
12001 DRXJ_16TO8(-5), /* im3 */
12002 DRXJ_16TO8(-51), /* im4 */
12003 DRXJ_16TO8(-17), /* im5 */
12004 DRXJ_16TO8(31), /* im6 */
12005 DRXJ_16TO8(-48), /* im7 */
12006 DRXJ_16TO8(-95), /* im8 */
12007 DRXJ_16TO8(25), /* im9 */
12008 DRXJ_16TO8(37), /* im10 */
12009 DRXJ_16TO8(-123), /* im11 */
12010 DRXJ_16TO8(-77), /* im12 */
12011 DRXJ_16TO8(94), /* im13 */
12012 DRXJ_16TO8(-10), /* im14 */
12013 DRXJ_16TO8(-149), /* im15 */
12014 DRXJ_16TO8(10), /* im16 */
12015 DRXJ_16TO8(108), /* im17 */
12016 DRXJ_16TO8(-49), /* im18 */
12017 DRXJ_16TO8(-59), /* im19 */
12018 DRXJ_16TO8(90), /* im20 */
12019 DRXJ_16TO8(73), /* im21 */
12020 DRXJ_16TO8(55), /* im22 */
12021 DRXJ_16TO8(148), /* im23 */
12022 DRXJ_16TO8(86), /* im24 */
12023 DRXJ_16TO8(146), /* im25 */
12024 DRXJ_16TO8(687), /* im26 */
12025 DRXJ_16TO8(877) /* im27 */
12027 const u8 dk_i_l_lp_taps_re[] = {
12028 DRXJ_16TO8(-23), /* re0 */
12029 DRXJ_16TO8(9), /* re1 */
12030 DRXJ_16TO8(16), /* re2 */
12031 DRXJ_16TO8(-26), /* re3 */
12032 DRXJ_16TO8(-3), /* re4 */
12033 DRXJ_16TO8(13), /* re5 */
12034 DRXJ_16TO8(-19), /* re6 */
12035 DRXJ_16TO8(-3), /* re7 */
12036 DRXJ_16TO8(13), /* re8 */
12037 DRXJ_16TO8(-26), /* re9 */
12038 DRXJ_16TO8(-4), /* re10 */
12039 DRXJ_16TO8(28), /* re11 */
12040 DRXJ_16TO8(-15), /* re12 */
12041 DRXJ_16TO8(-14), /* re13 */
12042 DRXJ_16TO8(10), /* re14 */
12043 DRXJ_16TO8(1), /* re15 */
12044 DRXJ_16TO8(39), /* re16 */
12045 DRXJ_16TO8(-18), /* re17 */
12046 DRXJ_16TO8(-90), /* re18 */
12047 DRXJ_16TO8(109), /* re19 */
12048 DRXJ_16TO8(113), /* re20 */
12049 DRXJ_16TO8(-235), /* re21 */
12050 DRXJ_16TO8(-49), /* re22 */
12051 DRXJ_16TO8(359), /* re23 */
12052 DRXJ_16TO8(-79), /* re24 */
12053 DRXJ_16TO8(-459), /* re25 */
12054 DRXJ_16TO8(206), /* re26 */
12055 DRXJ_16TO8(894) /* re27 */
12057 const u8 dk_i_l_lp_taps_im[] = {
12058 DRXJ_16TO8(-8), /* im0 */
12059 DRXJ_16TO8(-20), /* im1 */
12060 DRXJ_16TO8(17), /* im2 */
12061 DRXJ_16TO8(-14), /* im3 */
12062 DRXJ_16TO8(-52), /* im4 */
12063 DRXJ_16TO8(4), /* im5 */
12064 DRXJ_16TO8(9), /* im6 */
12065 DRXJ_16TO8(-62), /* im7 */
12066 DRXJ_16TO8(-47), /* im8 */
12067 DRXJ_16TO8(0), /* im9 */
12068 DRXJ_16TO8(-20), /* im10 */
12069 DRXJ_16TO8(-48), /* im11 */
12070 DRXJ_16TO8(-65), /* im12 */
12071 DRXJ_16TO8(-23), /* im13 */
12072 DRXJ_16TO8(44), /* im14 */
12073 DRXJ_16TO8(-60), /* im15 */
12074 DRXJ_16TO8(-113), /* im16 */
12075 DRXJ_16TO8(92), /* im17 */
12076 DRXJ_16TO8(81), /* im18 */
12077 DRXJ_16TO8(-125), /* im19 */
12078 DRXJ_16TO8(28), /* im20 */
12079 DRXJ_16TO8(182), /* im21 */
12080 DRXJ_16TO8(35), /* im22 */
12081 DRXJ_16TO8(94), /* im23 */
12082 DRXJ_16TO8(180), /* im24 */
12083 DRXJ_16TO8(134), /* im25 */
12084 DRXJ_16TO8(657), /* im26 */
12085 DRXJ_16TO8(1023) /* im27 */
12087 const u8 fm_taps_re[] = {
12088 DRXJ_16TO8(0), /* re0 */
12089 DRXJ_16TO8(0), /* re1 */
12090 DRXJ_16TO8(0), /* re2 */
12091 DRXJ_16TO8(0), /* re3 */
12092 DRXJ_16TO8(0), /* re4 */
12093 DRXJ_16TO8(0), /* re5 */
12094 DRXJ_16TO8(0), /* re6 */
12095 DRXJ_16TO8(0), /* re7 */
12096 DRXJ_16TO8(0), /* re8 */
12097 DRXJ_16TO8(0), /* re9 */
12098 DRXJ_16TO8(0), /* re10 */
12099 DRXJ_16TO8(0), /* re11 */
12100 DRXJ_16TO8(0), /* re12 */
12101 DRXJ_16TO8(0), /* re13 */
12102 DRXJ_16TO8(0), /* re14 */
12103 DRXJ_16TO8(0), /* re15 */
12104 DRXJ_16TO8(0), /* re16 */
12105 DRXJ_16TO8(0), /* re17 */
12106 DRXJ_16TO8(0), /* re18 */
12107 DRXJ_16TO8(0), /* re19 */
12108 DRXJ_16TO8(0), /* re20 */
12109 DRXJ_16TO8(0), /* re21 */
12110 DRXJ_16TO8(0), /* re22 */
12111 DRXJ_16TO8(0), /* re23 */
12112 DRXJ_16TO8(0), /* re24 */
12113 DRXJ_16TO8(0), /* re25 */
12114 DRXJ_16TO8(0), /* re26 */
12115 DRXJ_16TO8(0) /* re27 */
12117 const u8 fm_taps_im[] = {
12118 DRXJ_16TO8(-6), /* im0 */
12119 DRXJ_16TO8(2), /* im1 */
12120 DRXJ_16TO8(14), /* im2 */
12121 DRXJ_16TO8(-38), /* im3 */
12122 DRXJ_16TO8(58), /* im4 */
12123 DRXJ_16TO8(-62), /* im5 */
12124 DRXJ_16TO8(42), /* im6 */
12125 DRXJ_16TO8(0), /* im7 */
12126 DRXJ_16TO8(-45), /* im8 */
12127 DRXJ_16TO8(73), /* im9 */
12128 DRXJ_16TO8(-65), /* im10 */
12129 DRXJ_16TO8(23), /* im11 */
12130 DRXJ_16TO8(34), /* im12 */
12131 DRXJ_16TO8(-77), /* im13 */
12132 DRXJ_16TO8(80), /* im14 */
12133 DRXJ_16TO8(-39), /* im15 */
12134 DRXJ_16TO8(-25), /* im16 */
12135 DRXJ_16TO8(78), /* im17 */
12136 DRXJ_16TO8(-90), /* im18 */
12137 DRXJ_16TO8(52), /* im19 */
12138 DRXJ_16TO8(16), /* im20 */
12139 DRXJ_16TO8(-77), /* im21 */
12140 DRXJ_16TO8(97), /* im22 */
12141 DRXJ_16TO8(-62), /* im23 */
12142 DRXJ_16TO8(-8), /* im24 */
12143 DRXJ_16TO8(75), /* im25 */
12144 DRXJ_16TO8(-100), /* im26 */
12145 DRXJ_16TO8(70) /* im27 */
12148 struct i2c_device_addr *dev_addr = NULL;
12149 struct drxjscu_cmd cmd_scu = { /* command */ 0,
12150 /* parameter_len */ 0,
12151 /* result_len */ 0,
12152 /* *parameter */ NULL,
12155 u16 cmd_result = 0;
12157 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
12158 struct drxu_code_info ucode_info;
12159 struct drx_common_attr *common_attr = NULL;
12160 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
12161 struct drxj_data *ext_attr = NULL;
12164 ext_attr = (struct drxj_data *) demod->my_ext_attr;
12165 dev_addr = demod->my_i2c_dev_addr;
12167 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
12168 common_attr = demod->my_common_attr;
12170 /* Check if audio microcode is already uploaded */
12171 if (!(ext_attr->flag_aud_mc_uploaded)) {
12172 ucode_info.mc_data = common_attr->microcode;
12174 /* Upload only audio microcode */
12175 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_UPLOAD, true);
12177 pr_err("error %d\n", rc);
12181 if (common_attr->verify_microcode == true) {
12182 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_VERIFY, true);
12184 pr_err("error %d\n", rc);
12189 /* Prevent uploading audio microcode again */
12190 ext_attr->flag_aud_mc_uploaded = true;
12192 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
12194 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
12196 pr_err("error %d\n", rc);
12199 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
12201 pr_err("error %d\n", rc);
12204 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
12206 pr_err("error %d\n", rc);
12209 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
12211 pr_err("error %d\n", rc);
12214 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
12216 pr_err("error %d\n", rc);
12219 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
12221 pr_err("error %d\n", rc);
12224 /* Reset ATV SCU */
12225 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12226 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
12227 cmd_scu.parameter_len = 0;
12228 cmd_scu.result_len = 1;
12229 cmd_scu.parameter = NULL;
12230 cmd_scu.result = &cmd_result;
12231 rc = scu_command(dev_addr, &cmd_scu);
12233 pr_err("error %d\n", rc);
12237 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE, 0);
12239 pr_err("error %d\n", rc);
12243 /* TODO remove AUTO/OFF patches after ucode fix. */
12244 switch (*standard) {
12245 case DRX_STANDARD_NTSC:
12247 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_MN;
12249 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, IQM_RT_LO_INCR_MN, 0);
12251 pr_err("error %d\n", rc);
12254 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12256 pr_err("error %d\n", rc);
12259 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(ntsc_taps_re), ((u8 *)ntsc_taps_re), 0);
12261 pr_err("error %d\n", rc);
12264 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(ntsc_taps_im), ((u8 *)ntsc_taps_im), 0);
12266 pr_err("error %d\n", rc);
12270 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_MN, 0);
12272 pr_err("error %d\n", rc);
12275 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);
12277 pr_err("error %d\n", rc);
12280 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_MN, 0);
12282 pr_err("error %d\n", rc);
12285 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_MN | ATV_TOP_STD_VID_POL_MN), 0);
12287 pr_err("error %d\n", rc);
12290 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_MN, 0);
12292 pr_err("error %d\n", rc);
12296 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);
12298 pr_err("error %d\n", rc);
12301 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12303 pr_err("error %d\n", rc);
12306 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12308 pr_err("error %d\n", rc);
12311 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);
12313 pr_err("error %d\n", rc);
12316 ext_attr->phase_correction_bypass = false;
12317 ext_attr->enable_cvbs_output = true;
12319 case DRX_STANDARD_FM:
12321 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_FM;
12323 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2994, 0);
12325 pr_err("error %d\n", rc);
12328 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 0, 0);
12330 pr_err("error %d\n", rc);
12333 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(fm_taps_re), ((u8 *)fm_taps_re), 0);
12335 pr_err("error %d\n", rc);
12338 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(fm_taps_im), ((u8 *)fm_taps_im), 0);
12340 pr_err("error %d\n", rc);
12343 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_FM | ATV_TOP_STD_VID_POL_FM), 0);
12345 pr_err("error %d\n", rc);
12348 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_CONTROL__A, 0, 0);
12350 pr_err("error %d\n", rc);
12353 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, 0, 0);
12355 pr_err("error %d\n", rc);
12359 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);
12361 pr_err("error %d\n", rc);
12364 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF, 0);
12366 pr_err("error %d\n", rc);
12369 ext_attr->phase_correction_bypass = true;
12370 ext_attr->enable_cvbs_output = false;
12372 case DRX_STANDARD_PAL_SECAM_BG:
12373 /* PAL/SECAM B/G */
12374 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_B;
12376 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 1820, 0);
12378 pr_err("error %d\n", rc);
12380 } /* TODO check with IS */
12381 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12383 pr_err("error %d\n", rc);
12386 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(bg_taps_re), ((u8 *)bg_taps_re), 0);
12388 pr_err("error %d\n", rc);
12391 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(bg_taps_im), ((u8 *)bg_taps_im), 0);
12393 pr_err("error %d\n", rc);
12396 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_BG, 0);
12398 pr_err("error %d\n", rc);
12401 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG, 0);
12403 pr_err("error %d\n", rc);
12406 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);
12408 pr_err("error %d\n", rc);
12411 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_BG, 0);
12413 pr_err("error %d\n", rc);
12416 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_BG | ATV_TOP_STD_VID_POL_BG), 0);
12418 pr_err("error %d\n", rc);
12421 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);
12423 pr_err("error %d\n", rc);
12426 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12428 pr_err("error %d\n", rc);
12431 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12433 pr_err("error %d\n", rc);
12436 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);
12438 pr_err("error %d\n", rc);
12441 ext_attr->phase_correction_bypass = false;
12442 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12443 ext_attr->enable_cvbs_output = true;
12445 case DRX_STANDARD_PAL_SECAM_DK:
12446 /* PAL/SECAM D/K */
12447 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_DK;
12449 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12451 pr_err("error %d\n", rc);
12453 } /* TODO check with IS */
12454 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12456 pr_err("error %d\n", rc);
12459 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);
12461 pr_err("error %d\n", rc);
12464 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);
12466 pr_err("error %d\n", rc);
12469 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_DK, 0);
12471 pr_err("error %d\n", rc);
12474 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_DK, 0);
12476 pr_err("error %d\n", rc);
12479 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);
12481 pr_err("error %d\n", rc);
12484 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_DK, 0);
12486 pr_err("error %d\n", rc);
12489 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_DK | ATV_TOP_STD_VID_POL_DK), 0);
12491 pr_err("error %d\n", rc);
12494 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);
12496 pr_err("error %d\n", rc);
12499 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12501 pr_err("error %d\n", rc);
12504 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12506 pr_err("error %d\n", rc);
12509 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);
12511 pr_err("error %d\n", rc);
12514 ext_attr->phase_correction_bypass = false;
12515 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12516 ext_attr->enable_cvbs_output = true;
12518 case DRX_STANDARD_PAL_SECAM_I:
12520 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_I;
12522 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12524 pr_err("error %d\n", rc);
12526 } /* TODO check with IS */
12527 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12529 pr_err("error %d\n", rc);
12532 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);
12534 pr_err("error %d\n", rc);
12537 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);
12539 pr_err("error %d\n", rc);
12542 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_I, 0);
12544 pr_err("error %d\n", rc);
12547 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_I, 0);
12549 pr_err("error %d\n", rc);
12552 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);
12554 pr_err("error %d\n", rc);
12557 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_I, 0);
12559 pr_err("error %d\n", rc);
12562 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_I | ATV_TOP_STD_VID_POL_I), 0);
12564 pr_err("error %d\n", rc);
12567 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);
12569 pr_err("error %d\n", rc);
12572 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12574 pr_err("error %d\n", rc);
12577 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12579 pr_err("error %d\n", rc);
12582 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);
12584 pr_err("error %d\n", rc);
12587 ext_attr->phase_correction_bypass = false;
12588 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12589 ext_attr->enable_cvbs_output = true;
12591 case DRX_STANDARD_PAL_SECAM_L:
12592 /* PAL/SECAM L with negative modulation */
12593 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_L;
12595 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12597 pr_err("error %d\n", rc);
12599 } /* TODO check with IS */
12600 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_L, 0);
12602 pr_err("error %d\n", rc);
12605 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12607 pr_err("error %d\n", rc);
12610 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);
12612 pr_err("error %d\n", rc);
12615 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);
12617 pr_err("error %d\n", rc);
12620 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12622 pr_err("error %d\n", rc);
12624 } /* TODO check with IS */
12625 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);
12627 pr_err("error %d\n", rc);
12630 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_L, 0);
12632 pr_err("error %d\n", rc);
12635 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_L | ATV_TOP_STD_VID_POL_L), 0);
12637 pr_err("error %d\n", rc);
12640 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);
12642 pr_err("error %d\n", rc);
12645 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12647 pr_err("error %d\n", rc);
12650 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12652 pr_err("error %d\n", rc);
12655 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);
12657 pr_err("error %d\n", rc);
12660 ext_attr->phase_correction_bypass = false;
12661 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12662 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12663 ext_attr->enable_cvbs_output = true;
12665 case DRX_STANDARD_PAL_SECAM_LP:
12666 /* PAL/SECAM L with positive modulation */
12667 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_LP;
12669 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_LP, 0);
12671 pr_err("error %d\n", rc);
12674 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12676 pr_err("error %d\n", rc);
12678 } /* TODO check with IS */
12679 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12681 pr_err("error %d\n", rc);
12684 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);
12686 pr_err("error %d\n", rc);
12689 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);
12691 pr_err("error %d\n", rc);
12694 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12696 pr_err("error %d\n", rc);
12698 } /* TODO check with IS */
12699 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);
12701 pr_err("error %d\n", rc);
12704 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_LP, 0);
12706 pr_err("error %d\n", rc);
12709 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_LP | ATV_TOP_STD_VID_POL_LP), 0);
12711 pr_err("error %d\n", rc);
12714 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);
12716 pr_err("error %d\n", rc);
12719 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12721 pr_err("error %d\n", rc);
12724 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12726 pr_err("error %d\n", rc);
12729 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);
12731 pr_err("error %d\n", rc);
12734 ext_attr->phase_correction_bypass = false;
12735 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12736 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12737 ext_attr->enable_cvbs_output = true;
12743 /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
12744 if (!ext_attr->has_lna) {
12745 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x01, 0);
12747 pr_err("error %d\n", rc);
12752 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_STANDARD__A, 0x002, 0);
12754 pr_err("error %d\n", rc);
12757 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, IQM_AF_CLP_LEN_ATV, 0);
12759 pr_err("error %d\n", rc);
12762 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, IQM_AF_CLP_TH_ATV, 0);
12764 pr_err("error %d\n", rc);
12767 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, IQM_AF_SNS_LEN_ATV, 0);
12769 pr_err("error %d\n", rc);
12772 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12774 pr_err("error %d\n", rc);
12777 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_IF__A, 10248, 0);
12779 pr_err("error %d\n", rc);
12783 ext_attr->iqm_rc_rate_ofs = 0x00200000L;
12784 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
12786 pr_err("error %d\n", rc);
12789 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_OFF, 0);
12791 pr_err("error %d\n", rc);
12794 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, IQM_RC_STRETCH_ATV, 0);
12796 pr_err("error %d\n", rc);
12800 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);
12802 pr_err("error %d\n", rc);
12806 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_ATV__M, 0);
12808 pr_err("error %d\n", rc);
12811 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, IQM_CF_SYMMETRIC_IM__M, 0);
12813 pr_err("error %d\n", rc);
12816 /* default: SIF in standby */
12817 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_SYNC_SLICE__A, ATV_TOP_SYNC_SLICE_MN, 0);
12819 pr_err("error %d\n", rc);
12822 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_ACCU__A, ATV_TOP_MOD_ACCU__PRE, 0);
12824 pr_err("error %d\n", rc);
12828 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, 0x080, 0);
12830 pr_err("error %d\n", rc);
12833 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_FAGC_TH_RED__A, 10, 0);
12835 pr_err("error %d\n", rc);
12838 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AAGC_CNT__A, 7, 0);
12840 pr_err("error %d\n", rc);
12843 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_NAGC_KI_MIN__A, 0x0225, 0);
12845 pr_err("error %d\n", rc);
12848 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_NAGC_KI_MAX__A, 0x0547, 0);
12850 pr_err("error %d\n", rc);
12853 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_KI_CHANGE_TH__A, 20, 0);
12855 pr_err("error %d\n", rc);
12858 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_LOCK__A, 0, 0);
12860 pr_err("error %d\n", rc);
12864 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_DELAY__A, IQM_RT_DELAY__PRE, 0);
12866 pr_err("error %d\n", rc);
12869 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BPC_KI_MIN__A, 531, 0);
12871 pr_err("error %d\n", rc);
12874 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061, 0);
12876 pr_err("error %d\n", rc);
12879 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_REF_MIN__A, 100, 0);
12881 pr_err("error %d\n", rc);
12884 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_REF_MAX__A, 260, 0);
12886 pr_err("error %d\n", rc);
12889 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_LVL__A, 0, 0);
12891 pr_err("error %d\n", rc);
12894 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX__A, 0, 0);
12896 pr_err("error %d\n", rc);
12899 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MIN__A, 2047, 0);
12901 pr_err("error %d\n", rc);
12904 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
12906 pr_err("error %d\n", rc);
12910 /* Override reset values with current shadow settings */
12911 rc = atv_update_config(demod, true);
12913 pr_err("error %d\n", rc);
12917 /* Configure/restore AGC settings */
12918 rc = init_agc(demod);
12920 pr_err("error %d\n", rc);
12923 rc = set_agc_if(demod, &(ext_attr->atv_if_agc_cfg), false);
12925 pr_err("error %d\n", rc);
12928 rc = set_agc_rf(demod, &(ext_attr->atv_rf_agc_cfg), false);
12930 pr_err("error %d\n", rc);
12933 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12935 pr_err("error %d\n", rc);
12939 /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
12940 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12941 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
12942 cmd_scu.parameter_len = 1;
12943 cmd_scu.result_len = 1;
12944 cmd_scu.parameter = &cmd_param;
12945 cmd_scu.result = &cmd_result;
12946 rc = scu_command(dev_addr, &cmd_scu);
12948 pr_err("error %d\n", rc);
12952 /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
12953 if (ext_attr->mfx == 0x03) {
12954 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0, 0);
12956 pr_err("error %d\n", rc);
12960 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1, 0);
12962 pr_err("error %d\n", rc);
12965 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_IIR_CRIT__A, 225, 0);
12967 pr_err("error %d\n", rc);
12978 /* -------------------------------------------------------------------------- */
12980 #ifndef DRXJ_DIGITAL_ONLY
12982 * \fn int set_atv_channel ()
12983 * \brief Set ATV channel.
12984 * \param demod: instance of demod.
12987 * Not much needs to be done here, only start the SCU for NTSC/FM.
12988 * Mirrored channels are not expected in the RF domain, so IQM FS setting
12989 * doesn't need to be remembered.
12990 * The channel->mirror parameter is therefor ignored.
12994 set_atv_channel(struct drx_demod_instance *demod,
12995 s32 tuner_freq_offset,
12996 struct drx_channel *channel, enum drx_standard standard)
12998 struct drxjscu_cmd cmd_scu = { /* command */ 0,
12999 /* parameter_len */ 0,
13000 /* result_len */ 0,
13001 /* parameter */ NULL,
13004 u16 cmd_result = 0;
13005 struct drxj_data *ext_attr = NULL;
13006 struct i2c_device_addr *dev_addr = NULL;
13009 dev_addr = demod->my_i2c_dev_addr;
13010 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13013 Program frequency shifter
13014 No need to account for mirroring on RF
13016 if (channel->mirror == DRX_MIRROR_AUTO)
13017 ext_attr->mirror = DRX_MIRROR_NO;
13019 ext_attr->mirror = channel->mirror;
13021 rc = set_frequency(demod, channel, tuner_freq_offset);
13023 pr_err("error %d\n", rc);
13026 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE, 0);
13028 pr_err("error %d\n", rc);
13032 /* Start ATV SCU */
13033 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
13034 SCU_RAM_COMMAND_CMD_DEMOD_START;
13035 cmd_scu.parameter_len = 0;
13036 cmd_scu.result_len = 1;
13037 cmd_scu.parameter = NULL;
13038 cmd_scu.result = &cmd_result;
13039 rc = scu_command(dev_addr, &cmd_scu);
13041 pr_err("error %d\n", rc);
13045 /* if ( (ext_attr->standard == DRX_STANDARD_FM) && (ext_attr->flagSetAUDdone == true) )
13047 ext_attr->detectedRDS = (bool)false;
13056 /* -------------------------------------------------------------------------- */
13059 * \fn int get_atv_channel ()
13060 * \brief Set ATV channel.
13061 * \param demod: instance of demod.
13062 * \param channel: pointer to channel data.
13063 * \param standard: NTSC or FM.
13066 * Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
13067 * Computes the frequency offset in te RF domain and adds it to
13068 * channel->frequency. Determines the value for channel->bandwidth.
13071 #ifndef DRXJ_DIGITAL_ONLY
13073 get_atv_channel(struct drx_demod_instance *demod,
13074 struct drx_channel *channel, enum drx_standard standard)
13077 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
13081 channel->bandwidth = ((struct drxj_data *) demod->my_ext_attr)->curr_bandwidth;
13083 switch (standard) {
13084 case DRX_STANDARD_NTSC:
13085 case DRX_STANDARD_PAL_SECAM_BG:
13086 case DRX_STANDARD_PAL_SECAM_DK:
13087 case DRX_STANDARD_PAL_SECAM_I:
13088 case DRX_STANDARD_PAL_SECAM_L:
13090 u16 measured_offset = 0;
13092 /* get measured frequency offset */
13093 rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13095 pr_err("error %d\n", rc);
13098 /* Signed 8 bit register => sign extension needed */
13099 if ((measured_offset & 0x0080) != 0)
13100 measured_offset |= 0xFF80;
13102 (s32) (((s16) measured_offset) * 10);
13105 case DRX_STANDARD_PAL_SECAM_LP:
13107 u16 measured_offset = 0;
13109 /* get measured frequency offset */
13110 rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13112 pr_err("error %d\n", rc);
13115 /* Signed 8 bit register => sign extension needed */
13116 if ((measured_offset & 0x0080) != 0)
13117 measured_offset |= 0xFF80;
13119 (s32) (((s16) measured_offset) * 10);
13122 case DRX_STANDARD_FM:
13123 /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
13124 AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
13126 /* No bandwidth know for FM */
13127 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
13133 channel->frequency -= offset;
13140 /* -------------------------------------------------------------------------- */
13142 * \fn int get_atv_sig_strength()
13143 * \brief Retrieve signal strength for ATV & FM.
13144 * \param devmod Pointer to demodulator instance.
13145 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
13147 * \retval 0 sig_strength contains valid data.
13148 * \retval -EIO Erroneous data, sig_strength equals 0.
13150 * Taking into account:
13152 * * IF gain (not implemented yet, waiting for IF gain control by ucode)
13155 * All weights (digital, if, rf) must add up to 100.
13157 * TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
13161 get_atv_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
13163 struct i2c_device_addr *dev_addr = NULL;
13164 struct drxj_data *ext_attr = NULL;
13167 /* All weights must add up to 100 (%)
13168 TODO: change weights when IF ctrl is available */
13169 u32 digital_weight = 50; /* 0 .. 100 */
13170 u32 rf_weight = 50; /* 0 .. 100 */
13171 u32 if_weight = 0; /* 0 .. 100 */
13173 u16 digital_curr_gain = 0;
13174 u32 digital_max_gain = 0;
13175 u32 digital_min_gain = 0;
13176 u16 rf_curr_gain = 0;
13177 u32 rf_max_gain = 0x800; /* taken from ucode */
13178 u32 rf_min_gain = 0x7fff;
13179 u16 if_curr_gain = 0;
13180 u32 if_max_gain = 0x800; /* taken from ucode */
13181 u32 if_min_gain = 0x7fff;
13183 u32 digital_strength = 0; /* 0.. 100 */
13184 u32 rf_strength = 0; /* 0.. 100 */
13185 u32 if_strength = 0; /* 0.. 100 */
13187 dev_addr = demod->my_i2c_dev_addr;
13188 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13192 switch (ext_attr->standard) {
13193 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13194 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13195 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13196 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13197 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
13198 case DRX_STANDARD_NTSC:
13199 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &digital_curr_gain, 0);
13201 pr_err("error %d\n", rc);
13204 digital_max_gain = 22512; /* taken from ucode */
13205 digital_min_gain = 2400; /* taken from ucode */
13207 case DRX_STANDARD_FM:
13208 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &digital_curr_gain, 0);
13210 pr_err("error %d\n", rc);
13213 digital_max_gain = 0x4ff; /* taken from ucode */
13214 digital_min_gain = 0; /* taken from ucode */
13220 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &rf_curr_gain, 0);
13222 pr_err("error %d\n", rc);
13225 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &if_curr_gain, 0);
13227 pr_err("error %d\n", rc);
13232 if (digital_curr_gain >= digital_max_gain)
13233 digital_curr_gain = (u16)digital_max_gain;
13234 if (digital_curr_gain <= digital_min_gain)
13235 digital_curr_gain = (u16)digital_min_gain;
13236 if (if_curr_gain <= if_max_gain)
13237 if_curr_gain = (u16)if_max_gain;
13238 if (if_curr_gain >= if_min_gain)
13239 if_curr_gain = (u16)if_min_gain;
13240 if (rf_curr_gain <= rf_max_gain)
13241 rf_curr_gain = (u16)rf_max_gain;
13242 if (rf_curr_gain >= rf_min_gain)
13243 rf_curr_gain = (u16)rf_min_gain;
13245 /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
13246 of clipping at ADC */
13248 /* Compute signal strength (in %) per "gain domain" */
13251 /* TODO: ADC clipping not handled */
13252 digital_strength = (100 * (digital_max_gain - (u32) digital_curr_gain)) /
13253 (digital_max_gain - digital_min_gain);
13255 /* TODO: IF gain not implemented yet in microcode, check after impl. */
13256 if_strength = (100 * ((u32) if_curr_gain - if_max_gain)) /
13257 (if_min_gain - if_max_gain);
13260 /* TODO: ADC clipping not handled */
13261 rf_strength = (100 * ((u32) rf_curr_gain - rf_max_gain)) /
13262 (rf_min_gain - rf_max_gain);
13264 /* Compute a weighted signal strength (in %) */
13265 *sig_strength = (u16) (digital_weight * digital_strength +
13266 rf_weight * rf_strength + if_weight * if_strength);
13267 *sig_strength /= 100;
13274 /* -------------------------------------------------------------------------- */
13276 * \fn int atv_sig_quality()
13277 * \brief Retrieve signal quality indication for ATV.
13278 * \param devmod Pointer to demodulator instance.
13279 * \param sig_quality Pointer to signal quality structure.
13281 * \retval 0 sig_quality contains valid data.
13282 * \retval -EIO Erroneous data, sig_quality indicator equals 0.
13287 atv_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
13289 struct i2c_device_addr *dev_addr = NULL;
13290 u16 quality_indicator = 0;
13293 dev_addr = demod->my_i2c_dev_addr;
13295 /* defined values for fields not used */
13296 sig_quality->MER = 0;
13297 sig_quality->pre_viterbi_ber = 0;
13298 sig_quality->post_viterbi_ber = 0;
13299 sig_quality->scale_factor_ber = 1;
13300 sig_quality->packet_error = 0;
13301 sig_quality->post_reed_solomon_ber = 0;
13305 0x000..0x080: strong signal => 80% .. 100%
13306 0x080..0x700: weak signal => 30% .. 80%
13307 0x700..0x7ff: no signal => 0% .. 30%
13310 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_CR_LOCK__A, &quality_indicator, 0);
13312 pr_err("error %d\n", rc);
13315 quality_indicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
13316 if (quality_indicator <= 0x80) {
13317 sig_quality->indicator =
13318 80 + ((20 * (0x80 - quality_indicator)) / 0x80);
13319 } else if (quality_indicator <= 0x700)
13320 sig_quality->indicator = 30 + ((50 * (0x700 - quality_indicator)) / (0x700 - 0x81));
13322 sig_quality->indicator = (30 * (0x7FF - quality_indicator)) / (0x7FF - 0x701);
13328 #endif /* DRXJ_DIGITAL_ONLY */
13330 /*============================================================================*/
13331 /*== END ATV DATAPATH FUNCTIONS ==*/
13332 /*============================================================================*/
13334 #ifndef DRXJ_EXCLUDE_AUDIO
13335 /*===========================================================================*/
13336 /*===========================================================================*/
13337 /*== AUDIO DATAPATH FUNCTIONS ==*/
13338 /*===========================================================================*/
13339 /*===========================================================================*/
13342 * \brief Power up AUD.
13343 * \param demod instance of demodulator
13347 static int power_up_aud(struct drx_demod_instance *demod, bool set_standard)
13349 enum drx_aud_standard aud_standard = DRX_AUD_STANDARD_AUTO;
13350 struct i2c_device_addr *dev_addr = NULL;
13353 dev_addr = demod->my_i2c_dev_addr;
13355 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE, 0);
13357 pr_err("error %d\n", rc);
13360 /* setup TR interface: R/W mode, fifosize=8 */
13361 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_TOP_TR_MDE__A, 8, 0);
13363 pr_err("error %d\n", rc);
13366 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE, 0);
13368 pr_err("error %d\n", rc);
13372 if (set_standard) {
13373 rc = aud_ctrl_set_standard(demod, &aud_standard);
13375 pr_err("error %d\n", rc);
13385 /*============================================================================*/
13388 * \brief Power up AUD.
13389 * \param demod instance of demodulator
13393 static int power_down_aud(struct drx_demod_instance *demod)
13395 struct i2c_device_addr *dev_addr = NULL;
13396 struct drxj_data *ext_attr = NULL;
13399 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13400 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13402 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
13404 pr_err("error %d\n", rc);
13408 ext_attr->aud_data.audio_is_active = false;
13415 /*============================================================================*/
13417 * \brief Get Modus data from audio RAM
13418 * \param demod instance of demodulator
13419 * \param pointer to modus
13423 static int aud_get_modus(struct drx_demod_instance *demod, u16 *modus)
13425 struct i2c_device_addr *dev_addr = NULL;
13426 struct drxj_data *ext_attr = NULL;
13430 u16 r_modus_hi = 0;
13431 u16 r_modus_lo = 0;
13436 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13437 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13440 if (ext_attr->aud_data.audio_is_active == false) {
13441 rc = power_up_aud(demod, true);
13443 pr_err("error %d\n", rc);
13446 ext_attr->aud_data.audio_is_active = true;
13449 /* Modus register is combined in to RAM location */
13450 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_MODUS_HI__A, &r_modus_hi, 0);
13452 pr_err("error %d\n", rc);
13455 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_MODUS_LO__A, &r_modus_lo, 0);
13457 pr_err("error %d\n", rc);
13461 r_modus = ((r_modus_hi << 12) & AUD_DEM_RAM_MODUS_HI__M)
13462 | (((r_modus_lo & AUD_DEM_RAM_MODUS_LO__M)));
13472 /*============================================================================*/
13474 * \brief Get audio RDS dat
13475 * \param demod instance of demodulator
13476 * \param pointer to struct drx_cfg_aud_rds * \return int.
13480 aud_ctrl_get_cfg_rds(struct drx_demod_instance *demod, struct drx_cfg_aud_rds *status)
13482 struct i2c_device_addr *addr = NULL;
13483 struct drxj_data *ext_attr = NULL;
13486 u16 r_rds_array_cnt_init = 0;
13487 u16 r_rds_array_cnt_check = 0;
13488 u16 r_rds_data = 0;
13489 u16 rds_data_cnt = 0;
13491 addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13492 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13494 if (status == NULL)
13498 if (ext_attr->aud_data.audio_is_active == false) {
13499 rc = power_up_aud(demod, true);
13501 pr_err("error %d\n", rc);
13504 ext_attr->aud_data.audio_is_active = true;
13507 status->valid = false;
13509 rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_init, 0);
13511 pr_err("error %d\n", rc);
13515 if (r_rds_array_cnt_init ==
13516 AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID) {
13521 if (ext_attr->aud_data.rds_data_counter == r_rds_array_cnt_init) {
13526 /* RDS is detected, as long as FM radio is selected assume
13527 RDS will be available */
13528 ext_attr->aud_data.rds_data_present = true;
13531 /* read the data */
13532 for (rds_data_cnt = 0; rds_data_cnt < AUD_RDS_ARRAY_SIZE; rds_data_cnt++) {
13533 rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_DATA__A, &r_rds_data, 0);
13535 pr_err("error %d\n", rc);
13538 status->data[rds_data_cnt] = r_rds_data;
13541 rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_check, 0);
13543 pr_err("error %d\n", rc);
13547 if (r_rds_array_cnt_check == r_rds_array_cnt_init) {
13548 status->valid = true;
13549 ext_attr->aud_data.rds_data_counter = r_rds_array_cnt_check;
13557 /*============================================================================*/
13559 * \brief Get the current audio carrier detection status
13560 * \param demod instance of demodulator
13561 * \param pointer to aud_ctrl_get_status
13566 aud_ctrl_get_carrier_detect_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13568 struct drxj_data *ext_attr = NULL;
13569 struct i2c_device_addr *dev_addr = NULL;
13573 if (status == NULL)
13576 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13577 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13580 if (ext_attr->aud_data.audio_is_active == false) {
13581 rc = power_up_aud(demod, true);
13583 pr_err("error %d\n", rc);
13586 ext_attr->aud_data.audio_is_active = true;
13589 /* initialize the variables */
13590 status->carrier_a = false;
13591 status->carrier_b = false;
13592 status->nicam_status = DRX_AUD_NICAM_NOT_DETECTED;
13593 status->sap = false;
13594 status->stereo = false;
13596 /* read stereo sound mode indication */
13597 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RD_STATUS__A, &r_data, 0);
13599 pr_err("error %d\n", rc);
13603 /* carrier a detected */
13604 if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_A__M) == AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED)
13605 status->carrier_a = true;
13607 /* carrier b detected */
13608 if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_B__M) == AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED)
13609 status->carrier_b = true;
13610 /* nicam detected */
13611 if ((r_data & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
13612 AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED) {
13613 if ((r_data & AUD_DEM_RD_STATUS_BAD_NICAM__M) == AUD_DEM_RD_STATUS_BAD_NICAM_OK)
13614 status->nicam_status = DRX_AUD_NICAM_DETECTED;
13616 status->nicam_status = DRX_AUD_NICAM_BAD;
13619 /* audio mode bilingual or SAP detected */
13620 if ((r_data & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) == AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP)
13621 status->sap = true;
13623 /* stereo detected */
13624 if ((r_data & AUD_DEM_RD_STATUS_STAT_STEREO__M) == AUD_DEM_RD_STATUS_STAT_STEREO_STEREO)
13625 status->stereo = true;
13632 /*============================================================================*/
13634 * \brief Get the current audio status parameters
13635 * \param demod instance of demodulator
13636 * \param pointer to aud_ctrl_get_status
13641 aud_ctrl_get_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13643 struct drxj_data *ext_attr = NULL;
13644 struct i2c_device_addr *dev_addr = NULL;
13645 struct drx_cfg_aud_rds rds = { false, {0} };
13649 if (status == NULL)
13652 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13653 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13655 /* carrier detection */
13656 rc = aud_ctrl_get_carrier_detect_status(demod, status);
13658 pr_err("error %d\n", rc);
13663 status->rds = false;
13664 rc = aud_ctrl_get_cfg_rds(demod, &rds);
13666 pr_err("error %d\n", rc);
13669 status->rds = ext_attr->aud_data.rds_data_present;
13672 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_IDENT_VALUE__A, &r_data, 0);
13674 pr_err("error %d\n", rc);
13677 r_data >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
13678 status->fm_ident = (s8) r_data;
13685 /*============================================================================*/
13687 * \brief Get the current volume settings
13688 * \param demod instance of demodulator
13689 * \param pointer to struct drx_cfg_aud_volume * \return int.
13693 aud_ctrl_get_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13695 struct i2c_device_addr *dev_addr = NULL;
13696 struct drxj_data *ext_attr = NULL;
13701 u16 r_strength_left = 0;
13702 u16 r_strength_right = 0;
13704 if (volume == NULL)
13707 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13708 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13711 if (ext_attr->aud_data.audio_is_active == false) {
13712 rc = power_up_aud(demod, true);
13714 pr_err("error %d\n", rc);
13717 ext_attr->aud_data.audio_is_active = true;
13721 volume->mute = ext_attr->aud_data.volume.mute;
13722 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, &r_volume, 0);
13724 pr_err("error %d\n", rc);
13727 if (r_volume == 0) {
13728 volume->mute = true;
13729 volume->volume = ext_attr->aud_data.volume.volume;
13731 volume->mute = false;
13732 volume->volume = ((r_volume & AUD_DSP_WR_VOLUME_VOL_MAIN__M) >>
13733 AUD_DSP_WR_VOLUME_VOL_MAIN__B) -
13734 AUD_VOLUME_ZERO_DB;
13735 if (volume->volume < AUD_VOLUME_DB_MIN)
13736 volume->volume = AUD_VOLUME_DB_MIN;
13737 if (volume->volume > AUD_VOLUME_DB_MAX)
13738 volume->volume = AUD_VOLUME_DB_MAX;
13741 /* automatic volume control */
13742 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AVC__A, &r_avc, 0);
13744 pr_err("error %d\n", rc);
13748 if ((r_avc & AUD_DSP_WR_AVC_AVC_ON__M) == AUD_DSP_WR_AVC_AVC_ON_OFF) {
13749 volume->avc_mode = DRX_AUD_AVC_OFF;
13751 switch (r_avc & AUD_DSP_WR_AVC_AVC_DECAY__M) {
13752 case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
13753 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_20MS;
13755 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
13756 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_8S;
13758 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
13759 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_4S;
13761 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
13762 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_2S;
13770 /* max attenuation */
13771 switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_ATT__M) {
13772 case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
13773 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_12DB;
13775 case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
13776 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_18DB;
13778 case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
13779 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_24DB;
13787 switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M) {
13788 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
13789 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_0DB;
13791 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
13792 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_6DB;
13794 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
13795 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_12DB;
13802 /* reference level */
13803 volume->avc_ref_level = (u16) ((r_avc & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
13804 AUD_DSP_WR_AVC_AVC_REF_LEV__B);
13806 /* read qpeak registers and calculate strength of left and right carrier */
13807 /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
13808 /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
13813 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_QPEAK_L__A, &r_strength_left, 0);
13815 pr_err("error %d\n", rc);
13818 volume->strength_left = (((s16) log1_times100(r_strength_left)) -
13819 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
13821 /* right carrier */
13822 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_QPEAK_R__A, &r_strength_right, 0);
13824 pr_err("error %d\n", rc);
13827 volume->strength_right = (((s16) log1_times100(r_strength_right)) -
13828 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
13835 /*============================================================================*/
13837 * \brief Set the current volume settings
13838 * \param demod instance of demodulator
13839 * \param pointer to struct drx_cfg_aud_volume * \return int.
13843 aud_ctrl_set_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13845 struct i2c_device_addr *dev_addr = NULL;
13846 struct drxj_data *ext_attr = NULL;
13852 if (volume == NULL)
13855 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13856 ext_attr = (struct drxj_data *) demod->my_ext_attr;
13859 if (ext_attr->aud_data.audio_is_active == false) {
13860 rc = power_up_aud(demod, true);
13862 pr_err("error %d\n", rc);
13865 ext_attr->aud_data.audio_is_active = true;
13869 /* volume range from -60 to 12 (expressed in dB) */
13870 if ((volume->volume < AUD_VOLUME_DB_MIN) ||
13871 (volume->volume > AUD_VOLUME_DB_MAX))
13874 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, &w_volume, 0);
13876 pr_err("error %d\n", rc);
13880 /* clear the volume mask */
13881 w_volume &= (u16) ~AUD_DSP_WR_VOLUME_VOL_MAIN__M;
13882 if (volume->mute == true)
13883 w_volume |= (u16)(0);
13885 w_volume |= (u16)((volume->volume + AUD_VOLUME_ZERO_DB) << AUD_DSP_WR_VOLUME_VOL_MAIN__B);
13887 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
13889 pr_err("error %d\n", rc);
13893 /* automatic volume control */
13894 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AVC__A, &w_avc, 0);
13896 pr_err("error %d\n", rc);
13900 /* clear masks that require writing */
13901 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_ON__M;
13902 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_DECAY__M;
13904 if (volume->avc_mode == DRX_AUD_AVC_OFF) {
13905 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_OFF);
13908 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_ON);
13911 switch (volume->avc_mode) {
13912 case DRX_AUD_AVC_DECAYTIME_20MS:
13913 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
13915 case DRX_AUD_AVC_DECAYTIME_8S:
13916 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
13918 case DRX_AUD_AVC_DECAYTIME_4S:
13919 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
13921 case DRX_AUD_AVC_DECAYTIME_2S:
13922 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
13929 /* max attenuation */
13930 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
13931 switch (volume->avc_max_atten) {
13932 case DRX_AUD_AVC_MAX_ATTEN_12DB:
13933 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
13935 case DRX_AUD_AVC_MAX_ATTEN_18DB:
13936 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
13938 case DRX_AUD_AVC_MAX_ATTEN_24DB:
13939 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
13946 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
13947 switch (volume->avc_max_gain) {
13948 case DRX_AUD_AVC_MAX_GAIN_0DB:
13949 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
13951 case DRX_AUD_AVC_MAX_GAIN_6DB:
13952 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
13954 case DRX_AUD_AVC_MAX_GAIN_12DB:
13955 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
13961 /* avc reference level */
13962 if (volume->avc_ref_level > AUD_MAX_AVC_REF_LEVEL)
13965 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_REF_LEV__M;
13966 w_avc |= (u16) (volume->avc_ref_level << AUD_DSP_WR_AVC_AVC_REF_LEV__B);
13968 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_AVC__A, w_avc, 0);
13970 pr_err("error %d\n", rc);
13974 /* all done, store config in data structure */
13975 ext_attr->aud_data.volume = *volume;
13982 /*============================================================================*/
13984 * \brief Get the I2S settings
13985 * \param demod instance of demodulator
13986 * \param pointer to struct drx_cfg_i2s_output * \return int.
13990 aud_ctrl_get_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
13992 struct i2c_device_addr *dev_addr = NULL;
13993 struct drxj_data *ext_attr = NULL;
13995 u16 w_i2s_config = 0;
13996 u16 r_i2s_freq = 0;
13998 if (output == NULL)
14001 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14002 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14005 if (ext_attr->aud_data.audio_is_active == false) {
14006 rc = power_up_aud(demod, true);
14008 pr_err("error %d\n", rc);
14011 ext_attr->aud_data.audio_is_active = true;
14014 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14016 pr_err("error %d\n", rc);
14019 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, &r_i2s_freq, 0);
14021 pr_err("error %d\n", rc);
14026 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M) {
14027 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
14028 output->mode = DRX_I2S_MODE_MASTER;
14030 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
14031 output->mode = DRX_I2S_MODE_SLAVE;
14038 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M) {
14039 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
14040 output->format = DRX_I2S_FORMAT_WS_ADVANCED;
14042 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
14043 output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
14049 /* I2S word length */
14050 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M) {
14051 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
14052 output->word_length = DRX_I2S_WORDLENGTH_16;
14054 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
14055 output->word_length = DRX_I2S_WORDLENGTH_32;
14062 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M) {
14063 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
14064 output->polarity = DRX_I2S_POLARITY_LEFT;
14066 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
14067 output->polarity = DRX_I2S_POLARITY_RIGHT;
14073 /* I2S output enabled */
14074 if ((w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M) == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE)
14075 output->output_enable = true;
14077 output->output_enable = false;
14079 if (r_i2s_freq > 0) {
14080 output->frequency = 6144UL * 48000 / r_i2s_freq;
14081 if (output->word_length == DRX_I2S_WORDLENGTH_16)
14082 output->frequency *= 2;
14084 output->frequency = AUD_I2S_FREQUENCY_MAX;
14092 /*============================================================================*/
14094 * \brief Set the I2S settings
14095 * \param demod instance of demodulator
14096 * \param pointer to struct drx_cfg_i2s_output * \return int.
14100 aud_ctrl_set_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
14102 struct i2c_device_addr *dev_addr = NULL;
14103 struct drxj_data *ext_attr = NULL;
14105 u16 w_i2s_config = 0;
14106 u16 w_i2s_pads_data_da = 0;
14107 u16 w_i2s_pads_data_cl = 0;
14108 u16 w_i2s_pads_data_ws = 0;
14109 u32 w_i2s_freq = 0;
14111 if (output == NULL)
14114 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14115 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14118 if (ext_attr->aud_data.audio_is_active == false) {
14119 rc = power_up_aud(demod, true);
14121 pr_err("error %d\n", rc);
14124 ext_attr->aud_data.audio_is_active = true;
14127 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14129 pr_err("error %d\n", rc);
14134 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
14136 switch (output->mode) {
14137 case DRX_I2S_MODE_MASTER:
14138 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
14140 case DRX_I2S_MODE_SLAVE:
14141 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
14148 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
14150 switch (output->format) {
14151 case DRX_I2S_FORMAT_WS_ADVANCED:
14152 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
14154 case DRX_I2S_FORMAT_WS_WITH_DATA:
14155 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
14161 /* I2S word length */
14162 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
14164 switch (output->word_length) {
14165 case DRX_I2S_WORDLENGTH_16:
14166 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
14168 case DRX_I2S_WORDLENGTH_32:
14169 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
14176 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
14177 switch (output->polarity) {
14178 case DRX_I2S_POLARITY_LEFT:
14179 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
14181 case DRX_I2S_POLARITY_RIGHT:
14182 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
14188 /* I2S output enabled */
14189 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
14190 if (output->output_enable == true)
14191 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
14193 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
14198 w_i2s_freq = 6144 * 48000 * nrbits / ( 32 * frequency )
14200 16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
14201 32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
14203 if ((output->frequency > AUD_I2S_FREQUENCY_MAX) ||
14204 output->frequency < AUD_I2S_FREQUENCY_MIN) {
14208 w_i2s_freq = (6144UL * 48000UL) + (output->frequency >> 1);
14209 w_i2s_freq /= output->frequency;
14211 if (output->word_length == DRX_I2S_WORDLENGTH_16)
14214 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_I2S_CONFIG2__A, w_i2s_config, 0);
14216 pr_err("error %d\n", rc);
14219 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, (u16)w_i2s_freq, 0);
14221 pr_err("error %d\n", rc);
14225 /* configure I2S output pads for master or slave mode */
14226 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
14228 pr_err("error %d\n", rc);
14232 if (output->mode == DRX_I2S_MODE_MASTER) {
14233 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
14234 SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
14235 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
14236 SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
14237 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
14238 SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
14240 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
14241 SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
14242 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
14243 SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
14244 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
14245 SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
14248 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_DA_CFG__A, w_i2s_pads_data_da, 0);
14250 pr_err("error %d\n", rc);
14253 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_CL_CFG__A, w_i2s_pads_data_cl, 0);
14255 pr_err("error %d\n", rc);
14258 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_WS_CFG__A, w_i2s_pads_data_ws, 0);
14260 pr_err("error %d\n", rc);
14264 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
14266 pr_err("error %d\n", rc);
14270 /* all done, store config in data structure */
14271 ext_attr->aud_data.i2sdata = *output;
14278 /*============================================================================*/
14280 * \brief Get the Automatic Standard Select (ASS)
14281 * and Automatic Sound Change (ASC)
14282 * \param demod instance of demodulator
14283 * \param pointer to pDRXAudAutoSound_t
14288 aud_ctrl_get_cfg_auto_sound(struct drx_demod_instance *demod,
14289 enum drx_cfg_aud_auto_sound *auto_sound)
14291 struct drxj_data *ext_attr = NULL;
14295 if (auto_sound == NULL)
14298 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14301 if (ext_attr->aud_data.audio_is_active == false) {
14302 rc = power_up_aud(demod, true);
14304 pr_err("error %d\n", rc);
14307 ext_attr->aud_data.audio_is_active = true;
14310 rc = aud_get_modus(demod, &r_modus);
14312 pr_err("error %d\n", rc);
14316 switch (r_modus & (AUD_DEM_WR_MODUS_MOD_ASS__M |
14317 AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M)) {
14318 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14319 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14321 DRX_AUD_AUTO_SOUND_OFF;
14323 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14325 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
14327 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14329 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
14340 /*============================================================================*/
14342 * \brief Set the Automatic Standard Select (ASS)
14343 * and Automatic Sound Change (ASC)
14344 * \param demod instance of demodulator
14345 * \param pointer to pDRXAudAutoSound_t
14350 aud_ctr_setl_cfg_auto_sound(struct drx_demod_instance *demod,
14351 enum drx_cfg_aud_auto_sound *auto_sound)
14353 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14354 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14359 if (auto_sound == NULL)
14362 dev_addr = demod->my_i2c_dev_addr;
14363 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14366 if (ext_attr->aud_data.audio_is_active == false) {
14367 rc = power_up_aud(demod, true);
14369 pr_err("error %d\n", rc);
14372 ext_attr->aud_data.audio_is_active = true;
14375 rc = aud_get_modus(demod, &r_modus);
14377 pr_err("error %d\n", rc);
14382 /* clear ASS & ASC bits */
14383 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_ASS__M;
14384 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
14386 switch (*auto_sound) {
14387 case DRX_AUD_AUTO_SOUND_OFF:
14388 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
14389 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14391 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
14392 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14393 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
14395 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
14396 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14397 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14403 if (w_modus != r_modus) {
14404 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14406 pr_err("error %d\n", rc);
14410 /* copy to data structure */
14411 ext_attr->aud_data.auto_sound = *auto_sound;
14418 /*============================================================================*/
14420 * \brief Get the Automatic Standard Select thresholds
14421 * \param demod instance of demodulator
14422 * \param pointer to pDRXAudASSThres_t
14427 aud_ctrl_get_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14429 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14430 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14433 u16 thres_btsc = 0;
14434 u16 thres_nicam = 0;
14439 dev_addr = demod->my_i2c_dev_addr;
14440 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14443 if (ext_attr->aud_data.audio_is_active == false) {
14444 rc = power_up_aud(demod, true);
14446 pr_err("error %d\n", rc);
14449 ext_attr->aud_data.audio_is_active = true;
14452 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_A2_THRSHLD__A, &thres_a2, 0);
14454 pr_err("error %d\n", rc);
14457 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_BTSC_THRSHLD__A, &thres_btsc, 0);
14459 pr_err("error %d\n", rc);
14462 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_NICAM_THRSHLD__A, &thres_nicam, 0);
14464 pr_err("error %d\n", rc);
14468 thres->a2 = thres_a2;
14469 thres->btsc = thres_btsc;
14470 thres->nicam = thres_nicam;
14477 /*============================================================================*/
14479 * \brief Get the Automatic Standard Select thresholds
14480 * \param demod instance of demodulator
14481 * \param pointer to pDRXAudASSThres_t
14486 aud_ctrl_set_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14488 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14489 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14494 dev_addr = demod->my_i2c_dev_addr;
14495 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14498 if (ext_attr->aud_data.audio_is_active == false) {
14499 rc = power_up_aud(demod, true);
14501 pr_err("error %d\n", rc);
14504 ext_attr->aud_data.audio_is_active = true;
14507 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_A2_THRSHLD__A, thres->a2, 0);
14509 pr_err("error %d\n", rc);
14512 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc, 0);
14514 pr_err("error %d\n", rc);
14517 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam, 0);
14519 pr_err("error %d\n", rc);
14523 /* update DRXK data structure with hardware values */
14524 ext_attr->aud_data.ass_thresholds = *thres;
14531 /*============================================================================*/
14533 * \brief Get Audio Carrier settings
14534 * \param demod instance of demodulator
14535 * \param pointer to struct drx_aud_carrier ** \return int.
14539 aud_ctrl_get_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14541 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14542 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14560 if (carriers == NULL)
14563 dev_addr = demod->my_i2c_dev_addr;
14564 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14567 if (ext_attr->aud_data.audio_is_active == false) {
14568 rc = power_up_aud(demod, true);
14570 pr_err("error %d\n", rc);
14573 ext_attr->aud_data.audio_is_active = true;
14576 rc = aud_get_modus(demod, &w_modus);
14578 pr_err("error %d\n", rc);
14582 /* Behaviour of primary audio channel */
14583 switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_A__M)) {
14584 case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
14585 carriers->a.opt = DRX_NO_CARRIER_MUTE;
14587 case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
14588 carriers->a.opt = DRX_NO_CARRIER_NOISE;
14595 /* Behaviour of secondary audio channel */
14596 switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_B__M)) {
14597 case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
14598 carriers->b.opt = DRX_NO_CARRIER_MUTE;
14600 case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
14601 carriers->b.opt = DRX_NO_CARRIER_NOISE;
14608 /* frequency adjustment for primary & secondary audio channel */
14609 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_A_HI__A, &dco_a_hi, 0);
14611 pr_err("error %d\n", rc);
14614 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_A_LO__A, &dco_a_lo, 0);
14616 pr_err("error %d\n", rc);
14619 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_B_HI__A, &dco_b_hi, 0);
14621 pr_err("error %d\n", rc);
14624 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_B_LO__A, &dco_b_lo, 0);
14626 pr_err("error %d\n", rc);
14630 valA = (((u32) dco_a_hi) << 12) | ((u32) dco_a_lo & 0xFFF);
14631 valB = (((u32) dco_b_hi) << 12) | ((u32) dco_b_lo & 0xFFF);
14633 /* Multiply by 20250 * 1>>24 ~= 2 / 1657 */
14634 carriers->a.dco = DRX_S24TODRXFREQ(valA) * 2L / 1657L;
14635 carriers->b.dco = DRX_S24TODRXFREQ(valB) * 2L / 1657L;
14637 /* DC level of the incoming FM signal on the primary
14638 & seconday sound channel */
14639 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dc_lvl_a, 0);
14641 pr_err("error %d\n", rc);
14644 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dc_lvl_b, 0);
14646 pr_err("error %d\n", rc);
14650 /* offset (kHz) = (dcLvl / 322) */
14651 carriers->a.shift = (DRX_U16TODRXFREQ(dc_lvl_a) / 322L);
14652 carriers->b.shift = (DRX_U16TODRXFREQ(dc_lvl_b) / 322L);
14654 /* Carrier detetcion threshold for primary & secondary channel */
14655 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cm_thes_a, 0);
14657 pr_err("error %d\n", rc);
14660 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cm_thes_b, 0);
14662 pr_err("error %d\n", rc);
14666 carriers->a.thres = cm_thes_a;
14667 carriers->b.thres = cm_thes_b;
14674 /*============================================================================*/
14676 * \brief Set Audio Carrier settings
14677 * \param demod instance of demodulator
14678 * \param pointer to struct drx_aud_carrier ** \return int.
14682 aud_ctrl_set_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14684 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14685 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14696 if (carriers == NULL)
14699 dev_addr = demod->my_i2c_dev_addr;
14700 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14703 if (ext_attr->aud_data.audio_is_active == false) {
14704 rc = power_up_aud(demod, true);
14706 pr_err("error %d\n", rc);
14709 ext_attr->aud_data.audio_is_active = true;
14712 rc = aud_get_modus(demod, &r_modus);
14714 pr_err("error %d\n", rc);
14719 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_A__M;
14720 /* Behaviour of primary audio channel */
14721 switch (carriers->a.opt) {
14722 case DRX_NO_CARRIER_MUTE:
14723 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
14725 case DRX_NO_CARRIER_NOISE:
14726 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
14733 /* Behaviour of secondary audio channel */
14734 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_B__M;
14735 switch (carriers->b.opt) {
14736 case DRX_NO_CARRIER_MUTE:
14737 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
14739 case DRX_NO_CARRIER_NOISE:
14740 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
14747 /* now update the modus register */
14748 if (w_modus != r_modus) {
14749 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14751 pr_err("error %d\n", rc);
14756 /* frequency adjustment for primary & secondary audio channel */
14757 valA = (s32) ((carriers->a.dco) * 1657L / 2);
14758 valB = (s32) ((carriers->b.dco) * 1657L / 2);
14760 dco_a_hi = (u16) ((valA >> 12) & 0xFFF);
14761 dco_a_lo = (u16) (valA & 0xFFF);
14762 dco_b_hi = (u16) ((valB >> 12) & 0xFFF);
14763 dco_b_lo = (u16) (valB & 0xFFF);
14765 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_A_HI__A, dco_a_hi, 0);
14767 pr_err("error %d\n", rc);
14770 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_A_LO__A, dco_a_lo, 0);
14772 pr_err("error %d\n", rc);
14775 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_B_HI__A, dco_b_hi, 0);
14777 pr_err("error %d\n", rc);
14780 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_B_LO__A, dco_b_lo, 0);
14782 pr_err("error %d\n", rc);
14786 /* Carrier detetcion threshold for primary & secondary channel */
14787 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres, 0);
14789 pr_err("error %d\n", rc);
14792 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres, 0);
14794 pr_err("error %d\n", rc);
14798 /* update DRXK data structure */
14799 ext_attr->aud_data.carriers = *carriers;
14806 /*============================================================================*/
14808 * \brief Get I2S Source, I2S matrix and FM matrix
14809 * \param demod instance of demodulator
14810 * \param pointer to pDRXAudmixer_t
14815 aud_ctrl_get_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
14817 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14818 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14820 u16 src_i2s_matr = 0;
14826 dev_addr = demod->my_i2c_dev_addr;
14827 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14830 if (ext_attr->aud_data.audio_is_active == false) {
14831 rc = power_up_aud(demod, true);
14833 pr_err("error %d\n", rc);
14836 ext_attr->aud_data.audio_is_active = true;
14839 /* Source Selctor */
14840 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
14842 pr_err("error %d\n", rc);
14846 switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M) {
14847 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
14848 mixer->source_i2s = DRX_AUD_SRC_MONO;
14850 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
14851 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_AB;
14853 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
14854 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_A;
14856 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
14857 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_B;
14864 switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M) {
14865 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
14866 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_MONO;
14868 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
14869 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_STEREO;
14871 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
14872 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_A_MONO;
14874 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
14875 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_B_MONO;
14882 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
14884 pr_err("error %d\n", rc);
14887 switch (fm_matr & AUD_DEM_WR_FM_MATRIX__M) {
14888 case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
14889 mixer->matrix_fm = DRX_AUD_FM_MATRIX_NO_MATRIX;
14891 case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
14892 mixer->matrix_fm = DRX_AUD_FM_MATRIX_GERMAN;
14894 case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
14895 mixer->matrix_fm = DRX_AUD_FM_MATRIX_KOREAN;
14897 case AUD_DEM_WR_FM_MATRIX_SOUND_A:
14898 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_A;
14900 case AUD_DEM_WR_FM_MATRIX_SOUND_B:
14901 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_B;
14912 /*============================================================================*/
14914 * \brief Set I2S Source, I2S matrix and FM matrix
14915 * \param demod instance of demodulator
14916 * \param pointer to DRXAudmixer_t
14921 aud_ctrl_set_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
14923 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14924 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14926 u16 src_i2s_matr = 0;
14932 dev_addr = demod->my_i2c_dev_addr;
14933 ext_attr = (struct drxj_data *) demod->my_ext_attr;
14936 if (ext_attr->aud_data.audio_is_active == false) {
14937 rc = power_up_aud(demod, true);
14939 pr_err("error %d\n", rc);
14942 ext_attr->aud_data.audio_is_active = true;
14945 /* Source Selctor */
14946 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
14948 pr_err("error %d\n", rc);
14951 src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
14953 switch (mixer->source_i2s) {
14954 case DRX_AUD_SRC_MONO:
14955 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
14957 case DRX_AUD_SRC_STEREO_OR_AB:
14958 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
14960 case DRX_AUD_SRC_STEREO_OR_A:
14961 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
14963 case DRX_AUD_SRC_STEREO_OR_B:
14964 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
14971 src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
14972 switch (mixer->matrix_i2s) {
14973 case DRX_AUD_I2S_MATRIX_MONO:
14974 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
14976 case DRX_AUD_I2S_MATRIX_STEREO:
14977 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO;
14979 case DRX_AUD_I2S_MATRIX_A_MONO:
14980 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
14982 case DRX_AUD_I2S_MATRIX_B_MONO:
14983 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
14988 /* write the result */
14989 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, src_i2s_matr, 0);
14991 pr_err("error %d\n", rc);
14996 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
14998 pr_err("error %d\n", rc);
15001 fm_matr &= (u16) ~AUD_DEM_WR_FM_MATRIX__M;
15002 switch (mixer->matrix_fm) {
15003 case DRX_AUD_FM_MATRIX_NO_MATRIX:
15004 fm_matr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
15006 case DRX_AUD_FM_MATRIX_GERMAN:
15007 fm_matr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
15009 case DRX_AUD_FM_MATRIX_KOREAN:
15010 fm_matr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
15012 case DRX_AUD_FM_MATRIX_SOUND_A:
15013 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
15015 case DRX_AUD_FM_MATRIX_SOUND_B:
15016 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
15022 /* Only write if ASS is off */
15023 if (ext_attr->aud_data.auto_sound == DRX_AUD_AUTO_SOUND_OFF) {
15024 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, fm_matr, 0);
15026 pr_err("error %d\n", rc);
15031 /* update the data structure with hardware state */
15032 ext_attr->aud_data.mixer = *mixer;
15039 /*============================================================================*/
15041 * \brief Set AV Sync settings
15042 * \param demod instance of demodulator
15043 * \param pointer to DRXICfgAVSync_t
15048 aud_ctrl_set_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15050 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15051 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15053 u16 w_aud_vid_sync = 0;
15055 if (av_sync == NULL)
15058 dev_addr = demod->my_i2c_dev_addr;
15059 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15062 if (ext_attr->aud_data.audio_is_active == false) {
15063 rc = power_up_aud(demod, true);
15065 pr_err("error %d\n", rc);
15068 ext_attr->aud_data.audio_is_active = true;
15071 /* audio/video synchronisation */
15072 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15074 pr_err("error %d\n", rc);
15078 w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_ON__M;
15080 if (*av_sync == DRX_AUD_AVSYNC_OFF)
15081 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
15083 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
15085 w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
15087 switch (*av_sync) {
15088 case DRX_AUD_AVSYNC_NTSC:
15089 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
15091 case DRX_AUD_AVSYNC_MONOCHROME:
15092 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
15094 case DRX_AUD_AVSYNC_PAL_SECAM:
15095 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
15097 case DRX_AUD_AVSYNC_OFF:
15104 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, w_aud_vid_sync, 0);
15106 pr_err("error %d\n", rc);
15114 /*============================================================================*/
15116 * \brief Get AV Sync settings
15117 * \param demod instance of demodulator
15118 * \param pointer to DRXICfgAVSync_t
15123 aud_ctrl_get_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15125 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15126 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15128 u16 w_aud_vid_sync = 0;
15130 if (av_sync == NULL)
15133 dev_addr = demod->my_i2c_dev_addr;
15134 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15137 if (ext_attr->aud_data.audio_is_active == false) {
15138 rc = power_up_aud(demod, true);
15140 pr_err("error %d\n", rc);
15143 ext_attr->aud_data.audio_is_active = true;
15146 /* audio/video synchronisation */
15147 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15149 pr_err("error %d\n", rc);
15153 if ((w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_ON__M) ==
15154 AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE) {
15155 *av_sync = DRX_AUD_AVSYNC_OFF;
15159 switch (w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M) {
15160 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
15161 *av_sync = DRX_AUD_AVSYNC_NTSC;
15163 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
15164 *av_sync = DRX_AUD_AVSYNC_MONOCHROME;
15166 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
15167 *av_sync = DRX_AUD_AVSYNC_PAL_SECAM;
15178 /*============================================================================*/
15180 * \brief Get deviation mode
15181 * \param demod instance of demodulator
15182 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15186 aud_ctrl_get_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15194 rc = aud_get_modus(demod, &r_modus);
15196 pr_err("error %d\n", rc);
15200 switch (r_modus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M) {
15201 case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
15202 *dev = DRX_AUD_DEVIATION_NORMAL;
15204 case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
15205 *dev = DRX_AUD_DEVIATION_HIGH;
15216 /*============================================================================*/
15218 * \brief Get deviation mode
15219 * \param demod instance of demodulator
15220 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15224 aud_ctrl_set_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15226 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15227 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15235 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15236 dev_addr = demod->my_i2c_dev_addr;
15238 rc = aud_get_modus(demod, &r_modus);
15240 pr_err("error %d\n", rc);
15246 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
15249 case DRX_AUD_DEVIATION_NORMAL:
15250 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
15252 case DRX_AUD_DEVIATION_HIGH:
15253 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
15259 /* now update the modus register */
15260 if (w_modus != r_modus) {
15261 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15263 pr_err("error %d\n", rc);
15267 /* store in drxk data struct */
15268 ext_attr->aud_data.deviation = *dev;
15275 /*============================================================================*/
15277 * \brief Get Prescaler settings
15278 * \param demod instance of demodulator
15279 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15283 aud_ctrl_get_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15285 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15286 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15288 u16 r_max_fm_deviation = 0;
15289 u16 r_nicam_prescaler = 0;
15294 dev_addr = demod->my_i2c_dev_addr;
15295 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15298 if (ext_attr->aud_data.audio_is_active == false) {
15299 rc = power_up_aud(demod, true);
15301 pr_err("error %d\n", rc);
15304 ext_attr->aud_data.audio_is_active = true;
15307 /* read register data */
15308 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, &r_nicam_prescaler, 0);
15310 pr_err("error %d\n", rc);
15313 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_FM_PRESC__A, &r_max_fm_deviation, 0);
15315 pr_err("error %d\n", rc);
15319 /* calculate max FM deviation */
15320 r_max_fm_deviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15321 if (r_max_fm_deviation > 0) {
15322 presc->fm_deviation = 3600UL + (r_max_fm_deviation >> 1);
15323 presc->fm_deviation /= r_max_fm_deviation;
15325 presc->fm_deviation = 380; /* kHz */
15328 /* calculate NICAM gain from pre-scaler */
15330 nicam_gain = 20 * ( log10( preScaler / 16) )
15331 = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
15333 because log1_times100() cannot return negative numbers
15334 = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
15336 for 0.1dB resolution:
15338 nicam_gain = 200 * ( log10( preScaler / 16) )
15339 = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
15340 = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
15343 r_nicam_prescaler >>= 8;
15344 if (r_nicam_prescaler <= 1)
15345 presc->nicam_gain = -241;
15347 presc->nicam_gain = (s16)(((s32)(log1_times100(10 * r_nicam_prescaler * r_nicam_prescaler)) - (s32)(log1_times100(10 * 16 * 16))));
15354 /*============================================================================*/
15356 * \brief Set Prescaler settings
15357 * \param demod instance of demodulator
15358 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15362 aud_ctrl_set_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15364 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15365 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15367 u16 w_max_fm_deviation = 0;
15368 u16 nicam_prescaler;
15373 dev_addr = demod->my_i2c_dev_addr;
15374 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15377 if (ext_attr->aud_data.audio_is_active == false) {
15378 rc = power_up_aud(demod, true);
15380 pr_err("error %d\n", rc);
15383 ext_attr->aud_data.audio_is_active = true;
15386 /* setting of max FM deviation */
15387 w_max_fm_deviation = (u16) (frac(3600UL, presc->fm_deviation, 0));
15388 w_max_fm_deviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15389 if (w_max_fm_deviation >= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION)
15390 w_max_fm_deviation = AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
15392 /* NICAM Prescaler */
15393 if ((presc->nicam_gain >= -241) && (presc->nicam_gain <= 180)) {
15396 prescaler = 16 * 10^( gd_b / 20 )
15398 minval of gd_b = -20*log( 16 ) = -24.1dB
15400 negative numbers not allowed for d_b2lin_times100, so
15402 prescaler = 16 * 10^( gd_b / 20 )
15403 = 10^( (gd_b / 20) + log10(16) )
15404 = 10^( (gd_b + 20log10(16)) / 20 )
15408 = 10^( G0.1dB + 200log10(16)) / 200 )
15411 nicam_prescaler = (u16)
15412 ((d_b2lin_times100(presc->nicam_gain + 241UL) + 50UL) / 100UL);
15415 if (nicam_prescaler > 127)
15416 nicam_prescaler = 127;
15418 /* shift before writing to register */
15419 nicam_prescaler <<= 8;
15423 /* end of setting NICAM Prescaler */
15425 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, nicam_prescaler, 0);
15427 pr_err("error %d\n", rc);
15430 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_FM_PRESC__A, w_max_fm_deviation, 0);
15432 pr_err("error %d\n", rc);
15436 ext_attr->aud_data.prescale = *presc;
15443 /*============================================================================*/
15446 * \param demod instance of demodulator
15447 * \param pointer to struct drx_aud_beep * \return int.
15450 static int aud_ctrl_beep(struct drx_demod_instance *demod, struct drx_aud_beep *beep)
15452 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15453 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15462 dev_addr = demod->my_i2c_dev_addr;
15463 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15466 if (ext_attr->aud_data.audio_is_active == false) {
15467 rc = power_up_aud(demod, true);
15469 pr_err("error %d\n", rc);
15472 ext_attr->aud_data.audio_is_active = true;
15475 if ((beep->volume > 0) || (beep->volume < -127))
15478 if (beep->frequency > 3000)
15481 volume = (u16) beep->volume + 127;
15482 the_beep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
15484 frequency = ((u32) beep->frequency) * 23 / 500;
15485 if (frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M)
15486 frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
15487 the_beep |= (u16) frequency;
15489 if (beep->mute == true)
15492 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_BEEPER__A, the_beep, 0);
15494 pr_err("error %d\n", rc);
15503 /*============================================================================*/
15505 * \brief Set an audio standard
15506 * \param demod instance of demodulator
15507 * \param pointer to enum drx_aud_standard * \return int.
15511 aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15513 struct i2c_device_addr *dev_addr = NULL;
15514 struct drxj_data *ext_attr = NULL;
15515 enum drx_standard current_standard = DRX_STANDARD_UNKNOWN;
15517 u16 w_standard = 0;
15521 bool mute_buffer = false;
15522 s16 volume_buffer = 0;
15525 if (standard == NULL)
15528 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15529 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15532 if (ext_attr->aud_data.audio_is_active == false) {
15533 rc = power_up_aud(demod, false);
15535 pr_err("error %d\n", rc);
15538 ext_attr->aud_data.audio_is_active = true;
15541 /* reset RDS data availability flag */
15542 ext_attr->aud_data.rds_data_present = false;
15544 /* we need to mute from here to avoid noise during standard switching */
15545 mute_buffer = ext_attr->aud_data.volume.mute;
15546 volume_buffer = ext_attr->aud_data.volume.volume;
15548 ext_attr->aud_data.volume.mute = true;
15549 /* restore data structure from DRX ExtAttr, call volume first to mute */
15550 rc = aud_ctrl_set_cfg_volume(demod, &ext_attr->aud_data.volume);
15552 pr_err("error %d\n", rc);
15555 rc = aud_ctrl_set_cfg_carrier(demod, &ext_attr->aud_data.carriers);
15557 pr_err("error %d\n", rc);
15560 rc = aud_ctrl_set_cfg_ass_thres(demod, &ext_attr->aud_data.ass_thresholds);
15562 pr_err("error %d\n", rc);
15565 rc = aud_ctr_setl_cfg_auto_sound(demod, &ext_attr->aud_data.auto_sound);
15567 pr_err("error %d\n", rc);
15570 rc = aud_ctrl_set_cfg_mixer(demod, &ext_attr->aud_data.mixer);
15572 pr_err("error %d\n", rc);
15575 rc = aud_ctrl_set_cfg_av_sync(demod, &ext_attr->aud_data.av_sync);
15577 pr_err("error %d\n", rc);
15580 rc = aud_ctrl_set_cfg_output_i2s(demod, &ext_attr->aud_data.i2sdata);
15582 pr_err("error %d\n", rc);
15586 /* get prescaler from presets */
15587 rc = aud_ctrl_set_cfg_prescale(demod, &ext_attr->aud_data.prescale);
15589 pr_err("error %d\n", rc);
15593 rc = aud_get_modus(demod, &r_modus);
15595 pr_err("error %d\n", rc);
15601 switch (*standard) {
15602 case DRX_AUD_STANDARD_AUTO:
15603 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15605 case DRX_AUD_STANDARD_BTSC:
15606 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
15607 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_MONO_AND_SAP)
15608 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
15610 case DRX_AUD_STANDARD_A2:
15611 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
15613 case DRX_AUD_STANDARD_EIAJ:
15614 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
15616 case DRX_AUD_STANDARD_FM_STEREO:
15617 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
15619 case DRX_AUD_STANDARD_BG_FM:
15620 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
15622 case DRX_AUD_STANDARD_D_K1:
15623 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
15625 case DRX_AUD_STANDARD_D_K2:
15626 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
15628 case DRX_AUD_STANDARD_D_K3:
15629 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
15631 case DRX_AUD_STANDARD_BG_NICAM_FM:
15632 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
15634 case DRX_AUD_STANDARD_L_NICAM_AM:
15635 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
15637 case DRX_AUD_STANDARD_I_NICAM_FM:
15638 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
15640 case DRX_AUD_STANDARD_D_K_NICAM_FM:
15641 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
15643 case DRX_AUD_STANDARD_UNKNOWN:
15644 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15650 if (*standard == DRX_AUD_STANDARD_AUTO) {
15651 /* we need the current standard here */
15652 current_standard = ext_attr->standard;
15654 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
15656 if ((current_standard == DRX_STANDARD_PAL_SECAM_L) || (current_standard == DRX_STANDARD_PAL_SECAM_LP))
15657 w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
15659 w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
15661 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
15662 if (current_standard == DRX_STANDARD_NTSC)
15663 w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
15665 w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
15669 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
15671 /* just get hardcoded deemphasis and activate here */
15672 if (ext_attr->aud_data.deemph == DRX_AUD_FM_DEEMPH_50US)
15673 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
15675 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
15677 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_BTSC__M;
15678 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_STEREO)
15679 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
15681 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
15683 if (w_modus != r_modus) {
15684 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15686 pr_err("error %d\n", rc);
15691 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_STANDARD_SEL__A, w_standard, 0);
15693 pr_err("error %d\n", rc);
15697 /**************************************************************************/
15698 /* NOT calling aud_ctrl_set_cfg_volume to avoid interfering standard */
15699 /* detection, need to keep things very minimal here, but keep audio */
15700 /* buffers intact */
15701 /**************************************************************************/
15702 ext_attr->aud_data.volume.mute = mute_buffer;
15703 if (ext_attr->aud_data.volume.mute == false) {
15704 w_volume |= (u16) ((volume_buffer + AUD_VOLUME_ZERO_DB) <<
15705 AUD_DSP_WR_VOLUME_VOL_MAIN__B);
15706 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
15708 pr_err("error %d\n", rc);
15713 /* write standard selected */
15714 ext_attr->aud_data.audio_standard = *standard;
15721 /*============================================================================*/
15723 * \brief Get the current audio standard
15724 * \param demod instance of demodulator
15725 * \param pointer to enum drx_aud_standard * \return int.
15729 aud_ctrl_get_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15731 struct i2c_device_addr *dev_addr = NULL;
15732 struct drxj_data *ext_attr = NULL;
15736 if (standard == NULL)
15739 ext_attr = (struct drxj_data *) demod->my_ext_attr;
15740 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15743 if (ext_attr->aud_data.audio_is_active == false) {
15744 rc = power_up_aud(demod, true);
15746 pr_err("error %d\n", rc);
15749 ext_attr->aud_data.audio_is_active = true;
15752 *standard = DRX_AUD_STANDARD_UNKNOWN;
15754 rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RD_STANDARD_RES__A, &r_data, 0);
15756 pr_err("error %d\n", rc);
15760 /* return OK if the detection is not ready yet */
15761 if (r_data >= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE) {
15762 *standard = DRX_AUD_STANDARD_NOT_READY;
15766 /* detection done, return correct standard */
15768 /* no standard detected */
15769 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
15770 *standard = DRX_AUD_STANDARD_UNKNOWN;
15772 /* standard is KOREA(A2) */
15773 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
15774 *standard = DRX_AUD_STANDARD_A2;
15776 /* standard is EIA-J (Japan) */
15777 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
15778 *standard = DRX_AUD_STANDARD_EIAJ;
15780 /* standard is BTSC-stereo */
15781 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
15782 *standard = DRX_AUD_STANDARD_BTSC;
15784 /* standard is BTSC-mono (SAP) */
15785 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
15786 *standard = DRX_AUD_STANDARD_BTSC;
15788 /* standard is FM radio */
15789 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
15790 *standard = DRX_AUD_STANDARD_FM_STEREO;
15792 /* standard is BG FM */
15793 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
15794 *standard = DRX_AUD_STANDARD_BG_FM;
15796 /* standard is DK-1 FM */
15797 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
15798 *standard = DRX_AUD_STANDARD_D_K1;
15800 /* standard is DK-2 FM */
15801 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
15802 *standard = DRX_AUD_STANDARD_D_K2;
15804 /* standard is DK-3 FM */
15805 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
15806 *standard = DRX_AUD_STANDARD_D_K3;
15808 /* standard is BG-NICAM FM */
15809 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
15810 *standard = DRX_AUD_STANDARD_BG_NICAM_FM;
15812 /* standard is L-NICAM AM */
15813 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
15814 *standard = DRX_AUD_STANDARD_L_NICAM_AM;
15816 /* standard is I-NICAM FM */
15817 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
15818 *standard = DRX_AUD_STANDARD_I_NICAM_FM;
15820 /* standard is DK-NICAM FM */
15821 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
15822 *standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
15825 *standard = DRX_AUD_STANDARD_UNKNOWN;
15834 /*============================================================================*/
15836 * \brief Retreive lock status in case of FM standard
15837 * \param demod instance of demodulator
15838 * \param pointer to lock status
15843 fm_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
15845 struct drx_aud_status status;
15848 /* Check detection of audio carriers */
15849 rc = aud_ctrl_get_carrier_detect_status(demod, &status);
15851 pr_err("error %d\n", rc);
15855 /* locked if either primary or secondary carrier is detected */
15856 if ((status.carrier_a == true) || (status.carrier_b == true))
15857 *lock_stat = DRX_LOCKED;
15859 *lock_stat = DRX_NOT_LOCKED;
15867 /*============================================================================*/
15869 * \brief retreive signal quality in case of FM standard
15870 * \param demod instance of demodulator
15871 * \param pointer to signal quality
15874 * Only the quality indicator field is will be supplied.
15875 * This will either be 0% or 100%, nothing in between.
15879 fm_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
15881 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
15884 rc = fm_lock_status(demod, &lock_status);
15886 pr_err("error %d\n", rc);
15889 if (lock_status == DRX_LOCKED)
15890 sig_quality->indicator = 100;
15892 sig_quality->indicator = 0;
15902 /*===========================================================================*/
15903 /*== END AUDIO DATAPATH FUNCTIONS ==*/
15904 /*===========================================================================*/
15906 /*============================================================================*/
15907 /*============================================================================*/
15908 /*== OOB DATAPATH FUNCTIONS ==*/
15909 /*============================================================================*/
15910 /*============================================================================*/
15911 #ifndef DRXJ_DIGITAL_ONLY
15913 * \fn int get_oob_lock_status ()
15914 * \brief Get OOB lock status.
15915 * \param dev_addr I2C address
15916 \ oob_lock OOB lock status.
15919 * Gets OOB lock status
15923 get_oob_lock_status(struct drx_demod_instance *demod,
15924 struct i2c_device_addr *dev_addr, enum drx_lock_status *oob_lock)
15926 struct drxjscu_cmd scu_cmd;
15929 u16 oob_lock_state;
15931 *oob_lock = DRX_NOT_LOCKED;
15933 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
15934 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
15935 scu_cmd.result_len = 2;
15936 scu_cmd.result = cmd_result;
15937 scu_cmd.parameter_len = 0;
15939 rc = scu_command(dev_addr, &scu_cmd);
15941 pr_err("error %d\n", rc);
15945 if (scu_cmd.result[1] < 0x4000) {
15946 /* 0x00 NOT LOCKED */
15947 *oob_lock = DRX_NOT_LOCKED;
15948 } else if (scu_cmd.result[1] < 0x8000) {
15949 /* 0x40 DEMOD LOCKED */
15950 *oob_lock = DRXJ_OOB_SYNC_LOCK;
15951 } else if (scu_cmd.result[1] < 0xC000) {
15952 /* 0x80 DEMOD + OOB LOCKED (system lock) */
15953 oob_lock_state = scu_cmd.result[1] & 0x00FF;
15955 if (oob_lock_state & 0x0008)
15956 *oob_lock = DRXJ_OOB_SYNC_LOCK;
15957 else if ((oob_lock_state & 0x0002) && (oob_lock_state & 0x0001))
15958 *oob_lock = DRXJ_OOB_AGC_LOCK;
15960 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
15961 *oob_lock = DRX_NEVER_LOCK;
15964 /* *oob_lock = scu_cmd.result[1]; */
15972 * \fn int get_oob_symbol_rate_offset ()
15973 * \brief Get OOB Symbol rate offset. Unit is [ppm]
15974 * \param dev_addr I2C address
15975 * \ Symbol Rate Offset OOB parameter.
15978 * Gets OOB frequency offset
15982 get_oob_symbol_rate_offset(struct i2c_device_addr *dev_addr, s32 *symbol_rate_offset)
15984 /* offset = -{(timing_offset/2^19)*(symbol_rate/12,656250MHz)}*10^6 [ppm] */
15985 /* offset = -{(timing_offset/2^19)*(symbol_rate/12656250)}*10^6 [ppm] */
15986 /* after reconfiguration: */
15987 /* offset = -{(timing_offset*symbol_rate)/(2^19*12656250)}*10^6 [ppm] */
15988 /* shift symbol rate left by 5 without lossing information */
15989 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
15990 /* shift 10^6 left by 6 without loosing information */
15991 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
15992 /* trim 12656250/15625 = 810 */
15993 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*810)} [ppm] */
15994 /* offset = -[(symbol_rate * 2^-5)*(timing_offset)/(2^8)]/810 [ppm] */
15996 s32 timing_offset = 0;
15997 u32 unsigned_timing_offset = 0;
15998 s32 division_factor = 810;
16000 u32 symbol_rate = 0;
16001 bool negative = false;
16003 *symbol_rate_offset = 0;
16004 /* read data rate */
16005 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data, 0);
16007 pr_err("error %d\n", rc);
16010 switch (data & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16011 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16012 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16013 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16014 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16015 symbol_rate = 1024000; /* bps */
16017 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16018 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16019 symbol_rate = 772000; /* bps */
16021 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16022 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16023 symbol_rate = 1544000; /* bps */
16029 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_CON_CTI_DTI_R__A, &data, 0);
16031 pr_err("error %d\n", rc);
16034 /* convert data to positive and keep information about sign */
16035 if ((data & 0x8000) == 0x8000) {
16036 if (data == 0x8000)
16037 unsigned_timing_offset = 32768;
16039 unsigned_timing_offset = 0x00007FFF & (u32) (-data);
16042 unsigned_timing_offset = (u32) data;
16044 symbol_rate = symbol_rate >> 5;
16045 unsigned_timing_offset = (unsigned_timing_offset * symbol_rate);
16046 unsigned_timing_offset = frac(unsigned_timing_offset, 256, FRAC_ROUND);
16047 unsigned_timing_offset = frac(unsigned_timing_offset,
16048 division_factor, FRAC_ROUND);
16050 timing_offset = (s32) unsigned_timing_offset;
16052 timing_offset = -(s32) unsigned_timing_offset;
16054 *symbol_rate_offset = timing_offset;
16062 * \fn int get_oob_freq_offset ()
16063 * \brief Get OOB lock status.
16064 * \param dev_addr I2C address
16065 * \ freq_offset OOB frequency offset.
16068 * Gets OOB frequency offset
16072 get_oob_freq_offset(struct drx_demod_instance *demod, s32 *freq_offset)
16074 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
16075 struct i2c_device_addr *dev_addr = NULL;
16079 u16 symbol_rate_reg = 0;
16080 u32 symbol_rate = 0;
16081 s32 coarse_freq_offset = 0;
16082 s32 fine_freq_offset = 0;
16084 s32 coarse_sign = 1;
16087 u32 temp_freq_offset = 0;
16089 /* check arguments */
16090 if ((demod == NULL) || (freq_offset == NULL))
16093 dev_addr = demod->my_i2c_dev_addr;
16094 common_attr = (struct drx_common_attr *) demod->my_common_attr;
16098 /* read sign (spectrum inversion) */
16099 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_IQM_FRQ_W__A, &rot, 0);
16101 pr_err("error %d\n", rc);
16105 /* read frequency offset */
16106 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_FRQ_OFFSET__A, &data, 0);
16108 pr_err("error %d\n", rc);
16111 /* find COARSE frequency offset */
16112 /* coarse_freq_offset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
16113 if (data & 0x8000) {
16114 data = (0xffff - data + 1);
16117 mult32(data, (common_attr->sys_clock_freq * 1000) / 6, &data64hi,
16119 temp_freq_offset = (((data64lo >> 21) & 0x7ff) | (data64hi << 11));
16121 /* get value in KHz */
16122 coarse_freq_offset = coarse_sign * frac(temp_freq_offset, 1000, FRAC_ROUND); /* KHz */
16123 /* read data rate */
16124 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbol_rate_reg, 0);
16126 pr_err("error %d\n", rc);
16129 switch (symbol_rate_reg & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16130 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16131 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16132 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16133 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16134 symbol_rate = 1024000;
16136 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16137 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16138 symbol_rate = 772000;
16140 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16141 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16142 symbol_rate = 1544000;
16148 /* find FINE frequency offset */
16149 /* fine_freq_offset = ( (CORRECTION_VALUE*symbol_rate) >> 18 ); */
16150 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_CON_CPH_FRQ_R__A, &data, 0);
16152 pr_err("error %d\n", rc);
16155 /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
16156 fine_freq_offset = (symbol_rate >> 5);
16157 if (data & 0x8000) {
16158 fine_freq_offset *= 0xffff - data + 1; /* Hz */
16161 fine_freq_offset *= data; /* Hz */
16163 /* Left to divide with 8192 (2^13) */
16164 fine_freq_offset = frac(fine_freq_offset, 8192, FRAC_ROUND);
16165 /* and to divide with 1000 to get KHz */
16166 fine_freq_offset = fine_sign * frac(fine_freq_offset, 1000, FRAC_ROUND); /* KHz */
16168 if ((rot & 0x8000) == 0x8000)
16169 *freq_offset = -(coarse_freq_offset + fine_freq_offset);
16171 *freq_offset = (coarse_freq_offset + fine_freq_offset);
16179 * \fn int get_oob_frequency ()
16180 * \brief Get OOB frequency (Unit:KHz).
16181 * \param dev_addr I2C address
16182 * \ frequency OOB frequency parameters.
16185 * Gets OOB frequency
16189 get_oob_frequency(struct drx_demod_instance *demod, s32 *frequency)
16191 struct i2c_device_addr *dev_addr = NULL;
16194 s32 freq_offset = 0;
16197 dev_addr = demod->my_i2c_dev_addr;
16199 *frequency = 0; /* KHz */
16201 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data, 0);
16203 pr_err("error %d\n", rc);
16207 freq = (s32) ((s32) data * 50 + 50000L);
16209 rc = get_oob_freq_offset(demod, &freq_offset);
16211 pr_err("error %d\n", rc);
16215 *frequency = freq + freq_offset;
16223 * \fn int get_oobmer ()
16224 * \brief Get OOB MER.
16225 * \param dev_addr I2C address
16226 \ MER OOB parameter in dB.
16229 * Gets OOB MER. Table for MER is in Programming guide.
16232 static int get_oobmer(struct i2c_device_addr *dev_addr, u32 *mer)
16239 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_EQU_MER_MER_R__A, &data, 0);
16241 pr_err("error %d\n", rc);
16245 case 0: /* fall through */
16282 case 13: /* fall through */
16286 case 15: /* fall through */
16290 case 17: /* fall through */
16294 case 19: /* fall through */
16298 case 21: /* fall through */
16302 case 23: /* fall through */
16303 case 24: /* fall through */
16307 case 26: /* fall through */
16308 case 27: /* fall through */
16312 case 29: /* fall through */
16313 case 30: /* fall through */
16314 case 31: /* fall through */
16318 case 33: /* fall through */
16319 case 34: /* fall through */
16320 case 35: /* fall through */
16324 case 37: /* fall through */
16325 case 38: /* fall through */
16326 case 39: /* fall through */
16330 case 41: /* fall through */
16331 case 42: /* fall through */
16332 case 43: /* fall through */
16333 case 44: /* fall through */
16337 case 46: /* fall through */
16338 case 47: /* fall through */
16339 case 48: /* fall through */
16340 case 49: /* fall through */
16341 case 50: /* fall through */
16344 case 51: /* fall through */
16345 case 52: /* fall through */
16346 case 53: /* fall through */
16347 case 54: /* fall through */
16348 case 55: /* fall through */
16349 case 56: /* fall through */
16353 case 58: /* fall through */
16354 case 59: /* fall through */
16355 case 60: /* fall through */
16356 case 61: /* fall through */
16357 case 62: /* fall through */
16369 #endif /*#ifndef DRXJ_DIGITAL_ONLY */
16372 * \fn int set_orx_nsu_aox()
16373 * \brief Configure OrxNsuAox for OOB
16374 * \param demod instance of demodulator.
16378 static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
16380 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
16384 /* Configure NSU_AOX */
16385 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
16387 pr_err("error %d\n", rc);
16391 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));
16393 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);
16394 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
16396 pr_err("error %d\n", rc);
16406 * \fn int ctrl_set_oob()
16407 * \brief Set OOB channel to be used.
16408 * \param demod instance of demodulator
16409 * \param oob_param OOB parameters for channel setting.
16410 * \frequency should be in KHz
16413 * Accepts only. Returns error otherwise.
16414 * Demapper value is written after scu_command START
16415 * because START command causes COMM_EXEC transition
16416 * from 0 to 1 which causes all registers to be
16417 * overwritten with initial value
16421 /* Nyquist filter impulse response */
16422 #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 */
16423 #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 */
16424 #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) */
16426 /* Coefficients for the nyquist fitler (total: 27 taps) */
16427 #define NYQFILTERLEN 27
16429 static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
16431 #ifndef DRXJ_DIGITAL_ONLY
16433 s32 freq = 0; /* KHz */
16434 struct i2c_device_addr *dev_addr = NULL;
16435 struct drxj_data *ext_attr = NULL;
16437 bool mirror_freq_spect_oob = false;
16438 u16 trk_filter_value = 0;
16439 struct drxjscu_cmd scu_cmd;
16440 u16 set_param_parameters[3];
16441 u16 cmd_result[2] = { 0, 0 };
16442 s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
16443 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
16444 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
16445 IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
16446 IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
16448 u8 mode_val[4] = { 2, 2, 0, 1 };
16449 u8 pfi_coeffs[4][6] = {
16450 {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) */
16451 {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) */
16452 {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) */
16453 {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) */
16457 dev_addr = demod->my_i2c_dev_addr;
16458 ext_attr = (struct drxj_data *) demod->my_ext_attr;
16459 mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
16461 /* Check parameters */
16462 if (oob_param == NULL) {
16463 /* power off oob module */
16464 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16465 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
16466 scu_cmd.parameter_len = 0;
16467 scu_cmd.result_len = 1;
16468 scu_cmd.result = cmd_result;
16469 rc = scu_command(dev_addr, &scu_cmd);
16471 pr_err("error %d\n", rc);
16474 rc = set_orx_nsu_aox(demod, false);
16476 pr_err("error %d\n", rc);
16479 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
16481 pr_err("error %d\n", rc);
16485 ext_attr->oob_power_on = false;
16489 freq = oob_param->frequency;
16490 if ((freq < 70000) || (freq > 130000))
16492 freq = (freq - 50000) / 50;
16497 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
16499 index = (u16) ((freq - 400) / 200);
16500 remainder = (u16) ((freq - 400) % 200);
16502 trk_filtercfg[index] - (trk_filtercfg[index] -
16503 trk_filtercfg[index +
16504 1]) / 10 * remainder /
16511 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
16513 pr_err("error %d\n", rc);
16516 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16517 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
16518 scu_cmd.parameter_len = 0;
16519 scu_cmd.result_len = 1;
16520 scu_cmd.result = cmd_result;
16521 rc = scu_command(dev_addr, &scu_cmd);
16523 pr_err("error %d\n", rc);
16529 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16530 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
16531 scu_cmd.parameter_len = 0;
16532 scu_cmd.result_len = 1;
16533 scu_cmd.result = cmd_result;
16534 rc = scu_command(dev_addr, &scu_cmd);
16536 pr_err("error %d\n", rc);
16542 /* set frequency, spectrum inversion and data rate */
16543 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16544 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
16545 scu_cmd.parameter_len = 3;
16546 /* 1-data rate;2-frequency */
16547 switch (oob_param->standard) {
16548 case DRX_OOB_MODE_A:
16550 /* signal is transmitted inverted */
16551 ((oob_param->spectrum_inverted == true) &
16552 /* and tuner is not mirroring the signal */
16553 (!mirror_freq_spect_oob)) |
16555 /* signal is transmitted noninverted */
16556 ((oob_param->spectrum_inverted == false) &
16557 /* and tuner is mirroring the signal */
16558 (mirror_freq_spect_oob))
16560 set_param_parameters[0] =
16561 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
16563 set_param_parameters[0] =
16564 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
16566 case DRX_OOB_MODE_B_GRADE_A:
16568 /* signal is transmitted inverted */
16569 ((oob_param->spectrum_inverted == true) &
16570 /* and tuner is not mirroring the signal */
16571 (!mirror_freq_spect_oob)) |
16573 /* signal is transmitted noninverted */
16574 ((oob_param->spectrum_inverted == false) &
16575 /* and tuner is mirroring the signal */
16576 (mirror_freq_spect_oob))
16578 set_param_parameters[0] =
16579 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
16581 set_param_parameters[0] =
16582 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
16584 case DRX_OOB_MODE_B_GRADE_B:
16587 /* signal is transmitted inverted */
16588 ((oob_param->spectrum_inverted == true) &
16589 /* and tuner is not mirroring the signal */
16590 (!mirror_freq_spect_oob)) |
16592 /* signal is transmitted noninverted */
16593 ((oob_param->spectrum_inverted == false) &
16594 /* and tuner is mirroring the signal */
16595 (mirror_freq_spect_oob))
16597 set_param_parameters[0] =
16598 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
16600 set_param_parameters[0] =
16601 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
16604 set_param_parameters[1] = (u16) (freq & 0xFFFF);
16605 set_param_parameters[2] = trk_filter_value;
16606 scu_cmd.parameter = set_param_parameters;
16607 scu_cmd.result_len = 1;
16608 scu_cmd.result = cmd_result;
16609 mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
16610 rc = scu_command(dev_addr, &scu_cmd);
16612 pr_err("error %d\n", rc);
16616 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
16618 pr_err("error %d\n", rc);
16620 } /* Write magic word to enable pdr reg write */
16621 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);
16623 pr_err("error %d\n", rc);
16626 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);
16628 pr_err("error %d\n", rc);
16631 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
16633 pr_err("error %d\n", rc);
16635 } /* Write magic word to disable pdr reg write */
16637 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
16639 pr_err("error %d\n", rc);
16642 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
16644 pr_err("error %d\n", rc);
16647 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
16649 pr_err("error %d\n", rc);
16654 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
16656 pr_err("error %d\n", rc);
16661 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
16663 pr_err("error %d\n", rc);
16667 /* initialization for target mode */
16668 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
16670 pr_err("error %d\n", rc);
16673 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
16675 pr_err("error %d\n", rc);
16679 /* Reset bits for timing and freq. recovery */
16680 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
16682 pr_err("error %d\n", rc);
16685 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
16687 pr_err("error %d\n", rc);
16690 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
16692 pr_err("error %d\n", rc);
16695 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
16697 pr_err("error %d\n", rc);
16701 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
16702 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
16704 pr_err("error %d\n", rc);
16707 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
16709 pr_err("error %d\n", rc);
16712 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
16714 pr_err("error %d\n", rc);
16717 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
16719 pr_err("error %d\n", rc);
16722 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
16724 pr_err("error %d\n", rc);
16728 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
16729 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
16731 pr_err("error %d\n", rc);
16734 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
16736 pr_err("error %d\n", rc);
16739 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
16741 pr_err("error %d\n", rc);
16744 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
16746 pr_err("error %d\n", rc);
16749 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
16751 pr_err("error %d\n", rc);
16755 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
16756 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
16758 pr_err("error %d\n", rc);
16761 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
16763 pr_err("error %d\n", rc);
16766 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
16768 pr_err("error %d\n", rc);
16771 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
16773 pr_err("error %d\n", rc);
16776 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
16778 pr_err("error %d\n", rc);
16782 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
16783 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
16785 pr_err("error %d\n", rc);
16788 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
16790 pr_err("error %d\n", rc);
16793 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
16795 pr_err("error %d\n", rc);
16798 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
16800 pr_err("error %d\n", rc);
16803 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
16805 pr_err("error %d\n", rc);
16809 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
16810 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
16812 pr_err("error %d\n", rc);
16815 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
16817 pr_err("error %d\n", rc);
16820 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
16822 pr_err("error %d\n", rc);
16825 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
16827 pr_err("error %d\n", rc);
16830 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
16832 pr_err("error %d\n", rc);
16836 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
16837 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
16839 pr_err("error %d\n", rc);
16842 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
16844 pr_err("error %d\n", rc);
16847 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
16849 pr_err("error %d\n", rc);
16852 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
16854 pr_err("error %d\n", rc);
16857 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
16859 pr_err("error %d\n", rc);
16863 /* PRE-Filter coefficients (PFI) */
16864 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);
16866 pr_err("error %d\n", rc);
16869 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
16871 pr_err("error %d\n", rc);
16875 /* NYQUIST-Filter coefficients (NYQ) */
16876 for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
16877 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
16879 pr_err("error %d\n", rc);
16882 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
16884 pr_err("error %d\n", rc);
16888 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
16890 pr_err("error %d\n", rc);
16893 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
16895 pr_err("error %d\n", rc);
16901 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16902 | SCU_RAM_COMMAND_CMD_DEMOD_START;
16903 scu_cmd.parameter_len = 0;
16904 scu_cmd.result_len = 1;
16905 scu_cmd.result = cmd_result;
16906 rc = scu_command(dev_addr, &scu_cmd);
16908 pr_err("error %d\n", rc);
16912 rc = set_orx_nsu_aox(demod, true);
16914 pr_err("error %d\n", rc);
16917 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
16919 pr_err("error %d\n", rc);
16923 ext_attr->oob_power_on = true;
16932 * \fn int ctrl_get_oob()
16933 * \brief Set modulation standard to be used.
16934 * \param demod instance of demodulator
16935 * \param oob_status OOB status parameters.
16939 ctrl_get_oob(struct drx_demod_instance *demod, struct drxoob_status *oob_status)
16941 #ifndef DRXJ_DIGITAL_ONLY
16943 struct i2c_device_addr *dev_addr = NULL;
16944 struct drxj_data *ext_attr = NULL;
16947 dev_addr = demod->my_i2c_dev_addr;
16948 ext_attr = (struct drxj_data *) demod->my_ext_attr;
16950 /* check arguments */
16951 if (oob_status == NULL)
16954 if (!ext_attr->oob_power_on)
16957 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_DDC_OFO_SET_W__A, &data, 0);
16959 pr_err("error %d\n", rc);
16962 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &data, 0);
16964 pr_err("error %d\n", rc);
16967 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_AAG_THR_W__A, &data, 0);
16969 pr_err("error %d\n", rc);
16972 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_DGN_KI__A, &data, 0);
16974 pr_err("error %d\n", rc);
16977 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
16979 pr_err("error %d\n", rc);
16983 rc = get_oob_lock_status(demod, dev_addr, &oob_status->lock);
16985 pr_err("error %d\n", rc);
16988 rc = get_oob_frequency(demod, &oob_status->frequency);
16990 pr_err("error %d\n", rc);
16993 rc = get_oobmer(dev_addr, &oob_status->mer);
16995 pr_err("error %d\n", rc);
16998 rc = get_oob_symbol_rate_offset(dev_addr, &oob_status->symbol_rate_offset);
17000 pr_err("error %d\n", rc);
17011 * \fn int ctrl_set_cfg_oob_pre_saw()
17012 * \brief Configure PreSAW treshold value
17013 * \param cfg_data Pointer to configuration parameter
17014 * \return Error code
17016 #ifndef DRXJ_DIGITAL_ONLY
17018 ctrl_set_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17020 struct i2c_device_addr *dev_addr = NULL;
17021 struct drxj_data *ext_attr = NULL;
17024 if (cfg_data == NULL)
17027 dev_addr = demod->my_i2c_dev_addr;
17028 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17030 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STHR_W__A, *cfg_data, 0);
17032 pr_err("error %d\n", rc);
17035 ext_attr->oob_pre_saw = *cfg_data;
17043 * \fn int ctrl_get_cfg_oob_pre_saw()
17044 * \brief Configure PreSAW treshold value
17045 * \param cfg_data Pointer to configuration parameter
17046 * \return Error code
17048 #ifndef DRXJ_DIGITAL_ONLY
17050 ctrl_get_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17052 struct drxj_data *ext_attr = NULL;
17054 if (cfg_data == NULL)
17057 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17059 *cfg_data = ext_attr->oob_pre_saw;
17066 * \fn int ctrl_set_cfg_oob_lo_power()
17067 * \brief Configure LO Power value
17068 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17070 #ifndef DRXJ_DIGITAL_ONLY
17072 ctrl_set_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17074 struct i2c_device_addr *dev_addr = NULL;
17075 struct drxj_data *ext_attr = NULL;
17078 if (cfg_data == NULL)
17081 dev_addr = demod->my_i2c_dev_addr;
17082 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17084 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_LOPOW_W__A, *cfg_data, 0);
17086 pr_err("error %d\n", rc);
17089 ext_attr->oob_lo_pow = *cfg_data;
17097 * \fn int ctrl_get_cfg_oob_lo_power()
17098 * \brief Configure LO Power value
17099 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17101 #ifndef DRXJ_DIGITAL_ONLY
17103 ctrl_get_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17105 struct drxj_data *ext_attr = NULL;
17107 if (cfg_data == NULL)
17110 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17112 *cfg_data = ext_attr->oob_lo_pow;
17117 /*============================================================================*/
17118 /*== END OOB DATAPATH FUNCTIONS ==*/
17119 /*============================================================================*/
17121 /*=============================================================================
17122 ===== MC command related functions ==========================================
17123 ===========================================================================*/
17125 /*=============================================================================
17126 ===== ctrl_set_channel() ==========================================================
17127 ===========================================================================*/
17129 * \fn int ctrl_set_channel()
17130 * \brief Select a new transmission channel.
17131 * \param demod instance of demod.
17132 * \param channel Pointer to channel data.
17135 * In case the tuner module is not used and in case of NTSC/FM the pogrammer
17136 * must tune the tuner to the centre frequency of the NTSC/FM channel.
17140 ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17143 s32 tuner_set_freq = 0;
17144 s32 tuner_get_freq = 0;
17145 s32 tuner_freq_offset = 0;
17146 s32 intermediate_freq = 0;
17147 struct drxj_data *ext_attr = NULL;
17148 struct i2c_device_addr *dev_addr = NULL;
17149 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17150 u32 tuner_mode = 0;
17151 struct drx_common_attr *common_attr = NULL;
17152 bool bridge_closed = false;
17153 #ifndef DRXJ_VSB_ONLY
17154 u32 min_symbol_rate = 0;
17155 u32 max_symbol_rate = 0;
17156 int bandwidth_temp = 0;
17159 /*== check arguments ======================================================*/
17160 if ((demod == NULL) || (channel == NULL))
17163 common_attr = (struct drx_common_attr *) demod->my_common_attr;
17164 dev_addr = demod->my_i2c_dev_addr;
17165 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17166 standard = ext_attr->standard;
17168 /* check valid standards */
17169 switch (standard) {
17170 case DRX_STANDARD_8VSB:
17171 #ifndef DRXJ_VSB_ONLY
17172 case DRX_STANDARD_ITU_A:
17173 case DRX_STANDARD_ITU_B:
17174 case DRX_STANDARD_ITU_C:
17175 #endif /* DRXJ_VSB_ONLY */
17176 #ifndef DRXJ_DIGITAL_ONLY
17177 case DRX_STANDARD_NTSC:
17178 case DRX_STANDARD_FM:
17179 case DRX_STANDARD_PAL_SECAM_BG:
17180 case DRX_STANDARD_PAL_SECAM_DK:
17181 case DRX_STANDARD_PAL_SECAM_I:
17182 case DRX_STANDARD_PAL_SECAM_L:
17183 case DRX_STANDARD_PAL_SECAM_LP:
17184 #endif /* DRXJ_DIGITAL_ONLY */
17186 case DRX_STANDARD_UNKNOWN:
17191 /* check bandwidth QAM annex B, NTSC and 8VSB */
17192 if ((standard == DRX_STANDARD_ITU_B) ||
17193 (standard == DRX_STANDARD_8VSB) ||
17194 (standard == DRX_STANDARD_NTSC)) {
17195 switch (channel->bandwidth) {
17196 case DRX_BANDWIDTH_6MHZ:
17197 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
17198 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17200 case DRX_BANDWIDTH_8MHZ: /* fall through */
17201 case DRX_BANDWIDTH_7MHZ: /* fall through */
17206 #ifndef DRXJ_DIGITAL_ONLY
17207 if (standard == DRX_STANDARD_PAL_SECAM_BG) {
17208 switch (channel->bandwidth) {
17209 case DRX_BANDWIDTH_7MHZ: /* fall through */
17210 case DRX_BANDWIDTH_8MHZ:
17213 case DRX_BANDWIDTH_6MHZ: /* fall through */
17214 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
17219 /* check bandwidth PAL/SECAM */
17220 if ((standard == DRX_STANDARD_PAL_SECAM_BG) ||
17221 (standard == DRX_STANDARD_PAL_SECAM_DK) ||
17222 (standard == DRX_STANDARD_PAL_SECAM_I) ||
17223 (standard == DRX_STANDARD_PAL_SECAM_L) ||
17224 (standard == DRX_STANDARD_PAL_SECAM_LP)) {
17225 switch (channel->bandwidth) {
17226 case DRX_BANDWIDTH_8MHZ:
17227 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
17228 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17230 case DRX_BANDWIDTH_6MHZ: /* fall through */
17231 case DRX_BANDWIDTH_7MHZ: /* fall through */
17238 /* For QAM annex A and annex C:
17239 -check symbolrate and constellation
17240 -derive bandwidth from symbolrate (input bandwidth is ignored)
17242 #ifndef DRXJ_VSB_ONLY
17243 if ((standard == DRX_STANDARD_ITU_A) ||
17244 (standard == DRX_STANDARD_ITU_C)) {
17245 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
17246 int bw_rolloff_factor = 0;
17248 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
17249 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
17250 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
17251 /* config SMA_TX pin to SAW switch mode */
17252 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
17254 pr_err("error %d\n", rc);
17258 if (channel->symbolrate < min_symbol_rate ||
17259 channel->symbolrate > max_symbol_rate) {
17263 switch (channel->constellation) {
17264 case DRX_CONSTELLATION_QAM16: /* fall through */
17265 case DRX_CONSTELLATION_QAM32: /* fall through */
17266 case DRX_CONSTELLATION_QAM64: /* fall through */
17267 case DRX_CONSTELLATION_QAM128: /* fall through */
17268 case DRX_CONSTELLATION_QAM256:
17269 bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
17270 bandwidth = bandwidth_temp / 100;
17272 if ((bandwidth_temp % 100) >= 50)
17275 if (bandwidth <= 6100000) {
17276 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17277 } else if ((bandwidth > 6100000)
17278 && (bandwidth <= 7100000)) {
17279 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
17280 } else if (bandwidth > 7100000) {
17281 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17289 /* For QAM annex B:
17290 -check constellation
17292 if (standard == DRX_STANDARD_ITU_B) {
17293 switch (channel->constellation) {
17294 case DRX_CONSTELLATION_AUTO:
17295 case DRX_CONSTELLATION_QAM256:
17296 case DRX_CONSTELLATION_QAM64:
17302 switch (channel->interleavemode) {
17303 case DRX_INTERLEAVEMODE_I128_J1:
17304 case DRX_INTERLEAVEMODE_I128_J1_V2:
17305 case DRX_INTERLEAVEMODE_I128_J2:
17306 case DRX_INTERLEAVEMODE_I64_J2:
17307 case DRX_INTERLEAVEMODE_I128_J3:
17308 case DRX_INTERLEAVEMODE_I32_J4:
17309 case DRX_INTERLEAVEMODE_I128_J4:
17310 case DRX_INTERLEAVEMODE_I16_J8:
17311 case DRX_INTERLEAVEMODE_I128_J5:
17312 case DRX_INTERLEAVEMODE_I8_J16:
17313 case DRX_INTERLEAVEMODE_I128_J6:
17314 case DRX_INTERLEAVEMODE_I128_J7:
17315 case DRX_INTERLEAVEMODE_I128_J8:
17316 case DRX_INTERLEAVEMODE_I12_J17:
17317 case DRX_INTERLEAVEMODE_I5_J4:
17318 case DRX_INTERLEAVEMODE_B52_M240:
17319 case DRX_INTERLEAVEMODE_B52_M720:
17320 case DRX_INTERLEAVEMODE_UNKNOWN:
17321 case DRX_INTERLEAVEMODE_AUTO:
17328 if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
17329 /* SAW SW, user UIO is used for switchable SAW */
17330 struct drxuio_data uio1 = { DRX_UIO1, false };
17332 switch (channel->bandwidth) {
17333 case DRX_BANDWIDTH_8MHZ:
17336 case DRX_BANDWIDTH_7MHZ:
17337 uio1.value = false;
17339 case DRX_BANDWIDTH_6MHZ:
17340 uio1.value = false;
17342 case DRX_BANDWIDTH_UNKNOWN:
17347 rc = ctrl_uio_write(demod, &uio1);
17349 pr_err("error %d\n", rc);
17353 #endif /* DRXJ_VSB_ONLY */
17354 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
17356 pr_err("error %d\n", rc);
17359 /*== Tune, fast mode ======================================================*/
17360 if (demod->my_tuner != NULL) {
17361 /* Determine tuner mode and freq to tune to ... */
17362 switch (standard) {
17363 #ifndef DRXJ_DIGITAL_ONLY
17364 case DRX_STANDARD_NTSC: /* fallthrough */
17365 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17366 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17367 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
17368 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
17369 case DRX_STANDARD_PAL_SECAM_LP:
17370 /* expecting center frequency, not picture carrier so no
17372 tuner_mode |= TUNER_MODE_ANALOG;
17373 tuner_set_freq = channel->frequency;
17375 case DRX_STANDARD_FM:
17376 /* center frequency (equals sound carrier) as input,
17377 tune to edge of SAW */
17378 tuner_mode |= TUNER_MODE_ANALOG;
17380 channel->frequency + DRXJ_FM_CARRIER_FREQ_OFFSET;
17383 case DRX_STANDARD_8VSB: /* fallthrough */
17384 #ifndef DRXJ_VSB_ONLY
17385 case DRX_STANDARD_ITU_A: /* fallthrough */
17386 case DRX_STANDARD_ITU_B: /* fallthrough */
17387 case DRX_STANDARD_ITU_C:
17389 tuner_mode |= TUNER_MODE_DIGITAL;
17390 tuner_set_freq = channel->frequency;
17392 case DRX_STANDARD_UNKNOWN:
17395 } /* switch(standard) */
17397 tuner_mode |= TUNER_MODE_SWITCH;
17398 switch (channel->bandwidth) {
17399 case DRX_BANDWIDTH_8MHZ:
17400 tuner_mode |= TUNER_MODE_8MHZ;
17402 case DRX_BANDWIDTH_7MHZ:
17403 tuner_mode |= TUNER_MODE_7MHZ;
17405 case DRX_BANDWIDTH_6MHZ:
17406 tuner_mode |= TUNER_MODE_6MHZ;
17409 /* TODO: for FM which bandwidth to use ?
17410 also check offset from centre frequency ?
17411 For now using 6MHz.
17413 tuner_mode |= TUNER_MODE_6MHZ;
17415 /* return (-EINVAL); */
17418 /* store bandwidth for GetChannel() */
17419 ext_attr->curr_bandwidth = channel->bandwidth;
17420 ext_attr->curr_symbol_rate = channel->symbolrate;
17421 ext_attr->frequency = tuner_set_freq;
17422 if (common_attr->tuner_port_nr == 1) {
17423 /* close tuner bridge */
17424 bridge_closed = true;
17425 rc = ctrl_i2c_bridge(demod, &bridge_closed);
17427 pr_err("error %d\n", rc);
17430 /* set tuner frequency */
17433 rc = drxbsp_tuner_set_frequency(demod->my_tuner, tuner_mode, tuner_set_freq);
17435 pr_err("error %d\n", rc);
17438 if (common_attr->tuner_port_nr == 1) {
17439 /* open tuner bridge */
17440 bridge_closed = false;
17441 rc = ctrl_i2c_bridge(demod, &bridge_closed);
17443 pr_err("error %d\n", rc);
17448 /* Get actual frequency set by tuner and compute offset */
17449 rc = drxbsp_tuner_get_frequency(demod->my_tuner, 0, &tuner_get_freq, &intermediate_freq);
17451 pr_err("error %d\n", rc);
17454 tuner_freq_offset = tuner_get_freq - tuner_set_freq;
17455 common_attr->intermediate_freq = intermediate_freq;
17457 /* no tuner instance defined, use fixed intermediate frequency */
17458 tuner_freq_offset = 0;
17459 intermediate_freq = demod->my_common_attr->intermediate_freq;
17460 } /* if ( demod->my_tuner != NULL ) */
17462 /*== Setup demod for specific standard ====================================*/
17463 switch (standard) {
17464 case DRX_STANDARD_8VSB:
17465 if (channel->mirror == DRX_MIRROR_AUTO)
17466 ext_attr->mirror = DRX_MIRROR_NO;
17468 ext_attr->mirror = channel->mirror;
17469 rc = set_vsb(demod);
17471 pr_err("error %d\n", rc);
17474 rc = set_frequency(demod, channel, tuner_freq_offset);
17476 pr_err("error %d\n", rc);
17480 #ifndef DRXJ_DIGITAL_ONLY
17481 case DRX_STANDARD_NTSC: /* fallthrough */
17482 case DRX_STANDARD_FM: /* fallthrough */
17483 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17484 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17485 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
17486 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
17487 case DRX_STANDARD_PAL_SECAM_LP:
17488 if (channel->mirror == DRX_MIRROR_AUTO)
17489 ext_attr->mirror = DRX_MIRROR_NO;
17491 ext_attr->mirror = channel->mirror;
17492 rc = set_atv_channel(demod, tuner_freq_offset, channel, standard);
17494 pr_err("error %d\n", rc);
17499 #ifndef DRXJ_VSB_ONLY
17500 case DRX_STANDARD_ITU_A: /* fallthrough */
17501 case DRX_STANDARD_ITU_B: /* fallthrough */
17502 case DRX_STANDARD_ITU_C:
17503 rc = set_qam_channel(demod, channel, tuner_freq_offset);
17505 pr_err("error %d\n", rc);
17510 case DRX_STANDARD_UNKNOWN:
17515 /*== Re-tune, slow mode ===================================================*/
17516 if (demod->my_tuner != NULL) {
17517 /* tune to slow mode */
17518 tuner_mode &= ~TUNER_MODE_SWITCH;
17519 tuner_mode |= TUNER_MODE_LOCK;
17521 if (common_attr->tuner_port_nr == 1) {
17522 /* close tuner bridge */
17523 bridge_closed = true;
17524 rc = ctrl_i2c_bridge(demod, &bridge_closed);
17526 pr_err("error %d\n", rc);
17531 /* set tuner frequency */
17532 rc = drxbsp_tuner_set_frequency(demod->my_tuner, tuner_mode, tuner_set_freq);
17534 pr_err("error %d\n", rc);
17537 if (common_attr->tuner_port_nr == 1) {
17538 /* open tuner bridge */
17539 bridge_closed = false;
17540 rc = ctrl_i2c_bridge(demod, &bridge_closed);
17542 pr_err("error %d\n", rc);
17548 /* if ( demod->my_tuner !=NULL ) */
17549 /* flag the packet error counter reset */
17550 ext_attr->reset_pkt_err_acc = true;
17557 /*=============================================================================
17558 ===== ctrl_get_channel() ==========================================================
17559 ===========================================================================*/
17561 * \fn int ctrl_get_channel()
17562 * \brief Retreive parameters of current transmission channel.
17563 * \param demod Pointer to demod instance.
17564 * \param channel Pointer to channel data.
17568 ctrl_get_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17570 struct i2c_device_addr *dev_addr = NULL;
17571 struct drxj_data *ext_attr = NULL;
17573 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17574 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17575 struct drx_common_attr *common_attr = NULL;
17576 s32 intermediate_freq = 0;
17577 s32 ctl_freq_offset = 0;
17578 u32 iqm_rc_rate_lo = 0;
17579 u32 adc_frequency = 0;
17580 #ifndef DRXJ_VSB_ONLY
17581 int bandwidth_temp = 0;
17585 /* check arguments */
17586 if ((demod == NULL) || (channel == NULL))
17589 dev_addr = demod->my_i2c_dev_addr;
17590 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17591 standard = ext_attr->standard;
17592 common_attr = (struct drx_common_attr *) demod->my_common_attr;
17594 /* initialize channel fields */
17595 channel->mirror = DRX_MIRROR_UNKNOWN;
17596 channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
17597 channel->priority = DRX_PRIORITY_UNKNOWN;
17598 channel->coderate = DRX_CODERATE_UNKNOWN;
17599 channel->guard = DRX_GUARD_UNKNOWN;
17600 channel->fftmode = DRX_FFTMODE_UNKNOWN;
17601 channel->classification = DRX_CLASSIFICATION_UNKNOWN;
17602 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
17603 channel->constellation = DRX_CONSTELLATION_UNKNOWN;
17604 channel->symbolrate = 0;
17605 channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
17606 channel->carrier = DRX_CARRIER_UNKNOWN;
17607 channel->framemode = DRX_FRAMEMODE_UNKNOWN;
17608 /* channel->interleaver = DRX_INTERLEAVER_UNKNOWN;*/
17609 channel->ldpc = DRX_LDPC_UNKNOWN;
17611 if (demod->my_tuner != NULL) {
17612 s32 tuner_freq_offset = 0;
17613 bool tuner_mirror = common_attr->mirror_freq_spect ? false : true;
17615 /* Get frequency from tuner */
17616 rc = drxbsp_tuner_get_frequency(demod->my_tuner, 0, &(channel->frequency), &intermediate_freq);
17618 pr_err("error %d\n", rc);
17621 tuner_freq_offset = channel->frequency - ext_attr->frequency;
17622 if (tuner_mirror) {
17623 /* positive image */
17624 channel->frequency += tuner_freq_offset;
17626 /* negative image */
17627 channel->frequency -= tuner_freq_offset;
17630 /* Handle sound carrier offset in RF domain */
17631 if (standard == DRX_STANDARD_FM)
17632 channel->frequency -= DRXJ_FM_CARRIER_FREQ_OFFSET;
17634 intermediate_freq = common_attr->intermediate_freq;
17637 /* check lock status */
17638 rc = ctrl_lock_status(demod, &lock_status);
17640 pr_err("error %d\n", rc);
17643 if ((lock_status == DRX_LOCKED) || (lock_status == DRXJ_DEMOD_LOCK)) {
17644 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &iqm_rc_rate_lo, 0);
17646 pr_err("error %d\n", rc);
17649 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
17651 channel->symbolrate =
17652 frac28(adc_frequency, (iqm_rc_rate_lo + (1 << 23))) >> 7;
17654 switch (standard) {
17655 case DRX_STANDARD_8VSB:
17656 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17657 /* get the channel frequency */
17658 rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17660 pr_err("error %d\n", rc);
17663 channel->frequency -= ctl_freq_offset;
17664 /* get the channel constellation */
17665 channel->constellation = DRX_CONSTELLATION_AUTO;
17667 #ifndef DRXJ_VSB_ONLY
17668 case DRX_STANDARD_ITU_A:
17669 case DRX_STANDARD_ITU_B:
17670 case DRX_STANDARD_ITU_C:
17672 /* get the channel frequency */
17673 rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17675 pr_err("error %d\n", rc);
17678 channel->frequency -= ctl_freq_offset;
17680 if (standard == DRX_STANDARD_ITU_B) {
17681 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17685 u32 roll_off = 113; /* default annex C */
17687 if (standard == DRX_STANDARD_ITU_A)
17691 channel->symbolrate * roll_off;
17692 bandwidth = bandwidth_temp / 100;
17694 if ((bandwidth_temp % 100) >= 50)
17697 if (bandwidth <= 6000000) {
17698 channel->bandwidth =
17699 DRX_BANDWIDTH_6MHZ;
17700 } else if ((bandwidth > 6000000)
17701 && (bandwidth <= 7000000)) {
17702 channel->bandwidth =
17703 DRX_BANDWIDTH_7MHZ;
17704 } else if (bandwidth > 7000000) {
17705 channel->bandwidth =
17706 DRX_BANDWIDTH_8MHZ;
17708 } /* if (standard == DRX_STANDARD_ITU_B) */
17711 struct drxjscu_cmd cmd_scu = { 0, 0, 0, NULL, NULL };
17712 u16 cmd_result[3] = { 0, 0, 0 };
17715 SCU_RAM_COMMAND_STANDARD_QAM |
17716 SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
17717 cmd_scu.parameter_len = 0;
17718 cmd_scu.result_len = 3;
17719 cmd_scu.parameter = NULL;
17720 cmd_scu.result = cmd_result;
17721 rc = scu_command(dev_addr, &cmd_scu);
17723 pr_err("error %d\n", rc);
17727 channel->interleavemode =
17728 (enum drx_interleave_mode) (cmd_scu.
17732 switch (ext_attr->constellation) {
17733 case DRX_CONSTELLATION_QAM256:
17734 channel->constellation =
17735 DRX_CONSTELLATION_QAM256;
17737 case DRX_CONSTELLATION_QAM128:
17738 channel->constellation =
17739 DRX_CONSTELLATION_QAM128;
17741 case DRX_CONSTELLATION_QAM64:
17742 channel->constellation =
17743 DRX_CONSTELLATION_QAM64;
17745 case DRX_CONSTELLATION_QAM32:
17746 channel->constellation =
17747 DRX_CONSTELLATION_QAM32;
17749 case DRX_CONSTELLATION_QAM16:
17750 channel->constellation =
17751 DRX_CONSTELLATION_QAM16;
17754 channel->constellation =
17755 DRX_CONSTELLATION_UNKNOWN;
17761 #ifndef DRXJ_DIGITAL_ONLY
17762 case DRX_STANDARD_NTSC: /* fall trough */
17763 case DRX_STANDARD_PAL_SECAM_BG:
17764 case DRX_STANDARD_PAL_SECAM_DK:
17765 case DRX_STANDARD_PAL_SECAM_I:
17766 case DRX_STANDARD_PAL_SECAM_L:
17767 case DRX_STANDARD_PAL_SECAM_LP:
17768 case DRX_STANDARD_FM:
17769 rc = get_atv_channel(demod, channel, standard);
17771 pr_err("error %d\n", rc);
17776 case DRX_STANDARD_UNKNOWN: /* fall trough */
17779 } /* switch ( standard ) */
17781 if (lock_status == DRX_LOCKED)
17782 channel->mirror = ext_attr->mirror;
17784 /* if ( lock_status == DRX_LOCKED ) */
17790 /*=============================================================================
17791 ===== SigQuality() ==========================================================
17792 ===========================================================================*/
17795 mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
17799 if (mer < min_mer) {
17801 } else if (mer < threshold_mer) {
17802 if ((threshold_mer - min_mer) != 0)
17803 indicator = 25 * (mer - min_mer) / (threshold_mer - min_mer);
17804 } else if (mer < max_mer) {
17805 if ((max_mer - threshold_mer) != 0)
17806 indicator = 25 + 75 * (mer - threshold_mer) / (max_mer - threshold_mer);
17817 * \fn int ctrl_sig_quality()
17818 * \brief Retreive signal quality form device.
17819 * \param devmod Pointer to demodulator instance.
17820 * \param sig_quality Pointer to signal quality data.
17822 * \retval 0 sig_quality contains valid data.
17823 * \retval -EINVAL sig_quality is NULL.
17824 * \retval -EIO Erroneous data, sig_quality contains invalid data.
17828 ctrl_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
17830 struct i2c_device_addr *dev_addr = NULL;
17831 struct drxj_data *ext_attr = NULL;
17833 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17834 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17837 u16 threshold_mer = 0;
17839 /* Check arguments */
17840 if ((sig_quality == NULL) || (demod == NULL))
17843 ext_attr = (struct drxj_data *) demod->my_ext_attr;
17844 standard = ext_attr->standard;
17846 /* get basic information */
17847 dev_addr = demod->my_i2c_dev_addr;
17848 rc = ctrl_lock_status(demod, &lock_status);
17850 pr_err("error %d\n", rc);
17853 switch (standard) {
17854 case DRX_STANDARD_8VSB:
17855 #ifdef DRXJ_SIGNAL_ACCUM_ERR
17856 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
17858 pr_err("error %d\n", rc);
17862 rc = get_vsb_post_rs_pck_err(dev_addr, &sig_quality->packet_error);
17864 pr_err("error %d\n", rc);
17868 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
17869 sig_quality->post_viterbi_ber = 500000;
17870 sig_quality->MER = 20;
17871 sig_quality->pre_viterbi_ber = 0;
17873 /* PostViterbi is compute in steps of 10^(-6) */
17874 rc = get_vs_bpre_viterbi_ber(dev_addr, &sig_quality->pre_viterbi_ber);
17876 pr_err("error %d\n", rc);
17879 rc = get_vs_bpost_viterbi_ber(dev_addr, &sig_quality->post_viterbi_ber);
17881 pr_err("error %d\n", rc);
17884 rc = get_vsbmer(dev_addr, &sig_quality->MER);
17886 pr_err("error %d\n", rc);
17892 threshold_mer = 145;
17893 sig_quality->post_reed_solomon_ber = 0;
17894 sig_quality->scale_factor_ber = 1000000;
17895 sig_quality->indicator =
17896 mer2indicator(sig_quality->MER, min_mer, threshold_mer,
17899 #ifndef DRXJ_VSB_ONLY
17900 case DRX_STANDARD_ITU_A:
17901 case DRX_STANDARD_ITU_B:
17902 case DRX_STANDARD_ITU_C:
17903 rc = ctrl_get_qam_sig_quality(demod, sig_quality);
17905 pr_err("error %d\n", rc);
17908 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
17909 switch (ext_attr->constellation) {
17910 case DRX_CONSTELLATION_QAM256:
17911 sig_quality->MER = 210;
17913 case DRX_CONSTELLATION_QAM128:
17914 sig_quality->MER = 180;
17916 case DRX_CONSTELLATION_QAM64:
17917 sig_quality->MER = 150;
17919 case DRX_CONSTELLATION_QAM32:
17920 sig_quality->MER = 120;
17922 case DRX_CONSTELLATION_QAM16:
17923 sig_quality->MER = 90;
17926 sig_quality->MER = 0;
17931 switch (ext_attr->constellation) {
17932 case DRX_CONSTELLATION_QAM256:
17934 threshold_mer = 270;
17937 case DRX_CONSTELLATION_QAM64:
17939 threshold_mer = 210;
17942 case DRX_CONSTELLATION_QAM128:
17943 case DRX_CONSTELLATION_QAM32:
17944 case DRX_CONSTELLATION_QAM16:
17949 sig_quality->indicator =
17950 mer2indicator(sig_quality->MER, min_mer, threshold_mer,
17954 #ifndef DRXJ_DIGITAL_ONLY
17955 case DRX_STANDARD_PAL_SECAM_BG:
17956 case DRX_STANDARD_PAL_SECAM_DK:
17957 case DRX_STANDARD_PAL_SECAM_I:
17958 case DRX_STANDARD_PAL_SECAM_L:
17959 case DRX_STANDARD_PAL_SECAM_LP:
17960 case DRX_STANDARD_NTSC:
17961 rc = atv_sig_quality(demod, sig_quality);
17963 pr_err("error %d\n", rc);
17967 case DRX_STANDARD_FM:
17968 rc = fm_sig_quality(demod, sig_quality);
17970 pr_err("error %d\n", rc);
17984 /*============================================================================*/
17987 * \fn int ctrl_lock_status()
17988 * \brief Retreive lock status .
17989 * \param dev_addr Pointer to demodulator device address.
17990 * \param lock_stat Pointer to lock status structure.
17995 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
17997 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17998 struct drxj_data *ext_attr = NULL;
17999 struct i2c_device_addr *dev_addr = NULL;
18000 struct drxjscu_cmd cmd_scu = { /* command */ 0,
18001 /* parameter_len */ 0,
18002 /* result_len */ 0,
18003 /* *parameter */ NULL,
18007 u16 cmd_result[2] = { 0, 0 };
18008 u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
18010 /* check arguments */
18011 if ((demod == NULL) || (lock_stat == NULL))
18014 dev_addr = demod->my_i2c_dev_addr;
18015 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18016 standard = ext_attr->standard;
18018 *lock_stat = DRX_NOT_LOCKED;
18020 /* define the SCU command code */
18021 switch (standard) {
18022 case DRX_STANDARD_8VSB:
18023 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
18024 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18027 #ifndef DRXJ_VSB_ONLY
18028 case DRX_STANDARD_ITU_A:
18029 case DRX_STANDARD_ITU_B:
18030 case DRX_STANDARD_ITU_C:
18031 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
18032 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18035 #ifndef DRXJ_DIGITAL_ONLY
18036 case DRX_STANDARD_NTSC:
18037 case DRX_STANDARD_PAL_SECAM_BG:
18038 case DRX_STANDARD_PAL_SECAM_DK:
18039 case DRX_STANDARD_PAL_SECAM_I:
18040 case DRX_STANDARD_PAL_SECAM_L:
18041 case DRX_STANDARD_PAL_SECAM_LP:
18042 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
18043 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18045 case DRX_STANDARD_FM:
18046 return fm_lock_status(demod, lock_stat);
18048 case DRX_STANDARD_UNKNOWN: /* fallthrough */
18053 /* define the SCU command paramters and execute the command */
18054 cmd_scu.parameter_len = 0;
18055 cmd_scu.result_len = 2;
18056 cmd_scu.parameter = NULL;
18057 cmd_scu.result = cmd_result;
18058 rc = scu_command(dev_addr, &cmd_scu);
18060 pr_err("error %d\n", rc);
18064 /* set the lock status */
18065 if (cmd_scu.result[1] < demod_lock) {
18066 /* 0x0000 NOT LOCKED */
18067 *lock_stat = DRX_NOT_LOCKED;
18068 } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
18069 *lock_stat = DRXJ_DEMOD_LOCK;
18070 } else if (cmd_scu.result[1] <
18071 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
18072 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
18073 *lock_stat = DRX_LOCKED;
18075 /* 0xC000 NEVER LOCKED */
18076 /* (system will never be able to lock to the signal) */
18077 *lock_stat = DRX_NEVER_LOCK;
18085 /*============================================================================*/
18088 * \fn int ctrl_constel()
18089 * \brief Retreive a constellation point via I2C.
18090 * \param demod Pointer to demodulator instance.
18091 * \param complex_nr Pointer to the structure in which to store the
18092 constellation point.
18096 ctrl_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
18099 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18100 /**< active standard */
18102 /* check arguments */
18103 if ((demod == NULL) || (complex_nr == NULL))
18106 /* read device info */
18107 standard = ((struct drxj_data *) demod->my_ext_attr)->standard;
18109 /* Read constellation point */
18110 switch (standard) {
18111 case DRX_STANDARD_8VSB:
18112 rc = ctrl_get_vsb_constel(demod, complex_nr);
18114 pr_err("error %d\n", rc);
18118 #ifndef DRXJ_VSB_ONLY
18119 case DRX_STANDARD_ITU_A: /* fallthrough */
18120 case DRX_STANDARD_ITU_B: /* fallthrough */
18121 case DRX_STANDARD_ITU_C:
18122 rc = ctrl_get_qam_constel(demod, complex_nr);
18124 pr_err("error %d\n", rc);
18129 case DRX_STANDARD_UNKNOWN:
18139 /*============================================================================*/
18142 * \fn int ctrl_set_standard()
18143 * \brief Set modulation standard to be used.
18144 * \param standard Modulation standard.
18147 * Setup stuff for the desired demodulation standard.
18148 * Disable and power down the previous selected demodulation standard
18152 ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18154 struct drxj_data *ext_attr = NULL;
18156 enum drx_standard prev_standard;
18158 /* check arguments */
18159 if ((standard == NULL) || (demod == NULL))
18162 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18163 prev_standard = ext_attr->standard;
18166 Stop and power down previous standard
18168 switch (prev_standard) {
18169 #ifndef DRXJ_VSB_ONLY
18170 case DRX_STANDARD_ITU_A: /* fallthrough */
18171 case DRX_STANDARD_ITU_B: /* fallthrough */
18172 case DRX_STANDARD_ITU_C:
18173 rc = power_down_qam(demod, false);
18175 pr_err("error %d\n", rc);
18180 case DRX_STANDARD_8VSB:
18181 rc = power_down_vsb(demod, false);
18183 pr_err("error %d\n", rc);
18187 #ifndef DRXJ_DIGITAL_ONLY
18188 case DRX_STANDARD_NTSC: /* fallthrough */
18189 case DRX_STANDARD_FM: /* fallthrough */
18190 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18191 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18192 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18193 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18194 case DRX_STANDARD_PAL_SECAM_LP:
18195 rc = power_down_atv(demod, prev_standard, false);
18197 pr_err("error %d\n", rc);
18202 case DRX_STANDARD_UNKNOWN:
18205 case DRX_STANDARD_AUTO: /* fallthrough */
18211 Initialize channel independent registers
18212 Power up new standard
18214 ext_attr->standard = *standard;
18216 switch (*standard) {
18217 #ifndef DRXJ_VSB_ONLY
18218 case DRX_STANDARD_ITU_A: /* fallthrough */
18219 case DRX_STANDARD_ITU_B: /* fallthrough */
18220 case DRX_STANDARD_ITU_C:
18223 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18225 pr_err("error %d\n", rc);
18231 case DRX_STANDARD_8VSB:
18232 rc = set_vsb_leak_n_gain(demod);
18234 pr_err("error %d\n", rc);
18238 #ifndef DRXJ_DIGITAL_ONLY
18239 case DRX_STANDARD_NTSC: /* fallthrough */
18240 case DRX_STANDARD_FM: /* fallthrough */
18241 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18242 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18243 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18244 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18245 case DRX_STANDARD_PAL_SECAM_LP:
18246 rc = set_atv_standard(demod, standard);
18248 pr_err("error %d\n", rc);
18251 rc = power_up_atv(demod, *standard);
18253 pr_err("error %d\n", rc);
18259 ext_attr->standard = DRX_STANDARD_UNKNOWN;
18266 /* Don't know what the standard is now ... try again */
18267 ext_attr->standard = DRX_STANDARD_UNKNOWN;
18271 /*============================================================================*/
18274 * \fn int ctrl_get_standard()
18275 * \brief Get modulation standard currently used to demodulate.
18276 * \param standard Modulation standard.
18279 * Returns 8VSB, NTSC, QAM only.
18283 ctrl_get_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18285 struct drxj_data *ext_attr = NULL;
18287 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18289 /* check arguments */
18290 if (standard == NULL)
18293 *standard = ext_attr->standard;
18296 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18298 pr_err("error %d\n", rc);
18308 /*============================================================================*/
18311 * \fn int ctrl_get_cfg_symbol_clock_offset()
18312 * \brief Get frequency offsets of STR.
18313 * \param pointer to s32.
18318 ctrl_get_cfg_symbol_clock_offset(struct drx_demod_instance *demod, s32 *rate_offset)
18320 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18322 struct drxj_data *ext_attr = NULL;
18324 /* check arguments */
18325 if (rate_offset == NULL)
18328 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18329 standard = ext_attr->standard;
18331 switch (standard) {
18332 case DRX_STANDARD_8VSB: /* fallthrough */
18333 #ifndef DRXJ_VSB_ONLY
18334 case DRX_STANDARD_ITU_A: /* fallthrough */
18335 case DRX_STANDARD_ITU_B: /* fallthrough */
18336 case DRX_STANDARD_ITU_C:
18338 rc = get_str_freq_offset(demod, rate_offset);
18340 pr_err("error %d\n", rc);
18344 case DRX_STANDARD_NTSC:
18345 case DRX_STANDARD_UNKNOWN:
18355 /*============================================================================*/
18358 * \fn int ctrl_power_mode()
18359 * \brief Set the power mode of the device to the specified power mode
18360 * \param demod Pointer to demodulator instance.
18361 * \param mode Pointer to new power mode.
18363 * \retval 0 Success
18364 * \retval -EIO I2C error or other failure
18365 * \retval -EINVAL Invalid mode argument.
18370 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
18372 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
18373 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
18374 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
18376 u16 sio_cc_pwd_mode = 0;
18378 common_attr = (struct drx_common_attr *) demod->my_common_attr;
18379 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18380 dev_addr = demod->my_i2c_dev_addr;
18382 /* Check arguments */
18386 /* If already in requested power mode, do nothing */
18387 if (common_attr->current_power_mode == *mode)
18392 case DRXJ_POWER_DOWN_MAIN_PATH:
18393 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
18395 case DRXJ_POWER_DOWN_CORE:
18396 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
18398 case DRXJ_POWER_DOWN_PLL:
18399 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
18401 case DRX_POWER_DOWN:
18402 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
18405 /* Unknow sleep mode */
18410 /* Check if device needs to be powered up */
18411 if ((common_attr->current_power_mode != DRX_POWER_UP)) {
18412 rc = power_up_device(demod);
18414 pr_err("error %d\n", rc);
18419 if ((*mode == DRX_POWER_UP)) {
18420 /* Restore analog & pin configuartion */
18422 /* Power down to requested mode */
18423 /* Backup some register settings */
18424 /* Set pins with possible pull-ups connected to them in input mode */
18425 /* Analog power down */
18426 /* ADC power down */
18427 /* Power down device */
18428 /* stop all comm_exec */
18430 Stop and power down previous standard
18433 switch (ext_attr->standard) {
18434 case DRX_STANDARD_ITU_A:
18435 case DRX_STANDARD_ITU_B:
18436 case DRX_STANDARD_ITU_C:
18437 rc = power_down_qam(demod, true);
18439 pr_err("error %d\n", rc);
18443 case DRX_STANDARD_8VSB:
18444 rc = power_down_vsb(demod, true);
18446 pr_err("error %d\n", rc);
18450 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18451 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18452 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
18453 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
18454 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
18455 case DRX_STANDARD_NTSC: /* fallthrough */
18456 case DRX_STANDARD_FM:
18457 rc = power_down_atv(demod, ext_attr->standard, true);
18459 pr_err("error %d\n", rc);
18463 case DRX_STANDARD_UNKNOWN:
18466 case DRX_STANDARD_AUTO: /* fallthrough */
18471 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
18472 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
18474 pr_err("error %d\n", rc);
18477 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
18479 pr_err("error %d\n", rc);
18483 /* Initialize HI, wakeup key especially before put IC to sleep */
18484 rc = init_hi(demod);
18486 pr_err("error %d\n", rc);
18490 ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
18491 rc = hi_cfg_command(demod);
18493 pr_err("error %d\n", rc);
18499 common_attr->current_power_mode = *mode;
18506 /*============================================================================*/
18509 * \fn int ctrl_version()
18510 * \brief Report version of microcode and if possible version of device
18511 * \param demod Pointer to demodulator instance.
18512 * \param version_list Pointer to pointer of linked list of versions.
18515 * Using static structures so no allocation of memory is needed.
18516 * Filling in all the fields each time, cause you don't know if they are
18517 * changed by the application.
18520 * Major version number will be last two digits of family number.
18521 * Minor number will be full respin number
18522 * Patch will be metal fix number+1
18524 * DRX3942J A2 => number: 42.1.2 text: "DRX3942J:A2"
18525 * DRX3933J B1 => number: 33.2.1 text: "DRX3933J:B1"
18529 ctrl_version(struct drx_demod_instance *demod, struct drx_version_list **version_list)
18531 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
18532 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
18533 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18535 u16 ucode_major_minor = 0; /* BCD Ma:Ma:Ma:Mi */
18536 u16 ucode_patch = 0; /* BCD Pa:Pa:Pa:Pa */
18546 static char ucode_name[] = "Microcode";
18547 static char device_name[] = "Device";
18549 dev_addr = demod->my_i2c_dev_addr;
18550 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18551 common_attr = (struct drx_common_attr *) demod->my_common_attr;
18553 /* Microcode version *************************************** */
18555 ext_attr->v_version[0].module_type = DRX_MODULE_MICROCODE;
18556 ext_attr->v_version[0].module_name = ucode_name;
18557 ext_attr->v_version[0].v_string = ext_attr->v_text[0];
18559 if (common_attr->is_opened == true) {
18560 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_VERSION_HI__A, &ucode_major_minor, 0);
18562 pr_err("error %d\n", rc);
18565 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_VERSION_LO__A, &ucode_patch, 0);
18567 pr_err("error %d\n", rc);
18571 /* Translate BCD to numbers and string */
18572 /* TODO: The most significant Ma and Pa will be ignored, check with spec */
18573 minor = (ucode_major_minor & 0xF);
18574 ucode_major_minor >>= 4;
18575 major = (ucode_major_minor & 0xF);
18576 ucode_major_minor >>= 4;
18577 major += (10 * (ucode_major_minor & 0xF));
18578 patch = (ucode_patch & 0xF);
18580 patch += (10 * (ucode_patch & 0xF));
18582 patch += (100 * (ucode_patch & 0xF));
18584 /* No microcode uploaded, No Rom existed, set version to 0.0.0 */
18589 ext_attr->v_version[0].v_major = major;
18590 ext_attr->v_version[0].v_minor = minor;
18591 ext_attr->v_version[0].v_patch = patch;
18593 if (major / 10 != 0) {
18594 ext_attr->v_version[0].v_string[idx++] =
18595 ((char)(major / 10)) + '0';
18598 ext_attr->v_version[0].v_string[idx++] = ((char)major) + '0';
18599 ext_attr->v_version[0].v_string[idx++] = '.';
18600 ext_attr->v_version[0].v_string[idx++] = ((char)minor) + '0';
18601 ext_attr->v_version[0].v_string[idx++] = '.';
18602 if (patch / 100 != 0) {
18603 ext_attr->v_version[0].v_string[idx++] =
18604 ((char)(patch / 100)) + '0';
18607 if (patch / 10 != 0) {
18608 ext_attr->v_version[0].v_string[idx++] =
18609 ((char)(patch / 10)) + '0';
18612 ext_attr->v_version[0].v_string[idx++] = ((char)patch) + '0';
18613 ext_attr->v_version[0].v_string[idx] = '\0';
18615 ext_attr->v_list_elements[0].version = &(ext_attr->v_version[0]);
18616 ext_attr->v_list_elements[0].next = &(ext_attr->v_list_elements[1]);
18618 /* Device version *************************************** */
18619 /* Check device id */
18620 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, &key, 0);
18622 pr_err("error %d\n", rc);
18625 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
18627 pr_err("error %d\n", rc);
18630 rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0);
18632 pr_err("error %d\n", rc);
18635 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
18637 pr_err("error %d\n", rc);
18640 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, key, 0);
18642 pr_err("error %d\n", rc);
18646 ext_attr->v_version[1].module_type = DRX_MODULE_DEVICE;
18647 ext_attr->v_version[1].module_name = device_name;
18648 ext_attr->v_version[1].v_string = ext_attr->v_text[1];
18649 ext_attr->v_version[1].v_string[0] = 'D';
18650 ext_attr->v_version[1].v_string[1] = 'R';
18651 ext_attr->v_version[1].v_string[2] = 'X';
18652 ext_attr->v_version[1].v_string[3] = '3';
18653 ext_attr->v_version[1].v_string[4] = '9';
18654 ext_attr->v_version[1].v_string[7] = 'J';
18655 ext_attr->v_version[1].v_string[8] = ':';
18656 ext_attr->v_version[1].v_string[11] = '\0';
18658 /* DRX39xxJ type Ax */
18659 /* TODO semantics of mfx and spin are unclear */
18660 subtype = (u16) ((jtag >> 12) & 0xFF);
18661 mfx = (u16) (jtag >> 29);
18662 ext_attr->v_version[1].v_minor = 1;
18664 ext_attr->v_version[1].v_patch = mfx + 2;
18666 ext_attr->v_version[1].v_patch = mfx + 1;
18667 ext_attr->v_version[1].v_string[6] = ((char)(subtype & 0xF)) + '0';
18668 ext_attr->v_version[1].v_major = (subtype & 0x0F);
18670 ext_attr->v_version[1].v_string[5] = ((char)(subtype & 0xF)) + '0';
18671 ext_attr->v_version[1].v_major += 10 * subtype;
18672 ext_attr->v_version[1].v_string[9] = 'A';
18674 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '2';
18676 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '1';
18678 ext_attr->v_list_elements[1].version = &(ext_attr->v_version[1]);
18679 ext_attr->v_list_elements[1].next = (struct drx_version_list *) (NULL);
18681 *version_list = &(ext_attr->v_list_elements[0]);
18686 *version_list = (struct drx_version_list *) (NULL);
18691 /*============================================================================*/
18694 * \fn int ctrl_probe_device()
18695 * \brief Probe device, check if it is present
18696 * \param demod Pointer to demodulator instance.
18698 * \retval 0 a drx39xxj device has been detected.
18699 * \retval -EIO no drx39xxj device detected.
18701 * This funtion can be caled before open() and after close().
18705 static int ctrl_probe_device(struct drx_demod_instance *demod)
18707 enum drx_power_mode org_power_mode = DRX_POWER_UP;
18708 int ret_status = 0;
18709 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18712 common_attr = (struct drx_common_attr *) demod->my_common_attr;
18714 if (common_attr->is_opened == false
18715 || common_attr->current_power_mode != DRX_POWER_UP) {
18716 struct i2c_device_addr *dev_addr = NULL;
18717 enum drx_power_mode power_mode = DRX_POWER_UP;
18720 dev_addr = demod->my_i2c_dev_addr;
18722 /* Remeber original power mode */
18723 org_power_mode = common_attr->current_power_mode;
18725 if (demod->my_common_attr->is_opened == false) {
18726 rc = power_up_device(demod);
18728 pr_err("error %d\n", rc);
18731 common_attr->current_power_mode = DRX_POWER_UP;
18733 /* Wake-up device, feedback from device */
18734 rc = ctrl_power_mode(demod, &power_mode);
18736 pr_err("error %d\n", rc);
18740 /* Initialize HI, wakeup key especially */
18741 rc = init_hi(demod);
18743 pr_err("error %d\n", rc);
18747 /* Check device id */
18748 rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0);
18750 pr_err("error %d\n", rc);
18753 jtag = (jtag >> 12) & 0xFFFF;
18755 case 0x3931: /* fallthrough */
18756 case 0x3932: /* fallthrough */
18757 case 0x3933: /* fallthrough */
18758 case 0x3934: /* fallthrough */
18759 case 0x3941: /* fallthrough */
18760 case 0x3942: /* fallthrough */
18761 case 0x3943: /* fallthrough */
18762 case 0x3944: /* fallthrough */
18763 case 0x3945: /* fallthrough */
18765 /* ok , do nothing */
18772 /* Device was not opened, return to orginal powermode,
18773 feedback from device */
18774 rc = ctrl_power_mode(demod, &org_power_mode);
18776 pr_err("error %d\n", rc);
18780 /* dummy read to make this function fail in case device
18781 suddenly disappears after a succesful drx_open */
18784 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18786 pr_err("error %d\n", rc);
18795 common_attr->current_power_mode = org_power_mode;
18799 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
18800 /*============================================================================*/
18803 * \fn int is_mc_block_audio()
18804 * \brief Check if MC block is Audio or not Audio.
18805 * \param addr Pointer to demodulator instance.
18806 * \param audioUpload true if MC block is Audio
18807 false if MC block not Audio
18810 bool is_mc_block_audio(u32 addr)
18812 if ((addr == AUD_XFP_PRAM_4K__A) || (addr == AUD_XDFP_PRAM_4K__A))
18818 /*============================================================================*/
18821 * \fn int ctrl_u_code_upload()
18822 * \brief Handle Audio or !Audio part of microcode upload.
18823 * \param demod Pointer to demodulator instance.
18824 * \param mc_info Pointer to information about microcode data.
18825 * \param action Either UCODE_UPLOAD or UCODE_VERIFY.
18826 * \param upload_audio_mc true if Audio MC need to be uploaded.
18827 false if !Audio MC need to be uploaded.
18831 ctrl_u_code_upload(struct drx_demod_instance *demod,
18832 struct drxu_code_info *mc_info,
18833 enum drxu_code_actionaction, bool upload_audio_mc)
18836 u16 mc_nr_of_blks = 0;
18837 u16 mc_magic_word = 0;
18838 u8 *mc_data = (u8 *)(NULL);
18839 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
18840 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
18843 dev_addr = demod->my_i2c_dev_addr;
18844 ext_attr = (struct drxj_data *) demod->my_ext_attr;
18846 /* Check arguments */
18847 if (!mc_info || !mc_info->mc_data) {
18851 mc_data = mc_info->mc_data;
18854 mc_magic_word = u_code_read16(mc_data);
18855 mc_data += sizeof(u16);
18856 mc_nr_of_blks = u_code_read16(mc_data);
18857 mc_data += sizeof(u16);
18859 if ((mc_magic_word != DRXJ_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
18860 /* wrong endianess or wrong data ? */
18864 /* Process microcode blocks */
18865 for (i = 0; i < mc_nr_of_blks; i++) {
18866 struct drxu_code_block_hdr block_hdr;
18867 u16 mc_block_nr_bytes = 0;
18869 /* Process block header */
18870 block_hdr.addr = u_code_read32(mc_data);
18871 mc_data += sizeof(u32);
18872 block_hdr.size = u_code_read16(mc_data);
18873 mc_data += sizeof(u16);
18874 block_hdr.flags = u_code_read16(mc_data);
18875 mc_data += sizeof(u16);
18876 block_hdr.CRC = u_code_read16(mc_data);
18877 mc_data += sizeof(u16);
18879 /* Check block header on:
18881 - data larger then 64Kb
18882 - if CRC enabled check CRC
18884 if ((block_hdr.size == 0) ||
18885 (block_hdr.size > 0x7FFF) ||
18886 (((block_hdr.flags & DRXJ_UCODE_CRC_FLAG) != 0) &&
18887 (block_hdr.CRC != u_code_compute_crc(mc_data, block_hdr.size)))
18893 mc_block_nr_bytes = block_hdr.size * sizeof(u16);
18895 /* Perform the desired action */
18896 /* Check which part of MC need to be uploaded - Audio or not Audio */
18897 if (is_mc_block_audio(block_hdr.addr) == upload_audio_mc) {
18899 /*===================================================================*/
18902 /* Upload microcode */
18903 if (demod->my_access_funct->
18904 write_block_func(dev_addr,
18905 (dr_xaddr_t) block_hdr.
18906 addr, mc_block_nr_bytes,
18915 /*===================================================================*/
18920 [DRXJ_UCODE_MAX_BUF_SIZE];
18921 u32 bytes_to_compare = 0;
18922 u32 bytes_left_to_compare = 0;
18923 u32 curr_addr = (dr_xaddr_t) 0;
18924 u8 *curr_ptr = NULL;
18926 bytes_left_to_compare = mc_block_nr_bytes;
18927 curr_addr = block_hdr.addr;
18928 curr_ptr = mc_data;
18930 while (bytes_left_to_compare != 0) {
18931 if (bytes_left_to_compare > ((u32)DRXJ_UCODE_MAX_BUF_SIZE))
18932 bytes_to_compare = ((u32)DRXJ_UCODE_MAX_BUF_SIZE);
18934 bytes_to_compare = bytes_left_to_compare;
18936 if (demod->my_access_funct->
18937 read_block_func(dev_addr,
18949 drxbsp_hst_memcmp(curr_ptr,
18958 (bytes_to_compare / 2));
18960 &(curr_ptr[bytes_to_compare]);
18961 bytes_left_to_compare -=
18962 ((u32) bytes_to_compare);
18963 } /* while( bytes_to_compare > DRXJ_UCODE_MAX_BUF_SIZE ) */
18967 /*===================================================================*/
18972 } /* switch ( action ) */
18975 /* if( is_mc_block_audio( block_hdr.addr ) == upload_audio_mc ) */
18977 mc_data += mc_block_nr_bytes;
18978 } /* for( i = 0 ; i<mc_nr_of_blks ; i++ ) */
18980 if (!upload_audio_mc)
18981 ext_attr->flag_aud_mc_uploaded = false;
18985 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
18987 /*============================================================================*/
18988 /*== CTRL Set/Get Config related functions ===================================*/
18989 /*============================================================================*/
18991 /*===== SigStrength() =========================================================*/
18993 * \fn int ctrl_sig_strength()
18994 * \brief Retrieve signal strength.
18995 * \param devmod Pointer to demodulator instance.
18996 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
18998 * \retval 0 sig_strength contains valid data.
18999 * \retval -EINVAL sig_strength is NULL.
19000 * \retval -EIO Erroneous data, sig_strength contains invalid data.
19004 ctrl_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
19006 struct drxj_data *ext_attr = NULL;
19007 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
19010 /* Check arguments */
19011 if ((sig_strength == NULL) || (demod == NULL))
19014 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19015 standard = ext_attr->standard;
19018 /* Signal strength indication for each standard */
19019 switch (standard) {
19020 case DRX_STANDARD_8VSB: /* fallthrough */
19021 #ifndef DRXJ_VSB_ONLY
19022 case DRX_STANDARD_ITU_A: /* fallthrough */
19023 case DRX_STANDARD_ITU_B: /* fallthrough */
19024 case DRX_STANDARD_ITU_C:
19026 rc = get_sig_strength(demod, sig_strength);
19028 pr_err("error %d\n", rc);
19032 #ifndef DRXJ_DIGITAL_ONLY
19033 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19034 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19035 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19036 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19037 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19038 case DRX_STANDARD_NTSC: /* fallthrough */
19039 case DRX_STANDARD_FM:
19040 rc = get_atv_sig_strength(demod, sig_strength);
19042 pr_err("error %d\n", rc);
19047 case DRX_STANDARD_UNKNOWN: /* fallthrough */
19053 /* find out if signal strength is calculated in the same way for all standards */
19059 /*============================================================================*/
19061 * \fn int ctrl_get_cfg_oob_misc()
19062 * \brief Get current state information of OOB.
19063 * \param pointer to struct drxj_cfg_oob_misc.
19067 #ifndef DRXJ_DIGITAL_ONLY
19069 ctrl_get_cfg_oob_misc(struct drx_demod_instance *demod, struct drxj_cfg_oob_misc *misc)
19071 struct i2c_device_addr *dev_addr = NULL;
19076 u16 digital_agc_mant = 0U;
19077 u16 digital_agc_exp = 0U;
19079 /* check arguments */
19083 dev_addr = demod->my_i2c_dev_addr;
19086 /* check if the same registers are used for all standards (QAM/VSB/ATV) */
19087 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC, 0);
19089 pr_err("error %d\n", rc);
19092 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &misc->agc.RFAGC, 0);
19094 pr_err("error %d\n", rc);
19097 rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
19099 pr_err("error %d\n", rc);
19103 digital_agc_mant = data & ORX_FWP_SRC_DGN_W_MANT__M;
19104 digital_agc_exp = (data & ORX_FWP_SRC_DGN_W_EXP__M)
19105 >> ORX_FWP_SRC_DGN_W_EXP__B;
19106 misc->agc.digital_agc = digital_agc_mant << digital_agc_exp;
19108 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_LOCK__A, &lock, 0);
19110 pr_err("error %d\n", rc);
19114 misc->ana_gain_lock = ((lock & 0x0001) ? true : false);
19115 misc->dig_gain_lock = ((lock & 0x0002) ? true : false);
19116 misc->freq_lock = ((lock & 0x0004) ? true : false);
19117 misc->phase_lock = ((lock & 0x0008) ? true : false);
19118 misc->sym_timing_lock = ((lock & 0x0010) ? true : false);
19119 misc->eq_lock = ((lock & 0x0020) ? true : false);
19121 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_STATE__A, &state, 0);
19123 pr_err("error %d\n", rc);
19126 misc->state = (state >> 8) & 0xff;
19135 * \fn int ctrl_get_cfg_vsb_misc()
19136 * \brief Get current state information of OOB.
19137 * \param pointer to struct drxj_cfg_oob_misc.
19142 ctrl_get_cfg_vsb_misc(struct drx_demod_instance *demod, struct drxj_cfg_vsb_misc *misc)
19144 struct i2c_device_addr *dev_addr = NULL;
19147 /* check arguments */
19151 dev_addr = demod->my_i2c_dev_addr;
19153 rc = get_vsb_symb_err(dev_addr, &misc->symb_error);
19155 pr_err("error %d\n", rc);
19164 /*============================================================================*/
19167 * \fn int ctrl_set_cfg_agc_if()
19168 * \brief Set IF AGC.
19169 * \param demod demod instance
19170 * \param agc_settings If agc configuration
19174 * Dispatch handling to standard specific function.
19178 ctrl_set_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19180 /* check arguments */
19181 if (agc_settings == NULL)
19184 switch (agc_settings->ctrl_mode) {
19185 case DRX_AGC_CTRL_AUTO: /* fallthrough */
19186 case DRX_AGC_CTRL_USER: /* fallthrough */
19187 case DRX_AGC_CTRL_OFF: /* fallthrough */
19194 switch (agc_settings->standard) {
19195 case DRX_STANDARD_8VSB: /* fallthrough */
19196 #ifndef DRXJ_VSB_ONLY
19197 case DRX_STANDARD_ITU_A: /* fallthrough */
19198 case DRX_STANDARD_ITU_B: /* fallthrough */
19199 case DRX_STANDARD_ITU_C:
19201 #ifndef DRXJ_DIGITAL_ONLY
19202 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19203 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19204 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19205 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19206 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19207 case DRX_STANDARD_NTSC: /* fallthrough */
19208 case DRX_STANDARD_FM:
19210 return set_agc_if(demod, agc_settings, true);
19211 case DRX_STANDARD_UNKNOWN:
19219 /*============================================================================*/
19222 * \fn int ctrl_get_cfg_agc_if()
19223 * \brief Retrieve IF AGC settings.
19224 * \param demod demod instance
19225 * \param agc_settings If agc configuration
19229 * Dispatch handling to standard specific function.
19233 ctrl_get_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19235 /* check arguments */
19236 if (agc_settings == NULL)
19240 switch (agc_settings->standard) {
19241 case DRX_STANDARD_8VSB: /* fallthrough */
19242 #ifndef DRXJ_VSB_ONLY
19243 case DRX_STANDARD_ITU_A: /* fallthrough */
19244 case DRX_STANDARD_ITU_B: /* fallthrough */
19245 case DRX_STANDARD_ITU_C:
19247 #ifndef DRXJ_DIGITAL_ONLY
19248 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19249 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19250 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19251 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19252 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19253 case DRX_STANDARD_NTSC: /* fallthrough */
19254 case DRX_STANDARD_FM:
19256 return get_agc_if(demod, agc_settings);
19257 case DRX_STANDARD_UNKNOWN:
19265 /*============================================================================*/
19268 * \fn int ctrl_set_cfg_agc_rf()
19269 * \brief Set RF AGC.
19270 * \param demod demod instance
19271 * \param agc_settings rf agc configuration
19275 * Dispatch handling to standard specific function.
19279 ctrl_set_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19281 /* check arguments */
19282 if (agc_settings == NULL)
19285 switch (agc_settings->ctrl_mode) {
19286 case DRX_AGC_CTRL_AUTO: /* fallthrough */
19287 case DRX_AGC_CTRL_USER: /* fallthrough */
19288 case DRX_AGC_CTRL_OFF:
19295 switch (agc_settings->standard) {
19296 case DRX_STANDARD_8VSB: /* fallthrough */
19297 #ifndef DRXJ_VSB_ONLY
19298 case DRX_STANDARD_ITU_A: /* fallthrough */
19299 case DRX_STANDARD_ITU_B: /* fallthrough */
19300 case DRX_STANDARD_ITU_C:
19302 #ifndef DRXJ_DIGITAL_ONLY
19303 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19304 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19305 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19306 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19307 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19308 case DRX_STANDARD_NTSC: /* fallthrough */
19309 case DRX_STANDARD_FM:
19311 return set_agc_rf(demod, agc_settings, true);
19312 case DRX_STANDARD_UNKNOWN:
19320 /*============================================================================*/
19323 * \fn int ctrl_get_cfg_agc_rf()
19324 * \brief Retrieve RF AGC settings.
19325 * \param demod demod instance
19326 * \param agc_settings Rf agc configuration
19330 * Dispatch handling to standard specific function.
19334 ctrl_get_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19336 /* check arguments */
19337 if (agc_settings == NULL)
19341 switch (agc_settings->standard) {
19342 case DRX_STANDARD_8VSB: /* fallthrough */
19343 #ifndef DRXJ_VSB_ONLY
19344 case DRX_STANDARD_ITU_A: /* fallthrough */
19345 case DRX_STANDARD_ITU_B: /* fallthrough */
19346 case DRX_STANDARD_ITU_C:
19348 #ifndef DRXJ_DIGITAL_ONLY
19349 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19350 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19351 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19352 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19353 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19354 case DRX_STANDARD_NTSC: /* fallthrough */
19355 case DRX_STANDARD_FM:
19357 return get_agc_rf(demod, agc_settings);
19358 case DRX_STANDARD_UNKNOWN:
19366 /*============================================================================*/
19369 * \fn int ctrl_get_cfg_agc_internal()
19370 * \brief Retrieve internal AGC value.
19371 * \param demod demod instance
19376 * Dispatch handling to standard specific function.
19380 ctrl_get_cfg_agc_internal(struct drx_demod_instance *demod, u16 *agc_internal)
19382 struct i2c_device_addr *dev_addr = NULL;
19384 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
19385 struct drxj_data *ext_attr = NULL;
19386 u16 iqm_cf_scale_sh = 0;
19387 u16 iqm_cf_power = 0;
19388 u16 iqm_cf_amp = 0;
19389 u16 iqm_cf_gain = 0;
19391 /* check arguments */
19392 if (agc_internal == NULL)
19394 dev_addr = demod->my_i2c_dev_addr;
19395 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19397 rc = ctrl_lock_status(demod, &lock_status);
19399 pr_err("error %d\n", rc);
19402 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
19408 switch (ext_attr->standard) {
19409 case DRX_STANDARD_8VSB:
19412 #ifndef DRXJ_VSB_ONLY
19413 case DRX_STANDARD_ITU_A:
19414 case DRX_STANDARD_ITU_B:
19415 case DRX_STANDARD_ITU_C:
19416 switch (ext_attr->constellation) {
19417 case DRX_CONSTELLATION_QAM256:
19418 case DRX_CONSTELLATION_QAM128:
19419 case DRX_CONSTELLATION_QAM32:
19420 case DRX_CONSTELLATION_QAM16:
19423 case DRX_CONSTELLATION_QAM64:
19435 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_POW__A, &iqm_cf_power, 0);
19437 pr_err("error %d\n", rc);
19440 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_SCALE_SH__A, &iqm_cf_scale_sh, 0);
19442 pr_err("error %d\n", rc);
19445 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_AMP__A, &iqm_cf_amp, 0);
19447 pr_err("error %d\n", rc);
19450 /* IQM_CF_PWR_CORRECTION_dB = 3;
19451 P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
19452 /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
19453 -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
19454 +6*7+10*log10(1+0.115/4); */
19455 /* PadcdB = P4dB +3 -6 +60; dBmV */
19456 *agc_internal = (u16) (log1_times100(iqm_cf_power)
19457 - 2 * log1_times100(iqm_cf_amp)
19458 - iqm_cf_gain - 120 * iqm_cf_scale_sh + 781);
19465 /*============================================================================*/
19468 * \fn int ctrl_set_cfg_pre_saw()
19469 * \brief Set Pre-saw reference.
19470 * \param demod demod instance
19475 * Dispatch handling to standard specific function.
19479 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19481 struct i2c_device_addr *dev_addr = NULL;
19482 struct drxj_data *ext_attr = NULL;
19485 dev_addr = demod->my_i2c_dev_addr;
19486 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19488 /* check arguments */
19489 if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
19494 /* Only if standard is currently active */
19495 if ((ext_attr->standard == pre_saw->standard) ||
19496 (DRXJ_ISQAMSTD(ext_attr->standard) &&
19497 DRXJ_ISQAMSTD(pre_saw->standard)) ||
19498 (DRXJ_ISATVSTD(ext_attr->standard) &&
19499 DRXJ_ISATVSTD(pre_saw->standard))) {
19500 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
19502 pr_err("error %d\n", rc);
19507 /* Store pre-saw settings */
19508 switch (pre_saw->standard) {
19509 case DRX_STANDARD_8VSB:
19510 ext_attr->vsb_pre_saw_cfg = *pre_saw;
19512 #ifndef DRXJ_VSB_ONLY
19513 case DRX_STANDARD_ITU_A: /* fallthrough */
19514 case DRX_STANDARD_ITU_B: /* fallthrough */
19515 case DRX_STANDARD_ITU_C:
19516 ext_attr->qam_pre_saw_cfg = *pre_saw;
19519 #ifndef DRXJ_DIGITAL_ONLY
19520 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19521 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19522 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19523 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19524 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19525 case DRX_STANDARD_NTSC: /* fallthrough */
19526 case DRX_STANDARD_FM:
19527 ext_attr->atv_pre_saw_cfg = *pre_saw;
19539 /*============================================================================*/
19542 * \fn int ctrl_set_cfg_afe_gain()
19543 * \brief Set AFE Gain.
19544 * \param demod demod instance
19549 * Dispatch handling to standard specific function.
19553 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19555 struct i2c_device_addr *dev_addr = NULL;
19556 struct drxj_data *ext_attr = NULL;
19560 /* check arguments */
19561 if (afe_gain == NULL)
19564 dev_addr = demod->my_i2c_dev_addr;
19565 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19567 switch (afe_gain->standard) {
19568 case DRX_STANDARD_8VSB: /* fallthrough */
19569 #ifndef DRXJ_VSB_ONLY
19570 case DRX_STANDARD_ITU_A: /* fallthrough */
19571 case DRX_STANDARD_ITU_B: /* fallthrough */
19572 case DRX_STANDARD_ITU_C:
19580 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
19581 So I (PJ) think interface requires choice between auto, user mode */
19583 if (afe_gain->gain >= 329)
19585 else if (afe_gain->gain <= 147)
19588 gain = (afe_gain->gain - 140 + 6) / 13;
19590 /* Only if standard is currently active */
19591 if (ext_attr->standard == afe_gain->standard) {
19592 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
19594 pr_err("error %d\n", rc);
19599 /* Store AFE Gain settings */
19600 switch (afe_gain->standard) {
19601 case DRX_STANDARD_8VSB:
19602 ext_attr->vsb_pga_cfg = gain * 13 + 140;
19604 #ifndef DRXJ_VSB_ONLY
19605 case DRX_STANDARD_ITU_A: /* fallthrough */
19606 case DRX_STANDARD_ITU_B: /* fallthrough */
19607 case DRX_STANDARD_ITU_C:
19608 ext_attr->qam_pga_cfg = gain * 13 + 140;
19620 /*============================================================================*/
19623 * \fn int ctrl_get_cfg_pre_saw()
19624 * \brief Get Pre-saw reference setting.
19625 * \param demod demod instance
19630 * Dispatch handling to standard specific function.
19634 ctrl_get_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19636 struct drxj_data *ext_attr = NULL;
19638 /* check arguments */
19639 if (pre_saw == NULL)
19642 ext_attr = (struct drxj_data *) demod->my_ext_attr;
19644 switch (pre_saw->standard) {
19645 case DRX_STANDARD_8VSB:
19646 *pre_saw = ext_attr->vsb_pre_saw_cfg;
19648 #ifndef DRXJ_VSB_ONLY
19649 case DRX_STANDARD_ITU_A: /* fallthrough */
19650 case DRX_STANDARD_ITU_B: /* fallthrough */
19651 case DRX_STANDARD_ITU_C:
19652 *pre_saw = ext_attr->qam_pre_saw_cfg;
19655 #ifndef DRXJ_DIGITAL_ONLY
19656 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19657 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19658 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
19659 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
19660 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19661 case DRX_STANDARD_NTSC:
19662 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
19663 *pre_saw = ext_attr->atv_pre_saw_cfg;
19665 case DRX_STANDARD_FM:
19666 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_FM;
19667 *pre_saw = ext_attr->atv_pre_saw_cfg;
19677 /*============================================================================*/
19680 * \fn int ctrl_get_cfg_afe_gain()
19681 * \brief Get AFE Gain.
19682 * \param demod demod instance
19687 * Dispatch handling to standard specific function.
19691 ctrl_get_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19693 struct drxj_data *ext_attr = NULL;
19695 /* check arguments */
19696 if (afe_gain == NULL)
19699 ext_attr = demod->my_ext_attr;
19701 switch (afe_gain->standard) {
19702 case DRX_STANDARD_8VSB:
19703 afe_gain->gain = ext_attr->vsb_pga_cfg;
19705 #ifndef DRXJ_VSB_ONLY
19706 case DRX_STANDARD_ITU_A: /* fallthrough */
19707 case DRX_STANDARD_ITU_B: /* fallthrough */
19708 case DRX_STANDARD_ITU_C:
19709 afe_gain->gain = ext_attr->qam_pga_cfg;
19719 /*============================================================================*/
19722 * \fn int ctrl_get_fec_meas_seq_count()
19723 * \brief Get FEC measurement sequnce number.
19724 * \param demod demod instance
19729 * Dispatch handling to standard specific function.
19733 ctrl_get_fec_meas_seq_count(struct drx_demod_instance *demod, u16 *fec_meas_seq_count)
19736 /* check arguments */
19737 if (fec_meas_seq_count == NULL)
19740 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, fec_meas_seq_count, 0);
19742 pr_err("error %d\n", rc);
19751 /*============================================================================*/
19754 * \fn int ctrl_get_accum_cr_rs_cw_err()
19755 * \brief Get accumulative corrected RS codeword number.
19756 * \param demod demod instance
19761 * Dispatch handling to standard specific function.
19765 ctrl_get_accum_cr_rs_cw_err(struct drx_demod_instance *demod, u32 *accum_cr_rs_cw_err)
19768 if (accum_cr_rs_cw_err == NULL)
19771 rc = DRXJ_DAP.read_reg32func(demod->my_i2c_dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, accum_cr_rs_cw_err, 0);
19773 pr_err("error %d\n", rc);
19783 * \fn int ctrl_set_cfg()
19784 * \brief Set 'some' configuration of the device.
19785 * \param devmod Pointer to demodulator instance.
19786 * \param config Pointer to configuration parameters (type and data).
19790 static int ctrl_set_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
19794 if (config == NULL)
19799 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
19801 pr_err("error %d\n", rc);
19805 switch (config->cfg_type) {
19806 case DRX_CFG_MPEG_OUTPUT:
19807 return ctrl_set_cfg_mpeg_output(demod,
19808 (struct drx_cfg_mpeg_output *) config->
19810 case DRX_CFG_PINS_SAFE_MODE:
19811 return ctrl_set_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
19812 case DRXJ_CFG_AGC_RF:
19813 return ctrl_set_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
19814 case DRXJ_CFG_AGC_IF:
19815 return ctrl_set_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
19816 case DRXJ_CFG_PRE_SAW:
19817 return ctrl_set_cfg_pre_saw(demod,
19818 (struct drxj_cfg_pre_saw *) config->cfg_data);
19819 case DRXJ_CFG_AFE_GAIN:
19820 return ctrl_set_cfg_afe_gain(demod,
19821 (struct drxj_cfg_afe_gain *) config->cfg_data);
19822 case DRXJ_CFG_SMART_ANT:
19823 return ctrl_set_cfg_smart_ant(demod,
19824 (struct drxj_cfg_smart_ant *) (config->
19826 case DRXJ_CFG_RESET_PACKET_ERR:
19827 return ctrl_set_cfg_reset_pkt_err(demod);
19828 #ifndef DRXJ_DIGITAL_ONLY
19829 case DRXJ_CFG_OOB_PRE_SAW:
19830 return ctrl_set_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
19831 case DRXJ_CFG_OOB_LO_POW:
19832 return ctrl_set_cfg_oob_lo_power(demod,
19833 (enum drxj_cfg_oob_lo_power *) (config->
19835 case DRXJ_CFG_ATV_MISC:
19836 return ctrl_set_cfg_atv_misc(demod,
19837 (struct drxj_cfg_atv_misc *) config->cfg_data);
19838 case DRXJ_CFG_ATV_EQU_COEF:
19839 return ctrl_set_cfg_atv_equ_coef(demod,
19840 (struct drxj_cfg_atv_equ_coef *) config->
19842 case DRXJ_CFG_ATV_OUTPUT:
19843 return ctrl_set_cfg_atv_output(demod,
19844 (struct drxj_cfg_atv_output *) config->
19847 case DRXJ_CFG_MPEG_OUTPUT_MISC:
19848 return ctrl_set_cfg_mpeg_output_misc(demod,
19849 (struct drxj_cfg_mpeg_output_misc *)
19851 #ifndef DRXJ_EXCLUDE_AUDIO
19852 case DRX_CFG_AUD_VOLUME:
19853 return aud_ctrl_set_cfg_volume(demod,
19854 (struct drx_cfg_aud_volume *) config->
19856 case DRX_CFG_I2S_OUTPUT:
19857 return aud_ctrl_set_cfg_output_i2s(demod,
19858 (struct drx_cfg_i2s_output *) config->
19860 case DRX_CFG_AUD_AUTOSOUND:
19861 return aud_ctr_setl_cfg_auto_sound(demod, (enum drx_cfg_aud_auto_sound *)
19863 case DRX_CFG_AUD_ASS_THRES:
19864 return aud_ctrl_set_cfg_ass_thres(demod, (struct drx_cfg_aud_ass_thres *)
19866 case DRX_CFG_AUD_CARRIER:
19867 return aud_ctrl_set_cfg_carrier(demod,
19868 (struct drx_cfg_aud_carriers *) config->
19870 case DRX_CFG_AUD_DEVIATION:
19871 return aud_ctrl_set_cfg_dev(demod,
19872 (enum drx_cfg_aud_deviation *) config->
19874 case DRX_CFG_AUD_PRESCALE:
19875 return aud_ctrl_set_cfg_prescale(demod,
19876 (struct drx_cfg_aud_prescale *) config->
19878 case DRX_CFG_AUD_MIXER:
19879 return aud_ctrl_set_cfg_mixer(demod,
19880 (struct drx_cfg_aud_mixer *) config->cfg_data);
19881 case DRX_CFG_AUD_AVSYNC:
19882 return aud_ctrl_set_cfg_av_sync(demod,
19883 (enum drx_cfg_aud_av_sync *) config->
19896 /*============================================================================*/
19899 * \fn int ctrl_get_cfg()
19900 * \brief Get 'some' configuration of the device.
19901 * \param devmod Pointer to demodulator instance.
19902 * \param config Pointer to configuration parameters (type and data).
19906 static int ctrl_get_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
19910 if (config == NULL)
19915 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
19917 pr_err("error %d\n", rc);
19922 switch (config->cfg_type) {
19923 case DRX_CFG_MPEG_OUTPUT:
19924 return ctrl_get_cfg_mpeg_output(demod,
19925 (struct drx_cfg_mpeg_output *) config->
19927 case DRX_CFG_PINS_SAFE_MODE:
19928 return ctrl_get_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
19929 case DRXJ_CFG_AGC_RF:
19930 return ctrl_get_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
19931 case DRXJ_CFG_AGC_IF:
19932 return ctrl_get_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
19933 case DRXJ_CFG_AGC_INTERNAL:
19934 return ctrl_get_cfg_agc_internal(demod, (u16 *)config->cfg_data);
19935 case DRXJ_CFG_PRE_SAW:
19936 return ctrl_get_cfg_pre_saw(demod,
19937 (struct drxj_cfg_pre_saw *) config->cfg_data);
19938 case DRXJ_CFG_AFE_GAIN:
19939 return ctrl_get_cfg_afe_gain(demod,
19940 (struct drxj_cfg_afe_gain *) config->cfg_data);
19941 case DRXJ_CFG_ACCUM_CR_RS_CW_ERR:
19942 return ctrl_get_accum_cr_rs_cw_err(demod, (u32 *)config->cfg_data);
19943 case DRXJ_CFG_FEC_MERS_SEQ_COUNT:
19944 return ctrl_get_fec_meas_seq_count(demod, (u16 *)config->cfg_data);
19945 case DRXJ_CFG_VSB_MISC:
19946 return ctrl_get_cfg_vsb_misc(demod,
19947 (struct drxj_cfg_vsb_misc *) config->cfg_data);
19948 case DRXJ_CFG_SYMBOL_CLK_OFFSET:
19949 return ctrl_get_cfg_symbol_clock_offset(demod,
19950 (s32 *)config->cfg_data);
19951 #ifndef DRXJ_DIGITAL_ONLY
19952 case DRXJ_CFG_OOB_MISC:
19953 return ctrl_get_cfg_oob_misc(demod,
19954 (struct drxj_cfg_oob_misc *) config->cfg_data);
19955 case DRXJ_CFG_OOB_PRE_SAW:
19956 return ctrl_get_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
19957 case DRXJ_CFG_OOB_LO_POW:
19958 return ctrl_get_cfg_oob_lo_power(demod,
19959 (enum drxj_cfg_oob_lo_power *) (config->
19961 case DRXJ_CFG_ATV_EQU_COEF:
19962 return ctrl_get_cfg_atv_equ_coef(demod,
19963 (struct drxj_cfg_atv_equ_coef *) config->
19965 case DRXJ_CFG_ATV_MISC:
19966 return ctrl_get_cfg_atv_misc(demod,
19967 (struct drxj_cfg_atv_misc *) config->cfg_data);
19968 case DRXJ_CFG_ATV_OUTPUT:
19969 return ctrl_get_cfg_atv_output(demod,
19970 (struct drxj_cfg_atv_output *) config->
19972 case DRXJ_CFG_ATV_AGC_STATUS:
19973 return ctrl_get_cfg_atv_agc_status(demod,
19974 (struct drxj_cfg_atv_agc_status *) config->
19977 case DRXJ_CFG_MPEG_OUTPUT_MISC:
19978 return ctrl_get_cfg_mpeg_output_misc(demod,
19979 (struct drxj_cfg_mpeg_output_misc *)
19981 case DRXJ_CFG_HW_CFG:
19982 return ctrl_get_cfg_hw_cfg(demod,
19983 (struct drxj_cfg_hw_cfg *) config->cfg_data);
19984 #ifndef DRXJ_EXCLUDE_AUDIO
19985 case DRX_CFG_AUD_VOLUME:
19986 return aud_ctrl_get_cfg_volume(demod,
19987 (struct drx_cfg_aud_volume *) config->
19989 case DRX_CFG_I2S_OUTPUT:
19990 return aud_ctrl_get_cfg_output_i2s(demod,
19991 (struct drx_cfg_i2s_output *) config->
19994 case DRX_CFG_AUD_RDS:
19995 return aud_ctrl_get_cfg_rds(demod,
19996 (struct drx_cfg_aud_rds *) config->cfg_data);
19997 case DRX_CFG_AUD_AUTOSOUND:
19998 return aud_ctrl_get_cfg_auto_sound(demod,
19999 (enum drx_cfg_aud_auto_sound *) config->
20001 case DRX_CFG_AUD_ASS_THRES:
20002 return aud_ctrl_get_cfg_ass_thres(demod,
20003 (struct drx_cfg_aud_ass_thres *) config->
20005 case DRX_CFG_AUD_CARRIER:
20006 return aud_ctrl_get_cfg_carrier(demod,
20007 (struct drx_cfg_aud_carriers *) config->
20009 case DRX_CFG_AUD_DEVIATION:
20010 return aud_ctrl_get_cfg_dev(demod,
20011 (enum drx_cfg_aud_deviation *) config->
20013 case DRX_CFG_AUD_PRESCALE:
20014 return aud_ctrl_get_cfg_prescale(demod,
20015 (struct drx_cfg_aud_prescale *) config->
20017 case DRX_CFG_AUD_MIXER:
20018 return aud_ctrl_get_cfg_mixer(demod,
20019 (struct drx_cfg_aud_mixer *) config->cfg_data);
20020 case DRX_CFG_AUD_AVSYNC:
20021 return aud_ctrl_get_cfg_av_sync(demod,
20022 (enum drx_cfg_aud_av_sync *) config->
20035 /*=============================================================================
20036 ===== EXPORTED FUNCTIONS ====================================================*/
20039 * \brief Open the demod instance, configure device, configure drxdriver
20040 * \return Status_t Return status.
20042 * drxj_open() can be called with a NULL ucode image => no ucode upload.
20043 * This means that drxj_open() must NOT contain SCU commands or, in general,
20044 * rely on SCU or AUD ucode to be present.
20047 int drxj_open(struct drx_demod_instance *demod)
20049 struct i2c_device_addr *dev_addr = NULL;
20050 struct drxj_data *ext_attr = NULL;
20051 struct drx_common_attr *common_attr = NULL;
20052 u32 driver_version = 0;
20053 struct drxu_code_info ucode_info;
20054 struct drx_cfg_mpeg_output cfg_mpeg_output;
20057 /* Check arguments */
20058 if (demod->my_ext_attr == NULL)
20061 dev_addr = demod->my_i2c_dev_addr;
20062 ext_attr = (struct drxj_data *) demod->my_ext_attr;
20063 common_attr = (struct drx_common_attr *) demod->my_common_attr;
20065 rc = power_up_device(demod);
20067 pr_err("error %d\n", rc);
20070 common_attr->current_power_mode = DRX_POWER_UP;
20072 /* has to be in front of setIqmAf and setOrxNsuAox */
20073 rc = get_device_capabilities(demod);
20075 pr_err("error %d\n", rc);
20079 /* Soft reset of sys- and osc-clockdomain */
20080 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);
20082 pr_err("error %d\n", rc);
20085 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
20087 pr_err("error %d\n", rc);
20090 rc = drxbsp_hst_sleep(1);
20092 pr_err("error %d\n", rc);
20096 /* TODO first make sure that everything keeps working before enabling this */
20097 /* PowerDownAnalogBlocks() */
20098 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);
20100 pr_err("error %d\n", rc);
20104 rc = set_iqm_af(demod, false);
20106 pr_err("error %d\n", rc);
20109 rc = set_orx_nsu_aox(demod, false);
20111 pr_err("error %d\n", rc);
20115 rc = init_hi(demod);
20117 pr_err("error %d\n", rc);
20121 /* disable mpegoutput pins */
20122 cfg_mpeg_output.enable_mpeg_output = false;
20123 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
20125 pr_err("error %d\n", rc);
20128 /* Stop AUD Inform SetAudio it will need to do all setting */
20129 rc = power_down_aud(demod);
20131 pr_err("error %d\n", rc);
20135 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
20137 pr_err("error %d\n", rc);
20141 /* Upload microcode */
20142 if (common_attr->microcode != NULL) {
20143 /* Dirty trick to use common ucode upload & verify,
20144 pretend device is already open */
20145 common_attr->is_opened = true;
20146 ucode_info.mc_data = common_attr->microcode;
20148 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20149 /* Upload microcode without audio part */
20150 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_UPLOAD, false);
20152 pr_err("error %d\n", rc);
20156 rc = drx_ctrl(demod, DRX_CTRL_LOAD_UCODE, &ucode_info);
20158 pr_err("error %d\n", rc);
20161 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20162 if (common_attr->verify_microcode == true) {
20163 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20164 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_VERIFY, false);
20166 pr_err("error %d\n", rc);
20170 rc = drx_ctrl(demod, DRX_CTRL_VERIFY_UCODE, &ucode_info);
20172 pr_err("error %d\n", rc);
20175 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20177 common_attr->is_opened = false;
20180 /* Run SCU for a little while to initialize microcode version numbers */
20181 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
20183 pr_err("error %d\n", rc);
20187 /* Open tuner instance */
20188 if (demod->my_tuner != NULL) {
20189 demod->my_tuner->my_common_attr->my_user_data = (void *)demod;
20191 if (common_attr->tuner_port_nr == 1) {
20192 bool bridge_closed = true;
20193 rc = ctrl_i2c_bridge(demod, &bridge_closed);
20195 pr_err("error %d\n", rc);
20200 rc = drxbsp_tuner_open(demod->my_tuner);
20202 pr_err("error %d\n", rc);
20206 if (common_attr->tuner_port_nr == 1) {
20207 bool bridge_closed = false;
20208 rc = ctrl_i2c_bridge(demod, &bridge_closed);
20210 pr_err("error %d\n", rc);
20214 common_attr->tuner_min_freq_rf =
20215 ((demod->my_tuner)->my_common_attr->min_freq_rf);
20216 common_attr->tuner_max_freq_rf =
20217 ((demod->my_tuner)->my_common_attr->max_freq_rf);
20220 /* Initialize scan timeout */
20221 common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
20222 common_attr->scan_desired_lock = DRX_LOCKED;
20224 /* Initialize default AFE configuartion for QAM */
20225 if (ext_attr->has_lna) {
20226 /* IF AGC off, PGA active */
20227 #ifndef DRXJ_VSB_ONLY
20228 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
20229 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
20230 ext_attr->qam_pga_cfg = 140 + (11 * 13);
20232 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
20233 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
20234 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
20236 /* IF AGC on, PGA not active */
20237 #ifndef DRXJ_VSB_ONLY
20238 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
20239 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20240 ext_attr->qam_if_agc_cfg.min_output_level = 0;
20241 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
20242 ext_attr->qam_if_agc_cfg.speed = 3;
20243 ext_attr->qam_if_agc_cfg.top = 1297;
20244 ext_attr->qam_pga_cfg = 140;
20246 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
20247 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20248 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
20249 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
20250 ext_attr->vsb_if_agc_cfg.speed = 3;
20251 ext_attr->vsb_if_agc_cfg.top = 1024;
20252 ext_attr->vsb_pga_cfg = 140;
20254 /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
20255 /* mc has not used them */
20256 #ifndef DRXJ_VSB_ONLY
20257 ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
20258 ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20259 ext_attr->qam_rf_agc_cfg.min_output_level = 0;
20260 ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
20261 ext_attr->qam_rf_agc_cfg.speed = 3;
20262 ext_attr->qam_rf_agc_cfg.top = 9500;
20263 ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
20264 ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
20265 ext_attr->qam_pre_saw_cfg.reference = 0x07;
20266 ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
20268 /* Initialize default AFE configuartion for VSB */
20269 ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
20270 ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20271 ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
20272 ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
20273 ext_attr->vsb_rf_agc_cfg.speed = 3;
20274 ext_attr->vsb_rf_agc_cfg.top = 9500;
20275 ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
20276 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
20277 ext_attr->vsb_pre_saw_cfg.reference = 0x07;
20278 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
20280 #ifndef DRXJ_DIGITAL_ONLY
20281 /* Initialize default AFE configuartion for ATV */
20282 ext_attr->atv_rf_agc_cfg.standard = DRX_STANDARD_NTSC;
20283 ext_attr->atv_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20284 ext_attr->atv_rf_agc_cfg.top = 9500;
20285 ext_attr->atv_rf_agc_cfg.cut_off_current = 4000;
20286 ext_attr->atv_rf_agc_cfg.speed = 3;
20287 ext_attr->atv_if_agc_cfg.standard = DRX_STANDARD_NTSC;
20288 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20289 ext_attr->atv_if_agc_cfg.speed = 3;
20290 ext_attr->atv_if_agc_cfg.top = 2400;
20291 ext_attr->atv_pre_saw_cfg.reference = 0x0007;
20292 ext_attr->atv_pre_saw_cfg.use_pre_saw = true;
20293 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
20295 ext_attr->standard = DRX_STANDARD_UNKNOWN;
20297 rc = smart_ant_init(demod);
20299 pr_err("error %d\n", rc);
20303 /* Stamp driver version number in SCU data RAM in BCD code
20304 Done to enable field application engineers to retreive drxdriver version
20305 via I2C from SCU RAM
20307 driver_version = (VERSION_MAJOR / 100) % 10;
20308 driver_version <<= 4;
20309 driver_version += (VERSION_MAJOR / 10) % 10;
20310 driver_version <<= 4;
20311 driver_version += (VERSION_MAJOR % 10);
20312 driver_version <<= 4;
20313 driver_version += (VERSION_MINOR % 10);
20314 driver_version <<= 4;
20315 driver_version += (VERSION_PATCH / 1000) % 10;
20316 driver_version <<= 4;
20317 driver_version += (VERSION_PATCH / 100) % 10;
20318 driver_version <<= 4;
20319 driver_version += (VERSION_PATCH / 10) % 10;
20320 driver_version <<= 4;
20321 driver_version += (VERSION_PATCH % 10);
20322 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
20324 pr_err("error %d\n", rc);
20327 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
20329 pr_err("error %d\n", rc);
20333 /* refresh the audio data structure with default */
20334 ext_attr->aud_data = drxj_default_aud_data_g;
20338 common_attr->is_opened = false;
20342 /*============================================================================*/
20345 * \brief Close the demod instance, power down the device
20346 * \return Status_t Return status.
20349 int drxj_close(struct drx_demod_instance *demod)
20351 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
20352 struct drx_common_attr *common_attr = demod->my_common_attr;
20354 enum drx_power_mode power_mode = DRX_POWER_UP;
20357 rc = ctrl_power_mode(demod, &power_mode);
20359 pr_err("error %d\n", rc);
20363 if (demod->my_tuner != NULL) {
20364 /* Check if bridge is used */
20365 if (common_attr->tuner_port_nr == 1) {
20366 bool bridge_closed = true;
20367 rc = ctrl_i2c_bridge(demod, &bridge_closed);
20369 pr_err("error %d\n", rc);
20373 rc = drxbsp_tuner_close(demod->my_tuner);
20375 pr_err("error %d\n", rc);
20378 if (common_attr->tuner_port_nr == 1) {
20379 bool bridge_closed = false;
20380 rc = ctrl_i2c_bridge(demod, &bridge_closed);
20382 pr_err("error %d\n", rc);
20388 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
20390 pr_err("error %d\n", rc);
20393 power_mode = DRX_POWER_DOWN;
20394 rc = ctrl_power_mode(demod, &power_mode);
20396 pr_err("error %d\n", rc);
20405 /*============================================================================*/
20408 * \brief DRXJ specific control function
20409 * \return Status_t Return status.
20412 drxj_ctrl(struct drx_demod_instance *demod, u32 ctrl, void *ctrl_data)
20415 /*======================================================================*/
20416 case DRX_CTRL_SET_CHANNEL:
20418 return ctrl_set_channel(demod, (struct drx_channel *)ctrl_data);
20421 /*======================================================================*/
20422 case DRX_CTRL_GET_CHANNEL:
20424 return ctrl_get_channel(demod, (struct drx_channel *)ctrl_data);
20427 /*======================================================================*/
20428 case DRX_CTRL_SIG_QUALITY:
20430 return ctrl_sig_quality(demod,
20431 (struct drx_sig_quality *) ctrl_data);
20434 /*======================================================================*/
20435 case DRX_CTRL_SIG_STRENGTH:
20437 return ctrl_sig_strength(demod, (u16 *)ctrl_data);
20440 /*======================================================================*/
20441 case DRX_CTRL_CONSTEL:
20443 return ctrl_constel(demod, (struct drx_complex *)ctrl_data);
20446 /*======================================================================*/
20447 case DRX_CTRL_SET_CFG:
20449 return ctrl_set_cfg(demod, (struct drx_cfg *)ctrl_data);
20452 /*======================================================================*/
20453 case DRX_CTRL_GET_CFG:
20455 return ctrl_get_cfg(demod, (struct drx_cfg *)ctrl_data);
20458 /*======================================================================*/
20459 case DRX_CTRL_I2C_BRIDGE:
20461 return ctrl_i2c_bridge(demod, (bool *)ctrl_data);
20464 /*======================================================================*/
20465 case DRX_CTRL_LOCK_STATUS:
20467 return ctrl_lock_status(demod,
20468 (enum drx_lock_status *)ctrl_data);
20471 /*======================================================================*/
20472 case DRX_CTRL_SET_STANDARD:
20474 return ctrl_set_standard(demod,
20475 (enum drx_standard *)ctrl_data);
20478 /*======================================================================*/
20479 case DRX_CTRL_GET_STANDARD:
20481 return ctrl_get_standard(demod,
20482 (enum drx_standard *)ctrl_data);
20485 /*======================================================================*/
20486 case DRX_CTRL_POWER_MODE:
20488 return ctrl_power_mode(demod, (enum drx_power_mode *)ctrl_data);
20491 /*======================================================================*/
20492 case DRX_CTRL_VERSION:
20494 return ctrl_version(demod,
20495 (struct drx_version_list **)ctrl_data);
20498 /*======================================================================*/
20499 case DRX_CTRL_PROBE_DEVICE:
20501 return ctrl_probe_device(demod);
20504 /*======================================================================*/
20505 case DRX_CTRL_SET_OOB:
20507 return ctrl_set_oob(demod, (struct drxoob *)ctrl_data);
20510 /*======================================================================*/
20511 case DRX_CTRL_GET_OOB:
20513 return ctrl_get_oob(demod, (struct drxoob_status *)ctrl_data);
20516 /*======================================================================*/
20517 case DRX_CTRL_SET_UIO_CFG:
20519 return ctrl_set_uio_cfg(demod, (struct drxuio_cfg *)ctrl_data);
20522 /*======================================================================*/
20523 case DRX_CTRL_GET_UIO_CFG:
20525 return ctrl_getuio_cfg(demod, (struct drxuio_cfg *)ctrl_data);
20528 /*======================================================================*/
20529 case DRX_CTRL_UIO_READ:
20531 return ctrl_uio_read(demod, (struct drxuio_data *)ctrl_data);
20534 /*======================================================================*/
20535 case DRX_CTRL_UIO_WRITE:
20537 return ctrl_uio_write(demod, (struct drxuio_data *)ctrl_data);
20540 /*======================================================================*/
20541 case DRX_CTRL_AUD_SET_STANDARD:
20543 return aud_ctrl_set_standard(demod,
20544 (enum drx_aud_standard *) ctrl_data);
20547 /*======================================================================*/
20548 case DRX_CTRL_AUD_GET_STANDARD:
20550 return aud_ctrl_get_standard(demod,
20551 (enum drx_aud_standard *) ctrl_data);
20554 /*======================================================================*/
20555 case DRX_CTRL_AUD_GET_STATUS:
20557 return aud_ctrl_get_status(demod,
20558 (struct drx_aud_status *) ctrl_data);
20561 /*======================================================================*/
20562 case DRX_CTRL_AUD_BEEP:
20564 return aud_ctrl_beep(demod, (struct drx_aud_beep *)ctrl_data);
20568 /*======================================================================*/
20569 case DRX_CTRL_I2C_READWRITE:
20571 return ctrl_i2c_write_read(demod,
20572 (struct drxi2c_data *) ctrl_data);
20575 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20576 case DRX_CTRL_LOAD_UCODE:
20578 return ctrl_u_code_upload(demod,
20579 (p_drxu_code_info_t) ctrl_data,
20580 UCODE_UPLOAD, false);
20583 case DRX_CTRL_VERIFY_UCODE:
20585 return ctrl_u_code_upload(demod,
20586 (p_drxu_code_info_t) ctrl_data,
20587 UCODE_VERIFY, false);
20590 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20591 case DRX_CTRL_VALIDATE_UCODE:
20593 return ctrl_validate_u_code(demod);