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
33 The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was
34 written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
36 This program is free software; you can redistribute it and/or modify
37 it under the terms of the GNU General Public License as published by
38 the Free Software Foundation; either version 2 of the License, or
39 (at your option) any later version.
41 This program is distributed in the hope that it will be useful,
42 but WITHOUT ANY WARRANTY; without even the implied warranty of
43 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45 GNU General Public License for more details.
47 You should have received a copy of the GNU General Public License
48 along with this program; if not, write to the Free Software
49 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
52 /*-----------------------------------------------------------------------------
54 ----------------------------------------------------------------------------*/
56 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
58 #include <linux/module.h>
59 #include <linux/init.h>
60 #include <linux/string.h>
61 #include <linux/slab.h>
63 #include "dvb_frontend.h"
69 /*============================================================================*/
70 /*=== DEFINES ================================================================*/
71 /*============================================================================*/
73 #define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
76 * \brief Maximum u32 value.
79 #define MAX_U32 ((u32) (0xFFFFFFFFL))
82 /* Customer configurable hardware settings, etc */
83 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
84 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
87 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
88 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
91 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
92 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
95 #ifndef OOB_CRX_DRIVE_STRENGTH
96 #define OOB_CRX_DRIVE_STRENGTH 0x02
99 #ifndef OOB_DRX_DRIVE_STRENGTH
100 #define OOB_DRX_DRIVE_STRENGTH 0x02
102 /**** START DJCOMBO patches to DRXJ registermap constants *********************/
103 /**** registermap 200706071303 from drxj **************************************/
104 #define ATV_TOP_CR_AMP_TH_FM 0x0
105 #define ATV_TOP_CR_AMP_TH_L 0xA
106 #define ATV_TOP_CR_AMP_TH_LP 0xA
107 #define ATV_TOP_CR_AMP_TH_BG 0x8
108 #define ATV_TOP_CR_AMP_TH_DK 0x8
109 #define ATV_TOP_CR_AMP_TH_I 0x8
110 #define ATV_TOP_CR_CONT_CR_D_MN 0x18
111 #define ATV_TOP_CR_CONT_CR_D_FM 0x0
112 #define ATV_TOP_CR_CONT_CR_D_L 0x20
113 #define ATV_TOP_CR_CONT_CR_D_LP 0x20
114 #define ATV_TOP_CR_CONT_CR_D_BG 0x18
115 #define ATV_TOP_CR_CONT_CR_D_DK 0x18
116 #define ATV_TOP_CR_CONT_CR_D_I 0x18
117 #define ATV_TOP_CR_CONT_CR_I_MN 0x80
118 #define ATV_TOP_CR_CONT_CR_I_FM 0x0
119 #define ATV_TOP_CR_CONT_CR_I_L 0x80
120 #define ATV_TOP_CR_CONT_CR_I_LP 0x80
121 #define ATV_TOP_CR_CONT_CR_I_BG 0x80
122 #define ATV_TOP_CR_CONT_CR_I_DK 0x80
123 #define ATV_TOP_CR_CONT_CR_I_I 0x80
124 #define ATV_TOP_CR_CONT_CR_P_MN 0x4
125 #define ATV_TOP_CR_CONT_CR_P_FM 0x0
126 #define ATV_TOP_CR_CONT_CR_P_L 0x4
127 #define ATV_TOP_CR_CONT_CR_P_LP 0x4
128 #define ATV_TOP_CR_CONT_CR_P_BG 0x4
129 #define ATV_TOP_CR_CONT_CR_P_DK 0x4
130 #define ATV_TOP_CR_CONT_CR_P_I 0x4
131 #define ATV_TOP_CR_OVM_TH_MN 0xA0
132 #define ATV_TOP_CR_OVM_TH_FM 0x0
133 #define ATV_TOP_CR_OVM_TH_L 0xA0
134 #define ATV_TOP_CR_OVM_TH_LP 0xA0
135 #define ATV_TOP_CR_OVM_TH_BG 0xA0
136 #define ATV_TOP_CR_OVM_TH_DK 0xA0
137 #define ATV_TOP_CR_OVM_TH_I 0xA0
138 #define ATV_TOP_EQU0_EQU_C0_FM 0x0
139 #define ATV_TOP_EQU0_EQU_C0_L 0x3
140 #define ATV_TOP_EQU0_EQU_C0_LP 0x3
141 #define ATV_TOP_EQU0_EQU_C0_BG 0x7
142 #define ATV_TOP_EQU0_EQU_C0_DK 0x0
143 #define ATV_TOP_EQU0_EQU_C0_I 0x3
144 #define ATV_TOP_EQU1_EQU_C1_FM 0x0
145 #define ATV_TOP_EQU1_EQU_C1_L 0x1F6
146 #define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
147 #define ATV_TOP_EQU1_EQU_C1_BG 0x197
148 #define ATV_TOP_EQU1_EQU_C1_DK 0x198
149 #define ATV_TOP_EQU1_EQU_C1_I 0x1F6
150 #define ATV_TOP_EQU2_EQU_C2_FM 0x0
151 #define ATV_TOP_EQU2_EQU_C2_L 0x28
152 #define ATV_TOP_EQU2_EQU_C2_LP 0x28
153 #define ATV_TOP_EQU2_EQU_C2_BG 0xC5
154 #define ATV_TOP_EQU2_EQU_C2_DK 0xB0
155 #define ATV_TOP_EQU2_EQU_C2_I 0x28
156 #define ATV_TOP_EQU3_EQU_C3_FM 0x0
157 #define ATV_TOP_EQU3_EQU_C3_L 0x192
158 #define ATV_TOP_EQU3_EQU_C3_LP 0x192
159 #define ATV_TOP_EQU3_EQU_C3_BG 0x12E
160 #define ATV_TOP_EQU3_EQU_C3_DK 0x18E
161 #define ATV_TOP_EQU3_EQU_C3_I 0x192
162 #define ATV_TOP_STD_MODE_MN 0x0
163 #define ATV_TOP_STD_MODE_FM 0x1
164 #define ATV_TOP_STD_MODE_L 0x0
165 #define ATV_TOP_STD_MODE_LP 0x0
166 #define ATV_TOP_STD_MODE_BG 0x0
167 #define ATV_TOP_STD_MODE_DK 0x0
168 #define ATV_TOP_STD_MODE_I 0x0
169 #define ATV_TOP_STD_VID_POL_MN 0x0
170 #define ATV_TOP_STD_VID_POL_FM 0x0
171 #define ATV_TOP_STD_VID_POL_L 0x2
172 #define ATV_TOP_STD_VID_POL_LP 0x2
173 #define ATV_TOP_STD_VID_POL_BG 0x0
174 #define ATV_TOP_STD_VID_POL_DK 0x0
175 #define ATV_TOP_STD_VID_POL_I 0x0
176 #define ATV_TOP_VID_AMP_MN 0x380
177 #define ATV_TOP_VID_AMP_FM 0x0
178 #define ATV_TOP_VID_AMP_L 0xF50
179 #define ATV_TOP_VID_AMP_LP 0xF50
180 #define ATV_TOP_VID_AMP_BG 0x380
181 #define ATV_TOP_VID_AMP_DK 0x394
182 #define ATV_TOP_VID_AMP_I 0x3D8
183 #define IQM_CF_OUT_ENA_OFDM__M 0x4
184 #define IQM_FS_ADJ_SEL_B_QAM 0x1
185 #define IQM_FS_ADJ_SEL_B_OFF 0x0
186 #define IQM_FS_ADJ_SEL_B_VSB 0x2
187 #define IQM_RC_ADJ_SEL_B_OFF 0x0
188 #define IQM_RC_ADJ_SEL_B_QAM 0x1
189 #define IQM_RC_ADJ_SEL_B_VSB 0x2
190 /**** END DJCOMBO patches to DRXJ registermap *********************************/
192 #include "drx_driver_version.h"
194 /* #define DRX_DEBUG */
199 /*-----------------------------------------------------------------------------
201 ----------------------------------------------------------------------------*/
203 /*-----------------------------------------------------------------------------
205 ----------------------------------------------------------------------------*/
206 #ifndef DRXJ_WAKE_UP_KEY
207 #define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
211 * \def DRXJ_DEF_I2C_ADDR
212 * \brief Default I2C addres of a demodulator instance.
214 #define DRXJ_DEF_I2C_ADDR (0x52)
217 * \def DRXJ_DEF_DEMOD_DEV_ID
218 * \brief Default device identifier of a demodultor instance.
220 #define DRXJ_DEF_DEMOD_DEV_ID (1)
223 * \def DRXJ_SCAN_TIMEOUT
224 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
226 #define DRXJ_SCAN_TIMEOUT 1000
230 * \brief Name of structure containing all data access protocol functions.
232 #define DRXJ_DAP drx_dap_drxj_funct_g
236 * \brief HI timing delay for I2C timing (in nano seconds)
238 * Used to compute HI_CFG_DIV
240 #define HI_I2C_DELAY 42
243 * \def HI_I2C_BRIDGE_DELAY
244 * \brief HI timing delay for I2C timing (in nano seconds)
246 * Used to compute HI_CFG_BDL
248 #define HI_I2C_BRIDGE_DELAY 750
251 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
253 #define VSB_TOP_MEASUREMENT_PERIOD 64
254 #define SYMBOLS_PER_SEGMENT 832
257 * \brief bit rate and segment rate constants used for SER and BER.
259 /* values taken from the QAM microcode */
260 #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
261 #define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
262 #define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
263 #define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
264 #define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
265 #define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
266 #define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
267 #define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
269 * \brief Min supported symbolrates.
271 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
272 #define DRXJ_QAM_SYMBOLRATE_MIN (520000)
276 * \brief Max supported symbolrates.
278 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
279 #define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
283 * \def DRXJ_QAM_MAX_WAITTIME
284 * \brief Maximal wait time for QAM auto constellation in ms
286 #ifndef DRXJ_QAM_MAX_WAITTIME
287 #define DRXJ_QAM_MAX_WAITTIME 900
290 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
291 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
294 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
295 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
299 * \def SCU status and results
302 #define DRX_SCU_READY 0
303 #define DRXJ_MAX_WAITTIME 100 /* ms */
304 #define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
305 #define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
308 * \def DRX_AUD_MAX_DEVIATION
309 * \brief Needed for calculation of prescale feature in AUD
311 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
312 #define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
316 * \brief Needed for calculation of NICAM prescale feature in AUD
318 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
319 #define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
323 * \brief Needed for calculation of NICAM prescale feature in AUD
325 #ifndef DRXJ_AUD_MAX_WAITTIME
326 #define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
329 /* ATV config changed flags */
330 #define DRXJ_ATV_CHANGED_COEF (0x00000001UL)
331 #define DRXJ_ATV_CHANGED_PEAK_FLT (0x00000008UL)
332 #define DRXJ_ATV_CHANGED_NOISE_FLT (0x00000010UL)
333 #define DRXJ_ATV_CHANGED_OUTPUT (0x00000020UL)
334 #define DRXJ_ATV_CHANGED_SIF_ATT (0x00000040UL)
337 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
338 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
341 * MICROCODE RELATED DEFINES
344 /* Magic word for checking correct Endianess of microcode data */
345 #define DRX_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L'))
347 /* CRC flag in ucode header, flags field. */
348 #define DRX_UCODE_CRC_FLAG (0x0001)
351 * Maximum size of buffer used to verify the microcode.
352 * Must be an even number
354 #define DRX_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
356 #if DRX_UCODE_MAX_BUF_SIZE & 1
357 #error DRX_UCODE_MAX_BUF_SIZE must be an even number
364 #define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
365 (mode == DRX_POWER_MODE_10) || \
366 (mode == DRX_POWER_MODE_11) || \
367 (mode == DRX_POWER_MODE_12) || \
368 (mode == DRX_POWER_MODE_13) || \
369 (mode == DRX_POWER_MODE_14) || \
370 (mode == DRX_POWER_MODE_15) || \
371 (mode == DRX_POWER_MODE_16) || \
372 (mode == DRX_POWER_DOWN))
374 /* Pin safe mode macro */
375 #define DRXJ_PIN_SAFE_MODE 0x0000
376 /*============================================================================*/
377 /*=== GLOBAL VARIABLEs =======================================================*/
378 /*============================================================================*/
383 * \brief Temporary register definitions.
384 * (register definitions that are not yet available in register master)
387 /******************************************************************************/
388 /* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
389 /* RAM adresses directly. This must be READ ONLY to avoid problems. */
390 /* Writing to the interface adresses is more than only writing the RAM */
392 /******************************************************************************/
394 * \brief RAM location of MODUS registers
396 #define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
397 #define AUD_DEM_RAM_MODUS_HI__M 0xF000
399 #define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
400 #define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
403 * \brief RAM location of I2S config registers
405 #define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
406 #define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
409 * \brief RAM location of DCO config registers
411 #define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
412 #define AUD_DEM_RAM_DCO_B_LO__A 0x1020462
413 #define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
414 #define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
417 * \brief RAM location of Threshold registers
419 #define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
420 #define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
421 #define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
424 * \brief RAM location of Carrier Threshold registers
426 #define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
427 #define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
430 * \brief FM Matrix register fix
432 #ifdef AUD_DEM_WR_FM_MATRIX__A
433 #undef AUD_DEM_WR_FM_MATRIX__A
435 #define AUD_DEM_WR_FM_MATRIX__A 0x105006F
437 /*============================================================================*/
439 * \brief Defines required for audio
441 #define AUD_VOLUME_ZERO_DB 115
442 #define AUD_VOLUME_DB_MIN -60
443 #define AUD_VOLUME_DB_MAX 12
444 #define AUD_CARRIER_STRENGTH_QP_0DB 0x4000
445 #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 421
446 #define AUD_MAX_AVC_REF_LEVEL 15
447 #define AUD_I2S_FREQUENCY_MAX 48000UL
448 #define AUD_I2S_FREQUENCY_MIN 12000UL
449 #define AUD_RDS_ARRAY_SIZE 18
452 * \brief Needed for calculation of prescale feature in AUD
454 #ifndef DRX_AUD_MAX_FM_DEVIATION
455 #define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
459 * \brief Needed for calculation of NICAM prescale feature in AUD
461 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
462 #define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
465 /*============================================================================*/
466 /* Values for I2S Master/Slave pin configurations */
467 #define SIO_PDR_I2S_CL_CFG_MODE__MASTER 0x0004
468 #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER 0x0008
469 #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE 0x0004
470 #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE 0x0000
472 #define SIO_PDR_I2S_DA_CFG_MODE__MASTER 0x0003
473 #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER 0x0008
474 #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE 0x0003
475 #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE 0x0008
477 #define SIO_PDR_I2S_WS_CFG_MODE__MASTER 0x0004
478 #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER 0x0008
479 #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE 0x0004
480 #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE 0x0000
482 /*============================================================================*/
483 /*=== REGISTER ACCESS MACROS =================================================*/
484 /*============================================================================*/
487 * This macro is used to create byte arrays for block writes.
488 * Block writes speed up I2C traffic between host and demod.
489 * The macro takes care of the required byte order in a 16 bits word.
490 * x -> lowbyte(x), highbyte(x)
492 #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
493 ((u8)((((u16)x)>>8)&0xFF))
495 * This macro is used to convert byte array to 16 bit register value for block read.
496 * Block read speed up I2C traffic between host and demod.
497 * The macro takes care of the required byte order in a 16 bits word.
499 #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
501 /*============================================================================*/
502 /*=== MISC DEFINES ===========================================================*/
503 /*============================================================================*/
505 /*============================================================================*/
506 /*=== HI COMMAND RELATED DEFINES =============================================*/
507 /*============================================================================*/
510 * \brief General maximum number of retries for ucode command interfaces
512 #define DRXJ_MAX_RETRIES (100)
514 /*============================================================================*/
515 /*=== STANDARD RELATED MACROS ================================================*/
516 /*============================================================================*/
518 #define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
519 (std == DRX_STANDARD_PAL_SECAM_DK) || \
520 (std == DRX_STANDARD_PAL_SECAM_I) || \
521 (std == DRX_STANDARD_PAL_SECAM_L) || \
522 (std == DRX_STANDARD_PAL_SECAM_LP) || \
523 (std == DRX_STANDARD_NTSC) || \
524 (std == DRX_STANDARD_FM))
526 #define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
527 (std == DRX_STANDARD_ITU_B) || \
528 (std == DRX_STANDARD_ITU_C) || \
529 (std == DRX_STANDARD_ITU_D))
531 /*-----------------------------------------------------------------------------
533 ----------------------------------------------------------------------------*/
535 * DRXJ DAP structures
538 static int drxj_dap_read_block(struct i2c_device_addr
*dev_addr
,
541 u8
*data
, u32 flags
);
543 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr
*dev_addr
,
546 u8 wdata
, u8
*rdata
);
548 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr
*dev_addr
,
551 u16 wdata
, u16
*rdata
);
553 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr
*dev_addr
,
556 u32 wdata
, u32
*rdata
);
558 static int drxj_dap_read_reg8(struct i2c_device_addr
*dev_addr
,
560 u8
*data
, u32 flags
);
562 static int drxj_dap_read_reg16(struct i2c_device_addr
*dev_addr
,
564 u16
*data
, u32 flags
);
566 static int drxj_dap_read_reg32(struct i2c_device_addr
*dev_addr
,
568 u32
*data
, u32 flags
);
570 static int drxj_dap_write_block(struct i2c_device_addr
*dev_addr
,
573 u8
*data
, u32 flags
);
575 static int drxj_dap_write_reg8(struct i2c_device_addr
*dev_addr
,
579 static int drxj_dap_write_reg16(struct i2c_device_addr
*dev_addr
,
581 u16 data
, u32 flags
);
583 static int drxj_dap_write_reg32(struct i2c_device_addr
*dev_addr
,
585 u32 data
, u32 flags
);
587 /* The version structure of this protocol implementation */
588 char drx_dap_drxj_module_name
[] = "DRXJ Data Access Protocol";
589 char drx_dap_drxj_version_text
[] = "0.0.0";
591 struct drx_version drx_dap_drxj_version
= {
592 DRX_MODULE_DAP
, /**< type identifier of the module */
593 drx_dap_drxj_module_name
, /**< name or description of module */
595 0, /**< major version number */
596 0, /**< minor version number */
597 0, /**< patch version number */
598 drx_dap_drxj_version_text
/**< version as text string */
601 /* The structure containing the protocol interface */
602 struct drx_access_func drx_dap_drxj_funct_g
= {
603 &drx_dap_drxj_version
,
604 drxj_dap_write_block
, /* Supported */
605 drxj_dap_read_block
, /* Supported */
606 drxj_dap_write_reg8
, /* Not supported */
607 drxj_dap_read_reg8
, /* Not supported */
608 drxj_dap_read_modify_write_reg8
, /* Not supported */
609 drxj_dap_write_reg16
, /* Supported */
610 drxj_dap_read_reg16
, /* Supported */
611 drxj_dap_read_modify_write_reg16
, /* Supported */
612 drxj_dap_write_reg32
, /* Supported */
613 drxj_dap_read_reg32
, /* Supported */
614 drxj_dap_read_modify_write_reg32
, /* Not supported */
617 struct drxj_data drxj_data_g
= {
618 false, /* has_lna : true if LNA (aka PGA) present */
619 false, /* has_oob : true if OOB supported */
620 false, /* has_ntsc: true if NTSC supported */
621 false, /* has_btsc: true if BTSC supported */
622 false, /* has_smatx: true if SMA_TX pin is available */
623 false, /* has_smarx: true if SMA_RX pin is available */
624 false, /* has_gpio : true if GPIO pin is available */
625 false, /* has_irqn : true if IRQN pin is available */
626 0, /* mfx A1/A2/A... */
629 false, /* tuner mirrors RF signal */
630 /* standard/channel settings */
631 DRX_STANDARD_UNKNOWN
, /* current standard */
632 DRX_CONSTELLATION_AUTO
, /* constellation */
633 0, /* frequency in KHz */
634 DRX_BANDWIDTH_UNKNOWN
, /* curr_bandwidth */
635 DRX_MIRROR_NO
, /* mirror */
637 /* signal quality information: */
638 /* default values taken from the QAM Programming guide */
639 /* fec_bits_desired should not be less than 4000000 */
640 4000000, /* fec_bits_desired */
642 4, /* qam_vd_prescale */
643 0xFFFF, /* qamVDPeriod */
644 204 * 8, /* fec_rs_plen annex A */
645 1, /* fec_rs_prescale */
646 FEC_RS_MEASUREMENT_PERIOD
, /* fec_rs_period */
647 true, /* reset_pkt_err_acc */
648 0, /* pkt_err_acc_start */
650 /* HI configuration */
651 0, /* hi_cfg_timing_div */
652 0, /* hi_cfg_bridge_delay */
653 0, /* hi_cfg_wake_up_key */
655 0, /* HICfgTimeout */
656 /* UIO configuartion */
657 DRX_UIO_MODE_DISABLE
, /* uio_sma_rx_mode */
658 DRX_UIO_MODE_DISABLE
, /* uio_sma_tx_mode */
659 DRX_UIO_MODE_DISABLE
, /* uioASELMode */
660 DRX_UIO_MODE_DISABLE
, /* uio_irqn_mode */
662 0UL, /* iqm_fs_rate_ofs */
663 false, /* pos_image */
665 0UL, /* iqm_rc_rate_ofs */
666 /* AUD information */
667 /* false, * flagSetAUDdone */
668 /* false, * detectedRDS */
669 /* true, * flagASDRequest */
670 /* false, * flagHDevClear */
671 /* false, * flagHDevSet */
672 /* (u16) 0xFFF, * rdsLastCount */
674 /* ATV configuartion */
675 0UL, /* flags cfg changes */
676 /* shadow of ATV_TOP_EQU0__A */
678 ATV_TOP_EQU0_EQU_C0_FM
,
679 ATV_TOP_EQU0_EQU_C0_L
,
680 ATV_TOP_EQU0_EQU_C0_LP
,
681 ATV_TOP_EQU0_EQU_C0_BG
,
682 ATV_TOP_EQU0_EQU_C0_DK
,
683 ATV_TOP_EQU0_EQU_C0_I
},
684 /* shadow of ATV_TOP_EQU1__A */
686 ATV_TOP_EQU1_EQU_C1_FM
,
687 ATV_TOP_EQU1_EQU_C1_L
,
688 ATV_TOP_EQU1_EQU_C1_LP
,
689 ATV_TOP_EQU1_EQU_C1_BG
,
690 ATV_TOP_EQU1_EQU_C1_DK
,
691 ATV_TOP_EQU1_EQU_C1_I
},
692 /* shadow of ATV_TOP_EQU2__A */
694 ATV_TOP_EQU2_EQU_C2_FM
,
695 ATV_TOP_EQU2_EQU_C2_L
,
696 ATV_TOP_EQU2_EQU_C2_LP
,
697 ATV_TOP_EQU2_EQU_C2_BG
,
698 ATV_TOP_EQU2_EQU_C2_DK
,
699 ATV_TOP_EQU2_EQU_C2_I
},
700 /* shadow of ATV_TOP_EQU3__A */
702 ATV_TOP_EQU3_EQU_C3_FM
,
703 ATV_TOP_EQU3_EQU_C3_L
,
704 ATV_TOP_EQU3_EQU_C3_LP
,
705 ATV_TOP_EQU3_EQU_C3_BG
,
706 ATV_TOP_EQU3_EQU_C3_DK
,
707 ATV_TOP_EQU3_EQU_C3_I
},
708 false, /* flag: true=bypass */
709 ATV_TOP_VID_PEAK__PRE
, /* shadow of ATV_TOP_VID_PEAK__A */
710 ATV_TOP_NOISE_TH__PRE
, /* shadow of ATV_TOP_NOISE_TH__A */
711 true, /* flag CVBS ouput enable */
712 false, /* flag SIF ouput enable */
713 DRXJ_SIF_ATTENUATION_0DB
, /* current SIF att setting */
714 { /* qam_rf_agc_cfg */
715 DRX_STANDARD_ITU_B
, /* standard */
716 DRX_AGC_CTRL_AUTO
, /* ctrl_mode */
717 0, /* output_level */
718 0, /* min_output_level */
719 0xFFFF, /* max_output_level */
724 { /* qam_if_agc_cfg */
725 DRX_STANDARD_ITU_B
, /* standard */
726 DRX_AGC_CTRL_AUTO
, /* ctrl_mode */
727 0, /* output_level */
728 0, /* min_output_level */
729 0xFFFF, /* max_output_level */
731 0x0000, /* top (don't care) */
732 0x0000 /* c.o.c. (don't care) */
734 { /* vsb_rf_agc_cfg */
735 DRX_STANDARD_8VSB
, /* standard */
736 DRX_AGC_CTRL_AUTO
, /* ctrl_mode */
737 0, /* output_level */
738 0, /* min_output_level */
739 0xFFFF, /* max_output_level */
741 0x0000, /* top (don't care) */
742 0x0000 /* c.o.c. (don't care) */
744 { /* vsb_if_agc_cfg */
745 DRX_STANDARD_8VSB
, /* standard */
746 DRX_AGC_CTRL_AUTO
, /* ctrl_mode */
747 0, /* output_level */
748 0, /* min_output_level */
749 0xFFFF, /* max_output_level */
751 0x0000, /* top (don't care) */
752 0x0000 /* c.o.c. (don't care) */
756 { /* qam_pre_saw_cfg */
757 DRX_STANDARD_ITU_B
, /* standard */
759 false /* use_pre_saw */
761 { /* vsb_pre_saw_cfg */
762 DRX_STANDARD_8VSB
, /* standard */
764 false /* use_pre_saw */
767 /* Version information */
770 "01234567890", /* human readable version microcode */
771 "01234567890" /* human readable version device specific code */
774 { /* struct drx_version for microcode */
782 { /* struct drx_version for device specific code */
792 { /* struct drx_version_list for microcode */
793 (struct drx_version
*) (NULL
),
794 (struct drx_version_list
*) (NULL
)
796 { /* struct drx_version_list for device specific code */
797 (struct drx_version
*) (NULL
),
798 (struct drx_version_list
*) (NULL
)
802 false, /* smart_ant_inverted */
803 /* Tracking filter setting for OOB */
813 false, /* oob_power_on */
814 0, /* mpeg_ts_static_bitrate */
815 false, /* disable_te_ihandling */
816 false, /* bit_reverse_mpeg_outout */
817 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO
, /* mpeg_output_clock_rate */
818 DRXJ_MPEG_START_WIDTH_1CLKCYC
, /* mpeg_start_width */
820 /* Pre SAW & Agc configuration for ATV */
822 DRX_STANDARD_NTSC
, /* standard */
824 true /* use_pre_saw */
827 DRX_STANDARD_NTSC
, /* standard */
828 DRX_AGC_CTRL_AUTO
, /* ctrl_mode */
829 0, /* output_level */
830 0, /* min_output_level (d.c.) */
831 0, /* max_output_level (d.c.) */
834 4000 /* cut-off current */
837 DRX_STANDARD_NTSC
, /* standard */
838 DRX_AGC_CTRL_AUTO
, /* ctrl_mode */
839 0, /* output_level */
840 0, /* min_output_level (d.c.) */
841 0, /* max_output_level (d.c.) */
844 0 /* c.o.c. (d.c.) */
846 140, /* ATV PGA config */
847 0, /* curr_symbol_rate */
849 false, /* pdr_safe_mode */
850 SIO_PDR_GPIO_CFG__PRE
, /* pdr_safe_restore_val_gpio */
851 SIO_PDR_VSYNC_CFG__PRE
, /* pdr_safe_restore_val_v_sync */
852 SIO_PDR_SMA_RX_CFG__PRE
, /* pdr_safe_restore_val_sma_rx */
853 SIO_PDR_SMA_TX_CFG__PRE
, /* pdr_safe_restore_val_sma_tx */
856 DRXJ_OOB_LO_POW_MINUS10DB
, /* oob_lo_pow */
858 false /* aud_data, only first member */
863 * \var drxj_default_addr_g
864 * \brief Default I2C address and device identifier.
866 struct i2c_device_addr drxj_default_addr_g
= {
867 DRXJ_DEF_I2C_ADDR
, /* i2c address */
868 DRXJ_DEF_DEMOD_DEV_ID
/* device id */
872 * \var drxj_default_comm_attr_g
873 * \brief Default common attributes of a drxj demodulator instance.
875 struct drx_common_attr drxj_default_comm_attr_g
= {
876 NULL
, /* ucode file */
877 true, /* ucode verify switch */
878 {0}, /* version record */
880 44000, /* IF in kHz in case no tuner instance is used */
881 (151875 - 0), /* system clock frequency in kHz */
882 0, /* oscillator frequency kHz */
883 0, /* oscillator deviation in ppm, signed */
884 false, /* If true mirror frequency spectrum */
886 /* MPEG output configuration */
887 true, /* If true, enable MPEG ouput */
888 false, /* If true, insert RS byte */
889 true, /* If true, parallel out otherwise serial */
890 false, /* If true, invert DATA signals */
891 false, /* If true, invert ERR signal */
892 false, /* If true, invert STR signals */
893 false, /* If true, invert VAL signals */
894 false, /* If true, invert CLK signals */
895 true, /* If true, static MPEG clockrate will
896 be used, otherwise clockrate will
897 adapt to the bitrate of the TS */
898 19392658UL, /* Maximum bitrate in b/s in case
899 static clockrate is selected */
900 DRX_MPEG_STR_WIDTH_1
/* MPEG Start width in clock cycles */
902 /* Initilisations below can be ommited, they require no user input and
903 are initialy 0, NULL or false. The compiler will initialize them to these
904 values when ommited. */
905 false, /* is_opened */
908 NULL
, /* no scan params yet */
909 0, /* current scan index */
910 0, /* next scan frequency */
911 false, /* scan ready flag */
912 0, /* max channels to scan */
913 0, /* nr of channels scanned */
914 NULL
, /* default scan function */
915 NULL
, /* default context pointer */
916 0, /* millisec to wait for demod lock */
917 DRXJ_DEMOD_LOCK
, /* desired lock */
920 /* Power management */
924 1, /* nr of I2C port to wich tuner is */
925 0L, /* minimum RF input frequency, in kHz */
926 0L, /* maximum RF input frequency, in kHz */
927 false, /* Rf Agc Polarity */
928 false, /* If Agc Polarity */
929 false, /* tuner slow mode */
931 { /* current channel (all 0) */
932 0UL /* channel.frequency */
934 DRX_STANDARD_UNKNOWN
, /* current standard */
935 DRX_STANDARD_UNKNOWN
, /* previous standard */
936 DRX_STANDARD_UNKNOWN
, /* di_cache_standard */
937 false, /* use_bootloader */
938 0UL, /* capabilities */
943 * \var drxj_default_demod_g
944 * \brief Default drxj demodulator instance.
946 struct drx_demod_instance drxj_default_demod_g
= {
947 &DRXJ_DAP
, /* data access protocol functions */
948 &drxj_default_addr_g
, /* i2c address & device id */
949 &drxj_default_comm_attr_g
, /* demod common attributes */
950 &drxj_data_g
/* demod device specific attributes */
954 * \brief Default audio data structure for DRK demodulator instance.
956 * This structure is DRXK specific.
959 struct drx_aud_data drxj_default_aud_data_g
= {
960 false, /* audio_is_active */
961 DRX_AUD_STANDARD_AUTO
, /* audio_standard */
965 false, /* output_enable */
966 48000, /* frequency */
967 DRX_I2S_MODE_MASTER
, /* mode */
968 DRX_I2S_WORDLENGTH_32
, /* word_length */
969 DRX_I2S_POLARITY_RIGHT
, /* polarity */
970 DRX_I2S_FORMAT_WS_WITH_DATA
/* format */
976 DRX_AUD_AVC_OFF
, /* avc_mode */
977 0, /* avc_ref_level */
978 DRX_AUD_AVC_MAX_GAIN_12DB
, /* avc_max_gain */
979 DRX_AUD_AVC_MAX_ATTEN_24DB
, /* avc_max_atten */
980 0, /* strength_left */
981 0 /* strength_right */
983 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON
, /* auto_sound */
995 DRX_NO_CARRIER_NOISE
, /* opt */
1002 DRX_NO_CARRIER_MUTE
, /* opt */
1010 DRX_AUD_SRC_STEREO_OR_A
, /* source_i2s */
1011 DRX_AUD_I2S_MATRIX_STEREO
, /* matrix_i2s */
1012 DRX_AUD_FM_MATRIX_SOUND_A
/* matrix_fm */
1014 DRX_AUD_DEVIATION_NORMAL
, /* deviation */
1015 DRX_AUD_AVSYNC_OFF
, /* av_sync */
1019 DRX_AUD_MAX_FM_DEVIATION
, /* fm_deviation */
1020 DRX_AUD_MAX_NICAM_PRESCALE
/* nicam_gain */
1022 DRX_AUD_FM_DEEMPH_75US
, /* deemph */
1023 DRX_BTSC_STEREO
, /* btsc_detect */
1024 0, /* rds_data_counter */
1025 false /* rds_data_present */
1028 /*-----------------------------------------------------------------------------
1030 ----------------------------------------------------------------------------*/
1031 struct drxjeq_stat
{
1039 struct drxj_hi_cmd
{
1049 /*============================================================================*/
1050 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
1051 /*============================================================================*/
1054 * struct drxu_code_block_hdr - Structure of the microcode block headers
1056 * @addr: Destination address of the data in this block
1057 * @size: Size of the block data following this header counted in
1059 * @CRC: CRC value of the data block, only valid if CRC flag is
1062 struct drxu_code_block_hdr
{
1069 /*-----------------------------------------------------------------------------
1071 ----------------------------------------------------------------------------*/
1072 /* Some prototypes */
1074 hi_command(struct i2c_device_addr
*dev_addr
,
1075 const struct drxj_hi_cmd
*cmd
, u16
*result
);
1078 ctrl_lock_status(struct drx_demod_instance
*demod
, enum drx_lock_status
*lock_stat
);
1081 ctrl_power_mode(struct drx_demod_instance
*demod
, enum drx_power_mode
*mode
);
1083 static int power_down_aud(struct drx_demod_instance
*demod
);
1086 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
);
1093 ctrl_set_cfg_pre_saw(struct drx_demod_instance
*demod
, struct drxj_cfg_pre_saw
*pre_saw
);
1096 ctrl_set_cfg_afe_gain(struct drx_demod_instance
*demod
, struct drxj_cfg_afe_gain
*afe_gain
);
1098 /*============================================================================*/
1099 /*============================================================================*/
1100 /*== HELPER FUNCTIONS ==*/
1101 /*============================================================================*/
1102 /*============================================================================*/
1106 * \fn void mult32(u32 a, u32 b, u32 *h, u32 *l)
1107 * \brief 32bitsx32bits signed multiplication
1108 * \param a 32 bits multiplicant, typecast from signed to unisgned
1109 * \param b 32 bits multiplier, typecast from signed to unisgned
1110 * \param h pointer to high part 64 bits result, typecast from signed to unisgned
1111 * \param l pointer to low part 64 bits result
1113 * For the 2n+n addition a + b:
1114 * if a >= 0, then h += 0 (sign extension = 0)
1115 * but if a < 0, then h += 2^n-1 ==> h -= 1.
1117 * Also, if a + b < 2^n, then a + b >= a && a + b >= b
1118 * but if a + b >= 2^n, then R = a + b - 2^n,
1119 * and because a < 2^n && b < 2*n ==> R < a && R < b.
1120 * Therefore, to detect overflow, simply compare the addition result with
1121 * one of the operands; if the result is smaller, overflow has occurred and
1122 * h must be incremented.
1124 * Booth multiplication uses additions and subtractions to reduce the number
1125 * of iterations. This is done by taking three subsequent bits abc and calculating
1126 * the following multiplication factor: -2a + b + c. This factor is multiplied
1127 * by the second operand and added to the result. Next, the first operand is
1128 * shifted two bits (hence one of the three bits is reused) and the process
1129 * repeated. The last iteration has only two bits left, but we simply add
1130 * a zero to the end.
1133 * 1 * a = 0 * 4a + 1 * a
1134 * 2 * a = 1 * 4a - 2 * a
1135 * 3 * a = 1 * 4a - 1 * a
1136 * -1 * a = 0 * 4a - 1 * a
1137 * -5 * a = -1 * 4a - 1 * a
1141 * Note that the function is type size independent. Any unsigned integer type
1142 * can be substituted for booth_t.
1146 #define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof(u32) * 8 - 1))) != 0)
1148 static void mult32(u32 a
, u32 b
, u32
*h
, u32
*l
)
1153 /* n/2 iterations; shift operand a left two bits after each iteration. */
1154 /* This automatically appends a zero to the operand for the last iteration. */
1155 for (i
= 0; i
< sizeof(a
) * 8; i
+= 2, a
= a
<< 2) {
1156 /* Shift result left two bits */
1157 *h
= (*h
<< 2) + (*l
>> (sizeof(*l
) * 8 - 2));
1160 /* Take the first three bits of operand a for the Booth conversion: */
1161 /* 0, 7: do nothing */
1164 /* 4 : subtract 2b */
1165 /* 5, 6: subtract b */
1166 switch (a
>> (sizeof(a
) * 8 - 3)) {
1169 *h
= *h
- DRX_IS_BOOTH_NEGATIVE(b
) + (*l
< b
);
1173 *h
= *h
- DRX_IS_BOOTH_NEGATIVE(b
) + (*l
< b
);
1177 *h
= *h
- !DRX_IS_BOOTH_NEGATIVE(b
) + !b
+ (*l
<
1185 *h
= *h
- !DRX_IS_BOOTH_NEGATIVE(b
) + !b
+ (*l
<
1196 /*============================================================================*/
1199 * \fn u32 frac28(u32 N, u32 D)
1200 * \brief Compute: (1<<28)*N/D
1203 * \return (1<<28)*N/D
1204 * This function is used to avoid floating-point calculations as they may
1205 * not be present on the target platform.
1207 * frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1208 * fraction used for setting the Frequency Shifter registers.
1209 * N and D can hold numbers up to width: 28-bits.
1210 * The 4 bits integer part and the 28 bits fractional part are calculated.
1212 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1214 * N: 0...(1<<28)-1 = 268435454
1218 static u32
frac28(u32 N
, u32 D
)
1224 R0
= (N
% D
) << 4; /* 32-28 == 4 shifts possible at max */
1225 Q1
= N
/ D
; /* integer part, only the 4 least significant bits
1226 will be visible in the result */
1228 /* division using radix 16, 7 nibbles in the result */
1229 for (i
= 0; i
< 7; i
++) {
1230 Q1
= (Q1
<< 4) | R0
/ D
;
1241 * \fn u32 log1_times100( u32 x)
1242 * \brief Compute: 100*log10(x)
1244 * \return 100*log10(x)
1247 * = 100*(log2(x)/log2(10)))
1248 * = (100*(2^15)*log2(x))/((2^15)*log2(10))
1249 * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1250 * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1251 * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1253 * where y = 2^k and 1<= (x/y) < 2
1256 static u32
log1_times100(u32 x
)
1258 static const u8 scale
= 15;
1259 static const u8 index_width
= 5;
1261 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1262 0 <= n < ((1<<INDEXWIDTH)+1)
1265 static const u32 log2lut
[] = {
1267 290941, /* 290941.300628 */
1268 573196, /* 573196.476418 */
1269 847269, /* 847269.179851 */
1270 1113620, /* 1113620.489452 */
1271 1372674, /* 1372673.576986 */
1272 1624818, /* 1624817.752104 */
1273 1870412, /* 1870411.981536 */
1274 2109788, /* 2109787.962654 */
1275 2343253, /* 2343252.817465 */
1276 2571091, /* 2571091.461923 */
1277 2793569, /* 2793568.696416 */
1278 3010931, /* 3010931.055901 */
1279 3223408, /* 3223408.452106 */
1280 3431216, /* 3431215.635215 */
1281 3634553, /* 3634553.498355 */
1282 3833610, /* 3833610.244726 */
1283 4028562, /* 4028562.434393 */
1284 4219576, /* 4219575.925308 */
1285 4406807, /* 4406806.721144 */
1286 4590402, /* 4590401.736809 */
1287 4770499, /* 4770499.491025 */
1288 4947231, /* 4947230.734179 */
1289 5120719, /* 5120719.018555 */
1290 5291081, /* 5291081.217197 */
1291 5458428, /* 5458427.996830 */
1292 5622864, /* 5622864.249668 */
1293 5784489, /* 5784489.488298 */
1294 5943398, /* 5943398.207380 */
1295 6099680, /* 6099680.215452 */
1296 6253421, /* 6253420.939751 */
1297 6404702, /* 6404701.706649 */
1298 6553600, /* 6553600.000000 */
1310 /* Scale x (normalize) */
1311 /* computing y in log(x/y) = log(x) - log(y) */
1312 if ((x
& (((u32
) (-1)) << (scale
+ 1))) == 0) {
1313 for (k
= scale
; k
> 0; k
--) {
1314 if (x
& (((u32
) 1) << scale
))
1319 for (k
= scale
; k
< 31; k
++) {
1320 if ((x
& (((u32
) (-1)) << (scale
+ 1))) == 0)
1326 Now x has binary point between bit[scale] and bit[scale-1]
1327 and 1.0 <= x < 2.0 */
1329 /* correction for divison: log(x) = log(x/y)+log(y) */
1330 y
= k
* ((((u32
) 1) << scale
) * 200);
1332 /* remove integer part */
1333 x
&= ((((u32
) 1) << scale
) - 1);
1335 i
= (u8
) (x
>> (scale
- index_width
));
1336 /* compute delta (x-a) */
1337 d
= x
& ((((u32
) 1) << (scale
- index_width
)) - 1);
1338 /* compute log, multiplication ( d* (.. )) must be within range ! */
1340 ((d
* (log2lut
[i
+ 1] - log2lut
[i
])) >> (scale
- index_width
));
1341 /* Conver to log10() */
1342 y
/= 108853; /* (log2(10) << scale) */
1353 * \fn u32 frac_times1e6( u16 N, u32 D)
1354 * \brief Compute: (N/D) * 1000000.
1355 * \param N nominator 16-bits.
1356 * \param D denominator 32-bits.
1358 * \retval ((N/D) * 1000000), 32 bits
1362 static u32
frac_times1e6(u32 N
, u32 D
)
1368 frac = (N * 1000000) / D
1369 To let it fit in a 32 bits computation:
1370 frac = (N * (1000000 >> 4)) / (D >> 4)
1371 This would result in a problem in case D < 16 (div by 0).
1372 So we do it more elaborate as shown below.
1374 frac
= (((u32
) N
) * (1000000 >> 4)) / D
;
1376 remainder
= (((u32
) N
) * (1000000 >> 4)) % D
;
1378 frac
+= remainder
/ D
;
1379 remainder
= remainder
% D
;
1380 if ((remainder
* 2) > D
)
1386 /*============================================================================*/
1390 * \brief Compute: 100 * 10^( gd_b / 200 ).
1391 * \param u32 gd_b Gain in 0.1dB
1392 * \return u32 Gainfactor in 0.01 resolution
1395 static u32
d_b2lin_times100(u32 gd_b
)
1398 u32 nr6d_b_steps
= 0;
1400 u32 remainder_fac
= 0;
1402 /* start with factors 2 (6.02dB) */
1403 nr6d_b_steps
= gd_b
* 1000UL / 60206UL;
1404 if (nr6d_b_steps
> 17) {
1405 /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
1408 result
= (1 << nr6d_b_steps
);
1410 /* calculate remaining factor,
1411 poly approximation of 10^(gd_b/200):
1413 y = 1E-04x2 + 0.0106x + 1.0026
1415 max deviation < 0.005 for range x = [0 ... 60]
1417 remainder
= ((gd_b
* 1000UL) % 60206UL) / 1000UL;
1418 /* using 1e-4 for poly calculation */
1419 remainder_fac
= 1 * remainder
* remainder
;
1420 remainder_fac
+= 106 * remainder
;
1421 remainder_fac
+= 10026;
1423 /* multiply by remaining factor */
1424 result
*= remainder_fac
;
1426 /* conversion from 1e-4 to 1e-2 */
1427 return (result
+ 50) / 100;
1430 #define FRAC_FLOOR 0
1432 #define FRAC_ROUND 2
1434 * \fn u32 frac( u32 N, u32 D, u16 RC )
1435 * \brief Compute: N/D.
1436 * \param N nominator 32-bits.
1437 * \param D denominator 32-bits.
1438 * \param RC-result correction: 0-floor; 1-ceil; 2-round
1440 * \retval N/D, 32 bits
1444 static u32
frac(u32 N
, u32 D
, u16 RC
)
1463 while (bit_cnt
-- > 0) {
1465 remainder
|= ((frac
& 0x80000000) >> 31);
1467 if (remainder
< D
) {
1475 /* result correction if needed */
1476 if ((RC
== FRAC_CEIL
) && (remainder
!= 0)) {
1477 /* ceil the result */
1478 /*(remainder is not zero -> value behind decimal point exists) */
1481 if ((RC
== FRAC_ROUND
) && (remainder
>= D
>> 1)) {
1482 /* remainder is bigger from D/2 -> round the result */
1492 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1493 * and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1496 static const u16 nicam_presc_table_val
[43] = {
1497 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1498 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1499 18, 20, 23, 25, 28, 32, 36, 40, 45,
1500 51, 57, 64, 71, 80, 90, 101, 113, 127
1503 /*============================================================================*/
1504 /*== END HELPER FUNCTIONS ==*/
1505 /*============================================================================*/
1507 /*============================================================================*/
1508 /*============================================================================*/
1509 /*== DRXJ DAP FUNCTIONS ==*/
1510 /*============================================================================*/
1511 /*============================================================================*/
1514 This layer takes care of some device specific register access protocols:
1515 -conversion to short address format
1516 -access to audio block
1517 This layer is placed between the drx_dap_fasi and the rest of the drxj
1518 specific implementation. This layer can use address map knowledge whereas
1519 dap_fasi may not use memory map knowledge.
1521 * For audio currently only 16 bits read and write register access is
1522 supported. More is not needed. RMW and 32 or 8 bit access on audio
1523 registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1524 single/multi master) will be ignored.
1526 TODO: check ignoring single/multimaster is ok for AUD access ?
1529 #define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1530 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
1531 /*============================================================================*/
1534 * \fn bool is_handled_by_aud_tr_if( u32 addr )
1535 * \brief Check if this address is handled by the audio token ring interface.
1538 * \retval true Yes, handled by audio token ring interface
1539 * \retval false No, not handled by audio token ring interface
1543 bool is_handled_by_aud_tr_if(u32 addr
)
1545 bool retval
= false;
1547 if ((DRXDAP_FASI_ADDR2BLOCK(addr
) == 4) &&
1548 (DRXDAP_FASI_ADDR2BANK(addr
) > 1) &&
1549 (DRXDAP_FASI_ADDR2BANK(addr
) < 6)) {
1556 /*============================================================================*/
1558 static int drxj_dap_read_block(struct i2c_device_addr
*dev_addr
,
1561 u8
*data
, u32 flags
)
1563 return drx_dap_fasi_funct_g
.read_block_func(dev_addr
,
1564 addr
, datasize
, data
, flags
);
1567 /*============================================================================*/
1569 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr
*dev_addr
,
1572 u8 wdata
, u8
*rdata
)
1574 return drx_dap_fasi_funct_g
.read_modify_write_reg8func(dev_addr
,
1576 raddr
, wdata
, rdata
);
1579 /*============================================================================*/
1582 * \fn int drxj_dap_rm_write_reg16short
1583 * \brief Read modify write 16 bits audio register using short format only.
1585 * \param waddr Address to write to
1586 * \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1587 * \param wdata Data to write
1588 * \param rdata Buffer for data to read
1591 * \retval -EIO Timeout, I2C error, illegal bank
1593 * 16 bits register read modify write access using short addressing format only.
1594 * Requires knowledge of the registermap, thus device dependent.
1595 * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1599 /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1600 See comments drxj_dap_read_modify_write_reg16 */
1601 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
1602 static int drxj_dap_rm_write_reg16short(struct i2c_device_addr
*dev_addr
,
1605 u16 wdata
, u16
*rdata
)
1613 rc
= drx_dap_fasi_funct_g
.write_reg16func(dev_addr
,
1614 SIO_HI_RA_RAM_S0_FLG_ACC__A
,
1615 SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M
,
1618 /* Write new data: triggers RMW */
1619 rc
= drx_dap_fasi_funct_g
.write_reg16func(dev_addr
, waddr
, wdata
,
1624 rc
= drx_dap_fasi_funct_g
.read_reg16func(dev_addr
, raddr
, rdata
,
1628 /* Reset RMW flag */
1629 rc
= drx_dap_fasi_funct_g
.write_reg16func(dev_addr
,
1630 SIO_HI_RA_RAM_S0_FLG_ACC__A
,
1638 /*============================================================================*/
1640 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr
*dev_addr
,
1643 u16 wdata
, u16
*rdata
)
1645 /* TODO: correct short/long addressing format decision,
1646 now long format has higher prio then short because short also
1647 needs virt bnks (not impl yet) for certain audio registers */
1648 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1649 return drx_dap_fasi_funct_g
.read_modify_write_reg16func(dev_addr
,
1651 raddr
, wdata
, rdata
);
1653 return drxj_dap_rm_write_reg16short(dev_addr
, waddr
, raddr
, wdata
, rdata
);
1657 /*============================================================================*/
1659 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr
*dev_addr
,
1662 u32 wdata
, u32
*rdata
)
1664 return drx_dap_fasi_funct_g
.read_modify_write_reg32func(dev_addr
,
1666 raddr
, wdata
, rdata
);
1669 /*============================================================================*/
1671 static int drxj_dap_read_reg8(struct i2c_device_addr
*dev_addr
,
1673 u8
*data
, u32 flags
)
1675 return drx_dap_fasi_funct_g
.read_reg8func(dev_addr
, addr
, data
, flags
);
1678 /*============================================================================*/
1681 * \fn int drxj_dap_read_aud_reg16
1682 * \brief Read 16 bits audio register
1688 * \retval -EIO Timeout, I2C error, illegal bank
1690 * 16 bits register read access via audio token ring interface.
1693 static int drxj_dap_read_aud_reg16(struct i2c_device_addr
*dev_addr
,
1694 u32 addr
, u16
*data
)
1696 u32 start_timer
= 0;
1697 u32 current_timer
= 0;
1698 u32 delta_timer
= 0;
1702 /* No read possible for bank 3, return with error */
1703 if (DRXDAP_FASI_ADDR2BANK(addr
) == 3) {
1706 const u32 write_bit
= ((dr_xaddr_t
) 1) << 16;
1708 /* Force reset write bit */
1709 addr
&= (~write_bit
);
1712 start_timer
= jiffies_to_msecs(jiffies
);
1714 /* RMW to aud TR IF until request is granted or timeout */
1715 stat
= drxj_dap_read_modify_write_reg16(dev_addr
,
1717 SIO_HI_RA_RAM_S0_RMWBUF__A
,
1718 0x0000, &tr_status
);
1723 current_timer
= jiffies_to_msecs(jiffies
);
1724 delta_timer
= current_timer
- start_timer
;
1725 if (delta_timer
> DRXJ_DAP_AUDTRIF_TIMEOUT
) {
1730 } while (((tr_status
& AUD_TOP_TR_CTR_FIFO_LOCK__M
) ==
1731 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED
) ||
1732 ((tr_status
& AUD_TOP_TR_CTR_FIFO_FULL__M
) ==
1733 AUD_TOP_TR_CTR_FIFO_FULL_FULL
));
1734 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1736 /* Wait for read ready status or timeout */
1738 start_timer
= jiffies_to_msecs(jiffies
);
1740 while ((tr_status
& AUD_TOP_TR_CTR_FIFO_RD_RDY__M
) !=
1741 AUD_TOP_TR_CTR_FIFO_RD_RDY_READY
) {
1742 stat
= drxj_dap_read_reg16(dev_addr
,
1744 &tr_status
, 0x0000);
1748 current_timer
= jiffies_to_msecs(jiffies
);
1749 delta_timer
= current_timer
- start_timer
;
1750 if (delta_timer
> DRXJ_DAP_AUDTRIF_TIMEOUT
) {
1754 } /* while ( ... ) */
1759 stat
= drxj_dap_read_modify_write_reg16(dev_addr
,
1760 AUD_TOP_TR_RD_REG__A
,
1761 SIO_HI_RA_RAM_S0_RMWBUF__A
,
1766 /*============================================================================*/
1768 static int drxj_dap_read_reg16(struct i2c_device_addr
*dev_addr
,
1770 u16
*data
, u32 flags
)
1775 if ((dev_addr
== NULL
) || (data
== NULL
))
1778 if (is_handled_by_aud_tr_if(addr
))
1779 stat
= drxj_dap_read_aud_reg16(dev_addr
, addr
, data
);
1781 stat
= drx_dap_fasi_funct_g
.read_reg16func(dev_addr
,
1787 /*============================================================================*/
1789 static int drxj_dap_read_reg32(struct i2c_device_addr
*dev_addr
,
1791 u32
*data
, u32 flags
)
1793 return drx_dap_fasi_funct_g
.read_reg32func(dev_addr
, addr
, data
, flags
);
1796 /*============================================================================*/
1798 static int drxj_dap_write_block(struct i2c_device_addr
*dev_addr
,
1801 u8
*data
, u32 flags
)
1803 return drx_dap_fasi_funct_g
.write_block_func(dev_addr
,
1804 addr
, datasize
, data
, flags
);
1807 /*============================================================================*/
1809 static int drxj_dap_write_reg8(struct i2c_device_addr
*dev_addr
,
1813 return drx_dap_fasi_funct_g
.write_reg8func(dev_addr
, addr
, data
, flags
);
1816 /*============================================================================*/
1819 * \fn int drxj_dap_write_aud_reg16
1820 * \brief Write 16 bits audio register
1826 * \retval -EIO Timeout, I2C error, illegal bank
1828 * 16 bits register write access via audio token ring interface.
1831 static int drxj_dap_write_aud_reg16(struct i2c_device_addr
*dev_addr
,
1836 /* No write possible for bank 2, return with error */
1837 if (DRXDAP_FASI_ADDR2BANK(addr
) == 2) {
1840 u32 start_timer
= 0;
1841 u32 current_timer
= 0;
1842 u32 delta_timer
= 0;
1844 const u32 write_bit
= ((dr_xaddr_t
) 1) << 16;
1846 /* Force write bit */
1848 start_timer
= jiffies_to_msecs(jiffies
);
1850 /* RMW to aud TR IF until request is granted or timeout */
1851 stat
= drxj_dap_read_modify_write_reg16(dev_addr
,
1853 SIO_HI_RA_RAM_S0_RMWBUF__A
,
1858 current_timer
= jiffies_to_msecs(jiffies
);
1859 delta_timer
= current_timer
- start_timer
;
1860 if (delta_timer
> DRXJ_DAP_AUDTRIF_TIMEOUT
) {
1865 } while (((tr_status
& AUD_TOP_TR_CTR_FIFO_LOCK__M
) ==
1866 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED
) ||
1867 ((tr_status
& AUD_TOP_TR_CTR_FIFO_FULL__M
) ==
1868 AUD_TOP_TR_CTR_FIFO_FULL_FULL
));
1870 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
1875 /*============================================================================*/
1877 static int drxj_dap_write_reg16(struct i2c_device_addr
*dev_addr
,
1879 u16 data
, u32 flags
)
1884 if (dev_addr
== NULL
)
1887 if (is_handled_by_aud_tr_if(addr
))
1888 stat
= drxj_dap_write_aud_reg16(dev_addr
, addr
, data
);
1890 stat
= drx_dap_fasi_funct_g
.write_reg16func(dev_addr
,
1896 /*============================================================================*/
1898 static int drxj_dap_write_reg32(struct i2c_device_addr
*dev_addr
,
1900 u32 data
, u32 flags
)
1902 return drx_dap_fasi_funct_g
.write_reg32func(dev_addr
, addr
, data
, flags
);
1905 /*============================================================================*/
1907 /* Free data ram in SIO HI */
1908 #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
1909 #define SIO_HI_RA_RAM_USR_END__A 0x420060
1911 #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
1912 #define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
1913 #define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
1914 #define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
1917 * \fn int drxj_dap_atomic_read_write_block()
1918 * \brief Basic access routine for atomic read or write access
1919 * \param dev_addr pointer to i2c dev address
1920 * \param addr destination/source address
1921 * \param datasize size of data buffer in bytes
1922 * \param data pointer to data buffer
1925 * \retval -EIO Timeout, I2C error, illegal bank
1929 int drxj_dap_atomic_read_write_block(struct i2c_device_addr
*dev_addr
,
1932 u8
*data
, bool read_flag
)
1934 struct drxj_hi_cmd hi_cmd
;
1940 /* Parameter check */
1941 if (!data
|| !dev_addr
|| ((datasize
% 2)) || ((datasize
/ 2) > 8))
1944 /* Set up HI parameters to read or write n bytes */
1945 hi_cmd
.cmd
= SIO_HI_RA_RAM_CMD_ATOMIC_COPY
;
1947 (u16
) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START
) << 6) +
1948 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START
));
1950 (u16
) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START
);
1951 hi_cmd
.param3
= (u16
) ((datasize
/ 2) - 1);
1953 hi_cmd
.param3
|= DRXJ_HI_ATOMIC_WRITE
;
1955 hi_cmd
.param3
|= DRXJ_HI_ATOMIC_READ
;
1956 hi_cmd
.param4
= (u16
) ((DRXDAP_FASI_ADDR2BLOCK(addr
) << 6) +
1957 DRXDAP_FASI_ADDR2BANK(addr
));
1958 hi_cmd
.param5
= (u16
) DRXDAP_FASI_ADDR2OFFSET(addr
);
1961 /* write data to buffer */
1962 for (i
= 0; i
< (datasize
/ 2); i
++) {
1964 word
= ((u16
) data
[2 * i
]);
1965 word
+= (((u16
) data
[(2 * i
) + 1]) << 8);
1966 drxj_dap_write_reg16(dev_addr
,
1967 (DRXJ_HI_ATOMIC_BUF_START
+ i
),
1972 rc
= hi_command(dev_addr
, &hi_cmd
, &dummy
);
1974 pr_err("error %d\n", rc
);
1979 /* read data from buffer */
1980 for (i
= 0; i
< (datasize
/ 2); i
++) {
1981 drxj_dap_read_reg16(dev_addr
,
1982 (DRXJ_HI_ATOMIC_BUF_START
+ i
),
1984 data
[2 * i
] = (u8
) (word
& 0xFF);
1985 data
[(2 * i
) + 1] = (u8
) (word
>> 8);
1996 /*============================================================================*/
1999 * \fn int drxj_dap_atomic_read_reg32()
2000 * \brief Atomic read of 32 bits words
2003 int drxj_dap_atomic_read_reg32(struct i2c_device_addr
*dev_addr
,
2005 u32
*data
, u32 flags
)
2007 u8 buf
[sizeof(*data
)];
2014 rc
= drxj_dap_atomic_read_write_block(dev_addr
, addr
,
2015 sizeof(*data
), buf
, true);
2020 word
= (u32
) buf
[3];
2022 word
|= (u32
) buf
[2];
2024 word
|= (u32
) buf
[1];
2026 word
|= (u32
) buf
[0];
2033 /*============================================================================*/
2035 /*============================================================================*/
2036 /*== END DRXJ DAP FUNCTIONS ==*/
2037 /*============================================================================*/
2039 /*============================================================================*/
2040 /*============================================================================*/
2041 /*== HOST INTERFACE FUNCTIONS ==*/
2042 /*============================================================================*/
2043 /*============================================================================*/
2046 * \fn int hi_cfg_command()
2047 * \brief Configure HI with settings stored in the demod structure.
2048 * \param demod Demodulator.
2051 * This routine was created because to much orthogonal settings have
2052 * been put into one HI API function (configure). Especially the I2C bridge
2053 * enable/disable should not need re-configuration of the HI.
2056 static int hi_cfg_command(const struct drx_demod_instance
*demod
)
2058 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
2059 struct drxj_hi_cmd hi_cmd
;
2063 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
2065 hi_cmd
.cmd
= SIO_HI_RA_RAM_CMD_CONFIG
;
2066 hi_cmd
.param1
= SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY
;
2067 hi_cmd
.param2
= ext_attr
->hi_cfg_timing_div
;
2068 hi_cmd
.param3
= ext_attr
->hi_cfg_bridge_delay
;
2069 hi_cmd
.param4
= ext_attr
->hi_cfg_wake_up_key
;
2070 hi_cmd
.param5
= ext_attr
->hi_cfg_ctrl
;
2071 hi_cmd
.param6
= ext_attr
->hi_cfg_transmit
;
2073 rc
= hi_command(demod
->my_i2c_dev_addr
, &hi_cmd
, &result
);
2075 pr_err("error %d\n", rc
);
2079 /* Reset power down flag (set one call only) */
2080 ext_attr
->hi_cfg_ctrl
&= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ
));
2089 * \fn int hi_command()
2090 * \brief Configure HI with settings stored in the demod structure.
2091 * \param dev_addr I2C address.
2092 * \param cmd HI command.
2093 * \param result HI command result.
2096 * Sends command to HI
2100 hi_command(struct i2c_device_addr
*dev_addr
, const struct drxj_hi_cmd
*cmd
, u16
*result
)
2104 bool powerdown_cmd
= false;
2107 /* Write parameters */
2110 case SIO_HI_RA_RAM_CMD_CONFIG
:
2111 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY
:
2112 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_HI_RA_RAM_PAR_6__A
, cmd
->param6
, 0);
2114 pr_err("error %d\n", rc
);
2117 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_HI_RA_RAM_PAR_5__A
, cmd
->param5
, 0);
2119 pr_err("error %d\n", rc
);
2122 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_HI_RA_RAM_PAR_4__A
, cmd
->param4
, 0);
2124 pr_err("error %d\n", rc
);
2127 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_HI_RA_RAM_PAR_3__A
, cmd
->param3
, 0);
2129 pr_err("error %d\n", rc
);
2133 case SIO_HI_RA_RAM_CMD_BRDCTRL
:
2134 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_HI_RA_RAM_PAR_2__A
, cmd
->param2
, 0);
2136 pr_err("error %d\n", rc
);
2139 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_HI_RA_RAM_PAR_1__A
, cmd
->param1
, 0);
2141 pr_err("error %d\n", rc
);
2145 case SIO_HI_RA_RAM_CMD_NULL
:
2155 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_HI_RA_RAM_CMD__A
, cmd
->cmd
, 0);
2157 pr_err("error %d\n", rc
);
2161 if ((cmd
->cmd
) == SIO_HI_RA_RAM_CMD_RESET
)
2164 /* Detect power down to ommit reading result */
2165 powerdown_cmd
= (bool) ((cmd
->cmd
== SIO_HI_RA_RAM_CMD_CONFIG
) &&
2167 param5
) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M
)
2168 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ
));
2169 if (!powerdown_cmd
) {
2170 /* Wait until command rdy */
2173 if (nr_retries
> DRXJ_MAX_RETRIES
) {
2174 pr_err("timeout\n");
2178 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_HI_RA_RAM_CMD__A
, &wait_cmd
, 0);
2180 pr_err("error %d\n", rc
);
2183 } while (wait_cmd
!= 0);
2186 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_HI_RA_RAM_RES__A
, result
, 0);
2188 pr_err("error %d\n", rc
);
2193 /* if ( powerdown_cmd == true ) */
2200 * \fn int init_hi( const struct drx_demod_instance *demod )
2201 * \brief Initialise and configurate HI.
2202 * \param demod pointer to demod data.
2203 * \return int Return status.
2204 * \retval 0 Success.
2205 * \retval -EIO Failure.
2207 * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2208 * Need to store configuration in driver because of the way I2C
2209 * bridging is controlled.
2212 static int init_hi(const struct drx_demod_instance
*demod
)
2214 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
2215 struct drx_common_attr
*common_attr
= (struct drx_common_attr
*) (NULL
);
2216 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
2219 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
2220 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
2221 dev_addr
= demod
->my_i2c_dev_addr
;
2223 /* PATCH for bug 5003, HI ucode v3.1.0 */
2224 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, 0x4301D7, 0x801, 0);
2226 pr_err("error %d\n", rc
);
2230 /* Timing div, 250ns/Psys */
2231 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2232 ext_attr
->hi_cfg_timing_div
=
2233 (u16
) ((common_attr
->sys_clock_freq
/ 1000) * HI_I2C_DELAY
) / 1000;
2235 if ((ext_attr
->hi_cfg_timing_div
) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M
)
2236 ext_attr
->hi_cfg_timing_div
= SIO_HI_RA_RAM_PAR_2_CFG_DIV__M
;
2237 /* Bridge delay, uses oscilator clock */
2238 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2239 /* SDA brdige delay */
2240 ext_attr
->hi_cfg_bridge_delay
=
2241 (u16
) ((common_attr
->osc_clock_freq
/ 1000) * HI_I2C_BRIDGE_DELAY
) /
2244 if ((ext_attr
->hi_cfg_bridge_delay
) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M
)
2245 ext_attr
->hi_cfg_bridge_delay
= SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M
;
2246 /* SCL bridge delay, same as SDA for now */
2247 ext_attr
->hi_cfg_bridge_delay
+= ((ext_attr
->hi_cfg_bridge_delay
) <<
2248 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B
);
2249 /* Wakeup key, setting the read flag (as suggest in the documentation) does
2250 not always result into a working solution (barebones worked VI2C failed).
2251 Not setting the bit works in all cases . */
2252 ext_attr
->hi_cfg_wake_up_key
= DRXJ_WAKE_UP_KEY
;
2253 /* port/bridge/power down ctrl */
2254 ext_attr
->hi_cfg_ctrl
= (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE
);
2255 /* transit mode time out delay and watch dog divider */
2256 ext_attr
->hi_cfg_transmit
= SIO_HI_RA_RAM_PAR_6__PRE
;
2258 rc
= hi_cfg_command(demod
);
2260 pr_err("error %d\n", rc
);
2270 /*============================================================================*/
2271 /*== END HOST INTERFACE FUNCTIONS ==*/
2272 /*============================================================================*/
2274 /*============================================================================*/
2275 /*============================================================================*/
2276 /*== AUXILIARY FUNCTIONS ==*/
2277 /*============================================================================*/
2278 /*============================================================================*/
2281 * \fn int get_device_capabilities()
2282 * \brief Get and store device capabilities.
2283 * \param demod Pointer to demodulator instance.
2286 * \retval -EIO Failure
2288 * Depending on pulldowns on MDx pins the following internals are set:
2289 * * common_attr->osc_clock_freq
2290 * * ext_attr->has_lna
2291 * * ext_attr->has_ntsc
2292 * * ext_attr->has_btsc
2293 * * ext_attr->has_oob
2296 static int get_device_capabilities(struct drx_demod_instance
*demod
)
2298 struct drx_common_attr
*common_attr
= (struct drx_common_attr
*) (NULL
);
2299 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
2300 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
2301 u16 sio_pdr_ohw_cfg
= 0;
2302 u32 sio_top_jtagid_lo
= 0;
2306 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
2307 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
2308 dev_addr
= demod
->my_i2c_dev_addr
;
2310 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
2312 pr_err("error %d\n", rc
);
2315 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_PDR_OHW_CFG__A
, &sio_pdr_ohw_cfg
, 0);
2317 pr_err("error %d\n", rc
);
2320 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY__PRE
, 0);
2322 pr_err("error %d\n", rc
);
2326 switch ((sio_pdr_ohw_cfg
& SIO_PDR_OHW_CFG_FREF_SEL__M
)) {
2328 /* ignore (bypass ?) */
2332 common_attr
->osc_clock_freq
= 27000;
2336 common_attr
->osc_clock_freq
= 20250;
2340 common_attr
->osc_clock_freq
= 4000;
2347 Determine device capabilities
2348 Based on pinning v47
2350 rc
= DRXJ_DAP
.read_reg32func(dev_addr
, SIO_TOP_JTAGID_LO__A
, &sio_top_jtagid_lo
, 0);
2352 pr_err("error %d\n", rc
);
2355 ext_attr
->mfx
= (u8
) ((sio_top_jtagid_lo
>> 29) & 0xF);
2357 switch ((sio_top_jtagid_lo
>> 12) & 0xFF) {
2359 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
2361 pr_err("error %d\n", rc
);
2364 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_PDR_UIO_IN_HI__A
, &bid
, 0);
2366 pr_err("error %d\n", rc
);
2369 bid
= (bid
>> 10) & 0xf;
2370 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY__PRE
, 0);
2372 pr_err("error %d\n", rc
);
2376 ext_attr
->has_lna
= true;
2377 ext_attr
->has_ntsc
= false;
2378 ext_attr
->has_btsc
= false;
2379 ext_attr
->has_oob
= false;
2380 ext_attr
->has_smatx
= true;
2381 ext_attr
->has_smarx
= false;
2382 ext_attr
->has_gpio
= false;
2383 ext_attr
->has_irqn
= false;
2386 ext_attr
->has_lna
= false;
2387 ext_attr
->has_ntsc
= false;
2388 ext_attr
->has_btsc
= false;
2389 ext_attr
->has_oob
= false;
2390 ext_attr
->has_smatx
= true;
2391 ext_attr
->has_smarx
= false;
2392 ext_attr
->has_gpio
= false;
2393 ext_attr
->has_irqn
= false;
2396 ext_attr
->has_lna
= true;
2397 ext_attr
->has_ntsc
= true;
2398 ext_attr
->has_btsc
= false;
2399 ext_attr
->has_oob
= false;
2400 ext_attr
->has_smatx
= true;
2401 ext_attr
->has_smarx
= true;
2402 ext_attr
->has_gpio
= true;
2403 ext_attr
->has_irqn
= false;
2406 ext_attr
->has_lna
= false;
2407 ext_attr
->has_ntsc
= true;
2408 ext_attr
->has_btsc
= false;
2409 ext_attr
->has_oob
= false;
2410 ext_attr
->has_smatx
= true;
2411 ext_attr
->has_smarx
= true;
2412 ext_attr
->has_gpio
= true;
2413 ext_attr
->has_irqn
= false;
2416 ext_attr
->has_lna
= true;
2417 ext_attr
->has_ntsc
= true;
2418 ext_attr
->has_btsc
= true;
2419 ext_attr
->has_oob
= false;
2420 ext_attr
->has_smatx
= true;
2421 ext_attr
->has_smarx
= true;
2422 ext_attr
->has_gpio
= true;
2423 ext_attr
->has_irqn
= false;
2426 ext_attr
->has_lna
= false;
2427 ext_attr
->has_ntsc
= true;
2428 ext_attr
->has_btsc
= true;
2429 ext_attr
->has_oob
= false;
2430 ext_attr
->has_smatx
= true;
2431 ext_attr
->has_smarx
= true;
2432 ext_attr
->has_gpio
= true;
2433 ext_attr
->has_irqn
= false;
2436 ext_attr
->has_lna
= true;
2437 ext_attr
->has_ntsc
= false;
2438 ext_attr
->has_btsc
= false;
2439 ext_attr
->has_oob
= true;
2440 ext_attr
->has_smatx
= true;
2441 ext_attr
->has_smarx
= true;
2442 ext_attr
->has_gpio
= true;
2443 ext_attr
->has_irqn
= true;
2446 ext_attr
->has_lna
= false;
2447 ext_attr
->has_ntsc
= true;
2448 ext_attr
->has_btsc
= true;
2449 ext_attr
->has_oob
= true;
2450 ext_attr
->has_smatx
= true;
2451 ext_attr
->has_smarx
= true;
2452 ext_attr
->has_gpio
= true;
2453 ext_attr
->has_irqn
= true;
2456 ext_attr
->has_lna
= true;
2457 ext_attr
->has_ntsc
= true;
2458 ext_attr
->has_btsc
= true;
2459 ext_attr
->has_oob
= true;
2460 ext_attr
->has_smatx
= true;
2461 ext_attr
->has_smarx
= true;
2462 ext_attr
->has_gpio
= true;
2463 ext_attr
->has_irqn
= true;
2466 ext_attr
->has_lna
= false;
2467 ext_attr
->has_ntsc
= true;
2468 ext_attr
->has_btsc
= true;
2469 ext_attr
->has_oob
= true;
2470 ext_attr
->has_smatx
= true;
2471 ext_attr
->has_smarx
= true;
2472 ext_attr
->has_gpio
= true;
2473 ext_attr
->has_irqn
= true;
2476 /* Unknown device variant */
2487 * \fn int power_up_device()
2488 * \brief Power up device.
2489 * \param demod Pointer to demodulator instance.
2492 * \retval -EIO Failure, I2C or max retries reached
2496 #ifndef DRXJ_MAX_RETRIES_POWERUP
2497 #define DRXJ_MAX_RETRIES_POWERUP 10
2500 static int power_up_device(struct drx_demod_instance
*demod
)
2502 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
2504 u16 retry_count
= 0;
2505 struct i2c_device_addr wake_up_addr
;
2507 dev_addr
= demod
->my_i2c_dev_addr
;
2508 wake_up_addr
.i2c_addr
= DRXJ_WAKE_UP_KEY
;
2509 wake_up_addr
.i2c_dev_id
= dev_addr
->i2c_dev_id
;
2510 wake_up_addr
.user_data
= dev_addr
->user_data
;
2512 * I2C access may fail in this case: no ack
2513 * dummy write must be used to wake uop device, dummy read must be used to
2514 * reset HI state machine (avoiding actual writes)
2518 drxbsp_i2c_write_read(&wake_up_addr
, 1, &data
,
2519 (struct i2c_device_addr
*)(NULL
), 0,
2523 } while ((drxbsp_i2c_write_read
2524 ((struct i2c_device_addr
*) (NULL
), 0, (u8
*)(NULL
), dev_addr
, 1,
2526 != 0) && (retry_count
< DRXJ_MAX_RETRIES_POWERUP
));
2528 /* Need some recovery time .... */
2531 if (retry_count
== DRXJ_MAX_RETRIES_POWERUP
)
2537 /*----------------------------------------------------------------------------*/
2538 /* MPEG Output Configuration Functions - begin */
2539 /*----------------------------------------------------------------------------*/
2541 * \fn int ctrl_set_cfg_mpeg_output()
2542 * \brief Set MPEG output configuration of the device.
2543 * \param devmod Pointer to demodulator instance.
2544 * \param cfg_data Pointer to mpeg output configuaration.
2547 * Configure MPEG output parameters.
2551 ctrl_set_cfg_mpeg_output(struct drx_demod_instance
*demod
, struct drx_cfg_mpeg_output
*cfg_data
)
2553 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
2554 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
2555 struct drx_common_attr
*common_attr
= (struct drx_common_attr
*) (NULL
);
2557 u16 fec_oc_reg_mode
= 0;
2558 u16 fec_oc_reg_ipr_mode
= 0;
2559 u16 fec_oc_reg_ipr_invert
= 0;
2560 u32 max_bit_rate
= 0;
2563 u16 sio_pdr_md_cfg
= 0;
2564 /* data mask for the output data byte */
2565 u16 invert_data_mask
=
2566 FEC_OC_IPR_INVERT_MD7__M
| FEC_OC_IPR_INVERT_MD6__M
|
2567 FEC_OC_IPR_INVERT_MD5__M
| FEC_OC_IPR_INVERT_MD4__M
|
2568 FEC_OC_IPR_INVERT_MD3__M
| FEC_OC_IPR_INVERT_MD2__M
|
2569 FEC_OC_IPR_INVERT_MD1__M
| FEC_OC_IPR_INVERT_MD0__M
;
2571 /* check arguments */
2572 if ((demod
== NULL
) || (cfg_data
== NULL
))
2575 dev_addr
= demod
->my_i2c_dev_addr
;
2576 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
2577 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
2579 if (cfg_data
->enable_mpeg_output
== true) {
2580 /* quick and dirty patch to set MPEG incase current std is not
2582 switch (ext_attr
->standard
) {
2583 case DRX_STANDARD_8VSB
:
2584 case DRX_STANDARD_ITU_A
:
2585 case DRX_STANDARD_ITU_B
:
2586 case DRX_STANDARD_ITU_C
:
2589 /* not an MPEG producing std, just store MPEG cfg */
2590 common_attr
->mpeg_cfg
.enable_mpeg_output
=
2591 cfg_data
->enable_mpeg_output
;
2592 common_attr
->mpeg_cfg
.insert_rs_byte
=
2593 cfg_data
->insert_rs_byte
;
2594 common_attr
->mpeg_cfg
.enable_parallel
=
2595 cfg_data
->enable_parallel
;
2596 common_attr
->mpeg_cfg
.invert_data
= cfg_data
->invert_data
;
2597 common_attr
->mpeg_cfg
.invert_err
= cfg_data
->invert_err
;
2598 common_attr
->mpeg_cfg
.invert_str
= cfg_data
->invert_str
;
2599 common_attr
->mpeg_cfg
.invert_val
= cfg_data
->invert_val
;
2600 common_attr
->mpeg_cfg
.invert_clk
= cfg_data
->invert_clk
;
2601 common_attr
->mpeg_cfg
.static_clk
= cfg_data
->static_clk
;
2602 common_attr
->mpeg_cfg
.bitrate
= cfg_data
->bitrate
;
2606 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_OCR_INVERT__A
, 0, 0);
2608 pr_err("error %d\n", rc
);
2611 switch (ext_attr
->standard
) {
2612 case DRX_STANDARD_8VSB
:
2613 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_FCT_USAGE__A
, 7, 0);
2615 pr_err("error %d\n", rc
);
2617 } /* 2048 bytes fifo ram */
2618 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_TMD_CTL_UPD_RATE__A
, 10, 0);
2620 pr_err("error %d\n", rc
);
2623 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_TMD_INT_UPD_RATE__A
, 10, 0);
2625 pr_err("error %d\n", rc
);
2628 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_AVR_PARM_A__A
, 5, 0);
2630 pr_err("error %d\n", rc
);
2633 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_AVR_PARM_B__A
, 7, 0);
2635 pr_err("error %d\n", rc
);
2638 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_RCN_GAIN__A
, 10, 0);
2640 pr_err("error %d\n", rc
);
2643 /* Low Water Mark for synchronization */
2644 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_SNC_LWM__A
, 3, 0);
2646 pr_err("error %d\n", rc
);
2649 /* High Water Mark for synchronization */
2650 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_SNC_HWM__A
, 5, 0);
2652 pr_err("error %d\n", rc
);
2656 case DRX_STANDARD_ITU_A
:
2657 case DRX_STANDARD_ITU_C
:
2658 switch (ext_attr
->constellation
) {
2659 case DRX_CONSTELLATION_QAM256
:
2662 case DRX_CONSTELLATION_QAM128
:
2665 case DRX_CONSTELLATION_QAM64
:
2668 case DRX_CONSTELLATION_QAM32
:
2671 case DRX_CONSTELLATION_QAM16
:
2676 } /* ext_attr->constellation */
2677 /* max_bit_rate = symbol_rate * nr_bits * coef */
2678 /* coef = 188/204 */
2680 (ext_attr
->curr_symbol_rate
/ 8) * nr_bits
* 188;
2681 /* pass through b/c Annex A/c need following settings */
2682 case DRX_STANDARD_ITU_B
:
2683 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_FCT_USAGE__A
, FEC_OC_FCT_USAGE__PRE
, 0);
2685 pr_err("error %d\n", rc
);
2688 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_TMD_CTL_UPD_RATE__A
, FEC_OC_TMD_CTL_UPD_RATE__PRE
, 0);
2690 pr_err("error %d\n", rc
);
2693 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_TMD_INT_UPD_RATE__A
, 5, 0);
2695 pr_err("error %d\n", rc
);
2698 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_AVR_PARM_A__A
, FEC_OC_AVR_PARM_A__PRE
, 0);
2700 pr_err("error %d\n", rc
);
2703 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_AVR_PARM_B__A
, FEC_OC_AVR_PARM_B__PRE
, 0);
2705 pr_err("error %d\n", rc
);
2708 if (cfg_data
->static_clk
== true) {
2709 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_RCN_GAIN__A
, 0xD, 0);
2711 pr_err("error %d\n", rc
);
2715 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_RCN_GAIN__A
, FEC_OC_RCN_GAIN__PRE
, 0);
2717 pr_err("error %d\n", rc
);
2721 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_SNC_LWM__A
, 2, 0);
2723 pr_err("error %d\n", rc
);
2726 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_SNC_HWM__A
, 12, 0);
2728 pr_err("error %d\n", rc
);
2734 } /* swtich (standard) */
2736 /* Check insertion of the Reed-Solomon parity bytes */
2737 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_MODE__A
, &fec_oc_reg_mode
, 0);
2739 pr_err("error %d\n", rc
);
2742 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_IPR_MODE__A
, &fec_oc_reg_ipr_mode
, 0);
2744 pr_err("error %d\n", rc
);
2747 if (cfg_data
->insert_rs_byte
== true) {
2748 /* enable parity symbol forward */
2749 fec_oc_reg_mode
|= FEC_OC_MODE_PARITY__M
;
2750 /* MVAL disable during parity bytes */
2751 fec_oc_reg_ipr_mode
|= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M
;
2752 switch (ext_attr
->standard
) {
2753 case DRX_STANDARD_8VSB
:
2754 rcn_rate
= 0x004854D3;
2756 case DRX_STANDARD_ITU_B
:
2757 fec_oc_reg_mode
|= FEC_OC_MODE_TRANSPARENT__M
;
2758 switch (ext_attr
->constellation
) {
2759 case DRX_CONSTELLATION_QAM256
:
2760 rcn_rate
= 0x008945E7;
2762 case DRX_CONSTELLATION_QAM64
:
2763 rcn_rate
= 0x005F64D4;
2769 case DRX_STANDARD_ITU_A
:
2770 case DRX_STANDARD_ITU_C
:
2771 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2775 (u32
) (common_attr
->sys_clock_freq
/ 8))) /
2780 } /* ext_attr->standard */
2781 } else { /* insert_rs_byte == false */
2783 /* disable parity symbol forward */
2784 fec_oc_reg_mode
&= (~FEC_OC_MODE_PARITY__M
);
2785 /* MVAL enable during parity bytes */
2786 fec_oc_reg_ipr_mode
&= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M
);
2787 switch (ext_attr
->standard
) {
2788 case DRX_STANDARD_8VSB
:
2789 rcn_rate
= 0x0041605C;
2791 case DRX_STANDARD_ITU_B
:
2792 fec_oc_reg_mode
&= (~FEC_OC_MODE_TRANSPARENT__M
);
2793 switch (ext_attr
->constellation
) {
2794 case DRX_CONSTELLATION_QAM256
:
2795 rcn_rate
= 0x0082D6A0;
2797 case DRX_CONSTELLATION_QAM64
:
2798 rcn_rate
= 0x005AEC1A;
2804 case DRX_STANDARD_ITU_A
:
2805 case DRX_STANDARD_ITU_C
:
2806 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2810 (u32
) (common_attr
->sys_clock_freq
/ 8))) /
2815 } /* ext_attr->standard */
2818 if (cfg_data
->enable_parallel
== true) { /* MPEG data output is paralel -> clear ipr_mode[0] */
2819 fec_oc_reg_ipr_mode
&= (~(FEC_OC_IPR_MODE_SERIAL__M
));
2820 } else { /* MPEG data output is serial -> set ipr_mode[0] */
2821 fec_oc_reg_ipr_mode
|= FEC_OC_IPR_MODE_SERIAL__M
;
2824 /* Control slective inversion of output bits */
2825 if (cfg_data
->invert_data
== true)
2826 fec_oc_reg_ipr_invert
|= invert_data_mask
;
2828 fec_oc_reg_ipr_invert
&= (~(invert_data_mask
));
2830 if (cfg_data
->invert_err
== true)
2831 fec_oc_reg_ipr_invert
|= FEC_OC_IPR_INVERT_MERR__M
;
2833 fec_oc_reg_ipr_invert
&= (~(FEC_OC_IPR_INVERT_MERR__M
));
2835 if (cfg_data
->invert_str
== true)
2836 fec_oc_reg_ipr_invert
|= FEC_OC_IPR_INVERT_MSTRT__M
;
2838 fec_oc_reg_ipr_invert
&= (~(FEC_OC_IPR_INVERT_MSTRT__M
));
2840 if (cfg_data
->invert_val
== true)
2841 fec_oc_reg_ipr_invert
|= FEC_OC_IPR_INVERT_MVAL__M
;
2843 fec_oc_reg_ipr_invert
&= (~(FEC_OC_IPR_INVERT_MVAL__M
));
2845 if (cfg_data
->invert_clk
== true)
2846 fec_oc_reg_ipr_invert
|= FEC_OC_IPR_INVERT_MCLK__M
;
2848 fec_oc_reg_ipr_invert
&= (~(FEC_OC_IPR_INVERT_MCLK__M
));
2850 if (cfg_data
->static_clk
== true) { /* Static mode */
2853 u16 fec_oc_dto_burst_len
= 0;
2854 u16 fec_oc_dto_period
= 0;
2856 fec_oc_dto_burst_len
= FEC_OC_DTO_BURST_LEN__PRE
;
2858 switch (ext_attr
->standard
) {
2859 case DRX_STANDARD_8VSB
:
2860 fec_oc_dto_period
= 4;
2861 if (cfg_data
->insert_rs_byte
== true)
2862 fec_oc_dto_burst_len
= 208;
2864 case DRX_STANDARD_ITU_A
:
2866 u32 symbol_rate_th
= 6400000;
2867 if (cfg_data
->insert_rs_byte
== true) {
2868 fec_oc_dto_burst_len
= 204;
2869 symbol_rate_th
= 5900000;
2871 if (ext_attr
->curr_symbol_rate
>=
2873 fec_oc_dto_period
= 0;
2875 fec_oc_dto_period
= 1;
2879 case DRX_STANDARD_ITU_B
:
2880 fec_oc_dto_period
= 1;
2881 if (cfg_data
->insert_rs_byte
== true)
2882 fec_oc_dto_burst_len
= 128;
2884 case DRX_STANDARD_ITU_C
:
2885 fec_oc_dto_period
= 1;
2886 if (cfg_data
->insert_rs_byte
== true)
2887 fec_oc_dto_burst_len
= 204;
2893 common_attr
->sys_clock_freq
* 1000 / (fec_oc_dto_period
+
2896 frac28(bit_rate
, common_attr
->sys_clock_freq
* 1000);
2898 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_DTO_RATE_HI__A
, (u16
)((dto_rate
>> 16) & FEC_OC_DTO_RATE_HI__M
), 0);
2900 pr_err("error %d\n", rc
);
2903 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);
2905 pr_err("error %d\n", rc
);
2908 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);
2910 pr_err("error %d\n", rc
);
2913 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);
2915 pr_err("error %d\n", rc
);
2918 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_DTO_BURST_LEN__A
, fec_oc_dto_burst_len
, 0);
2920 pr_err("error %d\n", rc
);
2923 if (ext_attr
->mpeg_output_clock_rate
!= DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO
)
2924 fec_oc_dto_period
= ext_attr
->mpeg_output_clock_rate
- 1;
2925 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_DTO_PERIOD__A
, fec_oc_dto_period
, 0);
2927 pr_err("error %d\n", rc
);
2930 } else { /* Dynamic mode */
2932 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_DTO_MODE__A
, FEC_OC_DTO_MODE_DYNAMIC__M
, 0);
2934 pr_err("error %d\n", rc
);
2937 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_FCT_MODE__A
, 0, 0);
2939 pr_err("error %d\n", rc
);
2944 rc
= DRXJ_DAP
.write_reg32func(dev_addr
, FEC_OC_RCN_CTL_RATE_LO__A
, rcn_rate
, 0);
2946 pr_err("error %d\n", rc
);
2950 /* Write appropriate registers with requested configuration */
2951 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_MODE__A
, fec_oc_reg_mode
, 0);
2953 pr_err("error %d\n", rc
);
2956 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_IPR_MODE__A
, fec_oc_reg_ipr_mode
, 0);
2958 pr_err("error %d\n", rc
);
2961 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_IPR_INVERT__A
, fec_oc_reg_ipr_invert
, 0);
2963 pr_err("error %d\n", rc
);
2967 /* enabling for both parallel and serial now */
2968 /* Write magic word to enable pdr reg write */
2969 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, 0xFABA, 0);
2971 pr_err("error %d\n", rc
);
2974 /* Set MPEG TS pads to outputmode */
2975 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MSTRT_CFG__A
, 0x0013, 0);
2977 pr_err("error %d\n", rc
);
2980 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MERR_CFG__A
, 0x0013, 0);
2982 pr_err("error %d\n", rc
);
2985 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);
2987 pr_err("error %d\n", rc
);
2990 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MVAL_CFG__A
, 0x0013, 0);
2992 pr_err("error %d\n", rc
);
2996 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
<<
2997 SIO_PDR_MD0_CFG_DRIVE__B
| 0x03 << SIO_PDR_MD0_CFG_MODE__B
;
2998 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD0_CFG__A
, sio_pdr_md_cfg
, 0);
3000 pr_err("error %d\n", rc
);
3003 if (cfg_data
->enable_parallel
== true) { /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
3005 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
<<
3006 SIO_PDR_MD0_CFG_DRIVE__B
| 0x03 <<
3007 SIO_PDR_MD0_CFG_MODE__B
;
3008 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD0_CFG__A
, sio_pdr_md_cfg
, 0);
3010 pr_err("error %d\n", rc
);
3013 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD1_CFG__A
, sio_pdr_md_cfg
, 0);
3015 pr_err("error %d\n", rc
);
3018 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD2_CFG__A
, sio_pdr_md_cfg
, 0);
3020 pr_err("error %d\n", rc
);
3023 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD3_CFG__A
, sio_pdr_md_cfg
, 0);
3025 pr_err("error %d\n", rc
);
3028 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD4_CFG__A
, sio_pdr_md_cfg
, 0);
3030 pr_err("error %d\n", rc
);
3033 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD5_CFG__A
, sio_pdr_md_cfg
, 0);
3035 pr_err("error %d\n", rc
);
3038 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD6_CFG__A
, sio_pdr_md_cfg
, 0);
3040 pr_err("error %d\n", rc
);
3043 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD7_CFG__A
, sio_pdr_md_cfg
, 0);
3045 pr_err("error %d\n", rc
);
3048 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3049 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD1_CFG__A
, 0x0000, 0);
3051 pr_err("error %d\n", rc
);
3054 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD2_CFG__A
, 0x0000, 0);
3056 pr_err("error %d\n", rc
);
3059 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD3_CFG__A
, 0x0000, 0);
3061 pr_err("error %d\n", rc
);
3064 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD4_CFG__A
, 0x0000, 0);
3066 pr_err("error %d\n", rc
);
3069 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD5_CFG__A
, 0x0000, 0);
3071 pr_err("error %d\n", rc
);
3074 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD6_CFG__A
, 0x0000, 0);
3076 pr_err("error %d\n", rc
);
3079 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD7_CFG__A
, 0x0000, 0);
3081 pr_err("error %d\n", rc
);
3085 /* Enable Monitor Bus output over MPEG pads and ctl input */
3086 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MON_CFG__A
, 0x0000, 0);
3088 pr_err("error %d\n", rc
);
3091 /* Write nomagic word to enable pdr reg write */
3092 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
3094 pr_err("error %d\n", rc
);
3098 /* Write magic word to enable pdr reg write */
3099 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, 0xFABA, 0);
3101 pr_err("error %d\n", rc
);
3104 /* Set MPEG TS pads to inputmode */
3105 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MSTRT_CFG__A
, 0x0000, 0);
3107 pr_err("error %d\n", rc
);
3110 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MERR_CFG__A
, 0x0000, 0);
3112 pr_err("error %d\n", rc
);
3115 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MCLK_CFG__A
, 0x0000, 0);
3117 pr_err("error %d\n", rc
);
3120 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MVAL_CFG__A
, 0x0000, 0);
3122 pr_err("error %d\n", rc
);
3125 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD0_CFG__A
, 0x0000, 0);
3127 pr_err("error %d\n", rc
);
3130 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD1_CFG__A
, 0x0000, 0);
3132 pr_err("error %d\n", rc
);
3135 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD2_CFG__A
, 0x0000, 0);
3137 pr_err("error %d\n", rc
);
3140 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD3_CFG__A
, 0x0000, 0);
3142 pr_err("error %d\n", rc
);
3145 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD4_CFG__A
, 0x0000, 0);
3147 pr_err("error %d\n", rc
);
3150 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD5_CFG__A
, 0x0000, 0);
3152 pr_err("error %d\n", rc
);
3155 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD6_CFG__A
, 0x0000, 0);
3157 pr_err("error %d\n", rc
);
3160 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD7_CFG__A
, 0x0000, 0);
3162 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
);
3179 /* save values for restore after re-acquire */
3180 common_attr
->mpeg_cfg
.enable_mpeg_output
= cfg_data
->enable_mpeg_output
;
3181 common_attr
->mpeg_cfg
.insert_rs_byte
= cfg_data
->insert_rs_byte
;
3182 common_attr
->mpeg_cfg
.enable_parallel
= cfg_data
->enable_parallel
;
3183 common_attr
->mpeg_cfg
.invert_data
= cfg_data
->invert_data
;
3184 common_attr
->mpeg_cfg
.invert_err
= cfg_data
->invert_err
;
3185 common_attr
->mpeg_cfg
.invert_str
= cfg_data
->invert_str
;
3186 common_attr
->mpeg_cfg
.invert_val
= cfg_data
->invert_val
;
3187 common_attr
->mpeg_cfg
.invert_clk
= cfg_data
->invert_clk
;
3188 common_attr
->mpeg_cfg
.static_clk
= cfg_data
->static_clk
;
3189 common_attr
->mpeg_cfg
.bitrate
= cfg_data
->bitrate
;
3196 /*----------------------------------------------------------------------------*/
3200 * \fn int ctrl_get_cfg_mpeg_output()
3201 * \brief Get MPEG output configuration of the device.
3202 * \param devmod Pointer to demodulator instance.
3203 * \param cfg_data Pointer to MPEG output configuaration struct.
3206 * Retrieve MPEG output configuartion.
3210 ctrl_get_cfg_mpeg_output(struct drx_demod_instance
*demod
, struct drx_cfg_mpeg_output
*cfg_data
)
3212 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
3213 struct drx_common_attr
*common_attr
= (struct drx_common_attr
*) (NULL
);
3214 enum drx_lock_status lock_status
= DRX_NOT_LOCKED
;
3220 if (cfg_data
== NULL
)
3223 dev_addr
= demod
->my_i2c_dev_addr
;
3224 common_attr
= demod
->my_common_attr
;
3226 cfg_data
->enable_mpeg_output
= common_attr
->mpeg_cfg
.enable_mpeg_output
;
3227 cfg_data
->insert_rs_byte
= common_attr
->mpeg_cfg
.insert_rs_byte
;
3228 cfg_data
->enable_parallel
= common_attr
->mpeg_cfg
.enable_parallel
;
3229 cfg_data
->invert_data
= common_attr
->mpeg_cfg
.invert_data
;
3230 cfg_data
->invert_err
= common_attr
->mpeg_cfg
.invert_err
;
3231 cfg_data
->invert_str
= common_attr
->mpeg_cfg
.invert_str
;
3232 cfg_data
->invert_val
= common_attr
->mpeg_cfg
.invert_val
;
3233 cfg_data
->invert_clk
= common_attr
->mpeg_cfg
.invert_clk
;
3234 cfg_data
->static_clk
= common_attr
->mpeg_cfg
.static_clk
;
3235 cfg_data
->bitrate
= 0;
3237 rc
= ctrl_lock_status(demod
, &lock_status
);
3239 pr_err("error %d\n", rc
);
3242 if ((lock_status
== DRX_LOCKED
)) {
3243 rc
= DRXJ_DAP
.read_reg32func(dev_addr
, FEC_OC_RCN_DYN_RATE_LO__A
, &rate_reg
, 0);
3245 pr_err("error %d\n", rc
);
3248 /* Frcn_rate = rate_reg * Fsys / 2 ^ 25 */
3249 mult32(rate_reg
, common_attr
->sys_clock_freq
* 1000, &data64hi
,
3251 cfg_data
->bitrate
= (data64hi
<< 7) | (data64lo
>> 25);
3260 /*----------------------------------------------------------------------------*/
3261 /* MPEG Output Configuration Functions - end */
3262 /*----------------------------------------------------------------------------*/
3264 /*----------------------------------------------------------------------------*/
3265 /* miscellaneous configuartions - begin */
3266 /*----------------------------------------------------------------------------*/
3269 * \fn int set_mpegtei_handling()
3270 * \brief Activate MPEG TEI handling settings.
3271 * \param devmod Pointer to demodulator instance.
3274 * This routine should be called during a set channel of QAM/VSB
3277 static int set_mpegtei_handling(struct drx_demod_instance
*demod
)
3279 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
3280 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
3282 u16 fec_oc_dpr_mode
= 0;
3283 u16 fec_oc_snc_mode
= 0;
3284 u16 fec_oc_ems_mode
= 0;
3286 dev_addr
= demod
->my_i2c_dev_addr
;
3287 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
3289 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_DPR_MODE__A
, &fec_oc_dpr_mode
, 0);
3291 pr_err("error %d\n", rc
);
3294 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_SNC_MODE__A
, &fec_oc_snc_mode
, 0);
3296 pr_err("error %d\n", rc
);
3299 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_EMS_MODE__A
, &fec_oc_ems_mode
, 0);
3301 pr_err("error %d\n", rc
);
3305 /* reset to default, allow TEI bit to be changed */
3306 fec_oc_dpr_mode
&= (~FEC_OC_DPR_MODE_ERR_DISABLE__M
);
3307 fec_oc_snc_mode
&= (~(FEC_OC_SNC_MODE_ERROR_CTL__M
|
3308 FEC_OC_SNC_MODE_CORR_DISABLE__M
));
3309 fec_oc_ems_mode
&= (~FEC_OC_EMS_MODE_MODE__M
);
3311 if (ext_attr
->disable_te_ihandling
) {
3312 /* do not change TEI bit */
3313 fec_oc_dpr_mode
|= FEC_OC_DPR_MODE_ERR_DISABLE__M
;
3314 fec_oc_snc_mode
|= FEC_OC_SNC_MODE_CORR_DISABLE__M
|
3315 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B
));
3316 fec_oc_ems_mode
|= ((0x01) << (FEC_OC_EMS_MODE_MODE__B
));
3319 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_DPR_MODE__A
, fec_oc_dpr_mode
, 0);
3321 pr_err("error %d\n", rc
);
3324 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_SNC_MODE__A
, fec_oc_snc_mode
, 0);
3326 pr_err("error %d\n", rc
);
3329 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_EMS_MODE__A
, fec_oc_ems_mode
, 0);
3331 pr_err("error %d\n", rc
);
3340 /*----------------------------------------------------------------------------*/
3342 * \fn int bit_reverse_mpeg_output()
3343 * \brief Set MPEG output bit-endian settings.
3344 * \param devmod Pointer to demodulator instance.
3347 * This routine should be called during a set channel of QAM/VSB
3350 static int bit_reverse_mpeg_output(struct drx_demod_instance
*demod
)
3352 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
3353 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
3355 u16 fec_oc_ipr_mode
= 0;
3357 dev_addr
= demod
->my_i2c_dev_addr
;
3358 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
3360 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_IPR_MODE__A
, &fec_oc_ipr_mode
, 0);
3362 pr_err("error %d\n", rc
);
3366 /* reset to default (normal bit order) */
3367 fec_oc_ipr_mode
&= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M
);
3369 if (ext_attr
->bit_reverse_mpeg_outout
)
3370 fec_oc_ipr_mode
|= FEC_OC_IPR_MODE_REVERSE_ORDER__M
;
3372 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_IPR_MODE__A
, fec_oc_ipr_mode
, 0);
3374 pr_err("error %d\n", rc
);
3383 /*----------------------------------------------------------------------------*/
3385 * \fn int set_mpeg_output_clock_rate()
3386 * \brief Set MPEG output clock rate.
3387 * \param devmod Pointer to demodulator instance.
3390 * This routine should be called during a set channel of QAM/VSB
3394 static int set_mpeg_output_clock_rate(struct drx_demod_instance
*demod
)
3396 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
3397 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
3400 dev_addr
= demod
->my_i2c_dev_addr
;
3401 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
3403 if (ext_attr
->mpeg_output_clock_rate
!= DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO
) {
3404 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_DTO_PERIOD__A
, ext_attr
->mpeg_output_clock_rate
- 1, 0);
3406 pr_err("error %d\n", rc
);
3417 /*----------------------------------------------------------------------------*/
3419 * \fn int set_mpeg_start_width()
3420 * \brief Set MPEG start width.
3421 * \param devmod Pointer to demodulator instance.
3424 * This routine should be called during a set channel of QAM/VSB
3427 static int set_mpeg_start_width(struct drx_demod_instance
*demod
)
3429 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
3430 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)(NULL
);
3431 struct drx_common_attr
*common_attr
= (struct drx_common_attr
*) NULL
;
3433 u16 fec_oc_comm_mb
= 0;
3435 dev_addr
= demod
->my_i2c_dev_addr
;
3436 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
3437 common_attr
= demod
->my_common_attr
;
3439 if ((common_attr
->mpeg_cfg
.static_clk
== true)
3440 && (common_attr
->mpeg_cfg
.enable_parallel
== false)) {
3441 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_COMM_MB__A
, &fec_oc_comm_mb
, 0);
3443 pr_err("error %d\n", rc
);
3446 fec_oc_comm_mb
&= ~FEC_OC_COMM_MB_CTL_ON
;
3447 if (ext_attr
->mpeg_start_width
== DRXJ_MPEG_START_WIDTH_8CLKCYC
)
3448 fec_oc_comm_mb
|= FEC_OC_COMM_MB_CTL_ON
;
3449 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_COMM_MB__A
, fec_oc_comm_mb
, 0);
3451 pr_err("error %d\n", rc
);
3462 /*----------------------------------------------------------------------------*/
3464 * \fn int ctrl_set_cfg_mpeg_output_misc()
3465 * \brief Set miscellaneous configuartions
3466 * \param devmod Pointer to demodulator instance.
3467 * \param cfg_data pDRXJCfgMisc_t
3470 * This routine can be used to set configuartion options that are DRXJ
3471 * specific and/or added to the requirements at a late stage.
3475 ctrl_set_cfg_mpeg_output_misc(struct drx_demod_instance
*demod
,
3476 struct drxj_cfg_mpeg_output_misc
*cfg_data
)
3478 struct drxj_data
*ext_attr
= NULL
;
3481 if (cfg_data
== NULL
)
3484 ext_attr
= demod
->my_ext_attr
;
3487 Set disable TEI bit handling flag.
3488 TEI must be left untouched by device in case of BER measurements using
3489 external equipment that is unable to ignore the TEI bit in the TS.
3490 Default will false (enable TEI bit handling).
3491 Reverse output bit order. Default is false (msb on MD7 (parallel) or out first (serial)).
3492 Set clock rate. Default is auto that is derived from symbol rate.
3493 The flags and values will also be used to set registers during a set channel.
3495 ext_attr
->disable_te_ihandling
= cfg_data
->disable_tei_handling
;
3496 ext_attr
->bit_reverse_mpeg_outout
= cfg_data
->bit_reverse_mpeg_outout
;
3497 ext_attr
->mpeg_output_clock_rate
= cfg_data
->mpeg_output_clock_rate
;
3498 ext_attr
->mpeg_start_width
= cfg_data
->mpeg_start_width
;
3499 /* Don't care what the active standard is, activate setting immediatly */
3500 rc
= set_mpegtei_handling(demod
);
3502 pr_err("error %d\n", rc
);
3505 rc
= bit_reverse_mpeg_output(demod
);
3507 pr_err("error %d\n", rc
);
3510 rc
= set_mpeg_output_clock_rate(demod
);
3512 pr_err("error %d\n", rc
);
3515 rc
= set_mpeg_start_width(demod
);
3517 pr_err("error %d\n", rc
);
3526 /*----------------------------------------------------------------------------*/
3529 * \fn int ctrl_get_cfg_mpeg_output_misc()
3530 * \brief Get miscellaneous configuartions.
3531 * \param devmod Pointer to demodulator instance.
3532 * \param cfg_data Pointer to DRXJCfgMisc_t.
3535 * This routine can be used to retreive the current setting of the configuartion
3536 * options that are DRXJ specific and/or added to the requirements at a
3541 ctrl_get_cfg_mpeg_output_misc(struct drx_demod_instance
*demod
,
3542 struct drxj_cfg_mpeg_output_misc
*cfg_data
)
3544 struct drxj_data
*ext_attr
= NULL
;
3548 if (cfg_data
== NULL
)
3551 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
3552 cfg_data
->disable_tei_handling
= ext_attr
->disable_te_ihandling
;
3553 cfg_data
->bit_reverse_mpeg_outout
= ext_attr
->bit_reverse_mpeg_outout
;
3554 cfg_data
->mpeg_start_width
= ext_attr
->mpeg_start_width
;
3555 if (ext_attr
->mpeg_output_clock_rate
!= DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO
) {
3556 cfg_data
->mpeg_output_clock_rate
= ext_attr
->mpeg_output_clock_rate
;
3558 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, FEC_OC_DTO_PERIOD__A
, &data
, 0);
3560 pr_err("error %d\n", rc
);
3563 cfg_data
->mpeg_output_clock_rate
=
3564 (enum drxj_mpeg_output_clock_rate
) (data
+ 1);
3572 /*----------------------------------------------------------------------------*/
3575 * \fn int ctrl_get_cfg_hw_cfg()
3576 * \brief Get HW configuartions.
3577 * \param devmod Pointer to demodulator instance.
3578 * \param cfg_data Pointer to Bool.
3581 * This routine can be used to retreive the current setting of the configuartion
3582 * options that are DRXJ specific and/or added to the requirements at a
3587 ctrl_get_cfg_hw_cfg(struct drx_demod_instance
*demod
, struct drxj_cfg_hw_cfg
*cfg_data
)
3592 if (cfg_data
== NULL
)
3595 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, 0xFABA, 0);
3597 pr_err("error %d\n", rc
);
3600 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_OHW_CFG__A
, &data
, 0);
3602 pr_err("error %d\n", rc
);
3605 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
3607 pr_err("error %d\n", rc
);
3611 cfg_data
->i2c_speed
= (enum drxji2c_speed
) ((data
>> 6) & 0x1);
3612 cfg_data
->xtal_freq
= (enum drxj_xtal_freq
) (data
& 0x3);
3620 /*----------------------------------------------------------------------------*/
3621 /* miscellaneous configuartions - end */
3622 /*----------------------------------------------------------------------------*/
3624 /*----------------------------------------------------------------------------*/
3625 /* UIO Configuration Functions - begin */
3626 /*----------------------------------------------------------------------------*/
3628 * \fn int ctrl_set_uio_cfg()
3629 * \brief Configure modus oprandi UIO.
3630 * \param demod Pointer to demodulator instance.
3631 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3634 static int ctrl_set_uio_cfg(struct drx_demod_instance
*demod
, struct drxuio_cfg
*uio_cfg
)
3636 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
3639 if ((uio_cfg
== NULL
) || (demod
== NULL
))
3642 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
3644 /* Write magic word to enable pdr reg write */
3645 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
3647 pr_err("error %d\n", rc
);
3650 switch (uio_cfg
->uio
) {
3651 /*====================================================================*/
3653 /* DRX_UIO1: SMA_TX UIO-1 */
3654 if (!ext_attr
->has_smatx
)
3656 switch (uio_cfg
->mode
) {
3657 case DRX_UIO_MODE_FIRMWARE_SMA
: /* falltrough */
3658 case DRX_UIO_MODE_FIRMWARE_SAW
: /* falltrough */
3659 case DRX_UIO_MODE_READWRITE
:
3660 ext_attr
->uio_sma_tx_mode
= uio_cfg
->mode
;
3662 case DRX_UIO_MODE_DISABLE
:
3663 ext_attr
->uio_sma_tx_mode
= uio_cfg
->mode
;
3664 /* pad configuration register is set 0 - input mode */
3665 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_SMA_TX_CFG__A
, 0, 0);
3667 pr_err("error %d\n", rc
);
3673 } /* switch ( uio_cfg->mode ) */
3675 /*====================================================================*/
3677 /* DRX_UIO2: SMA_RX UIO-2 */
3678 if (!ext_attr
->has_smarx
)
3680 switch (uio_cfg
->mode
) {
3681 case DRX_UIO_MODE_FIRMWARE0
: /* falltrough */
3682 case DRX_UIO_MODE_READWRITE
:
3683 ext_attr
->uio_sma_rx_mode
= uio_cfg
->mode
;
3685 case DRX_UIO_MODE_DISABLE
:
3686 ext_attr
->uio_sma_rx_mode
= uio_cfg
->mode
;
3687 /* pad configuration register is set 0 - input mode */
3688 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_SMA_RX_CFG__A
, 0, 0);
3690 pr_err("error %d\n", rc
);
3697 } /* switch ( uio_cfg->mode ) */
3699 /*====================================================================*/
3701 /* DRX_UIO3: GPIO UIO-3 */
3702 if (!ext_attr
->has_gpio
)
3704 switch (uio_cfg
->mode
) {
3705 case DRX_UIO_MODE_FIRMWARE0
: /* falltrough */
3706 case DRX_UIO_MODE_READWRITE
:
3707 ext_attr
->uio_gpio_mode
= uio_cfg
->mode
;
3709 case DRX_UIO_MODE_DISABLE
:
3710 ext_attr
->uio_gpio_mode
= uio_cfg
->mode
;
3711 /* pad configuration register is set 0 - input mode */
3712 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_GPIO_CFG__A
, 0, 0);
3714 pr_err("error %d\n", rc
);
3721 } /* switch ( uio_cfg->mode ) */
3723 /*====================================================================*/
3725 /* DRX_UIO4: IRQN UIO-4 */
3726 if (!ext_attr
->has_irqn
)
3728 switch (uio_cfg
->mode
) {
3729 case DRX_UIO_MODE_READWRITE
:
3730 ext_attr
->uio_irqn_mode
= uio_cfg
->mode
;
3732 case DRX_UIO_MODE_DISABLE
:
3733 /* pad configuration register is set 0 - input mode */
3734 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_IRQN_CFG__A
, 0, 0);
3736 pr_err("error %d\n", rc
);
3739 ext_attr
->uio_irqn_mode
= uio_cfg
->mode
;
3741 case DRX_UIO_MODE_FIRMWARE0
: /* falltrough */
3745 } /* switch ( uio_cfg->mode ) */
3747 /*====================================================================*/
3750 } /* switch ( uio_cfg->uio ) */
3752 /* Write magic word to disable pdr reg write */
3753 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
3755 pr_err("error %d\n", rc
);
3765 /*============================================================================*/
3767 * \fn int ctrl_getuio_cfg()
3768 * \brief Get modus oprandi UIO.
3769 * \param demod Pointer to demodulator instance.
3770 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3773 static int ctrl_getuio_cfg(struct drx_demod_instance
*demod
, struct drxuio_cfg
*uio_cfg
)
3776 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
3777 enum drxuio_mode
*uio_mode
[4] = { NULL
};
3778 bool *uio_available
[4] = { NULL
};
3780 ext_attr
= demod
->my_ext_attr
;
3782 uio_mode
[DRX_UIO1
] = &ext_attr
->uio_sma_tx_mode
;
3783 uio_mode
[DRX_UIO2
] = &ext_attr
->uio_sma_rx_mode
;
3784 uio_mode
[DRX_UIO3
] = &ext_attr
->uio_gpio_mode
;
3785 uio_mode
[DRX_UIO4
] = &ext_attr
->uio_irqn_mode
;
3787 uio_available
[DRX_UIO1
] = &ext_attr
->has_smatx
;
3788 uio_available
[DRX_UIO2
] = &ext_attr
->has_smarx
;
3789 uio_available
[DRX_UIO3
] = &ext_attr
->has_gpio
;
3790 uio_available
[DRX_UIO4
] = &ext_attr
->has_irqn
;
3792 if (uio_cfg
== NULL
)
3795 if ((uio_cfg
->uio
> DRX_UIO4
) || (uio_cfg
->uio
< DRX_UIO1
))
3798 if (!*uio_available
[uio_cfg
->uio
])
3801 uio_cfg
->mode
= *uio_mode
[uio_cfg
->uio
];
3808 * \fn int ctrl_uio_write()
3809 * \brief Write to a UIO.
3810 * \param demod Pointer to demodulator instance.
3811 * \param uio_data Pointer to data container for a certain UIO.
3815 ctrl_uio_write(struct drx_demod_instance
*demod
, struct drxuio_data
*uio_data
)
3817 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
3819 u16 pin_cfg_value
= 0;
3822 if ((uio_data
== NULL
) || (demod
== NULL
))
3825 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
3827 /* Write magic word to enable pdr reg write */
3828 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
3830 pr_err("error %d\n", rc
);
3833 switch (uio_data
->uio
) {
3834 /*====================================================================*/
3836 /* DRX_UIO1: SMA_TX UIO-1 */
3837 if (!ext_attr
->has_smatx
)
3839 if ((ext_attr
->uio_sma_tx_mode
!= DRX_UIO_MODE_READWRITE
)
3840 && (ext_attr
->uio_sma_tx_mode
!= DRX_UIO_MODE_FIRMWARE_SAW
)) {
3844 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3845 pin_cfg_value
|= 0x0113;
3846 /* io_pad_cfg_mode output mode is drive always */
3847 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3849 /* write to io pad configuration register - output mode */
3850 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_SMA_TX_CFG__A
, pin_cfg_value
, 0);
3852 pr_err("error %d\n", rc
);
3856 /* use corresponding bit in io data output registar */
3857 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_OUT_LO__A
, &value
, 0);
3859 pr_err("error %d\n", rc
);
3862 if (!uio_data
->value
)
3863 value
&= 0x7FFF; /* write zero to 15th bit - 1st UIO */
3865 value
|= 0x8000; /* write one to 15th bit - 1st UIO */
3867 /* write back to io data output register */
3868 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_OUT_LO__A
, value
, 0);
3870 pr_err("error %d\n", rc
);
3874 /*======================================================================*/
3876 /* DRX_UIO2: SMA_RX UIO-2 */
3877 if (!ext_attr
->has_smarx
)
3879 if (ext_attr
->uio_sma_rx_mode
!= DRX_UIO_MODE_READWRITE
)
3883 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3884 pin_cfg_value
|= 0x0113;
3885 /* io_pad_cfg_mode output mode is drive always */
3886 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3888 /* write to io pad configuration register - output mode */
3889 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_SMA_RX_CFG__A
, pin_cfg_value
, 0);
3891 pr_err("error %d\n", rc
);
3895 /* use corresponding bit in io data output registar */
3896 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_OUT_LO__A
, &value
, 0);
3898 pr_err("error %d\n", rc
);
3901 if (!uio_data
->value
)
3902 value
&= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
3904 value
|= 0x4000; /* write one to 14th bit - 2nd UIO */
3906 /* write back to io data output register */
3907 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_OUT_LO__A
, value
, 0);
3909 pr_err("error %d\n", rc
);
3913 /*====================================================================*/
3915 /* DRX_UIO3: ASEL UIO-3 */
3916 if (!ext_attr
->has_gpio
)
3918 if (ext_attr
->uio_gpio_mode
!= DRX_UIO_MODE_READWRITE
)
3922 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3923 pin_cfg_value
|= 0x0113;
3924 /* io_pad_cfg_mode output mode is drive always */
3925 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3927 /* write to io pad configuration register - output mode */
3928 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_GPIO_CFG__A
, pin_cfg_value
, 0);
3930 pr_err("error %d\n", rc
);
3934 /* use corresponding bit in io data output registar */
3935 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_OUT_HI__A
, &value
, 0);
3937 pr_err("error %d\n", rc
);
3940 if (!uio_data
->value
)
3941 value
&= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
3943 value
|= 0x0004; /* write one to 2nd bit - 3rd UIO */
3945 /* write back to io data output register */
3946 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_OUT_HI__A
, value
, 0);
3948 pr_err("error %d\n", rc
);
3952 /*=====================================================================*/
3954 /* DRX_UIO4: IRQN UIO-4 */
3955 if (!ext_attr
->has_irqn
)
3958 if (ext_attr
->uio_irqn_mode
!= DRX_UIO_MODE_READWRITE
)
3962 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3963 pin_cfg_value
|= 0x0113;
3964 /* io_pad_cfg_mode output mode is drive always */
3965 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3967 /* write to io pad configuration register - output mode */
3968 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_IRQN_CFG__A
, pin_cfg_value
, 0);
3970 pr_err("error %d\n", rc
);
3974 /* use corresponding bit in io data output registar */
3975 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_OUT_LO__A
, &value
, 0);
3977 pr_err("error %d\n", rc
);
3980 if (uio_data
->value
== false)
3981 value
&= 0xEFFF; /* write zero to 12th bit - 4th UIO */
3983 value
|= 0x1000; /* write one to 12th bit - 4th UIO */
3985 /* write back to io data output register */
3986 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_OUT_LO__A
, value
, 0);
3988 pr_err("error %d\n", rc
);
3992 /*=====================================================================*/
3995 } /* switch ( uio_data->uio ) */
3997 /* Write magic word to disable pdr reg write */
3998 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
4000 pr_err("error %d\n", rc
);
4011 *\fn int ctrl_uio_read
4012 *\brief Read from a UIO.
4013 * \param demod Pointer to demodulator instance.
4014 * \param uio_data Pointer to data container for a certain UIO.
4017 static int ctrl_uio_read(struct drx_demod_instance
*demod
, struct drxuio_data
*uio_data
)
4019 struct drxj_data
*ext_attr
= (struct drxj_data
*) (NULL
);
4021 u16 pin_cfg_value
= 0;
4024 if ((uio_data
== NULL
) || (demod
== NULL
))
4027 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
4029 /* Write magic word to enable pdr reg write */
4030 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
4032 pr_err("error %d\n", rc
);
4035 switch (uio_data
->uio
) {
4036 /*====================================================================*/
4038 /* DRX_UIO1: SMA_TX UIO-1 */
4039 if (!ext_attr
->has_smatx
)
4042 if (ext_attr
->uio_sma_tx_mode
!= DRX_UIO_MODE_READWRITE
)
4046 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4047 pin_cfg_value
|= 0x0110;
4048 /* io_pad_cfg_mode output mode is drive always */
4049 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4051 /* write to io pad configuration register - input mode */
4052 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_SMA_TX_CFG__A
, pin_cfg_value
, 0);
4054 pr_err("error %d\n", rc
);
4058 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_IN_LO__A
, &value
, 0);
4060 pr_err("error %d\n", rc
);
4063 if ((value
& 0x8000) != 0) { /* check 15th bit - 1st UIO */
4064 uio_data
->value
= true;
4066 uio_data
->value
= false;
4069 /*======================================================================*/
4071 /* DRX_UIO2: SMA_RX UIO-2 */
4072 if (!ext_attr
->has_smarx
)
4075 if (ext_attr
->uio_sma_rx_mode
!= DRX_UIO_MODE_READWRITE
)
4079 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4080 pin_cfg_value
|= 0x0110;
4081 /* io_pad_cfg_mode output mode is drive always */
4082 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4084 /* write to io pad configuration register - input mode */
4085 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_SMA_RX_CFG__A
, pin_cfg_value
, 0);
4087 pr_err("error %d\n", rc
);
4091 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_IN_LO__A
, &value
, 0);
4093 pr_err("error %d\n", rc
);
4097 if ((value
& 0x4000) != 0) /* check 14th bit - 2nd UIO */
4098 uio_data
->value
= true;
4100 uio_data
->value
= false;
4103 /*=====================================================================*/
4105 /* DRX_UIO3: GPIO UIO-3 */
4106 if (!ext_attr
->has_gpio
)
4109 if (ext_attr
->uio_gpio_mode
!= DRX_UIO_MODE_READWRITE
)
4113 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4114 pin_cfg_value
|= 0x0110;
4115 /* io_pad_cfg_mode output mode is drive always */
4116 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4118 /* write to io pad configuration register - input mode */
4119 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_GPIO_CFG__A
, pin_cfg_value
, 0);
4121 pr_err("error %d\n", rc
);
4125 /* read io input data registar */
4126 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_IN_HI__A
, &value
, 0);
4128 pr_err("error %d\n", rc
);
4131 if ((value
& 0x0004) != 0) { /* check 2nd bit - 3rd UIO */
4132 uio_data
->value
= true;
4134 uio_data
->value
= false;
4137 /*=====================================================================*/
4139 /* DRX_UIO4: IRQN UIO-4 */
4140 if (!ext_attr
->has_irqn
)
4143 if (ext_attr
->uio_irqn_mode
!= DRX_UIO_MODE_READWRITE
)
4147 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4148 pin_cfg_value
|= 0x0110;
4149 /* io_pad_cfg_mode output mode is drive always */
4150 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4152 /* write to io pad configuration register - input mode */
4153 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_IRQN_CFG__A
, pin_cfg_value
, 0);
4155 pr_err("error %d\n", rc
);
4159 /* read io input data registar */
4160 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_UIO_IN_LO__A
, &value
, 0);
4162 pr_err("error %d\n", rc
);
4165 if ((value
& 0x1000) != 0) /* check 12th bit - 4th UIO */
4166 uio_data
->value
= true;
4168 uio_data
->value
= false;
4171 /*====================================================================*/
4174 } /* switch ( uio_data->uio ) */
4176 /* Write magic word to disable pdr reg write */
4177 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
4179 pr_err("error %d\n", rc
);
4189 /*---------------------------------------------------------------------------*/
4190 /* UIO Configuration Functions - end */
4191 /*---------------------------------------------------------------------------*/
4193 /*----------------------------------------------------------------------------*/
4194 /* I2C Bridge Functions - begin */
4195 /*----------------------------------------------------------------------------*/
4197 * \fn int ctrl_i2c_bridge()
4198 * \brief Open or close the I2C switch to tuner.
4199 * \param demod Pointer to demodulator instance.
4200 * \param bridge_closed Pointer to bool indication if bridge is closed not.
4205 ctrl_i2c_bridge(struct drx_demod_instance
*demod
, bool *bridge_closed
)
4207 struct drxj_hi_cmd hi_cmd
;
4210 /* check arguments */
4211 if (bridge_closed
== NULL
)
4214 hi_cmd
.cmd
= SIO_HI_RA_RAM_CMD_BRDCTRL
;
4215 hi_cmd
.param1
= SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY
;
4217 hi_cmd
.param2
= SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED
;
4219 hi_cmd
.param2
= SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN
;
4221 return hi_command(demod
->my_i2c_dev_addr
, &hi_cmd
, &result
);
4224 /*----------------------------------------------------------------------------*/
4225 /* I2C Bridge Functions - end */
4226 /*----------------------------------------------------------------------------*/
4228 /*----------------------------------------------------------------------------*/
4229 /* Smart antenna Functions - begin */
4230 /*----------------------------------------------------------------------------*/
4232 * \fn int smart_ant_init()
4233 * \brief Initialize Smart Antenna.
4234 * \param pointer to struct drx_demod_instance.
4238 static int smart_ant_init(struct drx_demod_instance
*demod
)
4240 struct drxj_data
*ext_attr
= NULL
;
4241 struct i2c_device_addr
*dev_addr
= NULL
;
4242 struct drxuio_cfg uio_cfg
= { DRX_UIO1
, DRX_UIO_MODE_FIRMWARE_SMA
};
4246 dev_addr
= demod
->my_i2c_dev_addr
;
4247 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
4249 /* Write magic word to enable pdr reg write */
4250 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
4252 pr_err("error %d\n", rc
);
4255 /* init smart antenna */
4256 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_SA_TX_COMMAND__A
, &data
, 0);
4258 pr_err("error %d\n", rc
);
4261 if (ext_attr
->smart_ant_inverted
) {
4262 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);
4264 pr_err("error %d\n", rc
);
4268 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);
4270 pr_err("error %d\n", rc
);
4275 /* config SMA_TX pin to smart antenna mode */
4276 rc
= ctrl_set_uio_cfg(demod
, &uio_cfg
);
4278 pr_err("error %d\n", rc
);
4281 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_SMA_TX_CFG__A
, 0x13, 0);
4283 pr_err("error %d\n", rc
);
4286 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_PDR_SMA_TX_GPIO_FNC__A
, 0x03, 0);
4288 pr_err("error %d\n", rc
);
4292 /* Write magic word to disable pdr reg write */
4293 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
4295 pr_err("error %d\n", rc
);
4306 * \fn int ctrl_set_cfg_smart_ant()
4307 * \brief Set Smart Antenna.
4308 * \param pointer to struct drxj_cfg_smart_ant.
4313 ctrl_set_cfg_smart_ant(struct drx_demod_instance
*demod
, struct drxj_cfg_smart_ant
*smart_ant
)
4315 struct drxj_data
*ext_attr
= NULL
;
4316 struct i2c_device_addr
*dev_addr
= NULL
;
4320 static bool bit_inverted
;
4322 dev_addr
= demod
->my_i2c_dev_addr
;
4323 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
4325 /* check arguments */
4326 if (smart_ant
== NULL
)
4329 if (bit_inverted
!= ext_attr
->smart_ant_inverted
4330 || ext_attr
->uio_sma_tx_mode
!= DRX_UIO_MODE_FIRMWARE_SMA
) {
4331 rc
= smart_ant_init(demod
);
4333 pr_err("error %d\n", rc
);
4336 bit_inverted
= ext_attr
->smart_ant_inverted
;
4339 /* Write magic word to enable pdr reg write */
4340 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
4342 pr_err("error %d\n", rc
);
4346 switch (smart_ant
->io
) {
4347 case DRXJ_SMT_ANT_OUTPUT
:
4348 /* enable Tx if Mode B (input) is supported */
4350 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4351 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
4353 start_time
= jiffies_to_msecs(jiffies
);
4355 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_SA_TX_STATUS__A
, &data
, 0);
4357 pr_err("error %d\n", rc
);
4360 } while ((data
& SIO_SA_TX_STATUS_BUSY__M
) && ((jiffies_to_msecs(jiffies
) - start_time
) < DRXJ_MAX_WAITTIME
));
4362 if (data
& SIO_SA_TX_STATUS_BUSY__M
)
4365 /* write to smart antenna configuration register */
4366 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);
4368 pr_err("error %d\n", rc
);
4371 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);
4373 pr_err("error %d\n", rc
);
4376 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);
4378 pr_err("error %d\n", rc
);
4381 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_SA_TX_DATA3__A
, 0xff8d, 0);
4383 pr_err("error %d\n", rc
);
4387 /* trigger the sending */
4388 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_SA_TX_LENGTH__A
, 56, 0);
4390 pr_err("error %d\n", rc
);
4395 case DRXJ_SMT_ANT_INPUT
:
4396 /* disable Tx if Mode B (input) is supported */
4398 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4399 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
4404 /* Write magic word to enable pdr reg write */
4405 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
4407 pr_err("error %d\n", rc
);
4417 static int scu_command(struct i2c_device_addr
*dev_addr
, struct drxjscu_cmd
*cmd
)
4427 /* Wait until SCU command interface is ready to receive command */
4428 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_COMMAND__A
, &cur_cmd
, 0);
4430 pr_err("error %d\n", rc
);
4433 if (cur_cmd
!= DRX_SCU_READY
)
4436 switch (cmd
->parameter_len
) {
4438 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_PARAM_4__A
, *(cmd
->parameter
+ 4), 0);
4440 pr_err("error %d\n", rc
);
4444 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_PARAM_3__A
, *(cmd
->parameter
+ 3), 0);
4446 pr_err("error %d\n", rc
);
4450 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_PARAM_2__A
, *(cmd
->parameter
+ 2), 0);
4452 pr_err("error %d\n", rc
);
4456 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_PARAM_1__A
, *(cmd
->parameter
+ 1), 0);
4458 pr_err("error %d\n", rc
);
4462 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_PARAM_0__A
, *(cmd
->parameter
+ 0), 0);
4464 pr_err("error %d\n", rc
);
4471 /* this number of parameters is not supported */
4474 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_COMMAND__A
, cmd
->command
, 0);
4476 pr_err("error %d\n", rc
);
4480 /* Wait until SCU has processed command */
4481 start_time
= jiffies_to_msecs(jiffies
);
4483 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_COMMAND__A
, &cur_cmd
, 0);
4485 pr_err("error %d\n", rc
);
4488 } while (!(cur_cmd
== DRX_SCU_READY
)
4489 && ((jiffies_to_msecs(jiffies
) - start_time
) < DRXJ_MAX_WAITTIME
));
4491 if (cur_cmd
!= DRX_SCU_READY
)
4495 if ((cmd
->result_len
> 0) && (cmd
->result
!= NULL
)) {
4498 switch (cmd
->result_len
) {
4500 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_PARAM_3__A
, cmd
->result
+ 3, 0);
4502 pr_err("error %d\n", rc
);
4506 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_PARAM_2__A
, cmd
->result
+ 2, 0);
4508 pr_err("error %d\n", rc
);
4512 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_PARAM_1__A
, cmd
->result
+ 1, 0);
4514 pr_err("error %d\n", rc
);
4518 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_PARAM_0__A
, cmd
->result
+ 0, 0);
4520 pr_err("error %d\n", rc
);
4527 /* this number of parameters is not supported */
4531 /* Check if an error was reported by SCU */
4532 err
= cmd
->result
[0];
4534 /* check a few fixed error codes */
4535 if ((err
== (s16
) SCU_RAM_PARAM_0_RESULT_UNKSTD
)
4536 || (err
== (s16
) SCU_RAM_PARAM_0_RESULT_UNKCMD
)
4537 || (err
== (s16
) SCU_RAM_PARAM_0_RESULT_INVPAR
)
4538 || (err
== (s16
) SCU_RAM_PARAM_0_RESULT_SIZE
)
4542 /* here it is assumed that negative means error, and positive no error */
4556 * \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4557 * \brief Basic access routine for SCU atomic read or write access
4558 * \param dev_addr pointer to i2c dev address
4559 * \param addr destination/source address
4560 * \param datasize size of data buffer in bytes
4561 * \param data pointer to data buffer
4564 * \retval -EIO Timeout, I2C error, illegal bank
4567 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4569 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 */
4570 u8
*data
, bool read_flag
)
4572 struct drxjscu_cmd scu_cmd
;
4574 u16 set_param_parameters
[15];
4577 /* Parameter check */
4578 if (!data
|| !dev_addr
|| (datasize
% 2) || ((datasize
/ 2) > 16))
4581 set_param_parameters
[1] = (u16
) ADDR_AT_SCU_SPACE(addr
);
4582 if (read_flag
) { /* read */
4583 set_param_parameters
[0] = ((~(0x0080)) & datasize
);
4584 scu_cmd
.parameter_len
= 2;
4585 scu_cmd
.result_len
= datasize
/ 2 + 2;
4589 set_param_parameters
[0] = 0x0080 | datasize
;
4590 for (i
= 0; i
< (datasize
/ 2); i
++) {
4591 set_param_parameters
[i
+ 2] =
4592 (data
[2 * i
] | (data
[(2 * i
) + 1] << 8));
4594 scu_cmd
.parameter_len
= datasize
/ 2 + 2;
4595 scu_cmd
.result_len
= 1;
4599 SCU_RAM_COMMAND_STANDARD_TOP
|
4600 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS
;
4601 scu_cmd
.result
= cmd_result
;
4602 scu_cmd
.parameter
= set_param_parameters
;
4603 rc
= scu_command(dev_addr
, &scu_cmd
);
4605 pr_err("error %d\n", rc
);
4611 /* read data from buffer */
4612 for (i
= 0; i
< (datasize
/ 2); i
++) {
4613 data
[2 * i
] = (u8
) (scu_cmd
.result
[i
+ 2] & 0xFF);
4614 data
[(2 * i
) + 1] = (u8
) (scu_cmd
.result
[i
+ 2] >> 8);
4625 /*============================================================================*/
4628 * \fn int DRXJ_DAP_AtomicReadReg16()
4629 * \brief Atomic read of 16 bits words
4632 int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr
*dev_addr
,
4634 u16
*data
, u32 flags
)
4643 rc
= drxj_dap_scu_atomic_read_write_block(dev_addr
, addr
, 2, buf
, true);
4647 word
= (u16
) (buf
[0] + (buf
[1] << 8));
4654 /*============================================================================*/
4656 * \fn int drxj_dap_scu_atomic_write_reg16()
4657 * \brief Atomic read of 16 bits words
4660 int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr
*dev_addr
,
4662 u16 data
, u32 flags
)
4667 buf
[0] = (u8
) (data
& 0xff);
4668 buf
[1] = (u8
) ((data
>> 8) & 0xff);
4670 rc
= drxj_dap_scu_atomic_read_write_block(dev_addr
, addr
, 2, buf
, false);
4675 /* -------------------------------------------------------------------------- */
4677 * \brief Measure result of ADC synchronisation
4678 * \param demod demod instance
4679 * \param count (returned) count
4682 * \retval -EIO Failure: I2C error
4685 static int adc_sync_measurement(struct drx_demod_instance
*demod
, u16
*count
)
4687 struct i2c_device_addr
*dev_addr
= NULL
;
4691 dev_addr
= demod
->my_i2c_dev_addr
;
4693 /* Start measurement */
4694 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_COMM_EXEC__A
, IQM_AF_COMM_EXEC_ACTIVE
, 0);
4696 pr_err("error %d\n", rc
);
4699 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_START_LOCK__A
, 1, 0);
4701 pr_err("error %d\n", rc
);
4705 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4709 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_PHASE0__A
, &data
, 0);
4711 pr_err("error %d\n", rc
);
4715 *count
= *count
+ 1;
4716 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_PHASE1__A
, &data
, 0);
4718 pr_err("error %d\n", rc
);
4722 *count
= *count
+ 1;
4723 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_PHASE2__A
, &data
, 0);
4725 pr_err("error %d\n", rc
);
4729 *count
= *count
+ 1;
4737 * \brief Synchronize analog and digital clock domains
4738 * \param demod demod instance
4741 * \retval -EIO Failure: I2C error or failure to synchronize
4743 * An IQM reset will also reset the results of this synchronization.
4744 * After an IQM reset this routine needs to be called again.
4748 static int adc_synchronization(struct drx_demod_instance
*demod
)
4750 struct i2c_device_addr
*dev_addr
= NULL
;
4754 dev_addr
= demod
->my_i2c_dev_addr
;
4756 rc
= adc_sync_measurement(demod
, &count
);
4758 pr_err("error %d\n", rc
);
4763 /* Try sampling on a diffrent edge */
4766 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_CLKNEG__A
, &clk_neg
, 0);
4768 pr_err("error %d\n", rc
);
4772 clk_neg
^= IQM_AF_CLKNEG_CLKNEGDATA__M
;
4773 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_CLKNEG__A
, clk_neg
, 0);
4775 pr_err("error %d\n", rc
);
4779 rc
= adc_sync_measurement(demod
, &count
);
4781 pr_err("error %d\n", rc
);
4786 /* TODO: implement fallback scenarios */
4797 * \brief Configure IQM AF registers
4798 * \param demod instance of demodulator.
4802 static int iqm_set_af(struct drx_demod_instance
*demod
, bool active
)
4804 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
4809 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_STDBY__A
, &data
, 0);
4811 pr_err("error %d\n", rc
);
4815 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
));
4817 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
);
4818 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, data
, 0);
4820 pr_err("error %d\n", rc
);
4829 /* -------------------------------------------------------------------------- */
4831 ctrl_set_cfg_atv_output(struct drx_demod_instance
*demod
, struct drxj_cfg_atv_output
*output_cfg
);
4834 * \brief set configuration of pin-safe mode
4835 * \param demod instance of demodulator.
4836 * \param enable boolean; true: activate pin-safe mode, false: de-activate p.s.m.
4840 ctrl_set_cfg_pdr_safe_mode(struct drx_demod_instance
*demod
, bool *enable
)
4842 struct drxj_data
*ext_attr
= NULL
;
4843 struct i2c_device_addr
*dev_addr
= NULL
;
4849 dev_addr
= demod
->my_i2c_dev_addr
;
4850 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
4852 /* Write magic word to enable pdr reg write */
4853 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
4855 pr_err("error %d\n", rc
);
4860 bool bridge_enabled
= false;
4862 /* MPEG pins to input */
4863 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MSTRT_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4865 pr_err("error %d\n", rc
);
4868 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MERR_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4870 pr_err("error %d\n", rc
);
4873 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MCLK_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4875 pr_err("error %d\n", rc
);
4878 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MVAL_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4880 pr_err("error %d\n", rc
);
4883 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD0_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4885 pr_err("error %d\n", rc
);
4888 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD1_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4890 pr_err("error %d\n", rc
);
4893 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD2_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4895 pr_err("error %d\n", rc
);
4898 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD3_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4900 pr_err("error %d\n", rc
);
4903 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD4_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4905 pr_err("error %d\n", rc
);
4908 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD5_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4910 pr_err("error %d\n", rc
);
4913 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD6_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4915 pr_err("error %d\n", rc
);
4918 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_MD7_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4920 pr_err("error %d\n", rc
);
4924 /* PD_I2C_SDA2 Bridge off, Port2 Inactive
4925 PD_I2C_SCL2 Bridge off, Port2 Inactive */
4926 rc
= ctrl_i2c_bridge(demod
, &bridge_enabled
);
4928 pr_err("error %d\n", rc
);
4931 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2C_SDA2_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4933 pr_err("error %d\n", rc
);
4936 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2C_SCL2_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4938 pr_err("error %d\n", rc
);
4942 /* PD_GPIO Store and set to input
4943 PD_VSYNC Store and set to input
4944 PD_SMA_RX Store and set to input
4945 PD_SMA_TX Store and set to input */
4946 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_PDR_GPIO_CFG__A
, &ext_attr
->pdr_safe_restore_val_gpio
, 0);
4948 pr_err("error %d\n", rc
);
4951 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_PDR_VSYNC_CFG__A
, &ext_attr
->pdr_safe_restore_val_v_sync
, 0);
4953 pr_err("error %d\n", rc
);
4956 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_PDR_SMA_RX_CFG__A
, &ext_attr
->pdr_safe_restore_val_sma_rx
, 0);
4958 pr_err("error %d\n", rc
);
4961 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SIO_PDR_SMA_TX_CFG__A
, &ext_attr
->pdr_safe_restore_val_sma_tx
, 0);
4963 pr_err("error %d\n", rc
);
4966 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_GPIO_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4968 pr_err("error %d\n", rc
);
4971 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_VSYNC_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4973 pr_err("error %d\n", rc
);
4976 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_SMA_RX_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4978 pr_err("error %d\n", rc
);
4981 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_SMA_TX_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
4983 pr_err("error %d\n", rc
);
4987 /* PD_RF_AGC Analog DAC outputs, cannot be set to input or tristate!
4988 PD_IF_AGC Analog DAC outputs, cannot be set to input or tristate! */
4989 rc
= iqm_set_af(demod
, false);
4991 pr_err("error %d\n", rc
);
4995 /* PD_CVBS Analog DAC output, standby mode
4996 PD_SIF Analog DAC output, standby mode */
4997 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);
4999 pr_err("error %d\n", rc
);
5006 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2S_CL_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
5008 pr_err("error %d\n", rc
);
5011 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2S_DA_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
5013 pr_err("error %d\n", rc
);
5016 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2S_WS_CFG__A
, DRXJ_PIN_SAFE_MODE
, 0);
5018 pr_err("error %d\n", rc
);
5022 /* No need to restore MPEG pins;
5023 is done in SetStandard/SetChannel */
5025 /* PD_I2C_SDA2 Port2 active
5026 PD_I2C_SCL2 Port2 active */
5027 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2C_SDA2_CFG__A
, SIO_PDR_I2C_SDA2_CFG__PRE
, 0);
5029 pr_err("error %d\n", rc
);
5032 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2C_SCL2_CFG__A
, SIO_PDR_I2C_SCL2_CFG__PRE
, 0);
5034 pr_err("error %d\n", rc
);
5041 PD_SMA_TX Restore */
5042 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_GPIO_CFG__A
, ext_attr
->pdr_safe_restore_val_gpio
, 0);
5044 pr_err("error %d\n", rc
);
5047 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_VSYNC_CFG__A
, ext_attr
->pdr_safe_restore_val_v_sync
, 0);
5049 pr_err("error %d\n", rc
);
5052 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_SMA_RX_CFG__A
, ext_attr
->pdr_safe_restore_val_sma_rx
, 0);
5054 pr_err("error %d\n", rc
);
5057 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_SMA_TX_CFG__A
, ext_attr
->pdr_safe_restore_val_sma_tx
, 0);
5059 pr_err("error %d\n", rc
);
5063 /* PD_RF_AGC, PD_IF_AGC
5064 No need to restore; will be restored in SetStandard/SetChannel */
5067 No need to restore; will be restored in SetStandard/SetChannel */
5069 /* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
5070 Should be restored via DRX_CTRL_SET_AUD */
5073 /* Write magic word to disable pdr reg write */
5074 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
5076 pr_err("error %d\n", rc
);
5079 ext_attr
->pdr_safe_mode
= *enable
;
5087 /* -------------------------------------------------------------------------- */
5090 * \brief get configuration of pin-safe mode
5091 * \param demod instance of demodulator.
5092 * \param enable boolean indicating whether pin-safe mode is active
5096 ctrl_get_cfg_pdr_safe_mode(struct drx_demod_instance
*demod
, bool *enabled
)
5098 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
5100 if (enabled
== NULL
)
5103 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
5104 *enabled
= ext_attr
->pdr_safe_mode
;
5110 /*============================================================================*/
5111 /*== END AUXILIARY FUNCTIONS ==*/
5112 /*============================================================================*/
5114 /*============================================================================*/
5115 /*============================================================================*/
5116 /*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5117 /*============================================================================*/
5118 /*============================================================================*/
5120 * \fn int init_agc ()
5121 * \brief Initialize AGC for all standards.
5122 * \param demod instance of demodulator.
5123 * \param channel pointer to channel data.
5126 static int init_agc(struct drx_demod_instance
*demod
)
5128 struct i2c_device_addr
*dev_addr
= NULL
;
5129 struct drx_common_attr
*common_attr
= NULL
;
5130 struct drxj_data
*ext_attr
= NULL
;
5131 struct drxj_cfg_agc
*p_agc_rf_settings
= NULL
;
5132 struct drxj_cfg_agc
*p_agc_if_settings
= NULL
;
5134 u16 ingain_tgt_max
= 0;
5136 u16 sns_sum_max
= 0;
5137 u16 clp_sum_max
= 0;
5139 u16 ki_innergain_min
= 0;
5142 u16 if_iaccu_hi_tgt_min
= 0;
5144 u16 agc_ki_dgain
= 0;
5146 u16 clp_ctrl_mode
= 0;
5150 dev_addr
= demod
->my_i2c_dev_addr
;
5151 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
5152 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
5154 switch (ext_attr
->standard
) {
5155 case DRX_STANDARD_8VSB
:
5157 clp_dir_to
= (u16
) (-9);
5159 sns_dir_to
= (u16
) (-9);
5160 ki_innergain_min
= (u16
) (-32768);
5163 if_iaccu_hi_tgt_min
= 2047;
5165 ingain_tgt_max
= 16383;
5167 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_MINGAIN__A
, 0x7fff, 0);
5169 pr_err("error %d\n", rc
);
5172 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_MAXGAIN__A
, 0x0, 0);
5174 pr_err("error %d\n", rc
);
5177 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_SUM__A
, 0, 0);
5179 pr_err("error %d\n", rc
);
5182 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_CYCCNT__A
, 0, 0);
5184 pr_err("error %d\n", rc
);
5187 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_DIR_WD__A
, 0, 0);
5189 pr_err("error %d\n", rc
);
5192 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_DIR_STP__A
, 1, 0);
5194 pr_err("error %d\n", rc
);
5197 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_SUM__A
, 0, 0);
5199 pr_err("error %d\n", rc
);
5202 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_CYCCNT__A
, 0, 0);
5204 pr_err("error %d\n", rc
);
5207 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_DIR_WD__A
, 0, 0);
5209 pr_err("error %d\n", rc
);
5212 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_DIR_STP__A
, 1, 0);
5214 pr_err("error %d\n", rc
);
5217 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN__A
, 1024, 0);
5219 pr_err("error %d\n", rc
);
5222 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_VSB_AGC_POW_TGT__A
, 22600, 0);
5224 pr_err("error %d\n", rc
);
5227 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN_TGT__A
, 13200, 0);
5229 pr_err("error %d\n", rc
);
5232 p_agc_if_settings
= &(ext_attr
->vsb_if_agc_cfg
);
5233 p_agc_rf_settings
= &(ext_attr
->vsb_rf_agc_cfg
);
5235 #ifndef DRXJ_VSB_ONLY
5236 case DRX_STANDARD_ITU_A
:
5237 case DRX_STANDARD_ITU_C
:
5238 case DRX_STANDARD_ITU_B
:
5239 ingain_tgt_max
= 5119;
5241 clp_dir_to
= (u16
) (-5);
5243 sns_dir_to
= (u16
) (-3);
5244 ki_innergain_min
= 0;
5246 if_iaccu_hi_tgt_min
= 2047;
5250 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_MINGAIN__A
, 0x7fff, 0);
5252 pr_err("error %d\n", rc
);
5255 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_MAXGAIN__A
, 0x0, 0);
5257 pr_err("error %d\n", rc
);
5260 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_SUM__A
, 0, 0);
5262 pr_err("error %d\n", rc
);
5265 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_CYCCNT__A
, 0, 0);
5267 pr_err("error %d\n", rc
);
5270 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_DIR_WD__A
, 0, 0);
5272 pr_err("error %d\n", rc
);
5275 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_DIR_STP__A
, 1, 0);
5277 pr_err("error %d\n", rc
);
5280 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_SUM__A
, 0, 0);
5282 pr_err("error %d\n", rc
);
5285 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_CYCCNT__A
, 0, 0);
5287 pr_err("error %d\n", rc
);
5290 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_DIR_WD__A
, 0, 0);
5292 pr_err("error %d\n", rc
);
5295 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_DIR_STP__A
, 1, 0);
5297 pr_err("error %d\n", rc
);
5300 p_agc_if_settings
= &(ext_attr
->qam_if_agc_cfg
);
5301 p_agc_rf_settings
= &(ext_attr
->qam_rf_agc_cfg
);
5302 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN_TGT__A
, p_agc_if_settings
->top
, 0);
5304 pr_err("error %d\n", rc
);
5308 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_AGC_KI__A
, &agc_ki
, 0);
5310 pr_err("error %d\n", rc
);
5314 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI__A
, agc_ki
, 0);
5316 pr_err("error %d\n", rc
);
5322 case DRX_STANDARD_FM
:
5325 ki_innergain_min
= (u16
) (-32768);
5326 if_iaccu_hi_tgt_min
= 2047;
5330 clp_dir_to
= (u16
) (-9);
5331 sns_dir_to
= (u16
) (-9);
5332 ingain_tgt_max
= 9000;
5334 p_agc_if_settings
= &(ext_attr
->atv_if_agc_cfg
);
5335 p_agc_rf_settings
= &(ext_attr
->atv_rf_agc_cfg
);
5336 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN_TGT__A
, p_agc_if_settings
->top
, 0);
5338 pr_err("error %d\n", rc
);
5342 case DRX_STANDARD_NTSC
:
5343 case DRX_STANDARD_PAL_SECAM_BG
:
5344 case DRX_STANDARD_PAL_SECAM_DK
:
5345 case DRX_STANDARD_PAL_SECAM_I
:
5348 ki_innergain_min
= (u16
) (-32768);
5349 if_iaccu_hi_tgt_min
= 2047;
5353 clp_dir_to
= (u16
) (-9);
5354 ingain_tgt_max
= 9000;
5355 p_agc_if_settings
= &(ext_attr
->atv_if_agc_cfg
);
5356 p_agc_rf_settings
= &(ext_attr
->atv_rf_agc_cfg
);
5357 sns_dir_to
= (u16
) (-9);
5359 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN_TGT__A
, p_agc_if_settings
->top
, 0);
5361 pr_err("error %d\n", rc
);
5365 case DRX_STANDARD_PAL_SECAM_L
:
5366 case DRX_STANDARD_PAL_SECAM_LP
:
5369 ki_innergain_min
= (u16
) (-32768);
5370 if_iaccu_hi_tgt_min
= 2047;
5374 clp_dir_to
= (u16
) (-9);
5375 sns_dir_to
= (u16
) (-9);
5376 ingain_tgt_max
= 9000;
5378 p_agc_if_settings
= &(ext_attr
->atv_if_agc_cfg
);
5379 p_agc_rf_settings
= &(ext_attr
->atv_rf_agc_cfg
);
5380 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN_TGT__A
, p_agc_if_settings
->top
, 0);
5382 pr_err("error %d\n", rc
);
5391 /* for new AGC interface */
5392 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN_TGT_MIN__A
, p_agc_if_settings
->top
, 0);
5394 pr_err("error %d\n", rc
);
5397 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN__A
, p_agc_if_settings
->top
, 0);
5399 pr_err("error %d\n", rc
);
5401 } /* Gain fed from inner to outer AGC */
5402 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_INGAIN_TGT_MAX__A
, ingain_tgt_max
, 0);
5404 pr_err("error %d\n", rc
);
5407 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A
, if_iaccu_hi_tgt_min
, 0);
5409 pr_err("error %d\n", rc
);
5412 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI__A
, 0, 0);
5414 pr_err("error %d\n", rc
);
5416 } /* set to p_agc_settings->top before */
5417 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_IF_IACCU_LO__A
, 0, 0);
5419 pr_err("error %d\n", rc
);
5422 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_RF_IACCU_HI__A
, 0, 0);
5424 pr_err("error %d\n", rc
);
5427 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_RF_IACCU_LO__A
, 0, 0);
5429 pr_err("error %d\n", rc
);
5432 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_RF_MAX__A
, 32767, 0);
5434 pr_err("error %d\n", rc
);
5437 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_SUM_MAX__A
, clp_sum_max
, 0);
5439 pr_err("error %d\n", rc
);
5442 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_SUM_MAX__A
, sns_sum_max
, 0);
5444 pr_err("error %d\n", rc
);
5447 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_INNERGAIN_MIN__A
, ki_innergain_min
, 0);
5449 pr_err("error %d\n", rc
);
5452 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A
, 50, 0);
5454 pr_err("error %d\n", rc
);
5457 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_CYCLEN__A
, 500, 0);
5459 pr_err("error %d\n", rc
);
5462 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_CYCLEN__A
, 500, 0);
5464 pr_err("error %d\n", rc
);
5467 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A
, 20, 0);
5469 pr_err("error %d\n", rc
);
5472 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_MIN__A
, ki_min
, 0);
5474 pr_err("error %d\n", rc
);
5477 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_MAX__A
, ki_max
, 0);
5479 pr_err("error %d\n", rc
);
5482 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI_RED__A
, 0, 0);
5484 pr_err("error %d\n", rc
);
5487 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_SUM_MIN__A
, 8, 0);
5489 pr_err("error %d\n", rc
);
5492 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_CYCLEN__A
, 500, 0);
5494 pr_err("error %d\n", rc
);
5497 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_DIR_TO__A
, clp_dir_to
, 0);
5499 pr_err("error %d\n", rc
);
5502 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_SUM_MIN__A
, 8, 0);
5504 pr_err("error %d\n", rc
);
5507 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_SNS_DIR_TO__A
, sns_dir_to
, 0);
5509 pr_err("error %d\n", rc
);
5512 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A
, 50, 0);
5514 pr_err("error %d\n", rc
);
5517 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_CLP_CTRL_MODE__A
, clp_ctrl_mode
, 0);
5519 pr_err("error %d\n", rc
);
5523 agc_rf
= 0x800 + p_agc_rf_settings
->cut_off_current
;
5524 if (common_attr
->tuner_rf_agc_pol
== true)
5525 agc_rf
= 0x87ff - agc_rf
;
5528 if (common_attr
->tuner_if_agc_pol
== true)
5529 agc_rf
= 0x87ff - agc_rf
;
5531 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_AGC_RF__A
, agc_rf
, 0);
5533 pr_err("error %d\n", rc
);
5536 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_AGC_IF__A
, agc_if
, 0);
5538 pr_err("error %d\n", rc
);
5542 /* Set/restore Ki DGAIN factor */
5543 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_AGC_KI__A
, &data
, 0);
5545 pr_err("error %d\n", rc
);
5548 data
&= ~SCU_RAM_AGC_KI_DGAIN__M
;
5549 data
|= (agc_ki_dgain
<< SCU_RAM_AGC_KI_DGAIN__B
);
5550 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_AGC_KI__A
, data
, 0);
5552 pr_err("error %d\n", rc
);
5562 * \fn int set_frequency ()
5563 * \brief Set frequency shift.
5564 * \param demod instance of demodulator.
5565 * \param channel pointer to channel data.
5566 * \param tuner_freq_offset residual frequency from tuner.
5570 set_frequency(struct drx_demod_instance
*demod
,
5571 struct drx_channel
*channel
, s32 tuner_freq_offset
)
5573 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
5574 struct drxj_data
*ext_attr
= demod
->my_ext_attr
;
5576 s32 sampling_frequency
= 0;
5577 s32 frequency_shift
= 0;
5578 s32 if_freq_actual
= 0;
5579 s32 rf_freq_residual
= -1 * tuner_freq_offset
;
5581 s32 intermediate_freq
= 0;
5582 u32 iqm_fs_rate_ofs
= 0;
5583 bool adc_flip
= true;
5584 bool select_pos_image
= false;
5587 bool image_to_select
= true;
5588 s32 fm_frequency_shift
= 0;
5590 rf_mirror
= (ext_attr
->mirror
== DRX_MIRROR_YES
) ? true : false;
5591 tuner_mirror
= demod
->my_common_attr
->mirror_freq_spect
? false : true;
5593 Program frequency shifter
5594 No need to account for mirroring on RF
5596 switch (ext_attr
->standard
) {
5597 case DRX_STANDARD_ITU_A
: /* fallthrough */
5598 case DRX_STANDARD_ITU_C
: /* fallthrough */
5599 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
5600 case DRX_STANDARD_8VSB
:
5601 select_pos_image
= true;
5603 case DRX_STANDARD_FM
:
5604 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
5605 Sound carrier is already 3Mhz above centre frequency due
5606 to tuner setting so now add an extra shift of 1MHz... */
5607 fm_frequency_shift
= 1000;
5608 case DRX_STANDARD_ITU_B
: /* fallthrough */
5609 case DRX_STANDARD_NTSC
: /* fallthrough */
5610 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
5611 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
5612 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
5613 case DRX_STANDARD_PAL_SECAM_L
:
5614 select_pos_image
= false;
5619 intermediate_freq
= demod
->my_common_attr
->intermediate_freq
;
5620 sampling_frequency
= demod
->my_common_attr
->sys_clock_freq
/ 3;
5622 if_freq_actual
= intermediate_freq
+ rf_freq_residual
+ fm_frequency_shift
;
5624 if_freq_actual
= intermediate_freq
- rf_freq_residual
- fm_frequency_shift
;
5625 if (if_freq_actual
> sampling_frequency
/ 2) {
5627 adc_freq
= sampling_frequency
- if_freq_actual
;
5630 /* adc doesn't mirror */
5631 adc_freq
= if_freq_actual
;
5635 frequency_shift
= adc_freq
;
5637 (bool) (rf_mirror
^ tuner_mirror
^ adc_flip
^ select_pos_image
);
5638 iqm_fs_rate_ofs
= frac28(frequency_shift
, sampling_frequency
);
5640 if (image_to_select
)
5641 iqm_fs_rate_ofs
= ~iqm_fs_rate_ofs
+ 1;
5643 /* Program frequency shifter with tuner offset compensation */
5644 /* frequency_shift += tuner_freq_offset; TODO */
5645 rc
= DRXJ_DAP
.write_reg32func(dev_addr
, IQM_FS_RATE_OFS_LO__A
, iqm_fs_rate_ofs
, 0);
5647 pr_err("error %d\n", rc
);
5650 ext_attr
->iqm_fs_rate_ofs
= iqm_fs_rate_ofs
;
5651 ext_attr
->pos_image
= (bool) (rf_mirror
^ tuner_mirror
^ select_pos_image
);
5660 * \fn int get_sig_strength()
5661 * \brief Retrieve signal strength for VSB and QAM.
5662 * \param demod Pointer to demod instance
5663 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
5665 * \retval 0 sig_strength contains valid data.
5666 * \retval -EINVAL sig_strength is NULL.
5667 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5669 #define DRXJ_AGC_TOP 0x2800
5670 #define DRXJ_AGC_SNS 0x1600
5671 #define DRXJ_RFAGC_MAX 0x3fff
5672 #define DRXJ_RFAGC_MIN 0x800
5674 static int get_sig_strength(struct drx_demod_instance
*demod
, u16
*sig_strength
)
5676 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
5685 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_AGC_IF__A
, &if_gain
, 0);
5687 pr_err("error %d\n", rc
);
5690 if_gain
&= IQM_AF_AGC_IF__M
;
5691 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_AGC_RF__A
, &rf_gain
, 0);
5693 pr_err("error %d\n", rc
);
5696 rf_gain
&= IQM_AF_AGC_RF__M
;
5698 if_agc_sns
= DRXJ_AGC_SNS
;
5699 if_agc_top
= DRXJ_AGC_TOP
;
5700 rf_agc_max
= DRXJ_RFAGC_MAX
;
5701 rf_agc_min
= DRXJ_RFAGC_MIN
;
5703 if (if_gain
> if_agc_top
) {
5704 if (rf_gain
> rf_agc_max
)
5705 *sig_strength
= 100;
5706 else if (rf_gain
> rf_agc_min
) {
5707 if (rf_agc_max
== rf_agc_min
) {
5708 pr_err("error: rf_agc_max == rf_agc_min\n");
5712 75 + 25 * (rf_gain
- rf_agc_min
) / (rf_agc_max
-
5716 } else if (if_gain
> if_agc_sns
) {
5717 if (if_agc_top
== if_agc_sns
) {
5718 pr_err("error: if_agc_top == if_agc_sns\n");
5722 20 + 55 * (if_gain
- if_agc_sns
) / (if_agc_top
- if_agc_sns
);
5725 pr_err("error: if_agc_sns is zero!\n");
5728 *sig_strength
= (20 * if_gain
/ if_agc_sns
);
5738 * \fn int get_acc_pkt_err()
5739 * \brief Retrieve signal strength for VSB and QAM.
5740 * \param demod Pointer to demod instance
5741 * \param packet_err Pointer to packet error
5743 * \retval 0 sig_strength contains valid data.
5744 * \retval -EINVAL sig_strength is NULL.
5745 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5747 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5748 static int get_acc_pkt_err(struct drx_demod_instance
*demod
, u16
*packet_err
)
5752 static u16 last_pkt_err
;
5754 struct drxj_data
*ext_attr
= NULL
;
5755 struct i2c_device_addr
*dev_addr
= NULL
;
5757 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
5758 dev_addr
= demod
->my_i2c_dev_addr
;
5760 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A
, &data
, 0);
5762 pr_err("error %d\n", rc
);
5765 if (ext_attr
->reset_pkt_err_acc
) {
5766 last_pkt_err
= data
;
5768 ext_attr
->reset_pkt_err_acc
= false;
5771 if (data
< last_pkt_err
) {
5772 pkt_err
+= 0xffff - last_pkt_err
;
5775 pkt_err
+= (data
- last_pkt_err
);
5777 *packet_err
= pkt_err
;
5778 last_pkt_err
= data
;
5788 * \fn int ResetAccPktErr()
5789 * \brief Reset Accumulating packet error count.
5790 * \param demod Pointer to demod instance
5793 * \retval -EIO Erroneous data.
5795 static int ctrl_set_cfg_reset_pkt_err(struct drx_demod_instance
*demod
)
5797 struct drxj_data
*ext_attr
= NULL
;
5799 u16 packet_error
= 0;
5801 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
5802 ext_attr
->reset_pkt_err_acc
= true;
5803 /* call to reset counter */
5804 rc
= get_acc_pkt_err(demod
, &packet_error
);
5806 pr_err("error %d\n", rc
);
5816 * \fn static short get_str_freq_offset()
5817 * \brief Get symbol rate offset in QAM & 8VSB mode
5818 * \return Error code
5820 static int get_str_freq_offset(struct drx_demod_instance
*demod
, s32
*str_freq
)
5823 u32 symbol_frequency_ratio
= 0;
5824 u32 symbol_nom_frequency_ratio
= 0;
5826 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
5827 struct drxj_data
*ext_attr
= demod
->my_ext_attr
;
5829 rc
= drxj_dap_atomic_read_reg32(dev_addr
, IQM_RC_RATE_LO__A
, &symbol_frequency_ratio
, 0);
5831 pr_err("error %d\n", rc
);
5834 symbol_nom_frequency_ratio
= ext_attr
->iqm_rc_rate_ofs
;
5836 if (symbol_frequency_ratio
> symbol_nom_frequency_ratio
)
5839 frac_times1e6((symbol_frequency_ratio
-
5840 symbol_nom_frequency_ratio
),
5841 (symbol_frequency_ratio
+ (1 << 23)));
5844 frac_times1e6((symbol_nom_frequency_ratio
-
5845 symbol_frequency_ratio
),
5846 (symbol_frequency_ratio
+ (1 << 23)));
5854 * \fn static short get_ctl_freq_offset
5855 * \brief Get the value of ctl_freq in QAM & ATSC mode
5856 * \return Error code
5858 static int get_ctl_freq_offset(struct drx_demod_instance
*demod
, s32
*ctl_freq
)
5860 s32 sampling_frequency
= 0;
5861 s32 current_frequency
= 0;
5862 s32 nominal_frequency
= 0;
5863 s32 carrier_frequency_shift
= 0;
5867 struct drxj_data
*ext_attr
= NULL
;
5868 struct drx_common_attr
*common_attr
= NULL
;
5869 struct i2c_device_addr
*dev_addr
= NULL
;
5872 dev_addr
= demod
->my_i2c_dev_addr
;
5873 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
5874 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
5876 sampling_frequency
= common_attr
->sys_clock_freq
/ 3;
5878 /* both registers are sign extended */
5879 nominal_frequency
= ext_attr
->iqm_fs_rate_ofs
;
5880 rc
= drxj_dap_atomic_read_reg32(dev_addr
, IQM_FS_RATE_LO__A
, (u32
*)¤t_frequency
, 0);
5882 pr_err("error %d\n", rc
);
5886 if (ext_attr
->pos_image
) {
5887 /* negative image */
5888 carrier_frequency_shift
= nominal_frequency
- current_frequency
;
5890 /* positive image */
5891 carrier_frequency_shift
= current_frequency
- nominal_frequency
;
5894 /* carrier Frequency Shift In Hz */
5895 if (carrier_frequency_shift
< 0) {
5897 carrier_frequency_shift
*= sign
;
5900 /* *ctl_freq = carrier_frequency_shift * 50.625e6 / (1 << 28); */
5901 mult32(carrier_frequency_shift
, sampling_frequency
, &data64hi
, &data64lo
);
5903 (s32
) ((((data64lo
>> 28) & 0xf) | (data64hi
<< 4)) * sign
);
5911 /*============================================================================*/
5914 * \fn int set_agc_rf ()
5915 * \brief Configure RF AGC
5916 * \param demod instance of demodulator.
5917 * \param agc_settings AGC configuration structure
5921 set_agc_rf(struct drx_demod_instance
*demod
, struct drxj_cfg_agc
*agc_settings
, bool atomic
)
5923 struct i2c_device_addr
*dev_addr
= NULL
;
5924 struct drxj_data
*ext_attr
= NULL
;
5925 struct drxj_cfg_agc
*p_agc_settings
= NULL
;
5926 struct drx_common_attr
*common_attr
= NULL
;
5928 drx_write_reg16func_t scu_wr16
= NULL
;
5929 drx_read_reg16func_t scu_rr16
= NULL
;
5931 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
5932 dev_addr
= demod
->my_i2c_dev_addr
;
5933 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
5936 scu_rr16
= drxj_dap_scu_atomic_read_reg16
;
5937 scu_wr16
= drxj_dap_scu_atomic_write_reg16
;
5939 scu_rr16
= DRXJ_DAP
.read_reg16func
;
5940 scu_wr16
= DRXJ_DAP
.write_reg16func
;
5943 /* Configure AGC only if standard is currently active */
5944 if ((ext_attr
->standard
== agc_settings
->standard
) ||
5945 (DRXJ_ISQAMSTD(ext_attr
->standard
) &&
5946 DRXJ_ISQAMSTD(agc_settings
->standard
)) ||
5947 (DRXJ_ISATVSTD(ext_attr
->standard
) &&
5948 DRXJ_ISATVSTD(agc_settings
->standard
))) {
5951 switch (agc_settings
->ctrl_mode
) {
5952 case DRX_AGC_CTRL_AUTO
:
5954 /* Enable RF AGC DAC */
5955 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_STDBY__A
, &data
, 0);
5957 pr_err("error %d\n", rc
);
5960 data
|= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE
;
5961 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, data
, 0);
5963 pr_err("error %d\n", rc
);
5967 /* Enable SCU RF AGC loop */
5968 rc
= (*scu_rr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, &data
, 0);
5970 pr_err("error %d\n", rc
);
5973 data
&= ~SCU_RAM_AGC_KI_RF__M
;
5974 if (ext_attr
->standard
== DRX_STANDARD_8VSB
)
5975 data
|= (2 << SCU_RAM_AGC_KI_RF__B
);
5976 else if (DRXJ_ISQAMSTD(ext_attr
->standard
))
5977 data
|= (5 << SCU_RAM_AGC_KI_RF__B
);
5979 data
|= (4 << SCU_RAM_AGC_KI_RF__B
);
5981 if (common_attr
->tuner_rf_agc_pol
)
5982 data
|= SCU_RAM_AGC_KI_INV_RF_POL__M
;
5984 data
&= ~SCU_RAM_AGC_KI_INV_RF_POL__M
;
5985 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, data
, 0);
5987 pr_err("error %d\n", rc
);
5991 /* Set speed ( using complementary reduction value ) */
5992 rc
= (*scu_rr16
)(dev_addr
, SCU_RAM_AGC_KI_RED__A
, &data
, 0);
5994 pr_err("error %d\n", rc
);
5997 data
&= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M
;
5998 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);
6000 pr_err("error %d\n", rc
);
6004 if (agc_settings
->standard
== DRX_STANDARD_8VSB
)
6005 p_agc_settings
= &(ext_attr
->vsb_if_agc_cfg
);
6006 else if (DRXJ_ISQAMSTD(agc_settings
->standard
))
6007 p_agc_settings
= &(ext_attr
->qam_if_agc_cfg
);
6008 else if (DRXJ_ISATVSTD(agc_settings
->standard
))
6009 p_agc_settings
= &(ext_attr
->atv_if_agc_cfg
);
6013 /* Set TOP, only if IF-AGC is in AUTO mode */
6014 if (p_agc_settings
->ctrl_mode
== DRX_AGC_CTRL_AUTO
) {
6015 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A
, agc_settings
->top
, 0);
6017 pr_err("error %d\n", rc
);
6020 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI_TGT__A
, agc_settings
->top
, 0);
6022 pr_err("error %d\n", rc
);
6027 /* Cut-Off current */
6028 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_RF_IACCU_HI_CO__A
, agc_settings
->cut_off_current
, 0);
6030 pr_err("error %d\n", rc
);
6034 case DRX_AGC_CTRL_USER
:
6036 /* Enable RF AGC DAC */
6037 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_STDBY__A
, &data
, 0);
6039 pr_err("error %d\n", rc
);
6042 data
|= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE
;
6043 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, data
, 0);
6045 pr_err("error %d\n", rc
);
6049 /* Disable SCU RF AGC loop */
6050 rc
= (*scu_rr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, &data
, 0);
6052 pr_err("error %d\n", rc
);
6055 data
&= ~SCU_RAM_AGC_KI_RF__M
;
6056 if (common_attr
->tuner_rf_agc_pol
)
6057 data
|= SCU_RAM_AGC_KI_INV_RF_POL__M
;
6059 data
&= ~SCU_RAM_AGC_KI_INV_RF_POL__M
;
6060 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, data
, 0);
6062 pr_err("error %d\n", rc
);
6066 /* Write value to output pin */
6067 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_RF_IACCU_HI__A
, agc_settings
->output_level
, 0);
6069 pr_err("error %d\n", rc
);
6073 case DRX_AGC_CTRL_OFF
:
6075 /* Disable RF AGC DAC */
6076 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_STDBY__A
, &data
, 0);
6078 pr_err("error %d\n", rc
);
6081 data
&= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE
);
6082 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, data
, 0);
6084 pr_err("error %d\n", rc
);
6088 /* Disable SCU RF AGC loop */
6089 rc
= (*scu_rr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, &data
, 0);
6091 pr_err("error %d\n", rc
);
6094 data
&= ~SCU_RAM_AGC_KI_RF__M
;
6095 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, data
, 0);
6097 pr_err("error %d\n", rc
);
6103 } /* switch ( agcsettings->ctrl_mode ) */
6106 /* Store rf agc settings */
6107 switch (agc_settings
->standard
) {
6108 case DRX_STANDARD_8VSB
:
6109 ext_attr
->vsb_rf_agc_cfg
= *agc_settings
;
6111 #ifndef DRXJ_VSB_ONLY
6112 case DRX_STANDARD_ITU_A
:
6113 case DRX_STANDARD_ITU_B
:
6114 case DRX_STANDARD_ITU_C
:
6115 ext_attr
->qam_rf_agc_cfg
= *agc_settings
;
6119 case DRX_STANDARD_PAL_SECAM_BG
:
6120 case DRX_STANDARD_PAL_SECAM_DK
:
6121 case DRX_STANDARD_PAL_SECAM_I
:
6122 case DRX_STANDARD_PAL_SECAM_L
:
6123 case DRX_STANDARD_PAL_SECAM_LP
:
6124 case DRX_STANDARD_NTSC
:
6125 case DRX_STANDARD_FM
:
6126 ext_attr
->atv_rf_agc_cfg
= *agc_settings
;
6140 * \fn int get_agc_rf ()
6141 * \brief get configuration of RF AGC
6142 * \param demod instance of demodulator.
6143 * \param agc_settings AGC configuration structure
6147 get_agc_rf(struct drx_demod_instance
*demod
, struct drxj_cfg_agc
*agc_settings
)
6149 struct i2c_device_addr
*dev_addr
= NULL
;
6150 struct drxj_data
*ext_attr
= NULL
;
6151 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
6154 dev_addr
= demod
->my_i2c_dev_addr
;
6155 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
6157 /* Return stored AGC settings */
6158 standard
= agc_settings
->standard
;
6159 switch (agc_settings
->standard
) {
6160 case DRX_STANDARD_8VSB
:
6161 *agc_settings
= ext_attr
->vsb_rf_agc_cfg
;
6163 #ifndef DRXJ_VSB_ONLY
6164 case DRX_STANDARD_ITU_A
:
6165 case DRX_STANDARD_ITU_B
:
6166 case DRX_STANDARD_ITU_C
:
6167 *agc_settings
= ext_attr
->qam_rf_agc_cfg
;
6171 case DRX_STANDARD_PAL_SECAM_BG
:
6172 case DRX_STANDARD_PAL_SECAM_DK
:
6173 case DRX_STANDARD_PAL_SECAM_I
:
6174 case DRX_STANDARD_PAL_SECAM_L
:
6175 case DRX_STANDARD_PAL_SECAM_LP
:
6176 case DRX_STANDARD_NTSC
:
6177 case DRX_STANDARD_FM
:
6178 *agc_settings
= ext_attr
->atv_rf_agc_cfg
;
6184 agc_settings
->standard
= standard
;
6186 /* Get AGC output only if standard is currently active. */
6187 if ((ext_attr
->standard
== agc_settings
->standard
) ||
6188 (DRXJ_ISQAMSTD(ext_attr
->standard
) &&
6189 DRXJ_ISQAMSTD(agc_settings
->standard
)) ||
6190 (DRXJ_ISATVSTD(ext_attr
->standard
) &&
6191 DRXJ_ISATVSTD(agc_settings
->standard
))) {
6192 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_AGC_RF_IACCU_HI__A
, &(agc_settings
->output_level
), 0);
6194 pr_err("error %d\n", rc
);
6206 * \fn int set_agc_if ()
6207 * \brief Configure If AGC
6208 * \param demod instance of demodulator.
6209 * \param agc_settings AGC configuration structure
6213 set_agc_if(struct drx_demod_instance
*demod
, struct drxj_cfg_agc
*agc_settings
, bool atomic
)
6215 struct i2c_device_addr
*dev_addr
= NULL
;
6216 struct drxj_data
*ext_attr
= NULL
;
6217 struct drxj_cfg_agc
*p_agc_settings
= NULL
;
6218 struct drx_common_attr
*common_attr
= NULL
;
6219 drx_write_reg16func_t scu_wr16
= NULL
;
6220 drx_read_reg16func_t scu_rr16
= NULL
;
6223 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
6224 dev_addr
= demod
->my_i2c_dev_addr
;
6225 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
6228 scu_rr16
= drxj_dap_scu_atomic_read_reg16
;
6229 scu_wr16
= drxj_dap_scu_atomic_write_reg16
;
6231 scu_rr16
= DRXJ_DAP
.read_reg16func
;
6232 scu_wr16
= DRXJ_DAP
.write_reg16func
;
6235 /* Configure AGC only if standard is currently active */
6236 if ((ext_attr
->standard
== agc_settings
->standard
) ||
6237 (DRXJ_ISQAMSTD(ext_attr
->standard
) &&
6238 DRXJ_ISQAMSTD(agc_settings
->standard
)) ||
6239 (DRXJ_ISATVSTD(ext_attr
->standard
) &&
6240 DRXJ_ISATVSTD(agc_settings
->standard
))) {
6243 switch (agc_settings
->ctrl_mode
) {
6244 case DRX_AGC_CTRL_AUTO
:
6245 /* Enable IF AGC DAC */
6246 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_STDBY__A
, &data
, 0);
6248 pr_err("error %d\n", rc
);
6251 data
|= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
;
6252 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, data
, 0);
6254 pr_err("error %d\n", rc
);
6258 /* Enable SCU IF AGC loop */
6259 rc
= (*scu_rr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, &data
, 0);
6261 pr_err("error %d\n", rc
);
6264 data
&= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M
;
6265 data
&= ~SCU_RAM_AGC_KI_IF__M
;
6266 if (ext_attr
->standard
== DRX_STANDARD_8VSB
)
6267 data
|= (3 << SCU_RAM_AGC_KI_IF__B
);
6268 else if (DRXJ_ISQAMSTD(ext_attr
->standard
))
6269 data
|= (6 << SCU_RAM_AGC_KI_IF__B
);
6271 data
|= (5 << SCU_RAM_AGC_KI_IF__B
);
6273 if (common_attr
->tuner_if_agc_pol
)
6274 data
|= SCU_RAM_AGC_KI_INV_IF_POL__M
;
6276 data
&= ~SCU_RAM_AGC_KI_INV_IF_POL__M
;
6277 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, data
, 0);
6279 pr_err("error %d\n", rc
);
6283 /* Set speed (using complementary reduction value) */
6284 rc
= (*scu_rr16
)(dev_addr
, SCU_RAM_AGC_KI_RED__A
, &data
, 0);
6286 pr_err("error %d\n", rc
);
6289 data
&= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M
;
6290 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);
6292 pr_err("error %d\n", rc
);
6296 if (agc_settings
->standard
== DRX_STANDARD_8VSB
)
6297 p_agc_settings
= &(ext_attr
->vsb_rf_agc_cfg
);
6298 else if (DRXJ_ISQAMSTD(agc_settings
->standard
))
6299 p_agc_settings
= &(ext_attr
->qam_rf_agc_cfg
);
6300 else if (DRXJ_ISATVSTD(agc_settings
->standard
))
6301 p_agc_settings
= &(ext_attr
->atv_rf_agc_cfg
);
6306 if (p_agc_settings
->ctrl_mode
== DRX_AGC_CTRL_AUTO
) {
6307 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A
, p_agc_settings
->top
, 0);
6309 pr_err("error %d\n", rc
);
6312 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI_TGT__A
, p_agc_settings
->top
, 0);
6314 pr_err("error %d\n", rc
);
6318 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A
, 0, 0);
6320 pr_err("error %d\n", rc
);
6323 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI_TGT__A
, 0, 0);
6325 pr_err("error %d\n", rc
);
6331 case DRX_AGC_CTRL_USER
:
6333 /* Enable IF AGC DAC */
6334 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_STDBY__A
, &data
, 0);
6336 pr_err("error %d\n", rc
);
6339 data
|= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
;
6340 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, data
, 0);
6342 pr_err("error %d\n", rc
);
6346 /* Disable SCU IF AGC loop */
6347 rc
= (*scu_rr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, &data
, 0);
6349 pr_err("error %d\n", rc
);
6352 data
&= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M
;
6353 data
|= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M
;
6354 if (common_attr
->tuner_if_agc_pol
)
6355 data
|= SCU_RAM_AGC_KI_INV_IF_POL__M
;
6357 data
&= ~SCU_RAM_AGC_KI_INV_IF_POL__M
;
6358 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, data
, 0);
6360 pr_err("error %d\n", rc
);
6364 /* Write value to output pin */
6365 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A
, agc_settings
->output_level
, 0);
6367 pr_err("error %d\n", rc
);
6372 case DRX_AGC_CTRL_OFF
:
6374 /* Disable If AGC DAC */
6375 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_STDBY__A
, &data
, 0);
6377 pr_err("error %d\n", rc
);
6380 data
&= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
);
6381 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, data
, 0);
6383 pr_err("error %d\n", rc
);
6387 /* Disable SCU IF AGC loop */
6388 rc
= (*scu_rr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, &data
, 0);
6390 pr_err("error %d\n", rc
);
6393 data
&= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M
;
6394 data
|= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M
;
6395 rc
= (*scu_wr16
)(dev_addr
, SCU_RAM_AGC_KI__A
, data
, 0);
6397 pr_err("error %d\n", rc
);
6403 } /* switch ( agcsettings->ctrl_mode ) */
6405 /* always set the top to support configurations without if-loop */
6406 rc
= (*scu_wr16
) (dev_addr
, SCU_RAM_AGC_INGAIN_TGT_MIN__A
, agc_settings
->top
, 0);
6408 pr_err("error %d\n", rc
);
6413 /* Store if agc settings */
6414 switch (agc_settings
->standard
) {
6415 case DRX_STANDARD_8VSB
:
6416 ext_attr
->vsb_if_agc_cfg
= *agc_settings
;
6418 #ifndef DRXJ_VSB_ONLY
6419 case DRX_STANDARD_ITU_A
:
6420 case DRX_STANDARD_ITU_B
:
6421 case DRX_STANDARD_ITU_C
:
6422 ext_attr
->qam_if_agc_cfg
= *agc_settings
;
6426 case DRX_STANDARD_PAL_SECAM_BG
:
6427 case DRX_STANDARD_PAL_SECAM_DK
:
6428 case DRX_STANDARD_PAL_SECAM_I
:
6429 case DRX_STANDARD_PAL_SECAM_L
:
6430 case DRX_STANDARD_PAL_SECAM_LP
:
6431 case DRX_STANDARD_NTSC
:
6432 case DRX_STANDARD_FM
:
6433 ext_attr
->atv_if_agc_cfg
= *agc_settings
;
6447 * \fn int get_agc_if ()
6448 * \brief get configuration of If AGC
6449 * \param demod instance of demodulator.
6450 * \param agc_settings AGC configuration structure
6454 get_agc_if(struct drx_demod_instance
*demod
, struct drxj_cfg_agc
*agc_settings
)
6456 struct i2c_device_addr
*dev_addr
= NULL
;
6457 struct drxj_data
*ext_attr
= NULL
;
6458 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
6461 dev_addr
= demod
->my_i2c_dev_addr
;
6462 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
6464 /* Return stored ATV AGC settings */
6465 standard
= agc_settings
->standard
;
6466 switch (agc_settings
->standard
) {
6467 case DRX_STANDARD_8VSB
:
6468 *agc_settings
= ext_attr
->vsb_if_agc_cfg
;
6470 #ifndef DRXJ_VSB_ONLY
6471 case DRX_STANDARD_ITU_A
:
6472 case DRX_STANDARD_ITU_B
:
6473 case DRX_STANDARD_ITU_C
:
6474 *agc_settings
= ext_attr
->qam_if_agc_cfg
;
6477 case DRX_STANDARD_PAL_SECAM_BG
:
6478 case DRX_STANDARD_PAL_SECAM_DK
:
6479 case DRX_STANDARD_PAL_SECAM_I
:
6480 case DRX_STANDARD_PAL_SECAM_L
:
6481 case DRX_STANDARD_PAL_SECAM_LP
:
6482 case DRX_STANDARD_NTSC
:
6483 case DRX_STANDARD_FM
:
6484 *agc_settings
= ext_attr
->atv_if_agc_cfg
;
6489 agc_settings
->standard
= standard
;
6491 /* Get AGC output only if standard is currently active */
6492 if ((ext_attr
->standard
== agc_settings
->standard
) ||
6493 (DRXJ_ISQAMSTD(ext_attr
->standard
) &&
6494 DRXJ_ISQAMSTD(agc_settings
->standard
)) ||
6495 (DRXJ_ISATVSTD(ext_attr
->standard
) &&
6496 DRXJ_ISATVSTD(agc_settings
->standard
))) {
6497 /* read output level */
6498 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_AGC_IF_IACCU_HI__A
, &(agc_settings
->output_level
), 0);
6500 pr_err("error %d\n", rc
);
6512 * \fn int set_iqm_af ()
6513 * \brief Configure IQM AF registers
6514 * \param demod instance of demodulator.
6518 static int set_iqm_af(struct drx_demod_instance
*demod
, bool active
)
6521 struct i2c_device_addr
*dev_addr
= NULL
;
6524 dev_addr
= demod
->my_i2c_dev_addr
;
6527 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_STDBY__A
, &data
, 0);
6529 pr_err("error %d\n", rc
);
6533 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
));
6535 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
);
6536 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, data
, 0);
6538 pr_err("error %d\n", rc
);
6547 /*============================================================================*/
6548 /*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
6549 /*============================================================================*/
6551 /*============================================================================*/
6552 /*============================================================================*/
6553 /*== 8VSB DATAPATH FUNCTIONS ==*/
6554 /*============================================================================*/
6555 /*============================================================================*/
6558 * \fn int power_down_vsb ()
6559 * \brief Powr down QAM related blocks.
6560 * \param demod instance of demodulator.
6561 * \param channel pointer to channel data.
6564 static int power_down_vsb(struct drx_demod_instance
*demod
, bool primary
)
6566 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
6567 struct drxjscu_cmd cmd_scu
= { /* command */ 0,
6568 /* parameter_len */ 0,
6570 /* *parameter */ NULL
,
6573 struct drx_cfg_mpeg_output cfg_mpeg_output
;
6579 reset of FEC and VSB HW
6581 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_VSB
|
6582 SCU_RAM_COMMAND_CMD_DEMOD_STOP
;
6583 cmd_scu
.parameter_len
= 0;
6584 cmd_scu
.result_len
= 1;
6585 cmd_scu
.parameter
= NULL
;
6586 cmd_scu
.result
= &cmd_result
;
6587 rc
= scu_command(dev_addr
, &cmd_scu
);
6589 pr_err("error %d\n", rc
);
6593 /* stop all comm_exec */
6594 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_COMM_EXEC__A
, FEC_COMM_EXEC_STOP
, 0);
6596 pr_err("error %d\n", rc
);
6599 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_COMM_EXEC__A
, VSB_COMM_EXEC_STOP
, 0);
6601 pr_err("error %d\n", rc
);
6605 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_COMM_EXEC__A
, IQM_COMM_EXEC_STOP
, 0);
6607 pr_err("error %d\n", rc
);
6610 rc
= set_iqm_af(demod
, false);
6612 pr_err("error %d\n", rc
);
6616 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FS_COMM_EXEC__A
, IQM_FS_COMM_EXEC_STOP
, 0);
6618 pr_err("error %d\n", rc
);
6621 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FD_COMM_EXEC__A
, IQM_FD_COMM_EXEC_STOP
, 0);
6623 pr_err("error %d\n", rc
);
6626 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_COMM_EXEC__A
, IQM_RC_COMM_EXEC_STOP
, 0);
6628 pr_err("error %d\n", rc
);
6631 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_COMM_EXEC__A
, IQM_RT_COMM_EXEC_STOP
, 0);
6633 pr_err("error %d\n", rc
);
6636 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_COMM_EXEC__A
, IQM_CF_COMM_EXEC_STOP
, 0);
6638 pr_err("error %d\n", rc
);
6643 cfg_mpeg_output
.enable_mpeg_output
= false;
6644 rc
= ctrl_set_cfg_mpeg_output(demod
, &cfg_mpeg_output
);
6646 pr_err("error %d\n", rc
);
6656 * \fn int set_vsb_leak_n_gain ()
6657 * \brief Set ATSC demod.
6658 * \param demod instance of demodulator.
6661 static int set_vsb_leak_n_gain(struct drx_demod_instance
*demod
)
6663 struct i2c_device_addr
*dev_addr
= NULL
;
6666 const u8 vsb_ffe_leak_gain_ram0
[] = {
6667 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
6668 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
6669 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
6670 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
6671 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
6672 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
6673 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
6674 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
6675 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
6676 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
6677 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
6678 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
6679 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
6680 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
6681 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
6682 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
6683 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
6684 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
6685 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
6686 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
6687 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
6688 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
6689 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
6690 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
6691 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
6692 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
6693 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
6694 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
6695 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
6696 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
6697 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
6698 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
6699 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
6700 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
6701 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
6702 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
6703 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
6704 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
6705 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
6706 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
6707 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
6708 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
6709 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
6710 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
6711 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
6712 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
6713 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
6714 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
6715 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
6716 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
6717 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
6718 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
6719 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
6720 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
6721 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
6722 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
6723 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
6724 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
6725 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
6726 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
6727 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
6728 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
6729 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
6730 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
6731 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
6732 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
6733 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
6734 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
6735 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
6736 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
6737 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
6738 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
6739 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
6740 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
6741 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
6742 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
6743 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
6744 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
6745 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
6746 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
6747 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
6748 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
6749 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
6750 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
6751 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
6752 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
6753 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
6754 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
6755 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
6756 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
6757 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
6758 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
6759 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
6760 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
6761 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
6762 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
6763 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
6764 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
6765 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
6766 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
6767 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
6768 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
6769 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
6770 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
6771 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
6772 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
6773 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
6774 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
6775 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
6776 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
6777 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
6778 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
6779 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
6780 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
6781 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
6782 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
6783 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
6784 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
6785 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
6786 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
6787 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
6788 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
6789 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
6790 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
6791 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
6792 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
6793 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
6794 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
6797 const u8 vsb_ffe_leak_gain_ram1
[] = {
6798 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
6799 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
6800 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
6801 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
6802 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
6803 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
6804 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
6805 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
6806 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
6807 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
6808 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
6809 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
6810 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
6811 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
6812 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
6813 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
6814 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
6815 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
6816 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
6817 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
6818 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
6819 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
6820 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
6821 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
6822 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
6823 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
6824 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
6825 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
6826 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
6827 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
6828 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
6829 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
6830 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
6831 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
6832 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
6833 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
6834 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
6835 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
6836 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
6837 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
6838 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
6839 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
6840 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
6841 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
6842 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
6843 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
6844 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
6845 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
6846 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
6847 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
6848 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
6849 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
6850 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
6851 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
6854 dev_addr
= demod
->my_i2c_dev_addr
;
6855 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);
6857 pr_err("error %d\n", rc
);
6860 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);
6862 pr_err("error %d\n", rc
);
6873 * \brief Set 8VSB demod.
6874 * \param demod instance of demodulator.
6878 static int set_vsb(struct drx_demod_instance
*demod
)
6880 struct i2c_device_addr
*dev_addr
= NULL
;
6882 struct drx_common_attr
*common_attr
= NULL
;
6883 struct drxjscu_cmd cmd_scu
;
6884 struct drxj_data
*ext_attr
= NULL
;
6887 const u8 vsb_taps_re
[] = {
6888 DRXJ_16TO8(-2), /* re0 */
6889 DRXJ_16TO8(4), /* re1 */
6890 DRXJ_16TO8(1), /* re2 */
6891 DRXJ_16TO8(-4), /* re3 */
6892 DRXJ_16TO8(1), /* re4 */
6893 DRXJ_16TO8(4), /* re5 */
6894 DRXJ_16TO8(-3), /* re6 */
6895 DRXJ_16TO8(-3), /* re7 */
6896 DRXJ_16TO8(6), /* re8 */
6897 DRXJ_16TO8(1), /* re9 */
6898 DRXJ_16TO8(-9), /* re10 */
6899 DRXJ_16TO8(3), /* re11 */
6900 DRXJ_16TO8(12), /* re12 */
6901 DRXJ_16TO8(-9), /* re13 */
6902 DRXJ_16TO8(-15), /* re14 */
6903 DRXJ_16TO8(17), /* re15 */
6904 DRXJ_16TO8(19), /* re16 */
6905 DRXJ_16TO8(-29), /* re17 */
6906 DRXJ_16TO8(-22), /* re18 */
6907 DRXJ_16TO8(45), /* re19 */
6908 DRXJ_16TO8(25), /* re20 */
6909 DRXJ_16TO8(-70), /* re21 */
6910 DRXJ_16TO8(-28), /* re22 */
6911 DRXJ_16TO8(111), /* re23 */
6912 DRXJ_16TO8(30), /* re24 */
6913 DRXJ_16TO8(-201), /* re25 */
6914 DRXJ_16TO8(-31), /* re26 */
6915 DRXJ_16TO8(629) /* re27 */
6918 dev_addr
= demod
->my_i2c_dev_addr
;
6919 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
6920 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
6922 /* stop all comm_exec */
6923 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_COMM_EXEC__A
, FEC_COMM_EXEC_STOP
, 0);
6925 pr_err("error %d\n", rc
);
6928 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_COMM_EXEC__A
, VSB_COMM_EXEC_STOP
, 0);
6930 pr_err("error %d\n", rc
);
6933 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FS_COMM_EXEC__A
, IQM_FS_COMM_EXEC_STOP
, 0);
6935 pr_err("error %d\n", rc
);
6938 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FD_COMM_EXEC__A
, IQM_FD_COMM_EXEC_STOP
, 0);
6940 pr_err("error %d\n", rc
);
6943 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_COMM_EXEC__A
, IQM_RC_COMM_EXEC_STOP
, 0);
6945 pr_err("error %d\n", rc
);
6948 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_COMM_EXEC__A
, IQM_RT_COMM_EXEC_STOP
, 0);
6950 pr_err("error %d\n", rc
);
6953 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_COMM_EXEC__A
, IQM_CF_COMM_EXEC_STOP
, 0);
6955 pr_err("error %d\n", rc
);
6959 /* reset demodulator */
6960 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_VSB
6961 | SCU_RAM_COMMAND_CMD_DEMOD_RESET
;
6962 cmd_scu
.parameter_len
= 0;
6963 cmd_scu
.result_len
= 1;
6964 cmd_scu
.parameter
= NULL
;
6965 cmd_scu
.result
= &cmd_result
;
6966 rc
= scu_command(dev_addr
, &cmd_scu
);
6968 pr_err("error %d\n", rc
);
6972 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_DCF_BYPASS__A
, 1, 0);
6974 pr_err("error %d\n", rc
);
6977 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FS_ADJ_SEL__A
, IQM_FS_ADJ_SEL_B_VSB
, 0);
6979 pr_err("error %d\n", rc
);
6982 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_ADJ_SEL__A
, IQM_RC_ADJ_SEL_B_VSB
, 0);
6984 pr_err("error %d\n", rc
);
6987 ext_attr
->iqm_rc_rate_ofs
= 0x00AD0D79;
6988 rc
= DRXJ_DAP
.write_reg32func(dev_addr
, IQM_RC_RATE_OFS_LO__A
, ext_attr
->iqm_rc_rate_ofs
, 0);
6990 pr_err("error %d\n", rc
);
6993 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_CFAGC_GAINSHIFT__A
, 4, 0);
6995 pr_err("error %d\n", rc
);
6998 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_CYGN1TRK__A
, 1, 0);
7000 pr_err("error %d\n", rc
);
7004 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_CROUT_ENA__A
, 1, 0);
7006 pr_err("error %d\n", rc
);
7009 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_STRETCH__A
, 28, 0);
7011 pr_err("error %d\n", rc
);
7014 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_ACTIVE__A
, 0, 0);
7016 pr_err("error %d\n", rc
);
7019 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_SYMMETRIC__A
, 0, 0);
7021 pr_err("error %d\n", rc
);
7024 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, 3, 0);
7026 pr_err("error %d\n", rc
);
7029 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_OUT_ENA__A
, IQM_CF_OUT_ENA_VSB__M
, 0);
7031 pr_err("error %d\n", rc
);
7034 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_SCALE__A
, 1393, 0);
7036 pr_err("error %d\n", rc
);
7039 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_SCALE_SH__A
, 0, 0);
7041 pr_err("error %d\n", rc
);
7044 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_POW_MEAS_LEN__A
, 1, 0);
7046 pr_err("error %d\n", rc
);
7050 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_RE0__A
, sizeof(vsb_taps_re
), ((u8
*)vsb_taps_re
), 0);
7052 pr_err("error %d\n", rc
);
7055 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_IM0__A
, sizeof(vsb_taps_re
), ((u8
*)vsb_taps_re
), 0);
7057 pr_err("error %d\n", rc
);
7061 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_BNTHRESH__A
, 330, 0);
7063 pr_err("error %d\n", rc
);
7065 } /* set higher threshold */
7066 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_CLPLASTNUM__A
, 90, 0);
7068 pr_err("error %d\n", rc
);
7070 } /* burst detection on */
7071 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_SNRTH_RCA1__A
, 0x0042, 0);
7073 pr_err("error %d\n", rc
);
7075 } /* drop thresholds by 1 dB */
7076 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_SNRTH_RCA2__A
, 0x0053, 0);
7078 pr_err("error %d\n", rc
);
7080 } /* drop thresholds by 2 dB */
7081 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_EQCTRL__A
, 0x1, 0);
7083 pr_err("error %d\n", rc
);
7086 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_GPIO__A
, 0, 0);
7088 pr_err("error %d\n", rc
);
7092 /* Initialize the FEC Subsystem */
7093 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_TOP_ANNEX__A
, FEC_TOP_ANNEX_D
, 0);
7095 pr_err("error %d\n", rc
);
7099 u16 fec_oc_snc_mode
= 0;
7100 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_SNC_MODE__A
, &fec_oc_snc_mode
, 0);
7102 pr_err("error %d\n", rc
);
7105 /* output data even when not locked */
7106 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_SNC_MODE__A
, fec_oc_snc_mode
| FEC_OC_SNC_MODE_UNLOCK_ENABLE__M
, 0);
7108 pr_err("error %d\n", rc
);
7114 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_CLP_LEN__A
, 0, 0);
7116 pr_err("error %d\n", rc
);
7119 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_CLP_TH__A
, 470, 0);
7121 pr_err("error %d\n", rc
);
7124 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_SNS_LEN__A
, 0, 0);
7126 pr_err("error %d\n", rc
);
7129 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_SNRTH_PT__A
, 0xD4, 0);
7131 pr_err("error %d\n", rc
);
7134 /* no transparent, no A&C framing; parity is set in mpegoutput */
7136 u16 fec_oc_reg_mode
= 0;
7137 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_MODE__A
, &fec_oc_reg_mode
, 0);
7139 pr_err("error %d\n", rc
);
7142 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);
7144 pr_err("error %d\n", rc
);
7149 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_DI_TIMEOUT_LO__A
, 0, 0);
7151 pr_err("error %d\n", rc
);
7153 } /* timeout counter for restarting */
7154 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_DI_TIMEOUT_HI__A
, 3, 0);
7156 pr_err("error %d\n", rc
);
7159 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_RS_MODE__A
, 0, 0);
7161 pr_err("error %d\n", rc
);
7163 } /* bypass disabled */
7164 /* initialize RS packet error measurement parameters */
7165 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_RS_MEASUREMENT_PERIOD__A
, FEC_RS_MEASUREMENT_PERIOD
, 0);
7167 pr_err("error %d\n", rc
);
7170 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_RS_MEASUREMENT_PRESCALE__A
, FEC_RS_MEASUREMENT_PRESCALE
, 0);
7172 pr_err("error %d\n", rc
);
7176 /* init measurement period of MER/SER */
7177 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_MEASUREMENT_PERIOD__A
, VSB_TOP_MEASUREMENT_PERIOD
, 0);
7179 pr_err("error %d\n", rc
);
7182 rc
= DRXJ_DAP
.write_reg32func(dev_addr
, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A
, 0, 0);
7184 pr_err("error %d\n", rc
);
7187 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_FEC_MEAS_COUNT__A
, 0, 0);
7189 pr_err("error %d\n", rc
);
7192 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A
, 0, 0);
7194 pr_err("error %d\n", rc
);
7198 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_CKGN1TRK__A
, 128, 0);
7200 pr_err("error %d\n", rc
);
7203 /* B-Input to ADC, PGA+filter in standby */
7204 if (!ext_attr
->has_lna
) {
7205 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_AMUX__A
, 0x02, 0);
7207 pr_err("error %d\n", rc
);
7212 /* turn on IQMAF. It has to be in front of setAgc**() */
7213 rc
= set_iqm_af(demod
, true);
7215 pr_err("error %d\n", rc
);
7218 rc
= adc_synchronization(demod
);
7220 pr_err("error %d\n", rc
);
7224 rc
= init_agc(demod
);
7226 pr_err("error %d\n", rc
);
7229 rc
= set_agc_if(demod
, &(ext_attr
->vsb_if_agc_cfg
), false);
7231 pr_err("error %d\n", rc
);
7234 rc
= set_agc_rf(demod
, &(ext_attr
->vsb_rf_agc_cfg
), false);
7236 pr_err("error %d\n", rc
);
7240 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
7242 struct drxj_cfg_afe_gain vsb_pga_cfg
= { DRX_STANDARD_8VSB
, 0 };
7244 vsb_pga_cfg
.gain
= ext_attr
->vsb_pga_cfg
;
7245 rc
= ctrl_set_cfg_afe_gain(demod
, &vsb_pga_cfg
);
7247 pr_err("error %d\n", rc
);
7251 rc
= ctrl_set_cfg_pre_saw(demod
, &(ext_attr
->vsb_pre_saw_cfg
));
7253 pr_err("error %d\n", rc
);
7257 /* Mpeg output has to be in front of FEC active */
7258 rc
= set_mpegtei_handling(demod
);
7260 pr_err("error %d\n", rc
);
7263 rc
= bit_reverse_mpeg_output(demod
);
7265 pr_err("error %d\n", rc
);
7268 rc
= set_mpeg_start_width(demod
);
7270 pr_err("error %d\n", rc
);
7274 /* TODO: move to set_standard after hardware reset value problem is solved */
7275 /* Configure initial MPEG output */
7276 struct drx_cfg_mpeg_output cfg_mpeg_output
;
7277 cfg_mpeg_output
.enable_mpeg_output
= true;
7278 cfg_mpeg_output
.insert_rs_byte
= common_attr
->mpeg_cfg
.insert_rs_byte
;
7279 cfg_mpeg_output
.enable_parallel
=
7280 common_attr
->mpeg_cfg
.enable_parallel
;
7281 cfg_mpeg_output
.invert_data
= common_attr
->mpeg_cfg
.invert_data
;
7282 cfg_mpeg_output
.invert_err
= common_attr
->mpeg_cfg
.invert_err
;
7283 cfg_mpeg_output
.invert_str
= common_attr
->mpeg_cfg
.invert_str
;
7284 cfg_mpeg_output
.invert_val
= common_attr
->mpeg_cfg
.invert_val
;
7285 cfg_mpeg_output
.invert_clk
= common_attr
->mpeg_cfg
.invert_clk
;
7286 cfg_mpeg_output
.static_clk
= common_attr
->mpeg_cfg
.static_clk
;
7287 cfg_mpeg_output
.bitrate
= common_attr
->mpeg_cfg
.bitrate
;
7288 rc
= ctrl_set_cfg_mpeg_output(demod
, &cfg_mpeg_output
);
7290 pr_err("error %d\n", rc
);
7295 /* TBD: what parameters should be set */
7296 cmd_param
= 0x00; /* Default mode AGC on, etc */
7297 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_VSB
7298 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM
;
7299 cmd_scu
.parameter_len
= 1;
7300 cmd_scu
.result_len
= 1;
7301 cmd_scu
.parameter
= &cmd_param
;
7302 cmd_scu
.result
= &cmd_result
;
7303 rc
= scu_command(dev_addr
, &cmd_scu
);
7305 pr_err("error %d\n", rc
);
7309 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_BEAGC_GAINSHIFT__A
, 0x0004, 0);
7311 pr_err("error %d\n", rc
);
7314 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_SNRTH_PT__A
, 0x00D2, 0);
7316 pr_err("error %d\n", rc
);
7319 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_SYSSMTRNCTRL__A
, VSB_TOP_SYSSMTRNCTRL__PRE
| VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M
, 0);
7321 pr_err("error %d\n", rc
);
7324 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_BEDETCTRL__A
, 0x142, 0);
7326 pr_err("error %d\n", rc
);
7329 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_LBAGCREFLVL__A
, 640, 0);
7331 pr_err("error %d\n", rc
);
7334 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_CYGN1ACQ__A
, 4, 0);
7336 pr_err("error %d\n", rc
);
7339 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_CYGN1TRK__A
, 2, 0);
7341 pr_err("error %d\n", rc
);
7344 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_CYGN2TRK__A
, 3, 0);
7346 pr_err("error %d\n", rc
);
7350 /* start demodulator */
7351 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_VSB
7352 | SCU_RAM_COMMAND_CMD_DEMOD_START
;
7353 cmd_scu
.parameter_len
= 0;
7354 cmd_scu
.result_len
= 1;
7355 cmd_scu
.parameter
= NULL
;
7356 cmd_scu
.result
= &cmd_result
;
7357 rc
= scu_command(dev_addr
, &cmd_scu
);
7359 pr_err("error %d\n", rc
);
7363 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_COMM_EXEC__A
, IQM_COMM_EXEC_ACTIVE
, 0);
7365 pr_err("error %d\n", rc
);
7368 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_COMM_EXEC__A
, VSB_COMM_EXEC_ACTIVE
, 0);
7370 pr_err("error %d\n", rc
);
7373 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_COMM_EXEC__A
, FEC_COMM_EXEC_ACTIVE
, 0);
7375 pr_err("error %d\n", rc
);
7385 * \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
7386 * \brief Get the values of packet error in 8VSB mode
7387 * \return Error code
7389 static int get_vsb_post_rs_pck_err(struct i2c_device_addr
*dev_addr
, u16
*pck_errs
)
7395 u16 packet_errors_mant
= 0;
7396 u16 packet_errors_exp
= 0;
7398 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_RS_NR_FAILURES__A
, &data
, 0);
7400 pr_err("error %d\n", rc
);
7403 packet_errors_mant
= data
& FEC_RS_NR_FAILURES_FIXED_MANT__M
;
7404 packet_errors_exp
= (data
& FEC_RS_NR_FAILURES_EXP__M
)
7405 >> FEC_RS_NR_FAILURES_EXP__B
;
7406 period
= FEC_RS_MEASUREMENT_PERIOD
;
7407 prescale
= FEC_RS_MEASUREMENT_PRESCALE
;
7408 /* packet error rate = (error packet number) per second */
7409 /* 77.3 us is time for per packet */
7410 if (period
* prescale
== 0) {
7411 pr_err("error: period and/or prescale is zero!\n");
7415 (u16
) frac_times1e6(packet_errors_mant
* (1 << packet_errors_exp
),
7416 (period
* prescale
* 77));
7424 * \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
7425 * \brief Get the values of ber in VSB mode
7426 * \return Error code
7428 static int get_vs_bpost_viterbi_ber(struct i2c_device_addr
*dev_addr
, u32
*ber
)
7434 u16 bit_errors_mant
= 0;
7435 u16 bit_errors_exp
= 0;
7437 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_RS_NR_BIT_ERRORS__A
, &data
, 0);
7439 pr_err("error %d\n", rc
);
7442 period
= FEC_RS_MEASUREMENT_PERIOD
;
7443 prescale
= FEC_RS_MEASUREMENT_PRESCALE
;
7445 bit_errors_mant
= data
& FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M
;
7446 bit_errors_exp
= (data
& FEC_RS_NR_BIT_ERRORS_EXP__M
)
7447 >> FEC_RS_NR_BIT_ERRORS_EXP__B
;
7449 if (((bit_errors_mant
<< bit_errors_exp
) >> 3) > 68700)
7452 if (period
* prescale
== 0) {
7453 pr_err("error: period and/or prescale is zero!\n");
7457 frac_times1e6(bit_errors_mant
<<
7459 2) ? (bit_errors_exp
- 3) : bit_errors_exp
),
7460 period
* prescale
* 207 *
7461 ((bit_errors_exp
> 2) ? 1 : 8));
7470 * \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7471 * \brief Get the values of ber in VSB mode
7472 * \return Error code
7474 static int get_vs_bpre_viterbi_ber(struct i2c_device_addr
*dev_addr
, u32
*ber
)
7479 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, VSB_TOP_NR_SYM_ERRS__A
, &data
, 0);
7481 pr_err("error %d\n", rc
);
7486 VSB_TOP_MEASUREMENT_PERIOD
* SYMBOLS_PER_SEGMENT
);
7495 * \fn static short get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ber)
7496 * \brief Get the values of ber in VSB mode
7497 * \return Error code
7499 static int get_vsb_symb_err(struct i2c_device_addr
*dev_addr
, u32
*ser
)
7505 u16 symb_errors_mant
= 0;
7506 u16 symb_errors_exp
= 0;
7508 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_RS_NR_SYMBOL_ERRORS__A
, &data
, 0);
7510 pr_err("error %d\n", rc
);
7513 period
= FEC_RS_MEASUREMENT_PERIOD
;
7514 prescale
= FEC_RS_MEASUREMENT_PRESCALE
;
7516 symb_errors_mant
= data
& FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M
;
7517 symb_errors_exp
= (data
& FEC_RS_NR_SYMBOL_ERRORS_EXP__M
)
7518 >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B
;
7520 if (period
* prescale
== 0) {
7521 pr_err("error: period and/or prescale is zero!\n");
7524 *ser
= (u32
) frac_times1e6((symb_errors_mant
<< symb_errors_exp
) * 1000,
7525 (period
* prescale
* 77318));
7534 * \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7535 * \brief Get the values of MER
7536 * \return Error code
7538 static int get_vsbmer(struct i2c_device_addr
*dev_addr
, u16
*mer
)
7543 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, VSB_TOP_ERR_ENERGY_H__A
, &data_hi
, 0);
7545 pr_err("error %d\n", rc
);
7549 (u16
) (log1_times100(21504) - log1_times100((data_hi
<< 6) / 52));
7557 /*============================================================================*/
7559 * \fn int ctrl_get_vsb_constel()
7560 * \brief Retreive a VSB constellation point via I2C.
7561 * \param demod Pointer to demodulator instance.
7562 * \param complex_nr Pointer to the structure in which to store the
7563 constellation point.
7567 ctrl_get_vsb_constel(struct drx_demod_instance
*demod
, struct drx_complex
*complex_nr
)
7569 struct i2c_device_addr
*dev_addr
= NULL
;
7571 /**< device address */
7572 u16 vsb_top_comm_mb
= 0; /**< VSB SL MB configuration */
7573 u16 vsb_top_comm_mb_init
= 0; /**< VSB SL MB intial configuration */
7574 u16 re
= 0; /**< constellation Re part */
7577 /* read device info */
7578 dev_addr
= demod
->my_i2c_dev_addr
;
7581 /* Monitor bus grabbing is an open external interface issue */
7582 /* Needs to be checked when external interface PG is updated */
7584 /* Configure MB (Monitor bus) */
7585 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, VSB_TOP_COMM_MB__A
, &vsb_top_comm_mb_init
, 0);
7587 pr_err("error %d\n", rc
);
7590 /* set observe flag & MB mux */
7591 vsb_top_comm_mb
= (vsb_top_comm_mb_init
|
7592 VSB_TOP_COMM_MB_OBS_OBS_ON
|
7593 VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2
);
7594 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_COMM_MB__A
, vsb_top_comm_mb
, 0);
7596 pr_err("error %d\n", rc
);
7600 /* Enable MB grabber in the FEC OC */
7601 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_OCR_MODE__A
, FEC_OC_OCR_MODE_GRAB_ENABLE__M
, 0);
7603 pr_err("error %d\n", rc
);
7607 /* Disable MB grabber in the FEC OC */
7608 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_OCR_MODE__A
, 0x0, 0);
7610 pr_err("error %d\n", rc
);
7615 rc
= DRXJ_DAP
.read_reg32func(dev_addr
, FEC_OC_OCR_GRAB_RD1__A
, &data
, 0);
7617 pr_err("error %d\n", rc
);
7620 re
= (u16
) (((data
>> 10) & 0x300) | ((data
>> 2) & 0xff));
7623 complex_nr
->re
= re
;
7626 /* Restore MB (Monitor bus) */
7627 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, VSB_TOP_COMM_MB__A
, vsb_top_comm_mb_init
, 0);
7629 pr_err("error %d\n", rc
);
7639 /*============================================================================*/
7640 /*== END 8VSB DATAPATH FUNCTIONS ==*/
7641 /*============================================================================*/
7643 /*============================================================================*/
7644 /*============================================================================*/
7645 /*== QAM DATAPATH FUNCTIONS ==*/
7646 /*============================================================================*/
7647 /*============================================================================*/
7650 * \fn int power_down_qam ()
7651 * \brief Powr down QAM related blocks.
7652 * \param demod instance of demodulator.
7653 * \param channel pointer to channel data.
7656 static int power_down_qam(struct drx_demod_instance
*demod
, bool primary
)
7658 struct drxjscu_cmd cmd_scu
= { /* command */ 0,
7659 /* parameter_len */ 0,
7661 /* *parameter */ NULL
,
7665 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
7666 struct drx_cfg_mpeg_output cfg_mpeg_output
;
7671 resets IQM, QAM and FEC HW blocks
7673 /* stop all comm_exec */
7674 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_COMM_EXEC__A
, FEC_COMM_EXEC_STOP
, 0);
7676 pr_err("error %d\n", rc
);
7679 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_COMM_EXEC__A
, QAM_COMM_EXEC_STOP
, 0);
7681 pr_err("error %d\n", rc
);
7685 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_QAM
|
7686 SCU_RAM_COMMAND_CMD_DEMOD_STOP
;
7687 cmd_scu
.parameter_len
= 0;
7688 cmd_scu
.result_len
= 1;
7689 cmd_scu
.parameter
= NULL
;
7690 cmd_scu
.result
= &cmd_result
;
7691 rc
= scu_command(dev_addr
, &cmd_scu
);
7693 pr_err("error %d\n", rc
);
7698 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_COMM_EXEC__A
, IQM_COMM_EXEC_STOP
, 0);
7700 pr_err("error %d\n", rc
);
7703 rc
= set_iqm_af(demod
, false);
7705 pr_err("error %d\n", rc
);
7709 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FS_COMM_EXEC__A
, IQM_FS_COMM_EXEC_STOP
, 0);
7711 pr_err("error %d\n", rc
);
7714 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FD_COMM_EXEC__A
, IQM_FD_COMM_EXEC_STOP
, 0);
7716 pr_err("error %d\n", rc
);
7719 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_COMM_EXEC__A
, IQM_RC_COMM_EXEC_STOP
, 0);
7721 pr_err("error %d\n", rc
);
7724 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_COMM_EXEC__A
, IQM_RT_COMM_EXEC_STOP
, 0);
7726 pr_err("error %d\n", rc
);
7729 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_COMM_EXEC__A
, IQM_CF_COMM_EXEC_STOP
, 0);
7731 pr_err("error %d\n", rc
);
7736 cfg_mpeg_output
.enable_mpeg_output
= false;
7737 rc
= ctrl_set_cfg_mpeg_output(demod
, &cfg_mpeg_output
);
7739 pr_err("error %d\n", rc
);
7748 /*============================================================================*/
7751 * \fn int set_qam_measurement ()
7752 * \brief Setup of the QAM Measuremnt intervals for signal quality
7753 * \param demod instance of demod.
7754 * \param constellation current constellation.
7758 * Take into account that for certain settings the errorcounters can overflow.
7759 * The implementation does not check this.
7761 * TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
7762 * constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
7766 #ifndef DRXJ_VSB_ONLY
7768 set_qam_measurement(struct drx_demod_instance
*demod
,
7769 enum drx_modulation constellation
, u32 symbol_rate
)
7771 struct i2c_device_addr
*dev_addr
= NULL
; /* device address for I2C writes */
7772 struct drxj_data
*ext_attr
= NULL
; /* Global data container for DRXJ specif data */
7774 u32 fec_bits_desired
= 0; /* BER accounting period */
7775 u16 fec_rs_plen
= 0; /* defines RS BER measurement period */
7776 u16 fec_rs_prescale
= 0; /* ReedSolomon Measurement Prescale */
7777 u32 fec_rs_period
= 0; /* Value for corresponding I2C register */
7778 u32 fec_rs_bit_cnt
= 0; /* Actual precise amount of bits */
7779 u32 fec_oc_snc_fail_period
= 0; /* Value for corresponding I2C register */
7780 u32 qam_vd_period
= 0; /* Value for corresponding I2C register */
7781 u32 qam_vd_bit_cnt
= 0; /* Actual precise amount of bits */
7782 u16 fec_vd_plen
= 0; /* no of trellis symbols: VD SER measur period */
7783 u16 qam_vd_prescale
= 0; /* Viterbi Measurement Prescale */
7785 dev_addr
= demod
->my_i2c_dev_addr
;
7786 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
7788 fec_bits_desired
= ext_attr
->fec_bits_desired
;
7789 fec_rs_prescale
= ext_attr
->fec_rs_prescale
;
7791 switch (constellation
) {
7792 case DRX_CONSTELLATION_QAM16
:
7793 fec_bits_desired
= 4 * symbol_rate
;
7795 case DRX_CONSTELLATION_QAM32
:
7796 fec_bits_desired
= 5 * symbol_rate
;
7798 case DRX_CONSTELLATION_QAM64
:
7799 fec_bits_desired
= 6 * symbol_rate
;
7801 case DRX_CONSTELLATION_QAM128
:
7802 fec_bits_desired
= 7 * symbol_rate
;
7804 case DRX_CONSTELLATION_QAM256
:
7805 fec_bits_desired
= 8 * symbol_rate
;
7811 /* Parameters for Reed-Solomon Decoder */
7812 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
7813 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
7814 /* result is within 32 bit arithmetic -> */
7815 /* no need for mult or frac functions */
7817 /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
7818 switch (ext_attr
->standard
) {
7819 case DRX_STANDARD_ITU_A
:
7820 case DRX_STANDARD_ITU_C
:
7821 fec_rs_plen
= 204 * 8;
7823 case DRX_STANDARD_ITU_B
:
7824 fec_rs_plen
= 128 * 7;
7830 ext_attr
->fec_rs_plen
= fec_rs_plen
; /* for getSigQual */
7831 fec_rs_bit_cnt
= fec_rs_prescale
* fec_rs_plen
; /* temp storage */
7832 if (fec_rs_bit_cnt
== 0) {
7833 pr_err("error: fec_rs_bit_cnt is zero!\n");
7836 fec_rs_period
= fec_bits_desired
/ fec_rs_bit_cnt
+ 1; /* ceil */
7837 if (ext_attr
->standard
!= DRX_STANDARD_ITU_B
)
7838 fec_oc_snc_fail_period
= fec_rs_period
;
7840 /* limit to max 16 bit value (I2C register width) if needed */
7841 if (fec_rs_period
> 0xFFFF)
7842 fec_rs_period
= 0xFFFF;
7844 /* write corresponding registers */
7845 switch (ext_attr
->standard
) {
7846 case DRX_STANDARD_ITU_A
:
7847 case DRX_STANDARD_ITU_C
:
7849 case DRX_STANDARD_ITU_B
:
7850 switch (constellation
) {
7851 case DRX_CONSTELLATION_QAM64
:
7852 fec_rs_period
= 31581;
7853 fec_oc_snc_fail_period
= 17932;
7855 case DRX_CONSTELLATION_QAM256
:
7856 fec_rs_period
= 45446;
7857 fec_oc_snc_fail_period
= 25805;
7867 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_SNC_FAIL_PERIOD__A
, (u16
)fec_oc_snc_fail_period
, 0);
7869 pr_err("error %d\n", rc
);
7872 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_RS_MEASUREMENT_PERIOD__A
, (u16
)fec_rs_period
, 0);
7874 pr_err("error %d\n", rc
);
7877 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_RS_MEASUREMENT_PRESCALE__A
, fec_rs_prescale
, 0);
7879 pr_err("error %d\n", rc
);
7882 ext_attr
->fec_rs_period
= (u16
) fec_rs_period
;
7883 ext_attr
->fec_rs_prescale
= fec_rs_prescale
;
7884 rc
= DRXJ_DAP
.write_reg32func(dev_addr
, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A
, 0, 0);
7886 pr_err("error %d\n", rc
);
7889 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_FEC_MEAS_COUNT__A
, 0, 0);
7891 pr_err("error %d\n", rc
);
7894 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A
, 0, 0);
7896 pr_err("error %d\n", rc
);
7900 if (ext_attr
->standard
== DRX_STANDARD_ITU_B
) {
7901 /* Parameters for Viterbi Decoder */
7902 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
7903 /* (qamvd_prescale*plen*(qam_constellation+1))) */
7904 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
7905 /* result is within 32 bit arithmetic -> */
7906 /* no need for mult or frac functions */
7908 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
7909 fec_vd_plen
= ext_attr
->fec_vd_plen
;
7910 qam_vd_prescale
= ext_attr
->qam_vd_prescale
;
7911 qam_vd_bit_cnt
= qam_vd_prescale
* fec_vd_plen
; /* temp storage */
7913 switch (constellation
) {
7914 case DRX_CONSTELLATION_QAM64
:
7915 /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
7917 qam_vd_bit_cnt
* (QAM_TOP_CONSTELLATION_QAM64
+ 1)
7918 * (QAM_TOP_CONSTELLATION_QAM64
+ 1);
7920 case DRX_CONSTELLATION_QAM256
:
7921 /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
7923 qam_vd_bit_cnt
* (QAM_TOP_CONSTELLATION_QAM256
+ 1)
7924 * (QAM_TOP_CONSTELLATION_QAM256
+ 1);
7929 if (qam_vd_period
== 0) {
7930 pr_err("error: qam_vd_period is zero!\n");
7933 qam_vd_period
= fec_bits_desired
/ qam_vd_period
;
7934 /* limit to max 16 bit value (I2C register width) if needed */
7935 if (qam_vd_period
> 0xFFFF)
7936 qam_vd_period
= 0xFFFF;
7938 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
7939 qam_vd_bit_cnt
*= qam_vd_period
;
7941 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_VD_MEASUREMENT_PERIOD__A
, (u16
)qam_vd_period
, 0);
7943 pr_err("error %d\n", rc
);
7946 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_VD_MEASUREMENT_PRESCALE__A
, qam_vd_prescale
, 0);
7948 pr_err("error %d\n", rc
);
7951 ext_attr
->qam_vd_period
= (u16
) qam_vd_period
;
7952 ext_attr
->qam_vd_prescale
= qam_vd_prescale
;
7960 /*============================================================================*/
7963 * \fn int set_qam16 ()
7964 * \brief QAM16 specific setup
7965 * \param demod instance of demod.
7968 static int set_qam16(struct drx_demod_instance
*demod
)
7970 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
7972 const u8 qam_dq_qual_fun
[] = {
7973 DRXJ_16TO8(2), /* fun0 */
7974 DRXJ_16TO8(2), /* fun1 */
7975 DRXJ_16TO8(2), /* fun2 */
7976 DRXJ_16TO8(2), /* fun3 */
7977 DRXJ_16TO8(3), /* fun4 */
7978 DRXJ_16TO8(3), /* fun5 */
7980 const u8 qam_eq_cma_rad
[] = {
7981 DRXJ_16TO8(13517), /* RAD0 */
7982 DRXJ_16TO8(13517), /* RAD1 */
7983 DRXJ_16TO8(13517), /* RAD2 */
7984 DRXJ_16TO8(13517), /* RAD3 */
7985 DRXJ_16TO8(13517), /* RAD4 */
7986 DRXJ_16TO8(13517), /* RAD5 */
7989 rc
= DRXJ_DAP
.write_block_func(dev_addr
, QAM_DQ_QUAL_FUN0__A
, sizeof(qam_dq_qual_fun
), ((u8
*)qam_dq_qual_fun
), 0);
7991 pr_err("error %d\n", rc
);
7994 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);
7996 pr_err("error %d\n", rc
);
8000 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RTH__A
, 140, 0);
8002 pr_err("error %d\n", rc
);
8005 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FTH__A
, 50, 0);
8007 pr_err("error %d\n", rc
);
8010 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_PTH__A
, 120, 0);
8012 pr_err("error %d\n", rc
);
8015 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_QTH__A
, 230, 0);
8017 pr_err("error %d\n", rc
);
8020 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_CTH__A
, 95, 0);
8022 pr_err("error %d\n", rc
);
8025 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MTH__A
, 105, 0);
8027 pr_err("error %d\n", rc
);
8031 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RATE_LIM__A
, 40, 0);
8033 pr_err("error %d\n", rc
);
8036 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FREQ_LIM__A
, 56, 0);
8038 pr_err("error %d\n", rc
);
8041 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_COUNT_LIM__A
, 3, 0);
8043 pr_err("error %d\n", rc
);
8047 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A
, 16, 0);
8049 pr_err("error %d\n", rc
);
8052 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A
, 220, 0);
8054 pr_err("error %d\n", rc
);
8057 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A
, 25, 0);
8059 pr_err("error %d\n", rc
);
8062 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A
, 6, 0);
8064 pr_err("error %d\n", rc
);
8067 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A
, (u16
)(-24), 0);
8069 pr_err("error %d\n", rc
);
8072 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A
, (u16
)(-65), 0);
8074 pr_err("error %d\n", rc
);
8077 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A
, (u16
)(-127), 0);
8079 pr_err("error %d\n", rc
);
8083 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_FINE__A
, 15, 0);
8085 pr_err("error %d\n", rc
);
8088 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_COARSE__A
, 40, 0);
8090 pr_err("error %d\n", rc
);
8093 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_FINE__A
, 2, 0);
8095 pr_err("error %d\n", rc
);
8098 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_MEDIUM__A
, 20, 0);
8100 pr_err("error %d\n", rc
);
8103 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_COARSE__A
, 255, 0);
8105 pr_err("error %d\n", rc
);
8108 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_FINE__A
, 2, 0);
8110 pr_err("error %d\n", rc
);
8113 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_MEDIUM__A
, 10, 0);
8115 pr_err("error %d\n", rc
);
8118 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_COARSE__A
, 50, 0);
8120 pr_err("error %d\n", rc
);
8123 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_FINE__A
, 12, 0);
8125 pr_err("error %d\n", rc
);
8128 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_MEDIUM__A
, 24, 0);
8130 pr_err("error %d\n", rc
);
8133 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_COARSE__A
, 24, 0);
8135 pr_err("error %d\n", rc
);
8138 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_FINE__A
, 12, 0);
8140 pr_err("error %d\n", rc
);
8143 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_MEDIUM__A
, 16, 0);
8145 pr_err("error %d\n", rc
);
8148 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_COARSE__A
, 16, 0);
8150 pr_err("error %d\n", rc
);
8153 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_FINE__A
, 16, 0);
8155 pr_err("error %d\n", rc
);
8158 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_MEDIUM__A
, 32, 0);
8160 pr_err("error %d\n", rc
);
8163 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_COARSE__A
, 240, 0);
8165 pr_err("error %d\n", rc
);
8168 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_FINE__A
, 5, 0);
8170 pr_err("error %d\n", rc
);
8173 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_MEDIUM__A
, 15, 0);
8175 pr_err("error %d\n", rc
);
8178 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_COARSE__A
, 32, 0);
8180 pr_err("error %d\n", rc
);
8184 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 40960, 0);
8186 pr_err("error %d\n", rc
);
8195 /*============================================================================*/
8198 * \fn int set_qam32 ()
8199 * \brief QAM32 specific setup
8200 * \param demod instance of demod.
8203 static int set_qam32(struct drx_demod_instance
*demod
)
8205 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
8207 const u8 qam_dq_qual_fun
[] = {
8208 DRXJ_16TO8(3), /* fun0 */
8209 DRXJ_16TO8(3), /* fun1 */
8210 DRXJ_16TO8(3), /* fun2 */
8211 DRXJ_16TO8(3), /* fun3 */
8212 DRXJ_16TO8(4), /* fun4 */
8213 DRXJ_16TO8(4), /* fun5 */
8215 const u8 qam_eq_cma_rad
[] = {
8216 DRXJ_16TO8(6707), /* RAD0 */
8217 DRXJ_16TO8(6707), /* RAD1 */
8218 DRXJ_16TO8(6707), /* RAD2 */
8219 DRXJ_16TO8(6707), /* RAD3 */
8220 DRXJ_16TO8(6707), /* RAD4 */
8221 DRXJ_16TO8(6707), /* RAD5 */
8224 rc
= DRXJ_DAP
.write_block_func(dev_addr
, QAM_DQ_QUAL_FUN0__A
, sizeof(qam_dq_qual_fun
), ((u8
*)qam_dq_qual_fun
), 0);
8226 pr_err("error %d\n", rc
);
8229 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);
8231 pr_err("error %d\n", rc
);
8235 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RTH__A
, 90, 0);
8237 pr_err("error %d\n", rc
);
8240 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FTH__A
, 50, 0);
8242 pr_err("error %d\n", rc
);
8245 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_PTH__A
, 100, 0);
8247 pr_err("error %d\n", rc
);
8250 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_QTH__A
, 170, 0);
8252 pr_err("error %d\n", rc
);
8255 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_CTH__A
, 80, 0);
8257 pr_err("error %d\n", rc
);
8260 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MTH__A
, 100, 0);
8262 pr_err("error %d\n", rc
);
8266 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RATE_LIM__A
, 40, 0);
8268 pr_err("error %d\n", rc
);
8271 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FREQ_LIM__A
, 56, 0);
8273 pr_err("error %d\n", rc
);
8276 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_COUNT_LIM__A
, 3, 0);
8278 pr_err("error %d\n", rc
);
8282 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A
, 12, 0);
8284 pr_err("error %d\n", rc
);
8287 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A
, 140, 0);
8289 pr_err("error %d\n", rc
);
8292 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A
, (u16
)(-8), 0);
8294 pr_err("error %d\n", rc
);
8297 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A
, (u16
)(-16), 0);
8299 pr_err("error %d\n", rc
);
8302 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A
, (u16
)(-26), 0);
8304 pr_err("error %d\n", rc
);
8307 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A
, (u16
)(-56), 0);
8309 pr_err("error %d\n", rc
);
8312 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A
, (u16
)(-86), 0);
8314 pr_err("error %d\n", rc
);
8318 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_FINE__A
, 15, 0);
8320 pr_err("error %d\n", rc
);
8323 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_COARSE__A
, 40, 0);
8325 pr_err("error %d\n", rc
);
8328 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_FINE__A
, 2, 0);
8330 pr_err("error %d\n", rc
);
8333 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_MEDIUM__A
, 20, 0);
8335 pr_err("error %d\n", rc
);
8338 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_COARSE__A
, 255, 0);
8340 pr_err("error %d\n", rc
);
8343 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_FINE__A
, 2, 0);
8345 pr_err("error %d\n", rc
);
8348 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_MEDIUM__A
, 10, 0);
8350 pr_err("error %d\n", rc
);
8353 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_COARSE__A
, 50, 0);
8355 pr_err("error %d\n", rc
);
8358 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_FINE__A
, 12, 0);
8360 pr_err("error %d\n", rc
);
8363 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_MEDIUM__A
, 24, 0);
8365 pr_err("error %d\n", rc
);
8368 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_COARSE__A
, 24, 0);
8370 pr_err("error %d\n", rc
);
8373 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_FINE__A
, 12, 0);
8375 pr_err("error %d\n", rc
);
8378 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_MEDIUM__A
, 16, 0);
8380 pr_err("error %d\n", rc
);
8383 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_COARSE__A
, 16, 0);
8385 pr_err("error %d\n", rc
);
8388 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_FINE__A
, 16, 0);
8390 pr_err("error %d\n", rc
);
8393 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_MEDIUM__A
, 32, 0);
8395 pr_err("error %d\n", rc
);
8398 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_COARSE__A
, 176, 0);
8400 pr_err("error %d\n", rc
);
8403 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_FINE__A
, 5, 0);
8405 pr_err("error %d\n", rc
);
8408 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_MEDIUM__A
, 15, 0);
8410 pr_err("error %d\n", rc
);
8413 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_COARSE__A
, 8, 0);
8415 pr_err("error %d\n", rc
);
8419 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 20480, 0);
8421 pr_err("error %d\n", rc
);
8430 /*============================================================================*/
8433 * \fn int set_qam64 ()
8434 * \brief QAM64 specific setup
8435 * \param demod instance of demod.
8438 static int set_qam64(struct drx_demod_instance
*demod
)
8440 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
8442 const u8 qam_dq_qual_fun
[] = { /* this is hw reset value. no necessary to re-write */
8443 DRXJ_16TO8(4), /* fun0 */
8444 DRXJ_16TO8(4), /* fun1 */
8445 DRXJ_16TO8(4), /* fun2 */
8446 DRXJ_16TO8(4), /* fun3 */
8447 DRXJ_16TO8(6), /* fun4 */
8448 DRXJ_16TO8(6), /* fun5 */
8450 const u8 qam_eq_cma_rad
[] = {
8451 DRXJ_16TO8(13336), /* RAD0 */
8452 DRXJ_16TO8(12618), /* RAD1 */
8453 DRXJ_16TO8(11988), /* RAD2 */
8454 DRXJ_16TO8(13809), /* RAD3 */
8455 DRXJ_16TO8(13809), /* RAD4 */
8456 DRXJ_16TO8(15609), /* RAD5 */
8459 rc
= DRXJ_DAP
.write_block_func(dev_addr
, QAM_DQ_QUAL_FUN0__A
, sizeof(qam_dq_qual_fun
), ((u8
*)qam_dq_qual_fun
), 0);
8461 pr_err("error %d\n", rc
);
8464 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);
8466 pr_err("error %d\n", rc
);
8470 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RTH__A
, 105, 0);
8472 pr_err("error %d\n", rc
);
8475 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FTH__A
, 60, 0);
8477 pr_err("error %d\n", rc
);
8480 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_PTH__A
, 100, 0);
8482 pr_err("error %d\n", rc
);
8485 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_QTH__A
, 195, 0);
8487 pr_err("error %d\n", rc
);
8490 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_CTH__A
, 80, 0);
8492 pr_err("error %d\n", rc
);
8495 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MTH__A
, 84, 0);
8497 pr_err("error %d\n", rc
);
8501 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RATE_LIM__A
, 40, 0);
8503 pr_err("error %d\n", rc
);
8506 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FREQ_LIM__A
, 32, 0);
8508 pr_err("error %d\n", rc
);
8511 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_COUNT_LIM__A
, 3, 0);
8513 pr_err("error %d\n", rc
);
8517 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A
, 12, 0);
8519 pr_err("error %d\n", rc
);
8522 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A
, 141, 0);
8524 pr_err("error %d\n", rc
);
8527 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A
, 7, 0);
8529 pr_err("error %d\n", rc
);
8532 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A
, 0, 0);
8534 pr_err("error %d\n", rc
);
8537 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A
, (u16
)(-15), 0);
8539 pr_err("error %d\n", rc
);
8542 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A
, (u16
)(-45), 0);
8544 pr_err("error %d\n", rc
);
8547 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A
, (u16
)(-80), 0);
8549 pr_err("error %d\n", rc
);
8553 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_FINE__A
, 15, 0);
8555 pr_err("error %d\n", rc
);
8558 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_COARSE__A
, 40, 0);
8560 pr_err("error %d\n", rc
);
8563 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_FINE__A
, 2, 0);
8565 pr_err("error %d\n", rc
);
8568 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_MEDIUM__A
, 30, 0);
8570 pr_err("error %d\n", rc
);
8573 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_COARSE__A
, 255, 0);
8575 pr_err("error %d\n", rc
);
8578 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_FINE__A
, 2, 0);
8580 pr_err("error %d\n", rc
);
8583 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_MEDIUM__A
, 15, 0);
8585 pr_err("error %d\n", rc
);
8588 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_COARSE__A
, 80, 0);
8590 pr_err("error %d\n", rc
);
8593 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_FINE__A
, 12, 0);
8595 pr_err("error %d\n", rc
);
8598 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_MEDIUM__A
, 24, 0);
8600 pr_err("error %d\n", rc
);
8603 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_COARSE__A
, 24, 0);
8605 pr_err("error %d\n", rc
);
8608 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_FINE__A
, 12, 0);
8610 pr_err("error %d\n", rc
);
8613 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_MEDIUM__A
, 16, 0);
8615 pr_err("error %d\n", rc
);
8618 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_COARSE__A
, 16, 0);
8620 pr_err("error %d\n", rc
);
8623 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_FINE__A
, 16, 0);
8625 pr_err("error %d\n", rc
);
8628 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_MEDIUM__A
, 48, 0);
8630 pr_err("error %d\n", rc
);
8633 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_COARSE__A
, 160, 0);
8635 pr_err("error %d\n", rc
);
8638 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_FINE__A
, 5, 0);
8640 pr_err("error %d\n", rc
);
8643 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_MEDIUM__A
, 15, 0);
8645 pr_err("error %d\n", rc
);
8648 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_COARSE__A
, 32, 0);
8650 pr_err("error %d\n", rc
);
8654 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 43008, 0);
8656 pr_err("error %d\n", rc
);
8665 /*============================================================================*/
8668 * \fn int set_qam128 ()
8669 * \brief QAM128 specific setup
8670 * \param demod: instance of demod.
8673 static int set_qam128(struct drx_demod_instance
*demod
)
8675 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
8677 const u8 qam_dq_qual_fun
[] = {
8678 DRXJ_16TO8(6), /* fun0 */
8679 DRXJ_16TO8(6), /* fun1 */
8680 DRXJ_16TO8(6), /* fun2 */
8681 DRXJ_16TO8(6), /* fun3 */
8682 DRXJ_16TO8(9), /* fun4 */
8683 DRXJ_16TO8(9), /* fun5 */
8685 const u8 qam_eq_cma_rad
[] = {
8686 DRXJ_16TO8(6164), /* RAD0 */
8687 DRXJ_16TO8(6598), /* RAD1 */
8688 DRXJ_16TO8(6394), /* RAD2 */
8689 DRXJ_16TO8(6409), /* RAD3 */
8690 DRXJ_16TO8(6656), /* RAD4 */
8691 DRXJ_16TO8(7238), /* RAD5 */
8694 rc
= DRXJ_DAP
.write_block_func(dev_addr
, QAM_DQ_QUAL_FUN0__A
, sizeof(qam_dq_qual_fun
), ((u8
*)qam_dq_qual_fun
), 0);
8696 pr_err("error %d\n", rc
);
8699 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);
8701 pr_err("error %d\n", rc
);
8705 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RTH__A
, 50, 0);
8707 pr_err("error %d\n", rc
);
8710 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FTH__A
, 60, 0);
8712 pr_err("error %d\n", rc
);
8715 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_PTH__A
, 100, 0);
8717 pr_err("error %d\n", rc
);
8720 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_QTH__A
, 140, 0);
8722 pr_err("error %d\n", rc
);
8725 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_CTH__A
, 80, 0);
8727 pr_err("error %d\n", rc
);
8730 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MTH__A
, 100, 0);
8732 pr_err("error %d\n", rc
);
8736 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RATE_LIM__A
, 40, 0);
8738 pr_err("error %d\n", rc
);
8741 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FREQ_LIM__A
, 32, 0);
8743 pr_err("error %d\n", rc
);
8746 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_COUNT_LIM__A
, 3, 0);
8748 pr_err("error %d\n", rc
);
8752 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A
, 8, 0);
8754 pr_err("error %d\n", rc
);
8757 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A
, 65, 0);
8759 pr_err("error %d\n", rc
);
8762 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A
, 5, 0);
8764 pr_err("error %d\n", rc
);
8767 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A
, 3, 0);
8769 pr_err("error %d\n", rc
);
8772 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A
, (u16
)(-1), 0);
8774 pr_err("error %d\n", rc
);
8777 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A
, 12, 0);
8779 pr_err("error %d\n", rc
);
8782 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A
, (u16
)(-23), 0);
8784 pr_err("error %d\n", rc
);
8788 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_FINE__A
, 15, 0);
8790 pr_err("error %d\n", rc
);
8793 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_COARSE__A
, 40, 0);
8795 pr_err("error %d\n", rc
);
8798 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_FINE__A
, 2, 0);
8800 pr_err("error %d\n", rc
);
8803 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_MEDIUM__A
, 40, 0);
8805 pr_err("error %d\n", rc
);
8808 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_COARSE__A
, 255, 0);
8810 pr_err("error %d\n", rc
);
8813 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_FINE__A
, 2, 0);
8815 pr_err("error %d\n", rc
);
8818 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_MEDIUM__A
, 20, 0);
8820 pr_err("error %d\n", rc
);
8823 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_COARSE__A
, 80, 0);
8825 pr_err("error %d\n", rc
);
8828 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_FINE__A
, 12, 0);
8830 pr_err("error %d\n", rc
);
8833 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_MEDIUM__A
, 24, 0);
8835 pr_err("error %d\n", rc
);
8838 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_COARSE__A
, 24, 0);
8840 pr_err("error %d\n", rc
);
8843 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_FINE__A
, 12, 0);
8845 pr_err("error %d\n", rc
);
8848 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_MEDIUM__A
, 16, 0);
8850 pr_err("error %d\n", rc
);
8853 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_COARSE__A
, 16, 0);
8855 pr_err("error %d\n", rc
);
8858 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_FINE__A
, 16, 0);
8860 pr_err("error %d\n", rc
);
8863 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_MEDIUM__A
, 32, 0);
8865 pr_err("error %d\n", rc
);
8868 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_COARSE__A
, 144, 0);
8870 pr_err("error %d\n", rc
);
8873 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_FINE__A
, 5, 0);
8875 pr_err("error %d\n", rc
);
8878 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_MEDIUM__A
, 15, 0);
8880 pr_err("error %d\n", rc
);
8883 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_COARSE__A
, 16, 0);
8885 pr_err("error %d\n", rc
);
8889 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 20992, 0);
8891 pr_err("error %d\n", rc
);
8900 /*============================================================================*/
8903 * \fn int set_qam256 ()
8904 * \brief QAM256 specific setup
8905 * \param demod: instance of demod.
8908 static int set_qam256(struct drx_demod_instance
*demod
)
8910 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
8912 const u8 qam_dq_qual_fun
[] = {
8913 DRXJ_16TO8(8), /* fun0 */
8914 DRXJ_16TO8(8), /* fun1 */
8915 DRXJ_16TO8(8), /* fun2 */
8916 DRXJ_16TO8(8), /* fun3 */
8917 DRXJ_16TO8(12), /* fun4 */
8918 DRXJ_16TO8(12), /* fun5 */
8920 const u8 qam_eq_cma_rad
[] = {
8921 DRXJ_16TO8(12345), /* RAD0 */
8922 DRXJ_16TO8(12345), /* RAD1 */
8923 DRXJ_16TO8(13626), /* RAD2 */
8924 DRXJ_16TO8(12931), /* RAD3 */
8925 DRXJ_16TO8(14719), /* RAD4 */
8926 DRXJ_16TO8(15356), /* RAD5 */
8929 rc
= DRXJ_DAP
.write_block_func(dev_addr
, QAM_DQ_QUAL_FUN0__A
, sizeof(qam_dq_qual_fun
), ((u8
*)qam_dq_qual_fun
), 0);
8931 pr_err("error %d\n", rc
);
8934 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);
8936 pr_err("error %d\n", rc
);
8940 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RTH__A
, 50, 0);
8942 pr_err("error %d\n", rc
);
8945 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FTH__A
, 60, 0);
8947 pr_err("error %d\n", rc
);
8950 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_PTH__A
, 100, 0);
8952 pr_err("error %d\n", rc
);
8955 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_QTH__A
, 150, 0);
8957 pr_err("error %d\n", rc
);
8960 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_CTH__A
, 80, 0);
8962 pr_err("error %d\n", rc
);
8965 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MTH__A
, 110, 0);
8967 pr_err("error %d\n", rc
);
8971 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RATE_LIM__A
, 40, 0);
8973 pr_err("error %d\n", rc
);
8976 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_FREQ_LIM__A
, 16, 0);
8978 pr_err("error %d\n", rc
);
8981 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_COUNT_LIM__A
, 3, 0);
8983 pr_err("error %d\n", rc
);
8987 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A
, 8, 0);
8989 pr_err("error %d\n", rc
);
8992 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A
, 74, 0);
8994 pr_err("error %d\n", rc
);
8997 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A
, 18, 0);
8999 pr_err("error %d\n", rc
);
9002 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A
, 13, 0);
9004 pr_err("error %d\n", rc
);
9007 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A
, 7, 0);
9009 pr_err("error %d\n", rc
);
9012 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A
, 0, 0);
9014 pr_err("error %d\n", rc
);
9017 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A
, (u16
)(-8), 0);
9019 pr_err("error %d\n", rc
);
9023 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_FINE__A
, 15, 0);
9025 pr_err("error %d\n", rc
);
9028 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CA_COARSE__A
, 40, 0);
9030 pr_err("error %d\n", rc
);
9033 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_FINE__A
, 2, 0);
9035 pr_err("error %d\n", rc
);
9038 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_MEDIUM__A
, 50, 0);
9040 pr_err("error %d\n", rc
);
9043 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CP_COARSE__A
, 255, 0);
9045 pr_err("error %d\n", rc
);
9048 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_FINE__A
, 2, 0);
9050 pr_err("error %d\n", rc
);
9053 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_MEDIUM__A
, 25, 0);
9055 pr_err("error %d\n", rc
);
9058 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CI_COARSE__A
, 80, 0);
9060 pr_err("error %d\n", rc
);
9063 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_FINE__A
, 12, 0);
9065 pr_err("error %d\n", rc
);
9068 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_MEDIUM__A
, 24, 0);
9070 pr_err("error %d\n", rc
);
9073 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EP_COARSE__A
, 24, 0);
9075 pr_err("error %d\n", rc
);
9078 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_FINE__A
, 12, 0);
9080 pr_err("error %d\n", rc
);
9083 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_MEDIUM__A
, 16, 0);
9085 pr_err("error %d\n", rc
);
9088 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_EI_COARSE__A
, 16, 0);
9090 pr_err("error %d\n", rc
);
9093 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_FINE__A
, 16, 0);
9095 pr_err("error %d\n", rc
);
9098 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_MEDIUM__A
, 48, 0);
9100 pr_err("error %d\n", rc
);
9103 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF_COARSE__A
, 80, 0);
9105 pr_err("error %d\n", rc
);
9108 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_FINE__A
, 5, 0);
9110 pr_err("error %d\n", rc
);
9113 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_MEDIUM__A
, 15, 0);
9115 pr_err("error %d\n", rc
);
9118 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_LC_CF1_COARSE__A
, 16, 0);
9120 pr_err("error %d\n", rc
);
9124 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_SL_SIG_POWER__A
, 43520, 0);
9126 pr_err("error %d\n", rc
);
9135 /*============================================================================*/
9136 #define QAM_SET_OP_ALL 0x1
9137 #define QAM_SET_OP_CONSTELLATION 0x2
9138 #define QAM_SET_OP_SPECTRUM 0X4
9141 * \fn int set_qam ()
9142 * \brief Set QAM demod.
9143 * \param demod: instance of demod.
9144 * \param channel: pointer to channel data.
9148 set_qam(struct drx_demod_instance
*demod
,
9149 struct drx_channel
*channel
, s32 tuner_freq_offset
, u32 op
)
9151 struct i2c_device_addr
*dev_addr
= NULL
;
9152 struct drxj_data
*ext_attr
= NULL
;
9153 struct drx_common_attr
*common_attr
= NULL
;
9155 u32 adc_frequency
= 0;
9156 u32 iqm_rc_rate
= 0;
9158 u16 lc_symbol_freq
= 0;
9159 u16 iqm_rc_stretch
= 0;
9160 u16 set_env_parameters
= 0;
9161 u16 set_param_parameters
[2] = { 0 };
9162 struct drxjscu_cmd cmd_scu
= { /* command */ 0,
9163 /* parameter_len */ 0,
9165 /* parameter */ NULL
,
9168 const u8 qam_a_taps
[] = {
9169 DRXJ_16TO8(-1), /* re0 */
9170 DRXJ_16TO8(1), /* re1 */
9171 DRXJ_16TO8(1), /* re2 */
9172 DRXJ_16TO8(-1), /* re3 */
9173 DRXJ_16TO8(-1), /* re4 */
9174 DRXJ_16TO8(2), /* re5 */
9175 DRXJ_16TO8(1), /* re6 */
9176 DRXJ_16TO8(-2), /* re7 */
9177 DRXJ_16TO8(0), /* re8 */
9178 DRXJ_16TO8(3), /* re9 */
9179 DRXJ_16TO8(-1), /* re10 */
9180 DRXJ_16TO8(-3), /* re11 */
9181 DRXJ_16TO8(4), /* re12 */
9182 DRXJ_16TO8(1), /* re13 */
9183 DRXJ_16TO8(-8), /* re14 */
9184 DRXJ_16TO8(4), /* re15 */
9185 DRXJ_16TO8(13), /* re16 */
9186 DRXJ_16TO8(-13), /* re17 */
9187 DRXJ_16TO8(-19), /* re18 */
9188 DRXJ_16TO8(28), /* re19 */
9189 DRXJ_16TO8(25), /* re20 */
9190 DRXJ_16TO8(-53), /* re21 */
9191 DRXJ_16TO8(-31), /* re22 */
9192 DRXJ_16TO8(96), /* re23 */
9193 DRXJ_16TO8(37), /* re24 */
9194 DRXJ_16TO8(-190), /* re25 */
9195 DRXJ_16TO8(-40), /* re26 */
9196 DRXJ_16TO8(619) /* re27 */
9198 const u8 qam_b64_taps
[] = {
9199 DRXJ_16TO8(0), /* re0 */
9200 DRXJ_16TO8(-2), /* re1 */
9201 DRXJ_16TO8(1), /* re2 */
9202 DRXJ_16TO8(2), /* re3 */
9203 DRXJ_16TO8(-2), /* re4 */
9204 DRXJ_16TO8(0), /* re5 */
9205 DRXJ_16TO8(4), /* re6 */
9206 DRXJ_16TO8(-2), /* re7 */
9207 DRXJ_16TO8(-4), /* re8 */
9208 DRXJ_16TO8(4), /* re9 */
9209 DRXJ_16TO8(3), /* re10 */
9210 DRXJ_16TO8(-6), /* re11 */
9211 DRXJ_16TO8(0), /* re12 */
9212 DRXJ_16TO8(6), /* re13 */
9213 DRXJ_16TO8(-5), /* re14 */
9214 DRXJ_16TO8(-3), /* re15 */
9215 DRXJ_16TO8(11), /* re16 */
9216 DRXJ_16TO8(-4), /* re17 */
9217 DRXJ_16TO8(-19), /* re18 */
9218 DRXJ_16TO8(19), /* re19 */
9219 DRXJ_16TO8(28), /* re20 */
9220 DRXJ_16TO8(-45), /* re21 */
9221 DRXJ_16TO8(-36), /* re22 */
9222 DRXJ_16TO8(90), /* re23 */
9223 DRXJ_16TO8(42), /* re24 */
9224 DRXJ_16TO8(-185), /* re25 */
9225 DRXJ_16TO8(-46), /* re26 */
9226 DRXJ_16TO8(614) /* re27 */
9228 const u8 qam_b256_taps
[] = {
9229 DRXJ_16TO8(-2), /* re0 */
9230 DRXJ_16TO8(4), /* re1 */
9231 DRXJ_16TO8(1), /* re2 */
9232 DRXJ_16TO8(-4), /* re3 */
9233 DRXJ_16TO8(0), /* re4 */
9234 DRXJ_16TO8(4), /* re5 */
9235 DRXJ_16TO8(-2), /* re6 */
9236 DRXJ_16TO8(-4), /* re7 */
9237 DRXJ_16TO8(5), /* re8 */
9238 DRXJ_16TO8(2), /* re9 */
9239 DRXJ_16TO8(-8), /* re10 */
9240 DRXJ_16TO8(2), /* re11 */
9241 DRXJ_16TO8(11), /* re12 */
9242 DRXJ_16TO8(-8), /* re13 */
9243 DRXJ_16TO8(-15), /* re14 */
9244 DRXJ_16TO8(16), /* re15 */
9245 DRXJ_16TO8(19), /* re16 */
9246 DRXJ_16TO8(-27), /* re17 */
9247 DRXJ_16TO8(-22), /* re18 */
9248 DRXJ_16TO8(44), /* re19 */
9249 DRXJ_16TO8(26), /* re20 */
9250 DRXJ_16TO8(-69), /* re21 */
9251 DRXJ_16TO8(-28), /* re22 */
9252 DRXJ_16TO8(110), /* re23 */
9253 DRXJ_16TO8(31), /* re24 */
9254 DRXJ_16TO8(-201), /* re25 */
9255 DRXJ_16TO8(-32), /* re26 */
9256 DRXJ_16TO8(628) /* re27 */
9258 const u8 qam_c_taps
[] = {
9259 DRXJ_16TO8(-3), /* re0 */
9260 DRXJ_16TO8(3), /* re1 */
9261 DRXJ_16TO8(2), /* re2 */
9262 DRXJ_16TO8(-4), /* re3 */
9263 DRXJ_16TO8(0), /* re4 */
9264 DRXJ_16TO8(4), /* re5 */
9265 DRXJ_16TO8(-1), /* re6 */
9266 DRXJ_16TO8(-4), /* re7 */
9267 DRXJ_16TO8(3), /* re8 */
9268 DRXJ_16TO8(3), /* re9 */
9269 DRXJ_16TO8(-5), /* re10 */
9270 DRXJ_16TO8(0), /* re11 */
9271 DRXJ_16TO8(9), /* re12 */
9272 DRXJ_16TO8(-4), /* re13 */
9273 DRXJ_16TO8(-12), /* re14 */
9274 DRXJ_16TO8(10), /* re15 */
9275 DRXJ_16TO8(16), /* re16 */
9276 DRXJ_16TO8(-21), /* re17 */
9277 DRXJ_16TO8(-20), /* re18 */
9278 DRXJ_16TO8(37), /* re19 */
9279 DRXJ_16TO8(25), /* re20 */
9280 DRXJ_16TO8(-62), /* re21 */
9281 DRXJ_16TO8(-28), /* re22 */
9282 DRXJ_16TO8(105), /* re23 */
9283 DRXJ_16TO8(31), /* re24 */
9284 DRXJ_16TO8(-197), /* re25 */
9285 DRXJ_16TO8(-33), /* re26 */
9286 DRXJ_16TO8(626) /* re27 */
9289 dev_addr
= demod
->my_i2c_dev_addr
;
9290 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
9291 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
9293 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_CONSTELLATION
)) {
9294 if (ext_attr
->standard
== DRX_STANDARD_ITU_B
) {
9295 switch (channel
->constellation
) {
9296 case DRX_CONSTELLATION_QAM256
:
9297 iqm_rc_rate
= 0x00AE3562;
9299 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256
;
9300 channel
->symbolrate
= 5360537;
9301 iqm_rc_stretch
= IQM_RC_STRETCH_QAM_B_256
;
9303 case DRX_CONSTELLATION_QAM64
:
9304 iqm_rc_rate
= 0x00C05A0E;
9305 lc_symbol_freq
= 409;
9306 channel
->symbolrate
= 5056941;
9307 iqm_rc_stretch
= IQM_RC_STRETCH_QAM_B_64
;
9313 adc_frequency
= (common_attr
->sys_clock_freq
* 1000) / 3;
9314 if (channel
->symbolrate
== 0) {
9315 pr_err("error: channel symbolrate is zero!\n");
9319 (adc_frequency
/ channel
->symbolrate
) * (1 << 21) +
9321 ((adc_frequency
% channel
->symbolrate
),
9322 channel
->symbolrate
) >> 7) - (1 << 23);
9325 (channel
->symbolrate
+
9326 (adc_frequency
>> 13),
9327 adc_frequency
) >> 16);
9328 if (lc_symbol_freq
> 511)
9329 lc_symbol_freq
= 511;
9331 iqm_rc_stretch
= 21;
9334 if (ext_attr
->standard
== DRX_STANDARD_ITU_A
) {
9335 set_env_parameters
= QAM_TOP_ANNEX_A
; /* annex */
9336 set_param_parameters
[0] = channel
->constellation
; /* constellation */
9337 set_param_parameters
[1] = DRX_INTERLEAVEMODE_I12_J17
; /* interleave mode */
9338 } else if (ext_attr
->standard
== DRX_STANDARD_ITU_B
) {
9339 set_env_parameters
= QAM_TOP_ANNEX_B
; /* annex */
9340 set_param_parameters
[0] = channel
->constellation
; /* constellation */
9341 set_param_parameters
[1] = channel
->interleavemode
; /* interleave mode */
9342 } else if (ext_attr
->standard
== DRX_STANDARD_ITU_C
) {
9343 set_env_parameters
= QAM_TOP_ANNEX_C
; /* annex */
9344 set_param_parameters
[0] = channel
->constellation
; /* constellation */
9345 set_param_parameters
[1] = DRX_INTERLEAVEMODE_I12_J17
; /* interleave mode */
9351 if (op
& QAM_SET_OP_ALL
) {
9353 STEP 1: reset demodulator
9354 resets IQM, QAM and FEC HW blocks
9355 resets SCU variables
9357 /* stop all comm_exec */
9358 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_COMM_EXEC__A
, FEC_COMM_EXEC_STOP
, 0);
9360 pr_err("error %d\n", rc
);
9363 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_COMM_EXEC__A
, QAM_COMM_EXEC_STOP
, 0);
9365 pr_err("error %d\n", rc
);
9368 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FS_COMM_EXEC__A
, IQM_FS_COMM_EXEC_STOP
, 0);
9370 pr_err("error %d\n", rc
);
9373 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FD_COMM_EXEC__A
, IQM_FD_COMM_EXEC_STOP
, 0);
9375 pr_err("error %d\n", rc
);
9378 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_COMM_EXEC__A
, IQM_RC_COMM_EXEC_STOP
, 0);
9380 pr_err("error %d\n", rc
);
9383 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_COMM_EXEC__A
, IQM_RT_COMM_EXEC_STOP
, 0);
9385 pr_err("error %d\n", rc
);
9388 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_COMM_EXEC__A
, IQM_CF_COMM_EXEC_STOP
, 0);
9390 pr_err("error %d\n", rc
);
9394 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_QAM
|
9395 SCU_RAM_COMMAND_CMD_DEMOD_RESET
;
9396 cmd_scu
.parameter_len
= 0;
9397 cmd_scu
.result_len
= 1;
9398 cmd_scu
.parameter
= NULL
;
9399 cmd_scu
.result
= &cmd_result
;
9400 rc
= scu_command(dev_addr
, &cmd_scu
);
9402 pr_err("error %d\n", rc
);
9407 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_CONSTELLATION
)) {
9409 STEP 2: configure demodulator
9411 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
9413 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_QAM
|
9414 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV
;
9415 cmd_scu
.parameter_len
= 1;
9416 cmd_scu
.result_len
= 1;
9417 cmd_scu
.parameter
= &set_env_parameters
;
9418 cmd_scu
.result
= &cmd_result
;
9419 rc
= scu_command(dev_addr
, &cmd_scu
);
9421 pr_err("error %d\n", rc
);
9425 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_QAM
|
9426 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM
;
9427 cmd_scu
.parameter_len
= 2;
9428 cmd_scu
.result_len
= 1;
9429 cmd_scu
.parameter
= set_param_parameters
;
9430 cmd_scu
.result
= &cmd_result
;
9431 rc
= scu_command(dev_addr
, &cmd_scu
);
9433 pr_err("error %d\n", rc
);
9436 /* set symbol rate */
9437 rc
= DRXJ_DAP
.write_reg32func(dev_addr
, IQM_RC_RATE_OFS_LO__A
, iqm_rc_rate
, 0);
9439 pr_err("error %d\n", rc
);
9442 ext_attr
->iqm_rc_rate_ofs
= iqm_rc_rate
;
9443 rc
= set_qam_measurement(demod
, channel
->constellation
, channel
->symbolrate
);
9445 pr_err("error %d\n", rc
);
9449 /* STEP 3: enable the system in a mode where the ADC provides valid signal
9450 setup constellation independent registers */
9451 /* from qam_cmd.py script (qam_driver_b) */
9452 /* TODO: remove re-writes of HW reset values */
9453 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_SPECTRUM
)) {
9454 rc
= set_frequency(demod
, channel
, tuner_freq_offset
);
9456 pr_err("error %d\n", rc
);
9461 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_CONSTELLATION
)) {
9463 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_SYMBOL_FREQ__A
, lc_symbol_freq
, 0);
9465 pr_err("error %d\n", rc
);
9468 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_STRETCH__A
, iqm_rc_stretch
, 0);
9470 pr_err("error %d\n", rc
);
9475 if (op
& QAM_SET_OP_ALL
) {
9476 if (!ext_attr
->has_lna
) {
9477 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_AMUX__A
, 0x02, 0);
9479 pr_err("error %d\n", rc
);
9483 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_SYMMETRIC__A
, 0, 0);
9485 pr_err("error %d\n", rc
);
9488 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, 3, 0);
9490 pr_err("error %d\n", rc
);
9493 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_OUT_ENA__A
, IQM_CF_OUT_ENA_QAM__M
, 0);
9495 pr_err("error %d\n", rc
);
9499 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_WR_RSV_0__A
, 0x5f, 0);
9501 pr_err("error %d\n", rc
);
9503 } /* scu temporary shut down agc */
9505 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_SYNC_SEL__A
, 3, 0);
9507 pr_err("error %d\n", rc
);
9510 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_CLP_LEN__A
, 0, 0);
9512 pr_err("error %d\n", rc
);
9515 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_CLP_TH__A
, 448, 0);
9517 pr_err("error %d\n", rc
);
9520 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_SNS_LEN__A
, 0, 0);
9522 pr_err("error %d\n", rc
);
9525 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_PDREF__A
, 4, 0);
9527 pr_err("error %d\n", rc
);
9530 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_STDBY__A
, 0x10, 0);
9532 pr_err("error %d\n", rc
);
9535 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_PGA_GAIN__A
, 11, 0);
9537 pr_err("error %d\n", rc
);
9541 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_POW_MEAS_LEN__A
, 1, 0);
9543 pr_err("error %d\n", rc
);
9546 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_SCALE_SH__A
, IQM_CF_SCALE_SH__PRE
, 0);
9548 pr_err("error %d\n", rc
);
9550 } /*! reset default val ! */
9552 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_TIMEOUT__A
, QAM_SY_TIMEOUT__PRE
, 0);
9554 pr_err("error %d\n", rc
);
9556 } /*! reset default val ! */
9557 if (ext_attr
->standard
== DRX_STANDARD_ITU_B
) {
9558 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_LWM__A
, QAM_SY_SYNC_LWM__PRE
, 0);
9560 pr_err("error %d\n", rc
);
9562 } /*! reset default val ! */
9563 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_AWM__A
, QAM_SY_SYNC_AWM__PRE
, 0);
9565 pr_err("error %d\n", rc
);
9567 } /*! reset default val ! */
9568 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_HWM__A
, QAM_SY_SYNC_HWM__PRE
, 0);
9570 pr_err("error %d\n", rc
);
9572 } /*! reset default val ! */
9574 switch (channel
->constellation
) {
9575 case DRX_CONSTELLATION_QAM16
:
9576 case DRX_CONSTELLATION_QAM64
:
9577 case DRX_CONSTELLATION_QAM256
:
9578 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_LWM__A
, 0x03, 0);
9580 pr_err("error %d\n", rc
);
9583 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_AWM__A
, 0x04, 0);
9585 pr_err("error %d\n", rc
);
9588 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_HWM__A
, QAM_SY_SYNC_HWM__PRE
, 0);
9590 pr_err("error %d\n", rc
);
9592 } /*! reset default val ! */
9594 case DRX_CONSTELLATION_QAM32
:
9595 case DRX_CONSTELLATION_QAM128
:
9596 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_LWM__A
, 0x03, 0);
9598 pr_err("error %d\n", rc
);
9601 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_AWM__A
, 0x05, 0);
9603 pr_err("error %d\n", rc
);
9606 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SY_SYNC_HWM__A
, 0x06, 0);
9608 pr_err("error %d\n", rc
);
9617 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_MODE__A
, QAM_LC_MODE__PRE
, 0);
9619 pr_err("error %d\n", rc
);
9621 } /*! reset default val ! */
9622 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_RATE_LIMIT__A
, 3, 0);
9624 pr_err("error %d\n", rc
);
9627 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_LPF_FACTORP__A
, 4, 0);
9629 pr_err("error %d\n", rc
);
9632 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_LPF_FACTORI__A
, 4, 0);
9634 pr_err("error %d\n", rc
);
9637 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_MODE__A
, 7, 0);
9639 pr_err("error %d\n", rc
);
9642 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB0__A
, 1, 0);
9644 pr_err("error %d\n", rc
);
9647 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB1__A
, 1, 0);
9649 pr_err("error %d\n", rc
);
9652 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB2__A
, 1, 0);
9654 pr_err("error %d\n", rc
);
9657 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB3__A
, 1, 0);
9659 pr_err("error %d\n", rc
);
9662 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB4__A
, 2, 0);
9664 pr_err("error %d\n", rc
);
9667 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB5__A
, 2, 0);
9669 pr_err("error %d\n", rc
);
9672 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB6__A
, 2, 0);
9674 pr_err("error %d\n", rc
);
9677 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB8__A
, 2, 0);
9679 pr_err("error %d\n", rc
);
9682 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB9__A
, 2, 0);
9684 pr_err("error %d\n", rc
);
9687 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB10__A
, 2, 0);
9689 pr_err("error %d\n", rc
);
9692 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB12__A
, 2, 0);
9694 pr_err("error %d\n", rc
);
9697 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB15__A
, 3, 0);
9699 pr_err("error %d\n", rc
);
9702 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB16__A
, 3, 0);
9704 pr_err("error %d\n", rc
);
9707 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB20__A
, 4, 0);
9709 pr_err("error %d\n", rc
);
9712 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_QUAL_TAB25__A
, 4, 0);
9714 pr_err("error %d\n", rc
);
9718 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FS_ADJ_SEL__A
, 1, 0);
9720 pr_err("error %d\n", rc
);
9723 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_ADJ_SEL__A
, 1, 0);
9725 pr_err("error %d\n", rc
);
9728 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_ADJ_SEL__A
, 1, 0);
9730 pr_err("error %d\n", rc
);
9733 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_POW_MEAS_LEN__A
, 0, 0);
9735 pr_err("error %d\n", rc
);
9738 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_GPIO__A
, 0, 0);
9740 pr_err("error %d\n", rc
);
9744 /* No more resets of the IQM, current standard correctly set =>
9745 now AGCs can be configured. */
9746 /* turn on IQMAF. It has to be in front of setAgc**() */
9747 rc
= set_iqm_af(demod
, true);
9749 pr_err("error %d\n", rc
);
9752 rc
= adc_synchronization(demod
);
9754 pr_err("error %d\n", rc
);
9758 rc
= init_agc(demod
);
9760 pr_err("error %d\n", rc
);
9763 rc
= set_agc_if(demod
, &(ext_attr
->qam_if_agc_cfg
), false);
9765 pr_err("error %d\n", rc
);
9768 rc
= set_agc_rf(demod
, &(ext_attr
->qam_rf_agc_cfg
), false);
9770 pr_err("error %d\n", rc
);
9774 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
9776 struct drxj_cfg_afe_gain qam_pga_cfg
= { DRX_STANDARD_ITU_B
, 0 };
9778 qam_pga_cfg
.gain
= ext_attr
->qam_pga_cfg
;
9779 rc
= ctrl_set_cfg_afe_gain(demod
, &qam_pga_cfg
);
9781 pr_err("error %d\n", rc
);
9785 rc
= ctrl_set_cfg_pre_saw(demod
, &(ext_attr
->qam_pre_saw_cfg
));
9787 pr_err("error %d\n", rc
);
9792 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_CONSTELLATION
)) {
9793 if (ext_attr
->standard
== DRX_STANDARD_ITU_A
) {
9794 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_RE0__A
, sizeof(qam_a_taps
), ((u8
*)qam_a_taps
), 0);
9796 pr_err("error %d\n", rc
);
9799 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_IM0__A
, sizeof(qam_a_taps
), ((u8
*)qam_a_taps
), 0);
9801 pr_err("error %d\n", rc
);
9804 } else if (ext_attr
->standard
== DRX_STANDARD_ITU_B
) {
9805 switch (channel
->constellation
) {
9806 case DRX_CONSTELLATION_QAM64
:
9807 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_RE0__A
, sizeof(qam_b64_taps
), ((u8
*)qam_b64_taps
), 0);
9809 pr_err("error %d\n", rc
);
9812 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_IM0__A
, sizeof(qam_b64_taps
), ((u8
*)qam_b64_taps
), 0);
9814 pr_err("error %d\n", rc
);
9818 case DRX_CONSTELLATION_QAM256
:
9819 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_RE0__A
, sizeof(qam_b256_taps
), ((u8
*)qam_b256_taps
), 0);
9821 pr_err("error %d\n", rc
);
9824 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_IM0__A
, sizeof(qam_b256_taps
), ((u8
*)qam_b256_taps
), 0);
9826 pr_err("error %d\n", rc
);
9833 } else if (ext_attr
->standard
== DRX_STANDARD_ITU_C
) {
9834 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_RE0__A
, sizeof(qam_c_taps
), ((u8
*)qam_c_taps
), 0);
9836 pr_err("error %d\n", rc
);
9839 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_IM0__A
, sizeof(qam_c_taps
), ((u8
*)qam_c_taps
), 0);
9841 pr_err("error %d\n", rc
);
9846 /* SETP 4: constellation specific setup */
9847 switch (channel
->constellation
) {
9848 case DRX_CONSTELLATION_QAM16
:
9849 rc
= set_qam16(demod
);
9851 pr_err("error %d\n", rc
);
9855 case DRX_CONSTELLATION_QAM32
:
9856 rc
= set_qam32(demod
);
9858 pr_err("error %d\n", rc
);
9862 case DRX_CONSTELLATION_QAM64
:
9863 rc
= set_qam64(demod
);
9865 pr_err("error %d\n", rc
);
9869 case DRX_CONSTELLATION_QAM128
:
9870 rc
= set_qam128(demod
);
9872 pr_err("error %d\n", rc
);
9876 case DRX_CONSTELLATION_QAM256
:
9877 rc
= set_qam256(demod
);
9879 pr_err("error %d\n", rc
);
9888 if ((op
& QAM_SET_OP_ALL
)) {
9889 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_SCALE_SH__A
, 0, 0);
9891 pr_err("error %d\n", rc
);
9895 /* Mpeg output has to be in front of FEC active */
9896 rc
= set_mpegtei_handling(demod
);
9898 pr_err("error %d\n", rc
);
9901 rc
= bit_reverse_mpeg_output(demod
);
9903 pr_err("error %d\n", rc
);
9906 rc
= set_mpeg_start_width(demod
);
9908 pr_err("error %d\n", rc
);
9912 /* TODO: move to set_standard after hardware reset value problem is solved */
9913 /* Configure initial MPEG output */
9914 struct drx_cfg_mpeg_output cfg_mpeg_output
;
9916 cfg_mpeg_output
.enable_mpeg_output
= true;
9917 cfg_mpeg_output
.insert_rs_byte
=
9918 common_attr
->mpeg_cfg
.insert_rs_byte
;
9919 cfg_mpeg_output
.enable_parallel
=
9920 common_attr
->mpeg_cfg
.enable_parallel
;
9921 cfg_mpeg_output
.invert_data
=
9922 common_attr
->mpeg_cfg
.invert_data
;
9923 cfg_mpeg_output
.invert_err
= common_attr
->mpeg_cfg
.invert_err
;
9924 cfg_mpeg_output
.invert_str
= common_attr
->mpeg_cfg
.invert_str
;
9925 cfg_mpeg_output
.invert_val
= common_attr
->mpeg_cfg
.invert_val
;
9926 cfg_mpeg_output
.invert_clk
= common_attr
->mpeg_cfg
.invert_clk
;
9927 cfg_mpeg_output
.static_clk
= common_attr
->mpeg_cfg
.static_clk
;
9928 cfg_mpeg_output
.bitrate
= common_attr
->mpeg_cfg
.bitrate
;
9929 rc
= ctrl_set_cfg_mpeg_output(demod
, &cfg_mpeg_output
);
9931 pr_err("error %d\n", rc
);
9937 if ((op
& QAM_SET_OP_ALL
) || (op
& QAM_SET_OP_CONSTELLATION
)) {
9939 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
9940 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_QAM
|
9941 SCU_RAM_COMMAND_CMD_DEMOD_START
;
9942 cmd_scu
.parameter_len
= 0;
9943 cmd_scu
.result_len
= 1;
9944 cmd_scu
.parameter
= NULL
;
9945 cmd_scu
.result
= &cmd_result
;
9946 rc
= scu_command(dev_addr
, &cmd_scu
);
9948 pr_err("error %d\n", rc
);
9953 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_COMM_EXEC__A
, IQM_COMM_EXEC_ACTIVE
, 0);
9955 pr_err("error %d\n", rc
);
9958 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_COMM_EXEC__A
, QAM_COMM_EXEC_ACTIVE
, 0);
9960 pr_err("error %d\n", rc
);
9963 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_COMM_EXEC__A
, FEC_COMM_EXEC_ACTIVE
, 0);
9965 pr_err("error %d\n", rc
);
9974 /*============================================================================*/
9976 ctrl_get_qam_sig_quality(struct drx_demod_instance
*demod
, struct drx_sig_quality
*sig_quality
);
9977 static int qam_flip_spec(struct drx_demod_instance
*demod
, struct drx_channel
*channel
)
9980 u32 iqm_fs_rate_ofs
= 0;
9981 u32 iqm_fs_rate_lo
= 0;
9982 u16 qam_ctl_ena
= 0;
9988 struct i2c_device_addr
*dev_addr
= NULL
;
9989 struct drxj_data
*ext_attr
= NULL
;
9991 dev_addr
= demod
->my_i2c_dev_addr
;
9992 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
9994 /* Silence the controlling of lc, equ, and the acquisition state machine */
9995 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_QAM_CTL_ENA__A
, &qam_ctl_ena
, 0);
9997 pr_err("error %d\n", rc
);
10000 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);
10002 pr_err("error %d\n", rc
);
10006 /* freeze the frequency control loop */
10007 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_CF__A
, 0, 0);
10009 pr_err("error %d\n", rc
);
10012 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_CF1__A
, 0, 0);
10014 pr_err("error %d\n", rc
);
10018 rc
= drxj_dap_atomic_read_reg32(dev_addr
, IQM_FS_RATE_OFS_LO__A
, &iqm_fs_rate_ofs
, 0);
10020 pr_err("error %d\n", rc
);
10023 rc
= drxj_dap_atomic_read_reg32(dev_addr
, IQM_FS_RATE_LO__A
, &iqm_fs_rate_lo
, 0);
10025 pr_err("error %d\n", rc
);
10028 ofsofs
= iqm_fs_rate_lo
- iqm_fs_rate_ofs
;
10029 iqm_fs_rate_ofs
= ~iqm_fs_rate_ofs
+ 1;
10030 iqm_fs_rate_ofs
-= 2 * ofsofs
;
10032 /* freeze dq/fq updating */
10033 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, QAM_DQ_MODE__A
, &data
, 0);
10035 pr_err("error %d\n", rc
);
10038 data
= (data
& 0xfff9);
10039 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_DQ_MODE__A
, data
, 0);
10041 pr_err("error %d\n", rc
);
10044 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_FQ_MODE__A
, data
, 0);
10046 pr_err("error %d\n", rc
);
10050 /* lc_cp / _ci / _ca */
10051 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_CI__A
, 0, 0);
10053 pr_err("error %d\n", rc
);
10056 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_LC_EP__A
, 0, 0);
10058 pr_err("error %d\n", rc
);
10061 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_FQ_LA_FACTOR__A
, 0, 0);
10063 pr_err("error %d\n", rc
);
10067 /* flip the spec */
10068 rc
= DRXJ_DAP
.write_reg32func(dev_addr
, IQM_FS_RATE_OFS_LO__A
, iqm_fs_rate_ofs
, 0);
10070 pr_err("error %d\n", rc
);
10073 ext_attr
->iqm_fs_rate_ofs
= iqm_fs_rate_ofs
;
10074 ext_attr
->pos_image
= (ext_attr
->pos_image
) ? false : true;
10076 /* freeze dq/fq updating */
10077 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, QAM_DQ_MODE__A
, &data
, 0);
10079 pr_err("error %d\n", rc
);
10083 data
= (data
& 0xfff9);
10084 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_DQ_MODE__A
, data
, 0);
10086 pr_err("error %d\n", rc
);
10089 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_FQ_MODE__A
, data
, 0);
10091 pr_err("error %d\n", rc
);
10095 for (i
= 0; i
< 28; i
++) {
10096 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, QAM_DQ_TAP_IM_EL0__A
+ (2 * i
), &data
, 0);
10098 pr_err("error %d\n", rc
);
10101 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_DQ_TAP_IM_EL0__A
+ (2 * i
), -data
, 0);
10103 pr_err("error %d\n", rc
);
10108 for (i
= 0; i
< 24; i
++) {
10109 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, QAM_FQ_TAP_IM_EL0__A
+ (2 * i
), &data
, 0);
10111 pr_err("error %d\n", rc
);
10114 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_FQ_TAP_IM_EL0__A
+ (2 * i
), -data
, 0);
10116 pr_err("error %d\n", rc
);
10122 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_DQ_MODE__A
, data
, 0);
10124 pr_err("error %d\n", rc
);
10127 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_FQ_MODE__A
, data
, 0);
10129 pr_err("error %d\n", rc
);
10133 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_FSM_STATE_TGT__A
, 4, 0);
10135 pr_err("error %d\n", rc
);
10140 while ((fsm_state
!= 4) && (i
++ < 100)) {
10141 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, SCU_RAM_QAM_FSM_STATE__A
, &fsm_state
, 0);
10143 pr_err("error %d\n", rc
);
10147 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_QAM_CTL_ENA__A
, (qam_ctl_ena
| 0x0016), 0);
10149 pr_err("error %d\n", rc
);
10159 #define NO_LOCK 0x0
10160 #define DEMOD_LOCKED 0x1
10161 #define SYNC_FLIPPED 0x2
10162 #define SPEC_MIRRORED 0x4
10164 * \fn int qam64auto ()
10165 * \brief auto do sync pattern switching and mirroring.
10166 * \param demod: instance of demod.
10167 * \param channel: pointer to channel data.
10168 * \param tuner_freq_offset: tuner frequency offset.
10169 * \param lock_status: pointer to lock status.
10173 qam64auto(struct drx_demod_instance
*demod
,
10174 struct drx_channel
*channel
,
10175 s32 tuner_freq_offset
, enum drx_lock_status
*lock_status
)
10177 struct drx_sig_quality sig_quality
;
10178 struct drxj_data
*ext_attr
= NULL
;
10180 u32 state
= NO_LOCK
;
10181 u32 start_time
= 0;
10182 u32 d_locked_time
= 0;
10183 u32 timeout_ofs
= 0;
10186 /* external attributes for storing aquired channel constellation */
10187 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
10188 *lock_status
= DRX_NOT_LOCKED
;
10189 start_time
= jiffies_to_msecs(jiffies
);
10192 rc
= ctrl_lock_status(demod
, lock_status
);
10194 pr_err("error %d\n", rc
);
10200 if (*lock_status
== DRXJ_DEMOD_LOCK
) {
10201 rc
= ctrl_get_qam_sig_quality(demod
, &sig_quality
);
10203 pr_err("error %d\n", rc
);
10206 if (sig_quality
.MER
> 208) {
10207 state
= DEMOD_LOCKED
;
10208 /* some delay to see if fec_lock possible TODO find the right value */
10209 timeout_ofs
+= DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
; /* see something, waiting longer */
10210 d_locked_time
= jiffies_to_msecs(jiffies
);
10215 if ((*lock_status
== DRXJ_DEMOD_LOCK
) && /* still demod_lock in 150ms */
10216 ((jiffies_to_msecs(jiffies
) - d_locked_time
) >
10217 DRXJ_QAM_FEC_LOCK_WAITTIME
)) {
10218 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, QAM_SY_TIMEOUT__A
, &data
, 0);
10220 pr_err("error %d\n", rc
);
10223 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, QAM_SY_TIMEOUT__A
, data
| 0x1, 0);
10225 pr_err("error %d\n", rc
);
10228 state
= SYNC_FLIPPED
;
10233 if (*lock_status
== DRXJ_DEMOD_LOCK
) {
10234 if (channel
->mirror
== DRX_MIRROR_AUTO
) {
10235 /* flip sync pattern back */
10236 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, QAM_SY_TIMEOUT__A
, &data
, 0);
10238 pr_err("error %d\n", rc
);
10241 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, QAM_SY_TIMEOUT__A
, data
& 0xFFFE, 0);
10243 pr_err("error %d\n", rc
);
10246 /* flip spectrum */
10247 ext_attr
->mirror
= DRX_MIRROR_YES
;
10248 rc
= qam_flip_spec(demod
, channel
);
10250 pr_err("error %d\n", rc
);
10253 state
= SPEC_MIRRORED
;
10254 /* reset timer TODO: still need 500ms? */
10255 start_time
= d_locked_time
=
10256 jiffies_to_msecs(jiffies
);
10258 } else { /* no need to wait lock */
10261 jiffies_to_msecs(jiffies
) -
10262 DRXJ_QAM_MAX_WAITTIME
- timeout_ofs
;
10266 case SPEC_MIRRORED
:
10267 if ((*lock_status
== DRXJ_DEMOD_LOCK
) && /* still demod_lock in 150ms */
10268 ((jiffies_to_msecs(jiffies
) - d_locked_time
) >
10269 DRXJ_QAM_FEC_LOCK_WAITTIME
)) {
10270 rc
= ctrl_get_qam_sig_quality(demod
, &sig_quality
);
10272 pr_err("error %d\n", rc
);
10275 if (sig_quality
.MER
> 208) {
10276 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, QAM_SY_TIMEOUT__A
, &data
, 0);
10278 pr_err("error %d\n", rc
);
10281 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, QAM_SY_TIMEOUT__A
, data
| 0x1, 0);
10283 pr_err("error %d\n", rc
);
10286 /* no need to wait lock */
10288 jiffies_to_msecs(jiffies
) -
10289 DRXJ_QAM_MAX_WAITTIME
- timeout_ofs
;
10298 ((*lock_status
!= DRX_LOCKED
) &&
10299 (*lock_status
!= DRX_NEVER_LOCK
) &&
10300 ((jiffies_to_msecs(jiffies
) - start_time
) <
10301 (DRXJ_QAM_MAX_WAITTIME
+ timeout_ofs
))
10303 /* Returning control to apllication ... */
10311 * \fn int qam256auto ()
10312 * \brief auto do sync pattern switching and mirroring.
10313 * \param demod: instance of demod.
10314 * \param channel: pointer to channel data.
10315 * \param tuner_freq_offset: tuner frequency offset.
10316 * \param lock_status: pointer to lock status.
10320 qam256auto(struct drx_demod_instance
*demod
,
10321 struct drx_channel
*channel
,
10322 s32 tuner_freq_offset
, enum drx_lock_status
*lock_status
)
10324 struct drx_sig_quality sig_quality
;
10325 struct drxj_data
*ext_attr
= NULL
;
10327 u32 state
= NO_LOCK
;
10328 u32 start_time
= 0;
10329 u32 d_locked_time
= 0;
10330 u32 timeout_ofs
= DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
;
10332 /* external attributes for storing aquired channel constellation */
10333 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
10334 *lock_status
= DRX_NOT_LOCKED
;
10335 start_time
= jiffies_to_msecs(jiffies
);
10338 rc
= ctrl_lock_status(demod
, lock_status
);
10340 pr_err("error %d\n", rc
);
10345 if (*lock_status
== DRXJ_DEMOD_LOCK
) {
10346 rc
= ctrl_get_qam_sig_quality(demod
, &sig_quality
);
10348 pr_err("error %d\n", rc
);
10351 if (sig_quality
.MER
> 268) {
10352 state
= DEMOD_LOCKED
;
10353 timeout_ofs
+= DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
; /* see something, wait longer */
10354 d_locked_time
= jiffies_to_msecs(jiffies
);
10359 if (*lock_status
== DRXJ_DEMOD_LOCK
) {
10360 if ((channel
->mirror
== DRX_MIRROR_AUTO
) &&
10361 ((jiffies_to_msecs(jiffies
) - d_locked_time
) >
10362 DRXJ_QAM_FEC_LOCK_WAITTIME
)) {
10363 ext_attr
->mirror
= DRX_MIRROR_YES
;
10364 rc
= qam_flip_spec(demod
, channel
);
10366 pr_err("error %d\n", rc
);
10369 state
= SPEC_MIRRORED
;
10370 /* reset timer TODO: still need 300ms? */
10371 start_time
= jiffies_to_msecs(jiffies
);
10372 timeout_ofs
= -DRXJ_QAM_MAX_WAITTIME
/ 2;
10376 case SPEC_MIRRORED
:
10383 ((*lock_status
< DRX_LOCKED
) &&
10384 (*lock_status
!= DRX_NEVER_LOCK
) &&
10385 ((jiffies_to_msecs(jiffies
) - start_time
) <
10386 (DRXJ_QAM_MAX_WAITTIME
+ timeout_ofs
)));
10394 * \fn int set_qam_channel ()
10395 * \brief Set QAM channel according to the requested constellation.
10396 * \param demod: instance of demod.
10397 * \param channel: pointer to channel data.
10401 set_qam_channel(struct drx_demod_instance
*demod
,
10402 struct drx_channel
*channel
, s32 tuner_freq_offset
)
10404 struct drxj_data
*ext_attr
= NULL
;
10406 enum drx_lock_status lock_status
= DRX_NOT_LOCKED
;
10407 bool auto_flag
= false;
10409 /* external attributes for storing aquired channel constellation */
10410 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
10412 /* set QAM channel constellation */
10413 switch (channel
->constellation
) {
10414 case DRX_CONSTELLATION_QAM16
:
10415 case DRX_CONSTELLATION_QAM32
:
10416 case DRX_CONSTELLATION_QAM64
:
10417 case DRX_CONSTELLATION_QAM128
:
10418 case DRX_CONSTELLATION_QAM256
:
10419 ext_attr
->constellation
= channel
->constellation
;
10420 if (channel
->mirror
== DRX_MIRROR_AUTO
)
10421 ext_attr
->mirror
= DRX_MIRROR_NO
;
10423 ext_attr
->mirror
= channel
->mirror
;
10424 rc
= set_qam(demod
, channel
, tuner_freq_offset
, QAM_SET_OP_ALL
);
10426 pr_err("error %d\n", rc
);
10430 if ((ext_attr
->standard
== DRX_STANDARD_ITU_B
) &&
10431 (channel
->constellation
== DRX_CONSTELLATION_QAM64
)) {
10432 rc
= qam64auto(demod
, channel
, tuner_freq_offset
, &lock_status
);
10434 pr_err("error %d\n", rc
);
10439 if ((ext_attr
->standard
== DRX_STANDARD_ITU_B
) &&
10440 (channel
->mirror
== DRX_MIRROR_AUTO
) &&
10441 (channel
->constellation
== DRX_CONSTELLATION_QAM256
)) {
10442 rc
= qam256auto(demod
, channel
, tuner_freq_offset
, &lock_status
);
10444 pr_err("error %d\n", rc
);
10449 case DRX_CONSTELLATION_AUTO
: /* for channel scan */
10450 if (ext_attr
->standard
== DRX_STANDARD_ITU_B
) {
10452 /* try to lock default QAM constellation: QAM64 */
10453 channel
->constellation
= DRX_CONSTELLATION_QAM256
;
10454 ext_attr
->constellation
= DRX_CONSTELLATION_QAM256
;
10455 if (channel
->mirror
== DRX_MIRROR_AUTO
)
10456 ext_attr
->mirror
= DRX_MIRROR_NO
;
10458 ext_attr
->mirror
= channel
->mirror
;
10459 rc
= set_qam(demod
, channel
, tuner_freq_offset
, QAM_SET_OP_ALL
);
10461 pr_err("error %d\n", rc
);
10464 rc
= qam256auto(demod
, channel
, tuner_freq_offset
, &lock_status
);
10466 pr_err("error %d\n", rc
);
10470 if (lock_status
< DRX_LOCKED
) {
10471 /* QAM254 not locked -> try to lock QAM64 constellation */
10472 channel
->constellation
=
10473 DRX_CONSTELLATION_QAM64
;
10474 ext_attr
->constellation
=
10475 DRX_CONSTELLATION_QAM64
;
10476 if (channel
->mirror
== DRX_MIRROR_AUTO
)
10477 ext_attr
->mirror
= DRX_MIRROR_NO
;
10479 ext_attr
->mirror
= channel
->mirror
;
10481 u16 qam_ctl_ena
= 0;
10482 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_QAM_CTL_ENA__A
, &qam_ctl_ena
, 0);
10484 pr_err("error %d\n", rc
);
10487 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);
10489 pr_err("error %d\n", rc
);
10492 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_QAM_FSM_STATE_TGT__A
, 0x2, 0);
10494 pr_err("error %d\n", rc
);
10496 } /* force to rate hunting */
10498 rc
= set_qam(demod
, channel
, tuner_freq_offset
, QAM_SET_OP_CONSTELLATION
);
10500 pr_err("error %d\n", rc
);
10503 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_QAM_CTL_ENA__A
, qam_ctl_ena
, 0);
10505 pr_err("error %d\n", rc
);
10509 rc
= qam64auto(demod
, channel
, tuner_freq_offset
, &lock_status
);
10511 pr_err("error %d\n", rc
);
10515 channel
->constellation
= DRX_CONSTELLATION_AUTO
;
10516 } else if (ext_attr
->standard
== DRX_STANDARD_ITU_C
) {
10517 channel
->constellation
= DRX_CONSTELLATION_QAM64
;
10518 ext_attr
->constellation
= DRX_CONSTELLATION_QAM64
;
10521 if (channel
->mirror
== DRX_MIRROR_AUTO
)
10522 ext_attr
->mirror
= DRX_MIRROR_NO
;
10524 ext_attr
->mirror
= channel
->mirror
;
10526 u16 qam_ctl_ena
= 0;
10527 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_QAM_CTL_ENA__A
, &qam_ctl_ena
, 0);
10529 pr_err("error %d\n", rc
);
10532 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);
10534 pr_err("error %d\n", rc
);
10537 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_QAM_FSM_STATE_TGT__A
, 0x2, 0);
10539 pr_err("error %d\n", rc
);
10541 } /* force to rate hunting */
10543 rc
= set_qam(demod
, channel
, tuner_freq_offset
, QAM_SET_OP_CONSTELLATION
);
10545 pr_err("error %d\n", rc
);
10548 rc
= DRXJ_DAP
.write_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_QAM_CTL_ENA__A
, qam_ctl_ena
, 0);
10550 pr_err("error %d\n", rc
);
10554 rc
= qam64auto(demod
, channel
, tuner_freq_offset
, &lock_status
);
10556 pr_err("error %d\n", rc
);
10559 channel
->constellation
= DRX_CONSTELLATION_AUTO
;
10561 channel
->constellation
= DRX_CONSTELLATION_AUTO
;
10571 /* restore starting value */
10573 channel
->constellation
= DRX_CONSTELLATION_AUTO
;
10577 /*============================================================================*/
10580 * \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
10581 * \brief Get RS error count in QAM mode (used for post RS BER calculation)
10582 * \return Error code
10584 * precondition: measurement period & measurement prescale must be set
10588 get_qamrs_err_count(struct i2c_device_addr
*dev_addr
, struct drxjrs_errors
*rs_errors
)
10591 u16 nr_bit_errors
= 0,
10592 nr_symbol_errors
= 0,
10593 nr_packet_errors
= 0, nr_failures
= 0, nr_snc_par_fail_count
= 0;
10595 /* check arguments */
10596 if (dev_addr
== NULL
)
10599 /* all reported errors are received in the */
10600 /* most recently finished measurment period */
10601 /* no of pre RS bit errors */
10602 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_RS_NR_BIT_ERRORS__A
, &nr_bit_errors
, 0);
10604 pr_err("error %d\n", rc
);
10607 /* no of symbol errors */
10608 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_RS_NR_SYMBOL_ERRORS__A
, &nr_symbol_errors
, 0);
10610 pr_err("error %d\n", rc
);
10613 /* no of packet errors */
10614 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_RS_NR_PACKET_ERRORS__A
, &nr_packet_errors
, 0);
10616 pr_err("error %d\n", rc
);
10619 /* no of failures to decode */
10620 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_RS_NR_FAILURES__A
, &nr_failures
, 0);
10622 pr_err("error %d\n", rc
);
10625 /* no of post RS bit erros */
10626 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_SNC_FAIL_COUNT__A
, &nr_snc_par_fail_count
, 0);
10628 pr_err("error %d\n", rc
);
10632 /* These register values are fetched in non-atomic fashion */
10633 /* It is possible that the read values contain unrelated information */
10635 rs_errors
->nr_bit_errors
= nr_bit_errors
& FEC_RS_NR_BIT_ERRORS__M
;
10636 rs_errors
->nr_symbol_errors
= nr_symbol_errors
& FEC_RS_NR_SYMBOL_ERRORS__M
;
10637 rs_errors
->nr_packet_errors
= nr_packet_errors
& FEC_RS_NR_PACKET_ERRORS__M
;
10638 rs_errors
->nr_failures
= nr_failures
& FEC_RS_NR_FAILURES__M
;
10639 rs_errors
->nr_snc_par_fail_count
=
10640 nr_snc_par_fail_count
& FEC_OC_SNC_FAIL_COUNT__M
;
10647 /*============================================================================*/
10650 * \fn int ctrl_get_qam_sig_quality()
10651 * \brief Retreive QAM signal quality from device.
10652 * \param devmod Pointer to demodulator instance.
10653 * \param sig_quality Pointer to signal quality data.
10655 * \retval 0 sig_quality contains valid data.
10656 * \retval -EINVAL sig_quality is NULL.
10657 * \retval -EIO Erroneous data, sig_quality contains invalid data.
10659 * Pre-condition: Device must be started and in lock.
10662 ctrl_get_qam_sig_quality(struct drx_demod_instance
*demod
, struct drx_sig_quality
*sig_quality
)
10664 struct i2c_device_addr
*dev_addr
= NULL
;
10665 struct drxj_data
*ext_attr
= NULL
;
10667 enum drx_modulation constellation
= DRX_CONSTELLATION_UNKNOWN
;
10668 struct drxjrs_errors measuredrs_errors
= { 0, 0, 0, 0, 0 };
10670 u32 pre_bit_err_rs
= 0; /* pre RedSolomon Bit Error Rate */
10671 u32 post_bit_err_rs
= 0; /* post RedSolomon Bit Error Rate */
10672 u32 pkt_errs
= 0; /* no of packet errors in RS */
10673 u16 qam_sl_err_power
= 0; /* accumulated error between raw and sliced symbols */
10674 u16 qsym_err_vd
= 0; /* quadrature symbol errors in QAM_VD */
10675 u16 fec_oc_period
= 0; /* SNC sync failure measurement period */
10676 u16 fec_rs_prescale
= 0; /* ReedSolomon Measurement Prescale */
10677 u16 fec_rs_period
= 0; /* Value for corresponding I2C register */
10678 /* calculation constants */
10679 u32 rs_bit_cnt
= 0; /* RedSolomon Bit Count */
10680 u32 qam_sl_sig_power
= 0; /* used for MER, depends of QAM constellation */
10681 /* intermediate results */
10682 u32 e
= 0; /* exponent value used for QAM BER/SER */
10683 u32 m
= 0; /* mantisa value used for QAM BER/SER */
10684 u32 ber_cnt
= 0; /* BER count */
10685 /* signal quality info */
10686 u32 qam_sl_mer
= 0; /* QAM MER */
10687 u32 qam_pre_rs_ber
= 0; /* Pre RedSolomon BER */
10688 u32 qam_post_rs_ber
= 0; /* Post RedSolomon BER */
10689 u32 qam_vd_ser
= 0; /* ViterbiDecoder SER */
10690 u16 qam_vd_prescale
= 0; /* Viterbi Measurement Prescale */
10691 u16 qam_vd_period
= 0; /* Viterbi Measurement period */
10692 u32 vd_bit_cnt
= 0; /* ViterbiDecoder Bit Count */
10694 /* get device basic information */
10695 dev_addr
= demod
->my_i2c_dev_addr
;
10696 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
10697 constellation
= ext_attr
->constellation
;
10699 /* read the physical registers */
10700 /* Get the RS error data */
10701 rc
= get_qamrs_err_count(dev_addr
, &measuredrs_errors
);
10703 pr_err("error %d\n", rc
);
10706 /* get the register value needed for MER */
10707 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, QAM_SL_ERR_POWER__A
, &qam_sl_err_power
, 0);
10709 pr_err("error %d\n", rc
);
10712 /* get the register value needed for post RS BER */
10713 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, FEC_OC_SNC_FAIL_PERIOD__A
, &fec_oc_period
, 0);
10715 pr_err("error %d\n", rc
);
10719 /* get constants needed for signal quality calculation */
10720 fec_rs_period
= ext_attr
->fec_rs_period
;
10721 fec_rs_prescale
= ext_attr
->fec_rs_prescale
;
10722 rs_bit_cnt
= fec_rs_period
* fec_rs_prescale
* ext_attr
->fec_rs_plen
;
10723 qam_vd_period
= ext_attr
->qam_vd_period
;
10724 qam_vd_prescale
= ext_attr
->qam_vd_prescale
;
10725 vd_bit_cnt
= qam_vd_period
* qam_vd_prescale
* ext_attr
->fec_vd_plen
;
10727 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
10728 switch (constellation
) {
10729 case DRX_CONSTELLATION_QAM16
:
10730 qam_sl_sig_power
= DRXJ_QAM_SL_SIG_POWER_QAM16
<< 2;
10732 case DRX_CONSTELLATION_QAM32
:
10733 qam_sl_sig_power
= DRXJ_QAM_SL_SIG_POWER_QAM32
<< 2;
10735 case DRX_CONSTELLATION_QAM64
:
10736 qam_sl_sig_power
= DRXJ_QAM_SL_SIG_POWER_QAM64
<< 2;
10738 case DRX_CONSTELLATION_QAM128
:
10739 qam_sl_sig_power
= DRXJ_QAM_SL_SIG_POWER_QAM128
<< 2;
10741 case DRX_CONSTELLATION_QAM256
:
10742 qam_sl_sig_power
= DRXJ_QAM_SL_SIG_POWER_QAM256
<< 2;
10748 /* ------------------------------ */
10749 /* MER Calculation */
10750 /* ------------------------------ */
10751 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
10753 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
10754 if (qam_sl_err_power
== 0)
10757 qam_sl_mer
= log1_times100(qam_sl_sig_power
) - log1_times100((u32
)qam_sl_err_power
);
10759 /* ----------------------------------------- */
10760 /* Pre Viterbi Symbol Error Rate Calculation */
10761 /* ----------------------------------------- */
10762 /* pre viterbi SER is good if it is bellow 0.025 */
10764 /* get the register value */
10765 /* no of quadrature symbol errors */
10766 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, QAM_VD_NR_QSYM_ERRORS__A
, &qsym_err_vd
, 0);
10768 pr_err("error %d\n", rc
);
10771 /* Extract the Exponent and the Mantisa */
10772 /* of number of quadrature symbol errors */
10773 e
= (qsym_err_vd
& QAM_VD_NR_QSYM_ERRORS_EXP__M
) >>
10774 QAM_VD_NR_QSYM_ERRORS_EXP__B
;
10775 m
= (qsym_err_vd
& QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M
) >>
10776 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B
;
10778 if ((m
<< e
) >> 3 > 549752)
10779 qam_vd_ser
= 500000;
10781 qam_vd_ser
= frac_times1e6(m
<< ((e
> 2) ? (e
- 3) : e
), vd_bit_cnt
* ((e
> 2) ? 1 : 8) / 8);
10783 /* --------------------------------------- */
10784 /* pre and post RedSolomon BER Calculation */
10785 /* --------------------------------------- */
10786 /* pre RS BER is good if it is below 3.5e-4 */
10788 /* get the register values */
10789 pre_bit_err_rs
= (u32
) measuredrs_errors
.nr_bit_errors
;
10790 pkt_errs
= post_bit_err_rs
= (u32
) measuredrs_errors
.nr_snc_par_fail_count
;
10792 /* Extract the Exponent and the Mantisa of the */
10793 /* pre Reed-Solomon bit error count */
10794 e
= (pre_bit_err_rs
& FEC_RS_NR_BIT_ERRORS_EXP__M
) >>
10795 FEC_RS_NR_BIT_ERRORS_EXP__B
;
10796 m
= (pre_bit_err_rs
& FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M
) >>
10797 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B
;
10801 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
10802 if (m
> (rs_bit_cnt
>> (e
+ 1)) || (rs_bit_cnt
>> e
) == 0)
10803 qam_pre_rs_ber
= 500000;
10805 qam_pre_rs_ber
= frac_times1e6(m
, rs_bit_cnt
>> e
);
10807 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
10808 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
10810 => c = (1000000*100*11.17)/1504 =
10811 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
10812 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
10813 *100 and /100 is for more precision.
10814 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
10816 Precision errors still possible.
10818 e
= post_bit_err_rs
* 742686;
10819 m
= fec_oc_period
* 100;
10820 if (fec_oc_period
== 0)
10821 qam_post_rs_ber
= 0xFFFFFFFF;
10823 qam_post_rs_ber
= e
/ m
;
10825 /* fill signal quality data structure */
10826 sig_quality
->MER
= ((u16
) qam_sl_mer
);
10827 if (ext_attr
->standard
== DRX_STANDARD_ITU_B
)
10828 sig_quality
->pre_viterbi_ber
= qam_vd_ser
;
10830 sig_quality
->pre_viterbi_ber
= qam_pre_rs_ber
;
10831 sig_quality
->post_viterbi_ber
= qam_pre_rs_ber
;
10832 sig_quality
->post_reed_solomon_ber
= qam_post_rs_ber
;
10833 sig_quality
->scale_factor_ber
= ((u32
) 1000000);
10834 #ifdef DRXJ_SIGNAL_ACCUM_ERR
10835 rc
= get_acc_pkt_err(demod
, &sig_quality
->packet_error
);
10837 pr_err("error %d\n", rc
);
10841 sig_quality
->packet_error
= ((u16
) pkt_errs
);
10851 * \fn int ctrl_get_qam_constel()
10852 * \brief Retreive a QAM constellation point via I2C.
10853 * \param demod Pointer to demodulator instance.
10854 * \param complex_nr Pointer to the structure in which to store the
10855 constellation point.
10859 ctrl_get_qam_constel(struct drx_demod_instance
*demod
, struct drx_complex
*complex_nr
)
10861 struct i2c_device_addr
*dev_addr
= NULL
;
10864 u16 fec_oc_ocr_mode
= 0;
10865 /**< FEC OCR grabber configuration */
10866 u16 qam_sl_comm_mb
= 0;/**< QAM SL MB configuration */
10867 u16 qam_sl_comm_mb_init
= 0;
10868 /**< QAM SL MB intial configuration */
10869 u16 im
= 0; /**< constellation Im part */
10870 u16 re
= 0; /**< constellation Re part */
10871 /**< device address */
10873 /* read device info */
10874 dev_addr
= demod
->my_i2c_dev_addr
;
10877 /* Monitor bus grabbing is an open external interface issue */
10878 /* Needs to be checked when external interface PG is updated */
10880 /* Configure MB (Monitor bus) */
10881 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, QAM_SL_COMM_MB__A
, &qam_sl_comm_mb_init
, 0);
10883 pr_err("error %d\n", rc
);
10886 /* set observe flag & MB mux */
10887 qam_sl_comm_mb
= qam_sl_comm_mb_init
& (~(QAM_SL_COMM_MB_OBS__M
+
10888 QAM_SL_COMM_MB_MUX_OBS__M
));
10889 qam_sl_comm_mb
|= (QAM_SL_COMM_MB_OBS_ON
+
10890 QAM_SL_COMM_MB_MUX_OBS_CONST_CORR
);
10891 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SL_COMM_MB__A
, qam_sl_comm_mb
, 0);
10893 pr_err("error %d\n", rc
);
10897 /* Enable MB grabber in the FEC OC */
10898 fec_oc_ocr_mode
= (/* output select: observe bus */
10899 (FEC_OC_OCR_MODE_MB_SELECT__M
&
10900 (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B
)) |
10901 /* grabber enable: on */
10902 (FEC_OC_OCR_MODE_GRAB_ENABLE__M
&
10903 (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B
)) |
10904 /* grabber select: observe bus */
10905 (FEC_OC_OCR_MODE_GRAB_SELECT__M
&
10906 (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B
)) |
10907 /* grabber mode: continuous */
10908 (FEC_OC_OCR_MODE_GRAB_COUNTED__M
&
10909 (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B
)));
10910 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_OCR_MODE__A
, fec_oc_ocr_mode
, 0);
10912 pr_err("error %d\n", rc
);
10916 /* Disable MB grabber in the FEC OC */
10917 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, FEC_OC_OCR_MODE__A
, 0x00, 0);
10919 pr_err("error %d\n", rc
);
10924 rc
= DRXJ_DAP
.read_reg32func(dev_addr
, FEC_OC_OCR_GRAB_RD0__A
, &data
, 0);
10926 pr_err("error %d\n", rc
);
10929 re
= (u16
) (data
& FEC_OC_OCR_GRAB_RD0__M
);
10930 im
= (u16
) ((data
>> 16) & FEC_OC_OCR_GRAB_RD1__M
);
10933 /* interpret data (re & im) according to the Monitor bus mapping ?? */
10935 /* sign extension, 10th bit is sign bit */
10936 if ((re
& 0x0200) == 0x0200)
10938 if ((im
& 0x0200) == 0x0200)
10940 complex_nr
->re
= ((s16
) re
);
10941 complex_nr
->im
= ((s16
) im
);
10943 /* Restore MB (Monitor bus) */
10944 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, QAM_SL_COMM_MB__A
, qam_sl_comm_mb_init
, 0);
10946 pr_err("error %d\n", rc
);
10955 #endif /* #ifndef DRXJ_VSB_ONLY */
10957 /*============================================================================*/
10958 /*== END QAM DATAPATH FUNCTIONS ==*/
10959 /*============================================================================*/
10961 /*============================================================================*/
10962 /*============================================================================*/
10963 /*== ATV DATAPATH FUNCTIONS ==*/
10964 /*============================================================================*/
10965 /*============================================================================*/
10968 Implementation notes.
10972 Four AGCs are used for NTSC:
10973 (1) RF (used to attenuate the input signal in case of to much power)
10974 (2) IF (used to attenuate the input signal in case of to much power)
10975 (3) Video AGC (used to amplify the output signal in case input to low)
10976 (4) SIF AGC (used to amplify the output signal in case input to low)
10978 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
10979 that the coupling between Video AGC and the RF and IF AGCs also works in
10980 favor of the SIF AGC.
10982 Three AGCs are used for FM:
10983 (1) RF (used to attenuate the input signal in case of to much power)
10984 (2) IF (used to attenuate the input signal in case of to much power)
10985 (3) SIF AGC (used to amplify the output signal in case input to low)
10987 The SIF AGC is now coupled to the RF/IF AGCs.
10988 The SIF AGC is needed for both SIF ouput and the internal SIF signal to
10991 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
10992 the ATV block. The AGC control algorithms are all implemented in
10997 (Shadow settings will not be used for now, they will be implemented
10998 later on because of the schedule)
11000 Several HW/SCU "settings" can be used for ATV. The standard selection
11001 will reset most of these settings. To avoid that the end user apllication
11002 has to perform these settings each time the ATV or FM standards is
11003 selected the driver will shadow these settings. This enables the end user
11004 to perform the settings only once after a drx_open(). The driver must
11005 write the shadow settings to HW/SCU incase:
11006 ( setstandard FM/ATV) ||
11007 ( settings have changed && FM/ATV standard is active)
11008 The shadow settings will be stored in the device specific data container.
11009 A set of flags will be defined to flag changes in shadow settings.
11010 A routine will be implemented to write all changed shadow settings to
11013 The "settings" will consist of: AGC settings, filter settings etc.
11015 Disadvantage of use of shadow settings:
11016 Direct changes in HW/SCU registers will not be reflected in the
11017 shadow settings and these changes will be overwritten during a next
11018 update. This can happen during evaluation. This will not be a problem
11019 for normal customer usage.
11021 /* -------------------------------------------------------------------------- */
11025 * \brief Get array index for atv coef (ext_attr->atvTopCoefX[index])
11027 * \param pointer to index
11031 static int atv_equ_coef_index(enum drx_standard standard
, int *index
)
11033 switch (standard
) {
11034 case DRX_STANDARD_PAL_SECAM_BG
:
11035 *index
= (int)DRXJ_COEF_IDX_BG
;
11037 case DRX_STANDARD_PAL_SECAM_DK
:
11038 *index
= (int)DRXJ_COEF_IDX_DK
;
11040 case DRX_STANDARD_PAL_SECAM_I
:
11041 *index
= (int)DRXJ_COEF_IDX_I
;
11043 case DRX_STANDARD_PAL_SECAM_L
:
11044 *index
= (int)DRXJ_COEF_IDX_L
;
11046 case DRX_STANDARD_PAL_SECAM_LP
:
11047 *index
= (int)DRXJ_COEF_IDX_LP
;
11049 case DRX_STANDARD_NTSC
:
11050 *index
= (int)DRXJ_COEF_IDX_MN
;
11052 case DRX_STANDARD_FM
:
11053 *index
= (int)DRXJ_COEF_IDX_FM
;
11056 *index
= (int)DRXJ_COEF_IDX_MN
; /* still return a valid index */
11064 /* -------------------------------------------------------------------------- */
11066 * \fn int atv_update_config ()
11067 * \brief Flush changes in ATV shadow registers to physical registers.
11068 * \param demod instance of demodulator
11069 * \param force_update don't look at standard or change flags, flush all.
11074 atv_update_config(struct drx_demod_instance
*demod
, bool force_update
)
11076 struct i2c_device_addr
*dev_addr
= NULL
;
11077 struct drxj_data
*ext_attr
= NULL
;
11080 dev_addr
= demod
->my_i2c_dev_addr
;
11081 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
11083 /* equalizer coefficients */
11084 if (force_update
||
11085 ((ext_attr
->atv_cfg_changed_flags
& DRXJ_ATV_CHANGED_COEF
) != 0)) {
11088 rc
= atv_equ_coef_index(ext_attr
->standard
, &index
);
11090 pr_err("error %d\n", rc
);
11093 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_EQU0__A
, ext_attr
->atv_top_equ0
[index
], 0);
11095 pr_err("error %d\n", rc
);
11098 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_EQU1__A
, ext_attr
->atv_top_equ1
[index
], 0);
11100 pr_err("error %d\n", rc
);
11103 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_EQU2__A
, ext_attr
->atv_top_equ2
[index
], 0);
11105 pr_err("error %d\n", rc
);
11108 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_EQU3__A
, ext_attr
->atv_top_equ3
[index
], 0);
11110 pr_err("error %d\n", rc
);
11115 /* bypass fast carrier recovery */
11116 if (force_update
) {
11119 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_RT_ROT_BP__A
, &data
, 0);
11121 pr_err("error %d\n", rc
);
11124 data
&= (~((u16
) IQM_RT_ROT_BP_ROT_OFF__M
));
11125 if (ext_attr
->phase_correction_bypass
)
11126 data
|= IQM_RT_ROT_BP_ROT_OFF_OFF
;
11128 data
|= IQM_RT_ROT_BP_ROT_OFF_ACTIVE
;
11129 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_ROT_BP__A
, data
, 0);
11131 pr_err("error %d\n", rc
);
11136 /* peak filter setting */
11137 if (force_update
||
11138 ((ext_attr
->atv_cfg_changed_flags
& DRXJ_ATV_CHANGED_PEAK_FLT
) != 0)) {
11139 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_VID_PEAK__A
, ext_attr
->atv_top_vid_peak
, 0);
11141 pr_err("error %d\n", rc
);
11146 /* noise filter setting */
11147 if (force_update
||
11148 ((ext_attr
->atv_cfg_changed_flags
& DRXJ_ATV_CHANGED_NOISE_FLT
) != 0)) {
11149 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_NOISE_TH__A
, ext_attr
->atv_top_noise_th
, 0);
11151 pr_err("error %d\n", rc
);
11156 /* SIF attenuation */
11157 if (force_update
||
11158 ((ext_attr
->atv_cfg_changed_flags
& DRXJ_ATV_CHANGED_SIF_ATT
) != 0)) {
11159 u16 attenuation
= 0;
11161 switch (ext_attr
->sif_attenuation
) {
11162 case DRXJ_SIF_ATTENUATION_0DB
:
11163 attenuation
= ATV_TOP_AF_SIF_ATT_0DB
;
11165 case DRXJ_SIF_ATTENUATION_3DB
:
11166 attenuation
= ATV_TOP_AF_SIF_ATT_M3DB
;
11168 case DRXJ_SIF_ATTENUATION_6DB
:
11169 attenuation
= ATV_TOP_AF_SIF_ATT_M6DB
;
11171 case DRXJ_SIF_ATTENUATION_9DB
:
11172 attenuation
= ATV_TOP_AF_SIF_ATT_M9DB
;
11178 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_AF_SIF_ATT__A
, attenuation
, 0);
11180 pr_err("error %d\n", rc
);
11185 /* SIF & CVBS enable */
11186 if (force_update
||
11187 ((ext_attr
->atv_cfg_changed_flags
& DRXJ_ATV_CHANGED_OUTPUT
) != 0)) {
11190 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ATV_TOP_STDBY__A
, &data
, 0);
11192 pr_err("error %d\n", rc
);
11195 if (ext_attr
->enable_cvbs_output
)
11196 data
|= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE
;
11198 data
&= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE
);
11200 if (ext_attr
->enable_sif_output
)
11201 data
&= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY
);
11203 data
|= ATV_TOP_STDBY_SIF_STDBY_STANDBY
;
11204 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_STDBY__A
, data
, 0);
11206 pr_err("error %d\n", rc
);
11211 ext_attr
->atv_cfg_changed_flags
= 0;
11218 /* -------------------------------------------------------------------------- */
11220 * \fn int ctrl_set_cfg_atv_output()
11221 * \brief Configure ATV ouputs
11222 * \param demod instance of demodulator
11223 * \param output_cfg output configuaration
11228 ctrl_set_cfg_atv_output(struct drx_demod_instance
*demod
, struct drxj_cfg_atv_output
*output_cfg
)
11230 struct drxj_data
*ext_attr
= NULL
;
11233 /* Check arguments */
11234 if (output_cfg
== NULL
)
11237 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
11238 if (output_cfg
->enable_sif_output
) {
11239 switch (output_cfg
->sif_attenuation
) {
11240 case DRXJ_SIF_ATTENUATION_0DB
: /* fallthrough */
11241 case DRXJ_SIF_ATTENUATION_3DB
: /* fallthrough */
11242 case DRXJ_SIF_ATTENUATION_6DB
: /* fallthrough */
11243 case DRXJ_SIF_ATTENUATION_9DB
:
11251 if (ext_attr
->sif_attenuation
!= output_cfg
->sif_attenuation
) {
11252 ext_attr
->sif_attenuation
= output_cfg
->sif_attenuation
;
11253 ext_attr
->atv_cfg_changed_flags
|= DRXJ_ATV_CHANGED_SIF_ATT
;
11257 if (ext_attr
->enable_cvbs_output
!= output_cfg
->enable_cvbs_output
) {
11258 ext_attr
->enable_cvbs_output
= output_cfg
->enable_cvbs_output
;
11259 ext_attr
->atv_cfg_changed_flags
|= DRXJ_ATV_CHANGED_OUTPUT
;
11262 if (ext_attr
->enable_sif_output
!= output_cfg
->enable_sif_output
) {
11263 ext_attr
->enable_sif_output
= output_cfg
->enable_sif_output
;
11264 ext_attr
->atv_cfg_changed_flags
|= DRXJ_ATV_CHANGED_OUTPUT
;
11267 rc
= atv_update_config(demod
, false);
11269 pr_err("error %d\n", rc
);
11278 /* -------------------------------------------------------------------------- */
11280 * \fn int ctrl_set_cfg_atv_equ_coef()
11281 * \brief Set ATV equalizer coefficients
11282 * \param demod instance of demodulator
11283 * \param coef the equalizer coefficients
11288 ctrl_set_cfg_atv_equ_coef(struct drx_demod_instance
*demod
, struct drxj_cfg_atv_equ_coef
*coef
)
11290 struct drxj_data
*ext_attr
= NULL
;
11294 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
11296 /* current standard needs to be an ATV standard */
11297 if (!DRXJ_ISATVSTD(ext_attr
->standard
))
11300 /* Check arguments */
11301 if ((coef
== NULL
) ||
11302 (coef
->coef0
> (ATV_TOP_EQU0_EQU_C0__M
/ 2)) ||
11303 (coef
->coef1
> (ATV_TOP_EQU1_EQU_C1__M
/ 2)) ||
11304 (coef
->coef2
> (ATV_TOP_EQU2_EQU_C2__M
/ 2)) ||
11305 (coef
->coef3
> (ATV_TOP_EQU3_EQU_C3__M
/ 2)) ||
11306 (coef
->coef0
< ((s16
) ~(ATV_TOP_EQU0_EQU_C0__M
>> 1))) ||
11307 (coef
->coef1
< ((s16
) ~(ATV_TOP_EQU1_EQU_C1__M
>> 1))) ||
11308 (coef
->coef2
< ((s16
) ~(ATV_TOP_EQU2_EQU_C2__M
>> 1))) ||
11309 (coef
->coef3
< ((s16
) ~(ATV_TOP_EQU3_EQU_C3__M
>> 1)))) {
11313 rc
= atv_equ_coef_index(ext_attr
->standard
, &index
);
11315 pr_err("error %d\n", rc
);
11318 ext_attr
->atv_top_equ0
[index
] = coef
->coef0
;
11319 ext_attr
->atv_top_equ1
[index
] = coef
->coef1
;
11320 ext_attr
->atv_top_equ2
[index
] = coef
->coef2
;
11321 ext_attr
->atv_top_equ3
[index
] = coef
->coef3
;
11322 ext_attr
->atv_cfg_changed_flags
|= DRXJ_ATV_CHANGED_COEF
;
11324 rc
= atv_update_config(demod
, false);
11326 pr_err("error %d\n", rc
);
11335 /* -------------------------------------------------------------------------- */
11337 * \fn int ctrl_get_cfg_atv_equ_coef()
11338 * \brief Get ATV equ coef settings
11339 * \param demod instance of demodulator
11340 * \param coef The ATV equ coefficients
11343 * The values are read from the shadow registers maintained by the drxdriver
11344 * If registers are manipulated outside of the drxdriver scope the reported
11345 * settings will not reflect these changes because of the use of shadow
11350 ctrl_get_cfg_atv_equ_coef(struct drx_demod_instance
*demod
, struct drxj_cfg_atv_equ_coef
*coef
)
11352 struct drxj_data
*ext_attr
= NULL
;
11356 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
11358 /* current standard needs to be an ATV standard */
11359 if (!DRXJ_ISATVSTD(ext_attr
->standard
))
11362 /* Check arguments */
11366 rc
= atv_equ_coef_index(ext_attr
->standard
, &index
);
11368 pr_err("error %d\n", rc
);
11371 coef
->coef0
= ext_attr
->atv_top_equ0
[index
];
11372 coef
->coef1
= ext_attr
->atv_top_equ1
[index
];
11373 coef
->coef2
= ext_attr
->atv_top_equ2
[index
];
11374 coef
->coef3
= ext_attr
->atv_top_equ3
[index
];
11381 /* -------------------------------------------------------------------------- */
11383 * \fn int ctrl_set_cfg_atv_misc()
11384 * \brief Set misc. settings for ATV.
11385 * \param demod instance of demodulator
11391 ctrl_set_cfg_atv_misc(struct drx_demod_instance
*demod
, struct drxj_cfg_atv_misc
*settings
)
11393 struct drxj_data
*ext_attr
= NULL
;
11396 /* Check arguments */
11397 if ((settings
== NULL
) ||
11398 ((settings
->peak_filter
) < (s16
) (-8)) ||
11399 ((settings
->peak_filter
) > (s16
) (15)) ||
11400 ((settings
->noise_filter
) > 15)) {
11404 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
11406 if (settings
->peak_filter
!= ext_attr
->atv_top_vid_peak
) {
11407 ext_attr
->atv_top_vid_peak
= settings
->peak_filter
;
11408 ext_attr
->atv_cfg_changed_flags
|= DRXJ_ATV_CHANGED_PEAK_FLT
;
11411 if (settings
->noise_filter
!= ext_attr
->atv_top_noise_th
) {
11412 ext_attr
->atv_top_noise_th
= settings
->noise_filter
;
11413 ext_attr
->atv_cfg_changed_flags
|= DRXJ_ATV_CHANGED_NOISE_FLT
;
11416 rc
= atv_update_config(demod
, false);
11418 pr_err("error %d\n", rc
);
11427 /* -------------------------------------------------------------------------- */
11429 * \fn int ctrl_get_cfg_atv_misc()
11430 * \brief Get misc settings of ATV.
11431 * \param demod instance of demodulator
11432 * \param settings misc. ATV settings
11435 * The values are read from the shadow registers maintained by the drxdriver
11436 * If registers are manipulated outside of the drxdriver scope the reported
11437 * settings will not reflect these changes because of the use of shadow
11441 ctrl_get_cfg_atv_misc(struct drx_demod_instance
*demod
, struct drxj_cfg_atv_misc
*settings
)
11443 struct drxj_data
*ext_attr
= NULL
;
11445 /* Check arguments */
11446 if (settings
== NULL
)
11449 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
11451 settings
->peak_filter
= ext_attr
->atv_top_vid_peak
;
11452 settings
->noise_filter
= ext_attr
->atv_top_noise_th
;
11457 /* -------------------------------------------------------------------------- */
11459 /* -------------------------------------------------------------------------- */
11461 * \fn int ctrl_get_cfg_atv_output()
11463 * \param demod instance of demodulator
11464 * \param output_cfg output configuaration
11469 ctrl_get_cfg_atv_output(struct drx_demod_instance
*demod
, struct drxj_cfg_atv_output
*output_cfg
)
11474 /* Check arguments */
11475 if (output_cfg
== NULL
)
11478 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, ATV_TOP_STDBY__A
, &data
, 0);
11480 pr_err("error %d\n", rc
);
11483 if (data
& ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE
)
11484 output_cfg
->enable_cvbs_output
= true;
11486 output_cfg
->enable_cvbs_output
= false;
11488 if (data
& ATV_TOP_STDBY_SIF_STDBY_STANDBY
) {
11489 output_cfg
->enable_sif_output
= false;
11491 output_cfg
->enable_sif_output
= true;
11492 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, ATV_TOP_AF_SIF_ATT__A
, &data
, 0);
11494 pr_err("error %d\n", rc
);
11497 output_cfg
->sif_attenuation
= (enum drxjsif_attenuation
) data
;
11505 /* -------------------------------------------------------------------------- */
11507 * \fn int ctrl_get_cfg_atv_agc_status()
11509 * \param demod instance of demodulator
11510 * \param agc_status agc status
11515 ctrl_get_cfg_atv_agc_status(struct drx_demod_instance
*demod
,
11516 struct drxj_cfg_atv_agc_status
*agc_status
)
11518 struct i2c_device_addr
*dev_addr
= NULL
;
11523 /* Check arguments */
11524 if (agc_status
== NULL
)
11527 dev_addr
= demod
->my_i2c_dev_addr
;
11530 RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
11531 = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
11533 IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
11535 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_AGC_RF__A
, &data
, 0);
11537 pr_err("error %d\n", rc
);
11540 tmp
= ((u32
) data
) * 27 - ((u32
) (data
>> 2)); /* nA */
11541 agc_status
->rf_agc_gain
= (u16
) (tmp
/ 1000); /* uA */
11543 if (tmp
% 1000 >= 500)
11544 (agc_status
->rf_agc_gain
)++;
11547 IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
11548 = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
11550 IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
11552 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_AGC_IF__A
, &data
, 0);
11554 pr_err("error %d\n", rc
);
11557 tmp
= ((u32
) data
) * 27 - ((u32
) (data
>> 2)); /* nA */
11558 agc_status
->if_agc_gain
= (u16
) (tmp
/ 1000); /* uA */
11560 if (tmp
% 1000 >= 500)
11561 (agc_status
->if_agc_gain
)++;
11564 videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
11565 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
11566 = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
11567 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
11568 = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
11571 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ATV_VID_GAIN_HI__A
, &data
, 0);
11573 pr_err("error %d\n", rc
);
11576 /* dividing by 32 inclusive rounding */
11578 if ((data
& 1) != 0)
11581 agc_status
->video_agc_gain
= ((s16
) data
) - 75; /* 0.1 dB */
11584 audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
11585 = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
11586 = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
11587 = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
11588 = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
11591 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ATV_SIF_GAIN__A
, &data
, 0);
11593 pr_err("error %d\n", rc
);
11596 data
&= SCU_RAM_ATV_SIF_GAIN__M
;
11597 /* dividing by 2 inclusive rounding */
11598 if ((data
& 1) != 0)
11601 agc_status
->audio_agc_gain
= ((s16
) data
) - 4; /* 0.1 dB */
11604 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_AGC_KI__A
, &data
, 0);
11606 pr_err("error %d\n", rc
);
11609 agc_status
->video_agc_loop_gain
=
11610 ((data
& SCU_RAM_AGC_KI_DGAIN__M
) >> SCU_RAM_AGC_KI_DGAIN__B
);
11611 agc_status
->rf_agc_loop_gain
=
11612 ((data
& SCU_RAM_AGC_KI_RF__M
) >> SCU_RAM_AGC_KI_RF__B
);
11613 agc_status
->if_agc_loop_gain
=
11614 ((data
& SCU_RAM_AGC_KI_IF__M
) >> SCU_RAM_AGC_KI_IF__B
);
11621 /* -------------------------------------------------------------------------- */
11624 * \fn int power_up_atv ()
11625 * \brief Power up ATV.
11626 * \param demod instance of demodulator
11627 * \param standard either NTSC or FM (sub strandard for ATV )
11630 * * Starts ATV and IQM
11631 * * AUdio already started during standard init for ATV.
11633 static int power_up_atv(struct drx_demod_instance
*demod
, enum drx_standard standard
)
11635 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
11639 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_COMM_EXEC__A
, ATV_COMM_EXEC_ACTIVE
, 0);
11641 pr_err("error %d\n", rc
);
11644 /* turn on IQM_AF */
11645 rc
= set_iqm_af(demod
, true);
11647 pr_err("error %d\n", rc
);
11650 rc
= adc_synchronization(demod
);
11652 pr_err("error %d\n", rc
);
11656 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_COMM_EXEC__A
, IQM_COMM_EXEC_ACTIVE
, 0);
11658 pr_err("error %d\n", rc
);
11662 /* Audio, already done during set standard */
11670 /* -------------------------------------------------------------------------- */
11673 * \fn int power_down_atv ()
11674 * \brief Power down ATV.
11675 * \param demod instance of demodulator
11676 * \param standard either NTSC or FM (sub strandard for ATV )
11679 * Stops and thus resets ATV and IQM block
11680 * SIF and CVBS ADC are powered down
11681 * Calls audio power down
11684 power_down_atv(struct drx_demod_instance
*demod
, enum drx_standard standard
, bool primary
)
11686 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
11687 struct drxjscu_cmd cmd_scu
= { /* command */ 0,
11688 /* parameter_len */ 0,
11689 /* result_len */ 0,
11690 /* *parameter */ NULL
,
11694 u16 cmd_result
= 0;
11698 /* Stop ATV SCU (will reset ATV and IQM hardware */
11699 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_ATV
|
11700 SCU_RAM_COMMAND_CMD_DEMOD_STOP
;
11701 cmd_scu
.parameter_len
= 0;
11702 cmd_scu
.result_len
= 1;
11703 cmd_scu
.parameter
= NULL
;
11704 cmd_scu
.result
= &cmd_result
;
11705 rc
= scu_command(dev_addr
, &cmd_scu
);
11707 pr_err("error %d\n", rc
);
11710 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
11711 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);
11713 pr_err("error %d\n", rc
);
11717 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_COMM_EXEC__A
, ATV_COMM_EXEC_STOP
, 0);
11719 pr_err("error %d\n", rc
);
11723 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_COMM_EXEC__A
, IQM_COMM_EXEC_STOP
, 0);
11725 pr_err("error %d\n", rc
);
11728 rc
= set_iqm_af(demod
, false);
11730 pr_err("error %d\n", rc
);
11734 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FS_COMM_EXEC__A
, IQM_FS_COMM_EXEC_STOP
, 0);
11736 pr_err("error %d\n", rc
);
11739 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FD_COMM_EXEC__A
, IQM_FD_COMM_EXEC_STOP
, 0);
11741 pr_err("error %d\n", rc
);
11744 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_COMM_EXEC__A
, IQM_RC_COMM_EXEC_STOP
, 0);
11746 pr_err("error %d\n", rc
);
11749 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_COMM_EXEC__A
, IQM_RT_COMM_EXEC_STOP
, 0);
11751 pr_err("error %d\n", rc
);
11754 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_COMM_EXEC__A
, IQM_CF_COMM_EXEC_STOP
, 0);
11756 pr_err("error %d\n", rc
);
11760 rc
= power_down_aud(demod
);
11762 pr_err("error %d\n", rc
);
11771 /* -------------------------------------------------------------------------- */
11773 * \fn int set_atv_standard ()
11774 * \brief Set up ATV demodulator.
11775 * \param demod instance of demodulator
11776 * \param standard either NTSC or FM (sub strandard for ATV )
11779 * Init all channel independent registers.
11780 * Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
11784 #define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */
11786 set_atv_standard(struct drx_demod_instance
*demod
, enum drx_standard
*standard
)
11788 /* TODO: enable alternative for tap settings via external file
11791 #ifdef DRXJ_ATV_COEF_FILE
11792 #include DRXJ_ATV_COEF_FILE
11794 ... code defining fixed coef's ...
11797 Cutsomer must create file "customer_coefs.c.inc" containing
11798 modified copy off the constants below, and define the compiler
11799 switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
11801 Still to check if this will work; DRXJ_16TO8 macro may cause
11804 const u8 ntsc_taps_re
[] = {
11805 DRXJ_16TO8(-12), /* re0 */
11806 DRXJ_16TO8(-9), /* re1 */
11807 DRXJ_16TO8(9), /* re2 */
11808 DRXJ_16TO8(19), /* re3 */
11809 DRXJ_16TO8(-4), /* re4 */
11810 DRXJ_16TO8(-24), /* re5 */
11811 DRXJ_16TO8(-6), /* re6 */
11812 DRXJ_16TO8(16), /* re7 */
11813 DRXJ_16TO8(6), /* re8 */
11814 DRXJ_16TO8(-16), /* re9 */
11815 DRXJ_16TO8(-5), /* re10 */
11816 DRXJ_16TO8(13), /* re11 */
11817 DRXJ_16TO8(-2), /* re12 */
11818 DRXJ_16TO8(-20), /* re13 */
11819 DRXJ_16TO8(4), /* re14 */
11820 DRXJ_16TO8(25), /* re15 */
11821 DRXJ_16TO8(-6), /* re16 */
11822 DRXJ_16TO8(-36), /* re17 */
11823 DRXJ_16TO8(2), /* re18 */
11824 DRXJ_16TO8(38), /* re19 */
11825 DRXJ_16TO8(-10), /* re20 */
11826 DRXJ_16TO8(-48), /* re21 */
11827 DRXJ_16TO8(35), /* re22 */
11828 DRXJ_16TO8(94), /* re23 */
11829 DRXJ_16TO8(-59), /* re24 */
11830 DRXJ_16TO8(-217), /* re25 */
11831 DRXJ_16TO8(50), /* re26 */
11832 DRXJ_16TO8(679) /* re27 */
11834 const u8 ntsc_taps_im
[] = {
11835 DRXJ_16TO8(11), /* im0 */
11836 DRXJ_16TO8(1), /* im1 */
11837 DRXJ_16TO8(-10), /* im2 */
11838 DRXJ_16TO8(2), /* im3 */
11839 DRXJ_16TO8(24), /* im4 */
11840 DRXJ_16TO8(21), /* im5 */
11841 DRXJ_16TO8(1), /* im6 */
11842 DRXJ_16TO8(-4), /* im7 */
11843 DRXJ_16TO8(7), /* im8 */
11844 DRXJ_16TO8(14), /* im9 */
11845 DRXJ_16TO8(27), /* im10 */
11846 DRXJ_16TO8(42), /* im11 */
11847 DRXJ_16TO8(22), /* im12 */
11848 DRXJ_16TO8(-20), /* im13 */
11849 DRXJ_16TO8(2), /* im14 */
11850 DRXJ_16TO8(98), /* im15 */
11851 DRXJ_16TO8(122), /* im16 */
11852 DRXJ_16TO8(0), /* im17 */
11853 DRXJ_16TO8(-85), /* im18 */
11854 DRXJ_16TO8(51), /* im19 */
11855 DRXJ_16TO8(247), /* im20 */
11856 DRXJ_16TO8(192), /* im21 */
11857 DRXJ_16TO8(-55), /* im22 */
11858 DRXJ_16TO8(-95), /* im23 */
11859 DRXJ_16TO8(217), /* im24 */
11860 DRXJ_16TO8(544), /* im25 */
11861 DRXJ_16TO8(553), /* im26 */
11862 DRXJ_16TO8(302) /* im27 */
11864 const u8 bg_taps_re
[] = {
11865 DRXJ_16TO8(-18), /* re0 */
11866 DRXJ_16TO8(18), /* re1 */
11867 DRXJ_16TO8(19), /* re2 */
11868 DRXJ_16TO8(-26), /* re3 */
11869 DRXJ_16TO8(-20), /* re4 */
11870 DRXJ_16TO8(36), /* re5 */
11871 DRXJ_16TO8(5), /* re6 */
11872 DRXJ_16TO8(-51), /* re7 */
11873 DRXJ_16TO8(15), /* re8 */
11874 DRXJ_16TO8(45), /* re9 */
11875 DRXJ_16TO8(-46), /* re10 */
11876 DRXJ_16TO8(-24), /* re11 */
11877 DRXJ_16TO8(71), /* re12 */
11878 DRXJ_16TO8(-17), /* re13 */
11879 DRXJ_16TO8(-83), /* re14 */
11880 DRXJ_16TO8(74), /* re15 */
11881 DRXJ_16TO8(75), /* re16 */
11882 DRXJ_16TO8(-134), /* re17 */
11883 DRXJ_16TO8(-40), /* re18 */
11884 DRXJ_16TO8(191), /* re19 */
11885 DRXJ_16TO8(-11), /* re20 */
11886 DRXJ_16TO8(-233), /* re21 */
11887 DRXJ_16TO8(74), /* re22 */
11888 DRXJ_16TO8(271), /* re23 */
11889 DRXJ_16TO8(-132), /* re24 */
11890 DRXJ_16TO8(-341), /* re25 */
11891 DRXJ_16TO8(172), /* re26 */
11892 DRXJ_16TO8(801) /* re27 */
11894 const u8 bg_taps_im
[] = {
11895 DRXJ_16TO8(-24), /* im0 */
11896 DRXJ_16TO8(-10), /* im1 */
11897 DRXJ_16TO8(9), /* im2 */
11898 DRXJ_16TO8(-5), /* im3 */
11899 DRXJ_16TO8(-51), /* im4 */
11900 DRXJ_16TO8(-17), /* im5 */
11901 DRXJ_16TO8(31), /* im6 */
11902 DRXJ_16TO8(-48), /* im7 */
11903 DRXJ_16TO8(-95), /* im8 */
11904 DRXJ_16TO8(25), /* im9 */
11905 DRXJ_16TO8(37), /* im10 */
11906 DRXJ_16TO8(-123), /* im11 */
11907 DRXJ_16TO8(-77), /* im12 */
11908 DRXJ_16TO8(94), /* im13 */
11909 DRXJ_16TO8(-10), /* im14 */
11910 DRXJ_16TO8(-149), /* im15 */
11911 DRXJ_16TO8(10), /* im16 */
11912 DRXJ_16TO8(108), /* im17 */
11913 DRXJ_16TO8(-49), /* im18 */
11914 DRXJ_16TO8(-59), /* im19 */
11915 DRXJ_16TO8(90), /* im20 */
11916 DRXJ_16TO8(73), /* im21 */
11917 DRXJ_16TO8(55), /* im22 */
11918 DRXJ_16TO8(148), /* im23 */
11919 DRXJ_16TO8(86), /* im24 */
11920 DRXJ_16TO8(146), /* im25 */
11921 DRXJ_16TO8(687), /* im26 */
11922 DRXJ_16TO8(877) /* im27 */
11924 const u8 dk_i_l_lp_taps_re
[] = {
11925 DRXJ_16TO8(-23), /* re0 */
11926 DRXJ_16TO8(9), /* re1 */
11927 DRXJ_16TO8(16), /* re2 */
11928 DRXJ_16TO8(-26), /* re3 */
11929 DRXJ_16TO8(-3), /* re4 */
11930 DRXJ_16TO8(13), /* re5 */
11931 DRXJ_16TO8(-19), /* re6 */
11932 DRXJ_16TO8(-3), /* re7 */
11933 DRXJ_16TO8(13), /* re8 */
11934 DRXJ_16TO8(-26), /* re9 */
11935 DRXJ_16TO8(-4), /* re10 */
11936 DRXJ_16TO8(28), /* re11 */
11937 DRXJ_16TO8(-15), /* re12 */
11938 DRXJ_16TO8(-14), /* re13 */
11939 DRXJ_16TO8(10), /* re14 */
11940 DRXJ_16TO8(1), /* re15 */
11941 DRXJ_16TO8(39), /* re16 */
11942 DRXJ_16TO8(-18), /* re17 */
11943 DRXJ_16TO8(-90), /* re18 */
11944 DRXJ_16TO8(109), /* re19 */
11945 DRXJ_16TO8(113), /* re20 */
11946 DRXJ_16TO8(-235), /* re21 */
11947 DRXJ_16TO8(-49), /* re22 */
11948 DRXJ_16TO8(359), /* re23 */
11949 DRXJ_16TO8(-79), /* re24 */
11950 DRXJ_16TO8(-459), /* re25 */
11951 DRXJ_16TO8(206), /* re26 */
11952 DRXJ_16TO8(894) /* re27 */
11954 const u8 dk_i_l_lp_taps_im
[] = {
11955 DRXJ_16TO8(-8), /* im0 */
11956 DRXJ_16TO8(-20), /* im1 */
11957 DRXJ_16TO8(17), /* im2 */
11958 DRXJ_16TO8(-14), /* im3 */
11959 DRXJ_16TO8(-52), /* im4 */
11960 DRXJ_16TO8(4), /* im5 */
11961 DRXJ_16TO8(9), /* im6 */
11962 DRXJ_16TO8(-62), /* im7 */
11963 DRXJ_16TO8(-47), /* im8 */
11964 DRXJ_16TO8(0), /* im9 */
11965 DRXJ_16TO8(-20), /* im10 */
11966 DRXJ_16TO8(-48), /* im11 */
11967 DRXJ_16TO8(-65), /* im12 */
11968 DRXJ_16TO8(-23), /* im13 */
11969 DRXJ_16TO8(44), /* im14 */
11970 DRXJ_16TO8(-60), /* im15 */
11971 DRXJ_16TO8(-113), /* im16 */
11972 DRXJ_16TO8(92), /* im17 */
11973 DRXJ_16TO8(81), /* im18 */
11974 DRXJ_16TO8(-125), /* im19 */
11975 DRXJ_16TO8(28), /* im20 */
11976 DRXJ_16TO8(182), /* im21 */
11977 DRXJ_16TO8(35), /* im22 */
11978 DRXJ_16TO8(94), /* im23 */
11979 DRXJ_16TO8(180), /* im24 */
11980 DRXJ_16TO8(134), /* im25 */
11981 DRXJ_16TO8(657), /* im26 */
11982 DRXJ_16TO8(1023) /* im27 */
11984 const u8 fm_taps_re
[] = {
11985 DRXJ_16TO8(0), /* re0 */
11986 DRXJ_16TO8(0), /* re1 */
11987 DRXJ_16TO8(0), /* re2 */
11988 DRXJ_16TO8(0), /* re3 */
11989 DRXJ_16TO8(0), /* re4 */
11990 DRXJ_16TO8(0), /* re5 */
11991 DRXJ_16TO8(0), /* re6 */
11992 DRXJ_16TO8(0), /* re7 */
11993 DRXJ_16TO8(0), /* re8 */
11994 DRXJ_16TO8(0), /* re9 */
11995 DRXJ_16TO8(0), /* re10 */
11996 DRXJ_16TO8(0), /* re11 */
11997 DRXJ_16TO8(0), /* re12 */
11998 DRXJ_16TO8(0), /* re13 */
11999 DRXJ_16TO8(0), /* re14 */
12000 DRXJ_16TO8(0), /* re15 */
12001 DRXJ_16TO8(0), /* re16 */
12002 DRXJ_16TO8(0), /* re17 */
12003 DRXJ_16TO8(0), /* re18 */
12004 DRXJ_16TO8(0), /* re19 */
12005 DRXJ_16TO8(0), /* re20 */
12006 DRXJ_16TO8(0), /* re21 */
12007 DRXJ_16TO8(0), /* re22 */
12008 DRXJ_16TO8(0), /* re23 */
12009 DRXJ_16TO8(0), /* re24 */
12010 DRXJ_16TO8(0), /* re25 */
12011 DRXJ_16TO8(0), /* re26 */
12012 DRXJ_16TO8(0) /* re27 */
12014 const u8 fm_taps_im
[] = {
12015 DRXJ_16TO8(-6), /* im0 */
12016 DRXJ_16TO8(2), /* im1 */
12017 DRXJ_16TO8(14), /* im2 */
12018 DRXJ_16TO8(-38), /* im3 */
12019 DRXJ_16TO8(58), /* im4 */
12020 DRXJ_16TO8(-62), /* im5 */
12021 DRXJ_16TO8(42), /* im6 */
12022 DRXJ_16TO8(0), /* im7 */
12023 DRXJ_16TO8(-45), /* im8 */
12024 DRXJ_16TO8(73), /* im9 */
12025 DRXJ_16TO8(-65), /* im10 */
12026 DRXJ_16TO8(23), /* im11 */
12027 DRXJ_16TO8(34), /* im12 */
12028 DRXJ_16TO8(-77), /* im13 */
12029 DRXJ_16TO8(80), /* im14 */
12030 DRXJ_16TO8(-39), /* im15 */
12031 DRXJ_16TO8(-25), /* im16 */
12032 DRXJ_16TO8(78), /* im17 */
12033 DRXJ_16TO8(-90), /* im18 */
12034 DRXJ_16TO8(52), /* im19 */
12035 DRXJ_16TO8(16), /* im20 */
12036 DRXJ_16TO8(-77), /* im21 */
12037 DRXJ_16TO8(97), /* im22 */
12038 DRXJ_16TO8(-62), /* im23 */
12039 DRXJ_16TO8(-8), /* im24 */
12040 DRXJ_16TO8(75), /* im25 */
12041 DRXJ_16TO8(-100), /* im26 */
12042 DRXJ_16TO8(70) /* im27 */
12045 struct i2c_device_addr
*dev_addr
= NULL
;
12046 struct drxjscu_cmd cmd_scu
= { /* command */ 0,
12047 /* parameter_len */ 0,
12048 /* result_len */ 0,
12049 /* *parameter */ NULL
,
12052 u16 cmd_result
= 0;
12054 struct drxj_data
*ext_attr
= NULL
;
12057 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
12058 dev_addr
= demod
->my_i2c_dev_addr
;
12060 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_COMM_EXEC__A
, ATV_COMM_EXEC_STOP
, 0);
12062 pr_err("error %d\n", rc
);
12065 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FS_COMM_EXEC__A
, IQM_FS_COMM_EXEC_STOP
, 0);
12067 pr_err("error %d\n", rc
);
12070 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_FD_COMM_EXEC__A
, IQM_FD_COMM_EXEC_STOP
, 0);
12072 pr_err("error %d\n", rc
);
12075 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_COMM_EXEC__A
, IQM_RC_COMM_EXEC_STOP
, 0);
12077 pr_err("error %d\n", rc
);
12080 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_COMM_EXEC__A
, IQM_RT_COMM_EXEC_STOP
, 0);
12082 pr_err("error %d\n", rc
);
12085 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_COMM_EXEC__A
, IQM_CF_COMM_EXEC_STOP
, 0);
12087 pr_err("error %d\n", rc
);
12090 /* Reset ATV SCU */
12091 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_ATV
|
12092 SCU_RAM_COMMAND_CMD_DEMOD_RESET
;
12093 cmd_scu
.parameter_len
= 0;
12094 cmd_scu
.result_len
= 1;
12095 cmd_scu
.parameter
= NULL
;
12096 cmd_scu
.result
= &cmd_result
;
12097 rc
= scu_command(dev_addr
, &cmd_scu
);
12099 pr_err("error %d\n", rc
);
12103 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_MOD_CONTROL__A
, ATV_TOP_MOD_CONTROL__PRE
, 0);
12105 pr_err("error %d\n", rc
);
12109 /* TODO remove AUTO/OFF patches after ucode fix. */
12110 switch (*standard
) {
12111 case DRX_STANDARD_NTSC
:
12113 cmd_param
= SCU_RAM_ATV_STANDARD_STANDARD_MN
;
12115 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_LO_INCR__A
, IQM_RT_LO_INCR_MN
, 0);
12117 pr_err("error %d\n", rc
);
12120 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, IQM_CF_MIDTAP_RE__M
, 0);
12122 pr_err("error %d\n", rc
);
12125 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_RE0__A
, sizeof(ntsc_taps_re
), ((u8
*)ntsc_taps_re
), 0);
12127 pr_err("error %d\n", rc
);
12130 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_IM0__A
, sizeof(ntsc_taps_im
), ((u8
*)ntsc_taps_im
), 0);
12132 pr_err("error %d\n", rc
);
12136 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_AMP_TH__A
, ATV_TOP_CR_AMP_TH_MN
, 0);
12138 pr_err("error %d\n", rc
);
12141 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);
12143 pr_err("error %d\n", rc
);
12146 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_OVM_TH__A
, ATV_TOP_CR_OVM_TH_MN
, 0);
12148 pr_err("error %d\n", rc
);
12151 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_STD__A
, (ATV_TOP_STD_MODE_MN
| ATV_TOP_STD_VID_POL_MN
), 0);
12153 pr_err("error %d\n", rc
);
12156 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_VID_AMP__A
, ATV_TOP_VID_AMP_MN
, 0);
12158 pr_err("error %d\n", rc
);
12162 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);
12164 pr_err("error %d\n", rc
);
12167 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_HI__A
, 0x1000, 0);
12169 pr_err("error %d\n", rc
);
12172 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_LO__A
, 0x0000, 0);
12174 pr_err("error %d\n", rc
);
12177 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);
12179 pr_err("error %d\n", rc
);
12182 ext_attr
->phase_correction_bypass
= false;
12183 ext_attr
->enable_cvbs_output
= true;
12185 case DRX_STANDARD_FM
:
12187 cmd_param
= SCU_RAM_ATV_STANDARD_STANDARD_FM
;
12189 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_LO_INCR__A
, 2994, 0);
12191 pr_err("error %d\n", rc
);
12194 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, 0, 0);
12196 pr_err("error %d\n", rc
);
12199 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_RE0__A
, sizeof(fm_taps_re
), ((u8
*)fm_taps_re
), 0);
12201 pr_err("error %d\n", rc
);
12204 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_IM0__A
, sizeof(fm_taps_im
), ((u8
*)fm_taps_im
), 0);
12206 pr_err("error %d\n", rc
);
12209 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_STD__A
, (ATV_TOP_STD_MODE_FM
| ATV_TOP_STD_VID_POL_FM
), 0);
12211 pr_err("error %d\n", rc
);
12214 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_MOD_CONTROL__A
, 0, 0);
12216 pr_err("error %d\n", rc
);
12219 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_CONT__A
, 0, 0);
12221 pr_err("error %d\n", rc
);
12225 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);
12227 pr_err("error %d\n", rc
);
12230 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_ROT_BP__A
, IQM_RT_ROT_BP_ROT_OFF_OFF
, 0);
12232 pr_err("error %d\n", rc
);
12235 ext_attr
->phase_correction_bypass
= true;
12236 ext_attr
->enable_cvbs_output
= false;
12238 case DRX_STANDARD_PAL_SECAM_BG
:
12239 /* PAL/SECAM B/G */
12240 cmd_param
= SCU_RAM_ATV_STANDARD_STANDARD_B
;
12242 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_LO_INCR__A
, 1820, 0);
12244 pr_err("error %d\n", rc
);
12246 } /* TODO check with IS */
12247 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, IQM_CF_MIDTAP_RE__M
, 0);
12249 pr_err("error %d\n", rc
);
12252 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_RE0__A
, sizeof(bg_taps_re
), ((u8
*)bg_taps_re
), 0);
12254 pr_err("error %d\n", rc
);
12257 rc
= DRXJ_DAP
.write_block_func(dev_addr
, IQM_CF_TAP_IM0__A
, sizeof(bg_taps_im
), ((u8
*)bg_taps_im
), 0);
12259 pr_err("error %d\n", rc
);
12262 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_VID_AMP__A
, ATV_TOP_VID_AMP_BG
, 0);
12264 pr_err("error %d\n", rc
);
12267 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_AMP_TH__A
, ATV_TOP_CR_AMP_TH_BG
, 0);
12269 pr_err("error %d\n", rc
);
12272 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);
12274 pr_err("error %d\n", rc
);
12277 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_OVM_TH__A
, ATV_TOP_CR_OVM_TH_BG
, 0);
12279 pr_err("error %d\n", rc
);
12282 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_STD__A
, (ATV_TOP_STD_MODE_BG
| ATV_TOP_STD_VID_POL_BG
), 0);
12284 pr_err("error %d\n", rc
);
12287 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);
12289 pr_err("error %d\n", rc
);
12292 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_HI__A
, 0x1000, 0);
12294 pr_err("error %d\n", rc
);
12297 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_LO__A
, 0x0000, 0);
12299 pr_err("error %d\n", rc
);
12302 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);
12304 pr_err("error %d\n", rc
);
12307 ext_attr
->phase_correction_bypass
= false;
12308 ext_attr
->atv_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
12309 ext_attr
->enable_cvbs_output
= true;
12311 case DRX_STANDARD_PAL_SECAM_DK
:
12312 /* PAL/SECAM D/K */
12313 cmd_param
= SCU_RAM_ATV_STANDARD_STANDARD_DK
;
12315 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_LO_INCR__A
, 2225, 0);
12317 pr_err("error %d\n", rc
);
12319 } /* TODO check with IS */
12320 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, IQM_CF_MIDTAP_RE__M
, 0);
12322 pr_err("error %d\n", rc
);
12325 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);
12327 pr_err("error %d\n", rc
);
12330 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);
12332 pr_err("error %d\n", rc
);
12335 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_AMP_TH__A
, ATV_TOP_CR_AMP_TH_DK
, 0);
12337 pr_err("error %d\n", rc
);
12340 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_VID_AMP__A
, ATV_TOP_VID_AMP_DK
, 0);
12342 pr_err("error %d\n", rc
);
12345 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);
12347 pr_err("error %d\n", rc
);
12350 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_OVM_TH__A
, ATV_TOP_CR_OVM_TH_DK
, 0);
12352 pr_err("error %d\n", rc
);
12355 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_STD__A
, (ATV_TOP_STD_MODE_DK
| ATV_TOP_STD_VID_POL_DK
), 0);
12357 pr_err("error %d\n", rc
);
12360 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);
12362 pr_err("error %d\n", rc
);
12365 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_HI__A
, 0x1000, 0);
12367 pr_err("error %d\n", rc
);
12370 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_LO__A
, 0x0000, 0);
12372 pr_err("error %d\n", rc
);
12375 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);
12377 pr_err("error %d\n", rc
);
12380 ext_attr
->phase_correction_bypass
= false;
12381 ext_attr
->atv_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
12382 ext_attr
->enable_cvbs_output
= true;
12384 case DRX_STANDARD_PAL_SECAM_I
:
12386 cmd_param
= SCU_RAM_ATV_STANDARD_STANDARD_I
;
12388 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_LO_INCR__A
, 2225, 0);
12390 pr_err("error %d\n", rc
);
12392 } /* TODO check with IS */
12393 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, IQM_CF_MIDTAP_RE__M
, 0);
12395 pr_err("error %d\n", rc
);
12398 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);
12400 pr_err("error %d\n", rc
);
12403 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);
12405 pr_err("error %d\n", rc
);
12408 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_AMP_TH__A
, ATV_TOP_CR_AMP_TH_I
, 0);
12410 pr_err("error %d\n", rc
);
12413 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_VID_AMP__A
, ATV_TOP_VID_AMP_I
, 0);
12415 pr_err("error %d\n", rc
);
12418 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);
12420 pr_err("error %d\n", rc
);
12423 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_OVM_TH__A
, ATV_TOP_CR_OVM_TH_I
, 0);
12425 pr_err("error %d\n", rc
);
12428 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_STD__A
, (ATV_TOP_STD_MODE_I
| ATV_TOP_STD_VID_POL_I
), 0);
12430 pr_err("error %d\n", rc
);
12433 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);
12435 pr_err("error %d\n", rc
);
12438 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_HI__A
, 0x1000, 0);
12440 pr_err("error %d\n", rc
);
12443 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_LO__A
, 0x0000, 0);
12445 pr_err("error %d\n", rc
);
12448 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);
12450 pr_err("error %d\n", rc
);
12453 ext_attr
->phase_correction_bypass
= false;
12454 ext_attr
->atv_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
12455 ext_attr
->enable_cvbs_output
= true;
12457 case DRX_STANDARD_PAL_SECAM_L
:
12458 /* PAL/SECAM L with negative modulation */
12459 cmd_param
= SCU_RAM_ATV_STANDARD_STANDARD_L
;
12461 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_LO_INCR__A
, 2225, 0);
12463 pr_err("error %d\n", rc
);
12465 } /* TODO check with IS */
12466 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_VID_AMP__A
, ATV_TOP_VID_AMP_L
, 0);
12468 pr_err("error %d\n", rc
);
12471 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, IQM_CF_MIDTAP_RE__M
, 0);
12473 pr_err("error %d\n", rc
);
12476 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);
12478 pr_err("error %d\n", rc
);
12481 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);
12483 pr_err("error %d\n", rc
);
12486 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_AMP_TH__A
, 0x2, 0);
12488 pr_err("error %d\n", rc
);
12490 } /* TODO check with IS */
12491 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);
12493 pr_err("error %d\n", rc
);
12496 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_OVM_TH__A
, ATV_TOP_CR_OVM_TH_L
, 0);
12498 pr_err("error %d\n", rc
);
12501 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_STD__A
, (ATV_TOP_STD_MODE_L
| ATV_TOP_STD_VID_POL_L
), 0);
12503 pr_err("error %d\n", rc
);
12506 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);
12508 pr_err("error %d\n", rc
);
12511 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_HI__A
, 0x1000, 0);
12513 pr_err("error %d\n", rc
);
12516 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_LO__A
, 0x0000, 0);
12518 pr_err("error %d\n", rc
);
12521 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);
12523 pr_err("error %d\n", rc
);
12526 ext_attr
->phase_correction_bypass
= false;
12527 ext_attr
->atv_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_USER
;
12528 ext_attr
->atv_if_agc_cfg
.output_level
= ext_attr
->atv_rf_agc_cfg
.top
;
12529 ext_attr
->enable_cvbs_output
= true;
12531 case DRX_STANDARD_PAL_SECAM_LP
:
12532 /* PAL/SECAM L with positive modulation */
12533 cmd_param
= SCU_RAM_ATV_STANDARD_STANDARD_LP
;
12535 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_VID_AMP__A
, ATV_TOP_VID_AMP_LP
, 0);
12537 pr_err("error %d\n", rc
);
12540 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_LO_INCR__A
, 2225, 0);
12542 pr_err("error %d\n", rc
);
12544 } /* TODO check with IS */
12545 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_MIDTAP__A
, IQM_CF_MIDTAP_RE__M
, 0);
12547 pr_err("error %d\n", rc
);
12550 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);
12552 pr_err("error %d\n", rc
);
12555 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);
12557 pr_err("error %d\n", rc
);
12560 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_AMP_TH__A
, 0x2, 0);
12562 pr_err("error %d\n", rc
);
12564 } /* TODO check with IS */
12565 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);
12567 pr_err("error %d\n", rc
);
12570 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_OVM_TH__A
, ATV_TOP_CR_OVM_TH_LP
, 0);
12572 pr_err("error %d\n", rc
);
12575 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_STD__A
, (ATV_TOP_STD_MODE_LP
| ATV_TOP_STD_VID_POL_LP
), 0);
12577 pr_err("error %d\n", rc
);
12580 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);
12582 pr_err("error %d\n", rc
);
12585 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_HI__A
, 0x1000, 0);
12587 pr_err("error %d\n", rc
);
12590 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_VID_GAIN_LO__A
, 0x0000, 0);
12592 pr_err("error %d\n", rc
);
12595 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);
12597 pr_err("error %d\n", rc
);
12600 ext_attr
->phase_correction_bypass
= false;
12601 ext_attr
->atv_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_USER
;
12602 ext_attr
->atv_if_agc_cfg
.output_level
= ext_attr
->atv_rf_agc_cfg
.top
;
12603 ext_attr
->enable_cvbs_output
= true;
12609 /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
12610 if (!ext_attr
->has_lna
) {
12611 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_AMUX__A
, 0x01, 0);
12613 pr_err("error %d\n", rc
);
12618 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_STANDARD__A
, 0x002, 0);
12620 pr_err("error %d\n", rc
);
12623 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_CLP_LEN__A
, IQM_AF_CLP_LEN_ATV
, 0);
12625 pr_err("error %d\n", rc
);
12628 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_CLP_TH__A
, IQM_AF_CLP_TH_ATV
, 0);
12630 pr_err("error %d\n", rc
);
12633 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_SNS_LEN__A
, IQM_AF_SNS_LEN_ATV
, 0);
12635 pr_err("error %d\n", rc
);
12638 rc
= ctrl_set_cfg_pre_saw(demod
, &(ext_attr
->atv_pre_saw_cfg
));
12640 pr_err("error %d\n", rc
);
12643 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_AGC_IF__A
, 10248, 0);
12645 pr_err("error %d\n", rc
);
12649 ext_attr
->iqm_rc_rate_ofs
= 0x00200000L
;
12650 rc
= DRXJ_DAP
.write_reg32func(dev_addr
, IQM_RC_RATE_OFS_LO__A
, ext_attr
->iqm_rc_rate_ofs
, 0);
12652 pr_err("error %d\n", rc
);
12655 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_ADJ_SEL__A
, IQM_RC_ADJ_SEL_B_OFF
, 0);
12657 pr_err("error %d\n", rc
);
12660 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RC_STRETCH__A
, IQM_RC_STRETCH_ATV
, 0);
12662 pr_err("error %d\n", rc
);
12666 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);
12668 pr_err("error %d\n", rc
);
12672 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_OUT_ENA__A
, IQM_CF_OUT_ENA_ATV__M
, 0);
12674 pr_err("error %d\n", rc
);
12677 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_CF_SYMMETRIC__A
, IQM_CF_SYMMETRIC_IM__M
, 0);
12679 pr_err("error %d\n", rc
);
12682 /* default: SIF in standby */
12683 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_SYNC_SLICE__A
, ATV_TOP_SYNC_SLICE_MN
, 0);
12685 pr_err("error %d\n", rc
);
12688 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_MOD_ACCU__A
, ATV_TOP_MOD_ACCU__PRE
, 0);
12690 pr_err("error %d\n", rc
);
12694 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_SIF_GAIN__A
, 0x080, 0);
12696 pr_err("error %d\n", rc
);
12699 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_FAGC_TH_RED__A
, 10, 0);
12701 pr_err("error %d\n", rc
);
12704 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_AAGC_CNT__A
, 7, 0);
12706 pr_err("error %d\n", rc
);
12709 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_NAGC_KI_MIN__A
, 0x0225, 0);
12711 pr_err("error %d\n", rc
);
12714 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_NAGC_KI_MAX__A
, 0x0547, 0);
12716 pr_err("error %d\n", rc
);
12719 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_KI_CHANGE_TH__A
, 20, 0);
12721 pr_err("error %d\n", rc
);
12724 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_LOCK__A
, 0, 0);
12726 pr_err("error %d\n", rc
);
12730 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_RT_DELAY__A
, IQM_RT_DELAY__PRE
, 0);
12732 pr_err("error %d\n", rc
);
12735 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_BPC_KI_MIN__A
, 531, 0);
12737 pr_err("error %d\n", rc
);
12740 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_PAGC_KI_MIN__A
, 1061, 0);
12742 pr_err("error %d\n", rc
);
12745 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_BP_REF_MIN__A
, 100, 0);
12747 pr_err("error %d\n", rc
);
12750 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_BP_REF_MAX__A
, 260, 0);
12752 pr_err("error %d\n", rc
);
12755 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_BP_LVL__A
, 0, 0);
12757 pr_err("error %d\n", rc
);
12760 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_AMS_MAX__A
, 0, 0);
12762 pr_err("error %d\n", rc
);
12765 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_AMS_MIN__A
, 2047, 0);
12767 pr_err("error %d\n", rc
);
12770 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_GPIO__A
, 0, 0);
12772 pr_err("error %d\n", rc
);
12776 /* Override reset values with current shadow settings */
12777 rc
= atv_update_config(demod
, true);
12779 pr_err("error %d\n", rc
);
12783 /* Configure/restore AGC settings */
12784 rc
= init_agc(demod
);
12786 pr_err("error %d\n", rc
);
12789 rc
= set_agc_if(demod
, &(ext_attr
->atv_if_agc_cfg
), false);
12791 pr_err("error %d\n", rc
);
12794 rc
= set_agc_rf(demod
, &(ext_attr
->atv_rf_agc_cfg
), false);
12796 pr_err("error %d\n", rc
);
12799 rc
= ctrl_set_cfg_pre_saw(demod
, &(ext_attr
->atv_pre_saw_cfg
));
12801 pr_err("error %d\n", rc
);
12805 /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
12806 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_ATV
|
12807 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV
;
12808 cmd_scu
.parameter_len
= 1;
12809 cmd_scu
.result_len
= 1;
12810 cmd_scu
.parameter
= &cmd_param
;
12811 cmd_scu
.result
= &cmd_result
;
12812 rc
= scu_command(dev_addr
, &cmd_scu
);
12814 pr_err("error %d\n", rc
);
12818 /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
12819 if (ext_attr
->mfx
== 0x03) {
12820 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_ENABLE_IIR_WA__A
, 0, 0);
12822 pr_err("error %d\n", rc
);
12826 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_ENABLE_IIR_WA__A
, 1, 0);
12828 pr_err("error %d\n", rc
);
12831 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ATV_IIR_CRIT__A
, 225, 0);
12833 pr_err("error %d\n", rc
);
12843 /* -------------------------------------------------------------------------- */
12846 * \fn int set_atv_channel ()
12847 * \brief Set ATV channel.
12848 * \param demod: instance of demod.
12851 * Not much needs to be done here, only start the SCU for NTSC/FM.
12852 * Mirrored channels are not expected in the RF domain, so IQM FS setting
12853 * doesn't need to be remembered.
12854 * The channel->mirror parameter is therefor ignored.
12858 set_atv_channel(struct drx_demod_instance
*demod
,
12859 s32 tuner_freq_offset
,
12860 struct drx_channel
*channel
, enum drx_standard standard
)
12862 struct drxjscu_cmd cmd_scu
= { /* command */ 0,
12863 /* parameter_len */ 0,
12864 /* result_len */ 0,
12865 /* parameter */ NULL
,
12868 u16 cmd_result
= 0;
12869 struct drxj_data
*ext_attr
= NULL
;
12870 struct i2c_device_addr
*dev_addr
= NULL
;
12873 dev_addr
= demod
->my_i2c_dev_addr
;
12874 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
12877 Program frequency shifter
12878 No need to account for mirroring on RF
12880 if (channel
->mirror
== DRX_MIRROR_AUTO
)
12881 ext_attr
->mirror
= DRX_MIRROR_NO
;
12883 ext_attr
->mirror
= channel
->mirror
;
12885 rc
= set_frequency(demod
, channel
, tuner_freq_offset
);
12887 pr_err("error %d\n", rc
);
12890 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ATV_TOP_CR_FREQ__A
, ATV_TOP_CR_FREQ__PRE
, 0);
12892 pr_err("error %d\n", rc
);
12896 /* Start ATV SCU */
12897 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_ATV
|
12898 SCU_RAM_COMMAND_CMD_DEMOD_START
;
12899 cmd_scu
.parameter_len
= 0;
12900 cmd_scu
.result_len
= 1;
12901 cmd_scu
.parameter
= NULL
;
12902 cmd_scu
.result
= &cmd_result
;
12903 rc
= scu_command(dev_addr
, &cmd_scu
);
12905 pr_err("error %d\n", rc
);
12909 /* if ( (ext_attr->standard == DRX_STANDARD_FM) && (ext_attr->flagSetAUDdone == true) )
12911 ext_attr->detectedRDS = (bool)false;
12919 /* -------------------------------------------------------------------------- */
12922 * \fn int get_atv_channel ()
12923 * \brief Set ATV channel.
12924 * \param demod: instance of demod.
12925 * \param channel: pointer to channel data.
12926 * \param standard: NTSC or FM.
12929 * Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
12930 * Computes the frequency offset in te RF domain and adds it to
12931 * channel->frequency. Determines the value for channel->bandwidth.
12935 get_atv_channel(struct drx_demod_instance
*demod
,
12936 struct drx_channel
*channel
, enum drx_standard standard
)
12939 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
12943 channel
->bandwidth
= ((struct drxj_data
*) demod
->my_ext_attr
)->curr_bandwidth
;
12945 switch (standard
) {
12946 case DRX_STANDARD_NTSC
:
12947 case DRX_STANDARD_PAL_SECAM_BG
:
12948 case DRX_STANDARD_PAL_SECAM_DK
:
12949 case DRX_STANDARD_PAL_SECAM_I
:
12950 case DRX_STANDARD_PAL_SECAM_L
:
12952 u16 measured_offset
= 0;
12954 /* get measured frequency offset */
12955 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ATV_TOP_CR_FREQ__A
, &measured_offset
, 0);
12957 pr_err("error %d\n", rc
);
12960 /* Signed 8 bit register => sign extension needed */
12961 if ((measured_offset
& 0x0080) != 0)
12962 measured_offset
|= 0xFF80;
12964 (s32
) (((s16
) measured_offset
) * 10);
12967 case DRX_STANDARD_PAL_SECAM_LP
:
12969 u16 measured_offset
= 0;
12971 /* get measured frequency offset */
12972 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ATV_TOP_CR_FREQ__A
, &measured_offset
, 0);
12974 pr_err("error %d\n", rc
);
12977 /* Signed 8 bit register => sign extension needed */
12978 if ((measured_offset
& 0x0080) != 0)
12979 measured_offset
|= 0xFF80;
12981 (s32
) (((s16
) measured_offset
) * 10);
12984 case DRX_STANDARD_FM
:
12985 /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
12986 AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
12988 /* No bandwidth know for FM */
12989 channel
->bandwidth
= DRX_BANDWIDTH_UNKNOWN
;
12995 channel
->frequency
-= offset
;
13002 /* -------------------------------------------------------------------------- */
13004 * \fn int get_atv_sig_strength()
13005 * \brief Retrieve signal strength for ATV & FM.
13006 * \param devmod Pointer to demodulator instance.
13007 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
13009 * \retval 0 sig_strength contains valid data.
13010 * \retval -EIO Erroneous data, sig_strength equals 0.
13012 * Taking into account:
13014 * * IF gain (not implemented yet, waiting for IF gain control by ucode)
13017 * All weights (digital, if, rf) must add up to 100.
13019 * TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
13023 get_atv_sig_strength(struct drx_demod_instance
*demod
, u16
*sig_strength
)
13025 struct i2c_device_addr
*dev_addr
= NULL
;
13026 struct drxj_data
*ext_attr
= NULL
;
13029 /* All weights must add up to 100 (%)
13030 TODO: change weights when IF ctrl is available */
13031 u32 digital_weight
= 50; /* 0 .. 100 */
13032 u32 rf_weight
= 50; /* 0 .. 100 */
13033 u32 if_weight
= 0; /* 0 .. 100 */
13035 u16 digital_curr_gain
= 0;
13036 u32 digital_max_gain
= 0;
13037 u32 digital_min_gain
= 0;
13038 u16 rf_curr_gain
= 0;
13039 u32 rf_max_gain
= 0x800; /* taken from ucode */
13040 u32 rf_min_gain
= 0x7fff;
13041 u16 if_curr_gain
= 0;
13042 u32 if_max_gain
= 0x800; /* taken from ucode */
13043 u32 if_min_gain
= 0x7fff;
13045 u32 digital_strength
= 0; /* 0.. 100 */
13046 u32 rf_strength
= 0; /* 0.. 100 */
13047 u32 if_strength
= 0; /* 0.. 100 */
13049 dev_addr
= demod
->my_i2c_dev_addr
;
13050 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13054 switch (ext_attr
->standard
) {
13055 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
13056 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
13057 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
13058 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
13059 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
13060 case DRX_STANDARD_NTSC
:
13061 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ATV_VID_GAIN_HI__A
, &digital_curr_gain
, 0);
13063 pr_err("error %d\n", rc
);
13066 digital_max_gain
= 22512; /* taken from ucode */
13067 digital_min_gain
= 2400; /* taken from ucode */
13069 case DRX_STANDARD_FM
:
13070 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ATV_SIF_GAIN__A
, &digital_curr_gain
, 0);
13072 pr_err("error %d\n", rc
);
13075 digital_max_gain
= 0x4ff; /* taken from ucode */
13076 digital_min_gain
= 0; /* taken from ucode */
13082 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_AGC_RF__A
, &rf_curr_gain
, 0);
13084 pr_err("error %d\n", rc
);
13087 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_AF_AGC_IF__A
, &if_curr_gain
, 0);
13089 pr_err("error %d\n", rc
);
13094 if (digital_curr_gain
>= digital_max_gain
)
13095 digital_curr_gain
= (u16
)digital_max_gain
;
13096 if (digital_curr_gain
<= digital_min_gain
)
13097 digital_curr_gain
= (u16
)digital_min_gain
;
13098 if (if_curr_gain
<= if_max_gain
)
13099 if_curr_gain
= (u16
)if_max_gain
;
13100 if (if_curr_gain
>= if_min_gain
)
13101 if_curr_gain
= (u16
)if_min_gain
;
13102 if (rf_curr_gain
<= rf_max_gain
)
13103 rf_curr_gain
= (u16
)rf_max_gain
;
13104 if (rf_curr_gain
>= rf_min_gain
)
13105 rf_curr_gain
= (u16
)rf_min_gain
;
13107 /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
13108 of clipping at ADC */
13110 /* Compute signal strength (in %) per "gain domain" */
13113 /* TODO: ADC clipping not handled */
13114 digital_strength
= (100 * (digital_max_gain
- (u32
) digital_curr_gain
)) /
13115 (digital_max_gain
- digital_min_gain
);
13117 /* TODO: IF gain not implemented yet in microcode, check after impl. */
13118 if_strength
= (100 * ((u32
) if_curr_gain
- if_max_gain
)) /
13119 (if_min_gain
- if_max_gain
);
13122 /* TODO: ADC clipping not handled */
13123 rf_strength
= (100 * ((u32
) rf_curr_gain
- rf_max_gain
)) /
13124 (rf_min_gain
- rf_max_gain
);
13126 /* Compute a weighted signal strength (in %) */
13127 *sig_strength
= (u16
) (digital_weight
* digital_strength
+
13128 rf_weight
* rf_strength
+ if_weight
* if_strength
);
13129 *sig_strength
/= 100;
13136 /* -------------------------------------------------------------------------- */
13138 * \fn int atv_sig_quality()
13139 * \brief Retrieve signal quality indication for ATV.
13140 * \param devmod Pointer to demodulator instance.
13141 * \param sig_quality Pointer to signal quality structure.
13143 * \retval 0 sig_quality contains valid data.
13144 * \retval -EIO Erroneous data, sig_quality indicator equals 0.
13149 atv_sig_quality(struct drx_demod_instance
*demod
, struct drx_sig_quality
*sig_quality
)
13151 struct i2c_device_addr
*dev_addr
= NULL
;
13152 u16 quality_indicator
= 0;
13155 dev_addr
= demod
->my_i2c_dev_addr
;
13157 /* defined values for fields not used */
13158 sig_quality
->MER
= 0;
13159 sig_quality
->pre_viterbi_ber
= 0;
13160 sig_quality
->post_viterbi_ber
= 0;
13161 sig_quality
->scale_factor_ber
= 1;
13162 sig_quality
->packet_error
= 0;
13163 sig_quality
->post_reed_solomon_ber
= 0;
13167 0x000..0x080: strong signal => 80% .. 100%
13168 0x080..0x700: weak signal => 30% .. 80%
13169 0x700..0x7ff: no signal => 0% .. 30%
13172 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ATV_CR_LOCK__A
, &quality_indicator
, 0);
13174 pr_err("error %d\n", rc
);
13177 quality_indicator
&= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M
;
13178 if (quality_indicator
<= 0x80) {
13179 sig_quality
->indicator
=
13180 80 + ((20 * (0x80 - quality_indicator
)) / 0x80);
13181 } else if (quality_indicator
<= 0x700)
13182 sig_quality
->indicator
= 30 + ((50 * (0x700 - quality_indicator
)) / (0x700 - 0x81));
13184 sig_quality
->indicator
= (30 * (0x7FF - quality_indicator
)) / (0x7FF - 0x701);
13191 /*============================================================================*/
13192 /*== END ATV DATAPATH FUNCTIONS ==*/
13193 /*============================================================================*/
13195 /*===========================================================================*/
13196 /*===========================================================================*/
13197 /*== AUDIO DATAPATH FUNCTIONS ==*/
13198 /*===========================================================================*/
13199 /*===========================================================================*/
13202 * \brief Power up AUD.
13203 * \param demod instance of demodulator
13207 static int power_up_aud(struct drx_demod_instance
*demod
, bool set_standard
)
13209 enum drx_aud_standard aud_standard
= DRX_AUD_STANDARD_AUTO
;
13210 struct i2c_device_addr
*dev_addr
= NULL
;
13213 dev_addr
= demod
->my_i2c_dev_addr
;
13215 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_TOP_COMM_EXEC__A
, AUD_TOP_COMM_EXEC_ACTIVE
, 0);
13217 pr_err("error %d\n", rc
);
13220 /* setup TR interface: R/W mode, fifosize=8 */
13221 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_TOP_TR_MDE__A
, 8, 0);
13223 pr_err("error %d\n", rc
);
13226 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_COMM_EXEC__A
, AUD_COMM_EXEC_ACTIVE
, 0);
13228 pr_err("error %d\n", rc
);
13232 if (set_standard
) {
13233 rc
= aud_ctrl_set_standard(demod
, &aud_standard
);
13235 pr_err("error %d\n", rc
);
13246 /*============================================================================*/
13249 * \brief Power up AUD.
13250 * \param demod instance of demodulator
13254 static int power_down_aud(struct drx_demod_instance
*demod
)
13256 struct i2c_device_addr
*dev_addr
= NULL
;
13257 struct drxj_data
*ext_attr
= NULL
;
13260 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13261 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13263 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_COMM_EXEC__A
, AUD_COMM_EXEC_STOP
, 0);
13265 pr_err("error %d\n", rc
);
13269 ext_attr
->aud_data
.audio_is_active
= false;
13277 /*============================================================================*/
13279 * \brief Get Modus data from audio RAM
13280 * \param demod instance of demodulator
13281 * \param pointer to modus
13285 static int aud_get_modus(struct drx_demod_instance
*demod
, u16
*modus
)
13287 struct i2c_device_addr
*dev_addr
= NULL
;
13288 struct drxj_data
*ext_attr
= NULL
;
13292 u16 r_modus_hi
= 0;
13293 u16 r_modus_lo
= 0;
13298 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13299 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13302 if (ext_attr
->aud_data
.audio_is_active
== false) {
13303 rc
= power_up_aud(demod
, true);
13305 pr_err("error %d\n", rc
);
13308 ext_attr
->aud_data
.audio_is_active
= true;
13311 /* Modus register is combined in to RAM location */
13312 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_MODUS_HI__A
, &r_modus_hi
, 0);
13314 pr_err("error %d\n", rc
);
13317 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_MODUS_LO__A
, &r_modus_lo
, 0);
13319 pr_err("error %d\n", rc
);
13323 r_modus
= ((r_modus_hi
<< 12) & AUD_DEM_RAM_MODUS_HI__M
)
13324 | (((r_modus_lo
& AUD_DEM_RAM_MODUS_LO__M
)));
13334 /*============================================================================*/
13336 * \brief Get audio RDS dat
13337 * \param demod instance of demodulator
13338 * \param pointer to struct drx_cfg_aud_rds * \return int.
13342 aud_ctrl_get_cfg_rds(struct drx_demod_instance
*demod
, struct drx_cfg_aud_rds
*status
)
13344 struct i2c_device_addr
*addr
= NULL
;
13345 struct drxj_data
*ext_attr
= NULL
;
13348 u16 r_rds_array_cnt_init
= 0;
13349 u16 r_rds_array_cnt_check
= 0;
13350 u16 r_rds_data
= 0;
13351 u16 rds_data_cnt
= 0;
13353 addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13354 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13356 if (status
== NULL
)
13360 if (ext_attr
->aud_data
.audio_is_active
== false) {
13361 rc
= power_up_aud(demod
, true);
13363 pr_err("error %d\n", rc
);
13366 ext_attr
->aud_data
.audio_is_active
= true;
13369 status
->valid
= false;
13371 rc
= DRXJ_DAP
.read_reg16func(addr
, AUD_DEM_RD_RDS_ARRAY_CNT__A
, &r_rds_array_cnt_init
, 0);
13373 pr_err("error %d\n", rc
);
13377 if (r_rds_array_cnt_init
==
13378 AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID
) {
13383 if (ext_attr
->aud_data
.rds_data_counter
== r_rds_array_cnt_init
) {
13388 /* RDS is detected, as long as FM radio is selected assume
13389 RDS will be available */
13390 ext_attr
->aud_data
.rds_data_present
= true;
13393 /* read the data */
13394 for (rds_data_cnt
= 0; rds_data_cnt
< AUD_RDS_ARRAY_SIZE
; rds_data_cnt
++) {
13395 rc
= DRXJ_DAP
.read_reg16func(addr
, AUD_DEM_RD_RDS_DATA__A
, &r_rds_data
, 0);
13397 pr_err("error %d\n", rc
);
13400 status
->data
[rds_data_cnt
] = r_rds_data
;
13403 rc
= DRXJ_DAP
.read_reg16func(addr
, AUD_DEM_RD_RDS_ARRAY_CNT__A
, &r_rds_array_cnt_check
, 0);
13405 pr_err("error %d\n", rc
);
13409 if (r_rds_array_cnt_check
== r_rds_array_cnt_init
) {
13410 status
->valid
= true;
13411 ext_attr
->aud_data
.rds_data_counter
= r_rds_array_cnt_check
;
13419 /*============================================================================*/
13421 * \brief Get the current audio carrier detection status
13422 * \param demod instance of demodulator
13423 * \param pointer to aud_ctrl_get_status
13428 aud_ctrl_get_carrier_detect_status(struct drx_demod_instance
*demod
, struct drx_aud_status
*status
)
13430 struct drxj_data
*ext_attr
= NULL
;
13431 struct i2c_device_addr
*dev_addr
= NULL
;
13435 if (status
== NULL
)
13438 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13439 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13442 if (ext_attr
->aud_data
.audio_is_active
== false) {
13443 rc
= power_up_aud(demod
, true);
13445 pr_err("error %d\n", rc
);
13448 ext_attr
->aud_data
.audio_is_active
= true;
13451 /* initialize the variables */
13452 status
->carrier_a
= false;
13453 status
->carrier_b
= false;
13454 status
->nicam_status
= DRX_AUD_NICAM_NOT_DETECTED
;
13455 status
->sap
= false;
13456 status
->stereo
= false;
13458 /* read stereo sound mode indication */
13459 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RD_STATUS__A
, &r_data
, 0);
13461 pr_err("error %d\n", rc
);
13465 /* carrier a detected */
13466 if ((r_data
& AUD_DEM_RD_STATUS_STAT_CARR_A__M
) == AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED
)
13467 status
->carrier_a
= true;
13469 /* carrier b detected */
13470 if ((r_data
& AUD_DEM_RD_STATUS_STAT_CARR_B__M
) == AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED
)
13471 status
->carrier_b
= true;
13472 /* nicam detected */
13473 if ((r_data
& AUD_DEM_RD_STATUS_STAT_NICAM__M
) ==
13474 AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED
) {
13475 if ((r_data
& AUD_DEM_RD_STATUS_BAD_NICAM__M
) == AUD_DEM_RD_STATUS_BAD_NICAM_OK
)
13476 status
->nicam_status
= DRX_AUD_NICAM_DETECTED
;
13478 status
->nicam_status
= DRX_AUD_NICAM_BAD
;
13481 /* audio mode bilingual or SAP detected */
13482 if ((r_data
& AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M
) == AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP
)
13483 status
->sap
= true;
13485 /* stereo detected */
13486 if ((r_data
& AUD_DEM_RD_STATUS_STAT_STEREO__M
) == AUD_DEM_RD_STATUS_STAT_STEREO_STEREO
)
13487 status
->stereo
= true;
13494 /*============================================================================*/
13496 * \brief Get the current audio status parameters
13497 * \param demod instance of demodulator
13498 * \param pointer to aud_ctrl_get_status
13503 aud_ctrl_get_status(struct drx_demod_instance
*demod
, struct drx_aud_status
*status
)
13505 struct drxj_data
*ext_attr
= NULL
;
13506 struct i2c_device_addr
*dev_addr
= NULL
;
13507 struct drx_cfg_aud_rds rds
= { false, {0} };
13511 if (status
== NULL
)
13514 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13515 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13517 /* carrier detection */
13518 rc
= aud_ctrl_get_carrier_detect_status(demod
, status
);
13520 pr_err("error %d\n", rc
);
13525 status
->rds
= false;
13526 rc
= aud_ctrl_get_cfg_rds(demod
, &rds
);
13528 pr_err("error %d\n", rc
);
13531 status
->rds
= ext_attr
->aud_data
.rds_data_present
;
13534 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_RD_FM_IDENT_VALUE__A
, &r_data
, 0);
13536 pr_err("error %d\n", rc
);
13539 r_data
>>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B
;
13540 status
->fm_ident
= (s8
) r_data
;
13547 /*============================================================================*/
13549 * \brief Get the current volume settings
13550 * \param demod instance of demodulator
13551 * \param pointer to struct drx_cfg_aud_volume * \return int.
13555 aud_ctrl_get_cfg_volume(struct drx_demod_instance
*demod
, struct drx_cfg_aud_volume
*volume
)
13557 struct i2c_device_addr
*dev_addr
= NULL
;
13558 struct drxj_data
*ext_attr
= NULL
;
13563 u16 r_strength_left
= 0;
13564 u16 r_strength_right
= 0;
13566 if (volume
== NULL
)
13569 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13570 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13573 if (ext_attr
->aud_data
.audio_is_active
== false) {
13574 rc
= power_up_aud(demod
, true);
13576 pr_err("error %d\n", rc
);
13579 ext_attr
->aud_data
.audio_is_active
= true;
13583 volume
->mute
= ext_attr
->aud_data
.volume
.mute
;
13584 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_VOLUME__A
, &r_volume
, 0);
13586 pr_err("error %d\n", rc
);
13589 if (r_volume
== 0) {
13590 volume
->mute
= true;
13591 volume
->volume
= ext_attr
->aud_data
.volume
.volume
;
13593 volume
->mute
= false;
13594 volume
->volume
= ((r_volume
& AUD_DSP_WR_VOLUME_VOL_MAIN__M
) >>
13595 AUD_DSP_WR_VOLUME_VOL_MAIN__B
) -
13596 AUD_VOLUME_ZERO_DB
;
13597 if (volume
->volume
< AUD_VOLUME_DB_MIN
)
13598 volume
->volume
= AUD_VOLUME_DB_MIN
;
13599 if (volume
->volume
> AUD_VOLUME_DB_MAX
)
13600 volume
->volume
= AUD_VOLUME_DB_MAX
;
13603 /* automatic volume control */
13604 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_AVC__A
, &r_avc
, 0);
13606 pr_err("error %d\n", rc
);
13610 if ((r_avc
& AUD_DSP_WR_AVC_AVC_ON__M
) == AUD_DSP_WR_AVC_AVC_ON_OFF
) {
13611 volume
->avc_mode
= DRX_AUD_AVC_OFF
;
13613 switch (r_avc
& AUD_DSP_WR_AVC_AVC_DECAY__M
) {
13614 case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC
:
13615 volume
->avc_mode
= DRX_AUD_AVC_DECAYTIME_20MS
;
13617 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC
:
13618 volume
->avc_mode
= DRX_AUD_AVC_DECAYTIME_8S
;
13620 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC
:
13621 volume
->avc_mode
= DRX_AUD_AVC_DECAYTIME_4S
;
13623 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC
:
13624 volume
->avc_mode
= DRX_AUD_AVC_DECAYTIME_2S
;
13632 /* max attenuation */
13633 switch (r_avc
& AUD_DSP_WR_AVC_AVC_MAX_ATT__M
) {
13634 case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB
:
13635 volume
->avc_max_atten
= DRX_AUD_AVC_MAX_ATTEN_12DB
;
13637 case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB
:
13638 volume
->avc_max_atten
= DRX_AUD_AVC_MAX_ATTEN_18DB
;
13640 case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB
:
13641 volume
->avc_max_atten
= DRX_AUD_AVC_MAX_ATTEN_24DB
;
13649 switch (r_avc
& AUD_DSP_WR_AVC_AVC_MAX_GAIN__M
) {
13650 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB
:
13651 volume
->avc_max_gain
= DRX_AUD_AVC_MAX_GAIN_0DB
;
13653 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB
:
13654 volume
->avc_max_gain
= DRX_AUD_AVC_MAX_GAIN_6DB
;
13656 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB
:
13657 volume
->avc_max_gain
= DRX_AUD_AVC_MAX_GAIN_12DB
;
13664 /* reference level */
13665 volume
->avc_ref_level
= (u16
) ((r_avc
& AUD_DSP_WR_AVC_AVC_REF_LEV__M
) >>
13666 AUD_DSP_WR_AVC_AVC_REF_LEV__B
);
13668 /* read qpeak registers and calculate strength of left and right carrier */
13669 /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
13670 /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
13675 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_RD_QPEAK_L__A
, &r_strength_left
, 0);
13677 pr_err("error %d\n", rc
);
13680 volume
->strength_left
= (((s16
) log1_times100(r_strength_left
)) -
13681 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100
) / 5;
13683 /* right carrier */
13684 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_RD_QPEAK_R__A
, &r_strength_right
, 0);
13686 pr_err("error %d\n", rc
);
13689 volume
->strength_right
= (((s16
) log1_times100(r_strength_right
)) -
13690 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100
) / 5;
13697 /*============================================================================*/
13699 * \brief Set the current volume settings
13700 * \param demod instance of demodulator
13701 * \param pointer to struct drx_cfg_aud_volume * \return int.
13705 aud_ctrl_set_cfg_volume(struct drx_demod_instance
*demod
, struct drx_cfg_aud_volume
*volume
)
13707 struct i2c_device_addr
*dev_addr
= NULL
;
13708 struct drxj_data
*ext_attr
= NULL
;
13714 if (volume
== NULL
)
13717 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13718 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13721 if (ext_attr
->aud_data
.audio_is_active
== false) {
13722 rc
= power_up_aud(demod
, true);
13724 pr_err("error %d\n", rc
);
13727 ext_attr
->aud_data
.audio_is_active
= true;
13731 /* volume range from -60 to 12 (expressed in dB) */
13732 if ((volume
->volume
< AUD_VOLUME_DB_MIN
) ||
13733 (volume
->volume
> AUD_VOLUME_DB_MAX
))
13736 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_VOLUME__A
, &w_volume
, 0);
13738 pr_err("error %d\n", rc
);
13742 /* clear the volume mask */
13743 w_volume
&= (u16
) ~AUD_DSP_WR_VOLUME_VOL_MAIN__M
;
13744 if (volume
->mute
== true)
13745 w_volume
|= (u16
)(0);
13747 w_volume
|= (u16
)((volume
->volume
+ AUD_VOLUME_ZERO_DB
) << AUD_DSP_WR_VOLUME_VOL_MAIN__B
);
13749 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_VOLUME__A
, w_volume
, 0);
13751 pr_err("error %d\n", rc
);
13755 /* automatic volume control */
13756 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_AVC__A
, &w_avc
, 0);
13758 pr_err("error %d\n", rc
);
13762 /* clear masks that require writing */
13763 w_avc
&= (u16
) ~AUD_DSP_WR_AVC_AVC_ON__M
;
13764 w_avc
&= (u16
) ~AUD_DSP_WR_AVC_AVC_DECAY__M
;
13766 if (volume
->avc_mode
== DRX_AUD_AVC_OFF
) {
13767 w_avc
|= (AUD_DSP_WR_AVC_AVC_ON_OFF
);
13770 w_avc
|= (AUD_DSP_WR_AVC_AVC_ON_ON
);
13773 switch (volume
->avc_mode
) {
13774 case DRX_AUD_AVC_DECAYTIME_20MS
:
13775 w_avc
|= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC
;
13777 case DRX_AUD_AVC_DECAYTIME_8S
:
13778 w_avc
|= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC
;
13780 case DRX_AUD_AVC_DECAYTIME_4S
:
13781 w_avc
|= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC
;
13783 case DRX_AUD_AVC_DECAYTIME_2S
:
13784 w_avc
|= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC
;
13791 /* max attenuation */
13792 w_avc
&= (u16
) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M
;
13793 switch (volume
->avc_max_atten
) {
13794 case DRX_AUD_AVC_MAX_ATTEN_12DB
:
13795 w_avc
|= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB
;
13797 case DRX_AUD_AVC_MAX_ATTEN_18DB
:
13798 w_avc
|= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB
;
13800 case DRX_AUD_AVC_MAX_ATTEN_24DB
:
13801 w_avc
|= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB
;
13808 w_avc
&= (u16
) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M
;
13809 switch (volume
->avc_max_gain
) {
13810 case DRX_AUD_AVC_MAX_GAIN_0DB
:
13811 w_avc
|= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB
;
13813 case DRX_AUD_AVC_MAX_GAIN_6DB
:
13814 w_avc
|= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB
;
13816 case DRX_AUD_AVC_MAX_GAIN_12DB
:
13817 w_avc
|= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB
;
13823 /* avc reference level */
13824 if (volume
->avc_ref_level
> AUD_MAX_AVC_REF_LEVEL
)
13827 w_avc
&= (u16
) ~AUD_DSP_WR_AVC_AVC_REF_LEV__M
;
13828 w_avc
|= (u16
) (volume
->avc_ref_level
<< AUD_DSP_WR_AVC_AVC_REF_LEV__B
);
13830 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_AVC__A
, w_avc
, 0);
13832 pr_err("error %d\n", rc
);
13836 /* all done, store config in data structure */
13837 ext_attr
->aud_data
.volume
= *volume
;
13844 /*============================================================================*/
13846 * \brief Get the I2S settings
13847 * \param demod instance of demodulator
13848 * \param pointer to struct drx_cfg_i2s_output * \return int.
13852 aud_ctrl_get_cfg_output_i2s(struct drx_demod_instance
*demod
, struct drx_cfg_i2s_output
*output
)
13854 struct i2c_device_addr
*dev_addr
= NULL
;
13855 struct drxj_data
*ext_attr
= NULL
;
13857 u16 w_i2s_config
= 0;
13858 u16 r_i2s_freq
= 0;
13860 if (output
== NULL
)
13863 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13864 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13867 if (ext_attr
->aud_data
.audio_is_active
== false) {
13868 rc
= power_up_aud(demod
, true);
13870 pr_err("error %d\n", rc
);
13873 ext_attr
->aud_data
.audio_is_active
= true;
13876 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_I2S_CONFIG2__A
, &w_i2s_config
, 0);
13878 pr_err("error %d\n", rc
);
13881 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_I2S_OUT_FS__A
, &r_i2s_freq
, 0);
13883 pr_err("error %d\n", rc
);
13888 switch (w_i2s_config
& AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M
) {
13889 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER
:
13890 output
->mode
= DRX_I2S_MODE_MASTER
;
13892 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE
:
13893 output
->mode
= DRX_I2S_MODE_SLAVE
;
13900 switch (w_i2s_config
& AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M
) {
13901 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY
:
13902 output
->format
= DRX_I2S_FORMAT_WS_ADVANCED
;
13904 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY
:
13905 output
->format
= DRX_I2S_FORMAT_WS_WITH_DATA
;
13911 /* I2S word length */
13912 switch (w_i2s_config
& AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M
) {
13913 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16
:
13914 output
->word_length
= DRX_I2S_WORDLENGTH_16
;
13916 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32
:
13917 output
->word_length
= DRX_I2S_WORDLENGTH_32
;
13924 switch (w_i2s_config
& AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M
) {
13925 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH
:
13926 output
->polarity
= DRX_I2S_POLARITY_LEFT
;
13928 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW
:
13929 output
->polarity
= DRX_I2S_POLARITY_RIGHT
;
13935 /* I2S output enabled */
13936 if ((w_i2s_config
& AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M
) == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE
)
13937 output
->output_enable
= true;
13939 output
->output_enable
= false;
13941 if (r_i2s_freq
> 0) {
13942 output
->frequency
= 6144UL * 48000 / r_i2s_freq
;
13943 if (output
->word_length
== DRX_I2S_WORDLENGTH_16
)
13944 output
->frequency
*= 2;
13946 output
->frequency
= AUD_I2S_FREQUENCY_MAX
;
13954 /*============================================================================*/
13956 * \brief Set the I2S settings
13957 * \param demod instance of demodulator
13958 * \param pointer to struct drx_cfg_i2s_output * \return int.
13962 aud_ctrl_set_cfg_output_i2s(struct drx_demod_instance
*demod
, struct drx_cfg_i2s_output
*output
)
13964 struct i2c_device_addr
*dev_addr
= NULL
;
13965 struct drxj_data
*ext_attr
= NULL
;
13967 u16 w_i2s_config
= 0;
13968 u16 w_i2s_pads_data_da
= 0;
13969 u16 w_i2s_pads_data_cl
= 0;
13970 u16 w_i2s_pads_data_ws
= 0;
13971 u32 w_i2s_freq
= 0;
13973 if (output
== NULL
)
13976 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
13977 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
13980 if (ext_attr
->aud_data
.audio_is_active
== false) {
13981 rc
= power_up_aud(demod
, true);
13983 pr_err("error %d\n", rc
);
13986 ext_attr
->aud_data
.audio_is_active
= true;
13989 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_I2S_CONFIG2__A
, &w_i2s_config
, 0);
13991 pr_err("error %d\n", rc
);
13996 w_i2s_config
&= (u16
) ~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M
;
13998 switch (output
->mode
) {
13999 case DRX_I2S_MODE_MASTER
:
14000 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER
;
14002 case DRX_I2S_MODE_SLAVE
:
14003 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE
;
14010 w_i2s_config
&= (u16
) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M
;
14012 switch (output
->format
) {
14013 case DRX_I2S_FORMAT_WS_ADVANCED
:
14014 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY
;
14016 case DRX_I2S_FORMAT_WS_WITH_DATA
:
14017 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY
;
14023 /* I2S word length */
14024 w_i2s_config
&= (u16
) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M
;
14026 switch (output
->word_length
) {
14027 case DRX_I2S_WORDLENGTH_16
:
14028 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16
;
14030 case DRX_I2S_WORDLENGTH_32
:
14031 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32
;
14038 w_i2s_config
&= (u16
) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M
;
14039 switch (output
->polarity
) {
14040 case DRX_I2S_POLARITY_LEFT
:
14041 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH
;
14043 case DRX_I2S_POLARITY_RIGHT
:
14044 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW
;
14050 /* I2S output enabled */
14051 w_i2s_config
&= (u16
) ~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M
;
14052 if (output
->output_enable
== true)
14053 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE
;
14055 w_i2s_config
|= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE
;
14060 w_i2s_freq = 6144 * 48000 * nrbits / ( 32 * frequency )
14062 16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
14063 32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
14065 if ((output
->frequency
> AUD_I2S_FREQUENCY_MAX
) ||
14066 output
->frequency
< AUD_I2S_FREQUENCY_MIN
) {
14070 w_i2s_freq
= (6144UL * 48000UL) + (output
->frequency
>> 1);
14071 w_i2s_freq
/= output
->frequency
;
14073 if (output
->word_length
== DRX_I2S_WORDLENGTH_16
)
14076 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_I2S_CONFIG2__A
, w_i2s_config
, 0);
14078 pr_err("error %d\n", rc
);
14081 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_I2S_OUT_FS__A
, (u16
)w_i2s_freq
, 0);
14083 pr_err("error %d\n", rc
);
14087 /* configure I2S output pads for master or slave mode */
14088 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY_KEY
, 0);
14090 pr_err("error %d\n", rc
);
14094 if (output
->mode
== DRX_I2S_MODE_MASTER
) {
14095 w_i2s_pads_data_da
= SIO_PDR_I2S_DA_CFG_MODE__MASTER
|
14096 SIO_PDR_I2S_DA_CFG_DRIVE__MASTER
;
14097 w_i2s_pads_data_cl
= SIO_PDR_I2S_CL_CFG_MODE__MASTER
|
14098 SIO_PDR_I2S_CL_CFG_DRIVE__MASTER
;
14099 w_i2s_pads_data_ws
= SIO_PDR_I2S_WS_CFG_MODE__MASTER
|
14100 SIO_PDR_I2S_WS_CFG_DRIVE__MASTER
;
14102 w_i2s_pads_data_da
= SIO_PDR_I2S_DA_CFG_MODE__SLAVE
|
14103 SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE
;
14104 w_i2s_pads_data_cl
= SIO_PDR_I2S_CL_CFG_MODE__SLAVE
|
14105 SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE
;
14106 w_i2s_pads_data_ws
= SIO_PDR_I2S_WS_CFG_MODE__SLAVE
|
14107 SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE
;
14110 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2S_DA_CFG__A
, w_i2s_pads_data_da
, 0);
14112 pr_err("error %d\n", rc
);
14115 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2S_CL_CFG__A
, w_i2s_pads_data_cl
, 0);
14117 pr_err("error %d\n", rc
);
14120 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_PDR_I2S_WS_CFG__A
, w_i2s_pads_data_ws
, 0);
14122 pr_err("error %d\n", rc
);
14126 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, SIO_TOP_COMM_KEY__PRE
, 0);
14128 pr_err("error %d\n", rc
);
14132 /* all done, store config in data structure */
14133 ext_attr
->aud_data
.i2sdata
= *output
;
14140 /*============================================================================*/
14142 * \brief Get the Automatic Standard Select (ASS)
14143 * and Automatic Sound Change (ASC)
14144 * \param demod instance of demodulator
14145 * \param pointer to pDRXAudAutoSound_t
14150 aud_ctrl_get_cfg_auto_sound(struct drx_demod_instance
*demod
,
14151 enum drx_cfg_aud_auto_sound
*auto_sound
)
14153 struct drxj_data
*ext_attr
= NULL
;
14157 if (auto_sound
== NULL
)
14160 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14163 if (ext_attr
->aud_data
.audio_is_active
== false) {
14164 rc
= power_up_aud(demod
, true);
14166 pr_err("error %d\n", rc
);
14169 ext_attr
->aud_data
.audio_is_active
= true;
14172 rc
= aud_get_modus(demod
, &r_modus
);
14174 pr_err("error %d\n", rc
);
14178 switch (r_modus
& (AUD_DEM_WR_MODUS_MOD_ASS__M
|
14179 AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M
)) {
14180 case AUD_DEM_WR_MODUS_MOD_ASS_OFF
| AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED
:
14181 case AUD_DEM_WR_MODUS_MOD_ASS_OFF
| AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED
:
14183 DRX_AUD_AUTO_SOUND_OFF
;
14185 case AUD_DEM_WR_MODUS_MOD_ASS_ON
| AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED
:
14187 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON
;
14189 case AUD_DEM_WR_MODUS_MOD_ASS_ON
| AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED
:
14191 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF
;
14202 /*============================================================================*/
14204 * \brief Set the Automatic Standard Select (ASS)
14205 * and Automatic Sound Change (ASC)
14206 * \param demod instance of demodulator
14207 * \param pointer to pDRXAudAutoSound_t
14212 aud_ctr_setl_cfg_auto_sound(struct drx_demod_instance
*demod
,
14213 enum drx_cfg_aud_auto_sound
*auto_sound
)
14215 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14216 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14221 if (auto_sound
== NULL
)
14224 dev_addr
= demod
->my_i2c_dev_addr
;
14225 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14228 if (ext_attr
->aud_data
.audio_is_active
== false) {
14229 rc
= power_up_aud(demod
, true);
14231 pr_err("error %d\n", rc
);
14234 ext_attr
->aud_data
.audio_is_active
= true;
14237 rc
= aud_get_modus(demod
, &r_modus
);
14239 pr_err("error %d\n", rc
);
14244 /* clear ASS & ASC bits */
14245 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_ASS__M
;
14246 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M
;
14248 switch (*auto_sound
) {
14249 case DRX_AUD_AUTO_SOUND_OFF
:
14250 w_modus
|= AUD_DEM_WR_MODUS_MOD_ASS_OFF
;
14251 w_modus
|= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED
;
14253 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON
:
14254 w_modus
|= AUD_DEM_WR_MODUS_MOD_ASS_ON
;
14255 w_modus
|= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED
;
14257 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF
:
14258 w_modus
|= AUD_DEM_WR_MODUS_MOD_ASS_ON
;
14259 w_modus
|= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED
;
14265 if (w_modus
!= r_modus
) {
14266 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_MODUS__A
, w_modus
, 0);
14268 pr_err("error %d\n", rc
);
14272 /* copy to data structure */
14273 ext_attr
->aud_data
.auto_sound
= *auto_sound
;
14280 /*============================================================================*/
14282 * \brief Get the Automatic Standard Select thresholds
14283 * \param demod instance of demodulator
14284 * \param pointer to pDRXAudASSThres_t
14289 aud_ctrl_get_cfg_ass_thres(struct drx_demod_instance
*demod
, struct drx_cfg_aud_ass_thres
*thres
)
14291 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14292 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14295 u16 thres_btsc
= 0;
14296 u16 thres_nicam
= 0;
14301 dev_addr
= demod
->my_i2c_dev_addr
;
14302 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14305 if (ext_attr
->aud_data
.audio_is_active
== false) {
14306 rc
= power_up_aud(demod
, true);
14308 pr_err("error %d\n", rc
);
14311 ext_attr
->aud_data
.audio_is_active
= true;
14314 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_A2_THRSHLD__A
, &thres_a2
, 0);
14316 pr_err("error %d\n", rc
);
14319 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_BTSC_THRSHLD__A
, &thres_btsc
, 0);
14321 pr_err("error %d\n", rc
);
14324 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_NICAM_THRSHLD__A
, &thres_nicam
, 0);
14326 pr_err("error %d\n", rc
);
14330 thres
->a2
= thres_a2
;
14331 thres
->btsc
= thres_btsc
;
14332 thres
->nicam
= thres_nicam
;
14339 /*============================================================================*/
14341 * \brief Get the Automatic Standard Select thresholds
14342 * \param demod instance of demodulator
14343 * \param pointer to pDRXAudASSThres_t
14348 aud_ctrl_set_cfg_ass_thres(struct drx_demod_instance
*demod
, struct drx_cfg_aud_ass_thres
*thres
)
14350 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14351 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14356 dev_addr
= demod
->my_i2c_dev_addr
;
14357 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14360 if (ext_attr
->aud_data
.audio_is_active
== false) {
14361 rc
= power_up_aud(demod
, true);
14363 pr_err("error %d\n", rc
);
14366 ext_attr
->aud_data
.audio_is_active
= true;
14369 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_A2_THRSHLD__A
, thres
->a2
, 0);
14371 pr_err("error %d\n", rc
);
14374 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_BTSC_THRSHLD__A
, thres
->btsc
, 0);
14376 pr_err("error %d\n", rc
);
14379 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_NICAM_THRSHLD__A
, thres
->nicam
, 0);
14381 pr_err("error %d\n", rc
);
14385 /* update DRXK data structure with hardware values */
14386 ext_attr
->aud_data
.ass_thresholds
= *thres
;
14393 /*============================================================================*/
14395 * \brief Get Audio Carrier settings
14396 * \param demod instance of demodulator
14397 * \param pointer to struct drx_aud_carrier ** \return int.
14401 aud_ctrl_get_cfg_carrier(struct drx_demod_instance
*demod
, struct drx_cfg_aud_carriers
*carriers
)
14403 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14404 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14422 if (carriers
== NULL
)
14425 dev_addr
= demod
->my_i2c_dev_addr
;
14426 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14429 if (ext_attr
->aud_data
.audio_is_active
== false) {
14430 rc
= power_up_aud(demod
, true);
14432 pr_err("error %d\n", rc
);
14435 ext_attr
->aud_data
.audio_is_active
= true;
14438 rc
= aud_get_modus(demod
, &w_modus
);
14440 pr_err("error %d\n", rc
);
14444 /* Behaviour of primary audio channel */
14445 switch (w_modus
& (AUD_DEM_WR_MODUS_MOD_CM_A__M
)) {
14446 case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE
:
14447 carriers
->a
.opt
= DRX_NO_CARRIER_MUTE
;
14449 case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE
:
14450 carriers
->a
.opt
= DRX_NO_CARRIER_NOISE
;
14457 /* Behaviour of secondary audio channel */
14458 switch (w_modus
& (AUD_DEM_WR_MODUS_MOD_CM_B__M
)) {
14459 case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE
:
14460 carriers
->b
.opt
= DRX_NO_CARRIER_MUTE
;
14462 case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE
:
14463 carriers
->b
.opt
= DRX_NO_CARRIER_NOISE
;
14470 /* frequency adjustment for primary & secondary audio channel */
14471 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_DCO_A_HI__A
, &dco_a_hi
, 0);
14473 pr_err("error %d\n", rc
);
14476 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_DCO_A_LO__A
, &dco_a_lo
, 0);
14478 pr_err("error %d\n", rc
);
14481 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_DCO_B_HI__A
, &dco_b_hi
, 0);
14483 pr_err("error %d\n", rc
);
14486 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_DCO_B_LO__A
, &dco_b_lo
, 0);
14488 pr_err("error %d\n", rc
);
14492 valA
= (((u32
) dco_a_hi
) << 12) | ((u32
) dco_a_lo
& 0xFFF);
14493 valB
= (((u32
) dco_b_hi
) << 12) | ((u32
) dco_b_lo
& 0xFFF);
14495 /* Multiply by 20250 * 1>>24 ~= 2 / 1657 */
14496 carriers
->a
.dco
= DRX_S24TODRXFREQ(valA
) * 2L / 1657L;
14497 carriers
->b
.dco
= DRX_S24TODRXFREQ(valB
) * 2L / 1657L;
14499 /* DC level of the incoming FM signal on the primary
14500 & seconday sound channel */
14501 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_RD_FM_DC_LEVEL_A__A
, &dc_lvl_a
, 0);
14503 pr_err("error %d\n", rc
);
14506 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_RD_FM_DC_LEVEL_B__A
, &dc_lvl_b
, 0);
14508 pr_err("error %d\n", rc
);
14512 /* offset (kHz) = (dcLvl / 322) */
14513 carriers
->a
.shift
= (DRX_U16TODRXFREQ(dc_lvl_a
) / 322L);
14514 carriers
->b
.shift
= (DRX_U16TODRXFREQ(dc_lvl_b
) / 322L);
14516 /* Carrier detetcion threshold for primary & secondary channel */
14517 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_CM_A_THRSHLD__A
, &cm_thes_a
, 0);
14519 pr_err("error %d\n", rc
);
14522 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RAM_CM_B_THRSHLD__A
, &cm_thes_b
, 0);
14524 pr_err("error %d\n", rc
);
14528 carriers
->a
.thres
= cm_thes_a
;
14529 carriers
->b
.thres
= cm_thes_b
;
14536 /*============================================================================*/
14538 * \brief Set Audio Carrier settings
14539 * \param demod instance of demodulator
14540 * \param pointer to struct drx_aud_carrier ** \return int.
14544 aud_ctrl_set_cfg_carrier(struct drx_demod_instance
*demod
, struct drx_cfg_aud_carriers
*carriers
)
14546 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14547 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14558 if (carriers
== NULL
)
14561 dev_addr
= demod
->my_i2c_dev_addr
;
14562 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14565 if (ext_attr
->aud_data
.audio_is_active
== false) {
14566 rc
= power_up_aud(demod
, true);
14568 pr_err("error %d\n", rc
);
14571 ext_attr
->aud_data
.audio_is_active
= true;
14574 rc
= aud_get_modus(demod
, &r_modus
);
14576 pr_err("error %d\n", rc
);
14581 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_CM_A__M
;
14582 /* Behaviour of primary audio channel */
14583 switch (carriers
->a
.opt
) {
14584 case DRX_NO_CARRIER_MUTE
:
14585 w_modus
|= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE
;
14587 case DRX_NO_CARRIER_NOISE
:
14588 w_modus
|= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE
;
14595 /* Behaviour of secondary audio channel */
14596 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_CM_B__M
;
14597 switch (carriers
->b
.opt
) {
14598 case DRX_NO_CARRIER_MUTE
:
14599 w_modus
|= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE
;
14601 case DRX_NO_CARRIER_NOISE
:
14602 w_modus
|= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE
;
14609 /* now update the modus register */
14610 if (w_modus
!= r_modus
) {
14611 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_MODUS__A
, w_modus
, 0);
14613 pr_err("error %d\n", rc
);
14618 /* frequency adjustment for primary & secondary audio channel */
14619 valA
= (s32
) ((carriers
->a
.dco
) * 1657L / 2);
14620 valB
= (s32
) ((carriers
->b
.dco
) * 1657L / 2);
14622 dco_a_hi
= (u16
) ((valA
>> 12) & 0xFFF);
14623 dco_a_lo
= (u16
) (valA
& 0xFFF);
14624 dco_b_hi
= (u16
) ((valB
>> 12) & 0xFFF);
14625 dco_b_lo
= (u16
) (valB
& 0xFFF);
14627 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_DCO_A_HI__A
, dco_a_hi
, 0);
14629 pr_err("error %d\n", rc
);
14632 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_DCO_A_LO__A
, dco_a_lo
, 0);
14634 pr_err("error %d\n", rc
);
14637 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_DCO_B_HI__A
, dco_b_hi
, 0);
14639 pr_err("error %d\n", rc
);
14642 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_DCO_B_LO__A
, dco_b_lo
, 0);
14644 pr_err("error %d\n", rc
);
14648 /* Carrier detetcion threshold for primary & secondary channel */
14649 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_CM_A_THRSHLD__A
, carriers
->a
.thres
, 0);
14651 pr_err("error %d\n", rc
);
14654 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_CM_B_THRSHLD__A
, carriers
->b
.thres
, 0);
14656 pr_err("error %d\n", rc
);
14660 /* update DRXK data structure */
14661 ext_attr
->aud_data
.carriers
= *carriers
;
14668 /*============================================================================*/
14670 * \brief Get I2S Source, I2S matrix and FM matrix
14671 * \param demod instance of demodulator
14672 * \param pointer to pDRXAudmixer_t
14677 aud_ctrl_get_cfg_mixer(struct drx_demod_instance
*demod
, struct drx_cfg_aud_mixer
*mixer
)
14679 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14680 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14682 u16 src_i2s_matr
= 0;
14688 dev_addr
= demod
->my_i2c_dev_addr
;
14689 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14692 if (ext_attr
->aud_data
.audio_is_active
== false) {
14693 rc
= power_up_aud(demod
, true);
14695 pr_err("error %d\n", rc
);
14698 ext_attr
->aud_data
.audio_is_active
= true;
14701 /* Source Selctor */
14702 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_SRC_I2S_MATR__A
, &src_i2s_matr
, 0);
14704 pr_err("error %d\n", rc
);
14708 switch (src_i2s_matr
& AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M
) {
14709 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO
:
14710 mixer
->source_i2s
= DRX_AUD_SRC_MONO
;
14712 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB
:
14713 mixer
->source_i2s
= DRX_AUD_SRC_STEREO_OR_AB
;
14715 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A
:
14716 mixer
->source_i2s
= DRX_AUD_SRC_STEREO_OR_A
;
14718 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B
:
14719 mixer
->source_i2s
= DRX_AUD_SRC_STEREO_OR_B
;
14726 switch (src_i2s_matr
& AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M
) {
14727 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO
:
14728 mixer
->matrix_i2s
= DRX_AUD_I2S_MATRIX_MONO
;
14730 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO
:
14731 mixer
->matrix_i2s
= DRX_AUD_I2S_MATRIX_STEREO
;
14733 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A
:
14734 mixer
->matrix_i2s
= DRX_AUD_I2S_MATRIX_A_MONO
;
14736 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B
:
14737 mixer
->matrix_i2s
= DRX_AUD_I2S_MATRIX_B_MONO
;
14744 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_WR_FM_MATRIX__A
, &fm_matr
, 0);
14746 pr_err("error %d\n", rc
);
14749 switch (fm_matr
& AUD_DEM_WR_FM_MATRIX__M
) {
14750 case AUD_DEM_WR_FM_MATRIX_NO_MATRIX
:
14751 mixer
->matrix_fm
= DRX_AUD_FM_MATRIX_NO_MATRIX
;
14753 case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX
:
14754 mixer
->matrix_fm
= DRX_AUD_FM_MATRIX_GERMAN
;
14756 case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX
:
14757 mixer
->matrix_fm
= DRX_AUD_FM_MATRIX_KOREAN
;
14759 case AUD_DEM_WR_FM_MATRIX_SOUND_A
:
14760 mixer
->matrix_fm
= DRX_AUD_FM_MATRIX_SOUND_A
;
14762 case AUD_DEM_WR_FM_MATRIX_SOUND_B
:
14763 mixer
->matrix_fm
= DRX_AUD_FM_MATRIX_SOUND_B
;
14774 /*============================================================================*/
14776 * \brief Set I2S Source, I2S matrix and FM matrix
14777 * \param demod instance of demodulator
14778 * \param pointer to DRXAudmixer_t
14783 aud_ctrl_set_cfg_mixer(struct drx_demod_instance
*demod
, struct drx_cfg_aud_mixer
*mixer
)
14785 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14786 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14788 u16 src_i2s_matr
= 0;
14794 dev_addr
= demod
->my_i2c_dev_addr
;
14795 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14798 if (ext_attr
->aud_data
.audio_is_active
== false) {
14799 rc
= power_up_aud(demod
, true);
14801 pr_err("error %d\n", rc
);
14804 ext_attr
->aud_data
.audio_is_active
= true;
14807 /* Source Selctor */
14808 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_SRC_I2S_MATR__A
, &src_i2s_matr
, 0);
14810 pr_err("error %d\n", rc
);
14813 src_i2s_matr
&= (u16
) ~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M
;
14815 switch (mixer
->source_i2s
) {
14816 case DRX_AUD_SRC_MONO
:
14817 src_i2s_matr
|= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO
;
14819 case DRX_AUD_SRC_STEREO_OR_AB
:
14820 src_i2s_matr
|= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB
;
14822 case DRX_AUD_SRC_STEREO_OR_A
:
14823 src_i2s_matr
|= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A
;
14825 case DRX_AUD_SRC_STEREO_OR_B
:
14826 src_i2s_matr
|= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B
;
14833 src_i2s_matr
&= (u16
) ~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M
;
14834 switch (mixer
->matrix_i2s
) {
14835 case DRX_AUD_I2S_MATRIX_MONO
:
14836 src_i2s_matr
|= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO
;
14838 case DRX_AUD_I2S_MATRIX_STEREO
:
14839 src_i2s_matr
|= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO
;
14841 case DRX_AUD_I2S_MATRIX_A_MONO
:
14842 src_i2s_matr
|= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A
;
14844 case DRX_AUD_I2S_MATRIX_B_MONO
:
14845 src_i2s_matr
|= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B
;
14850 /* write the result */
14851 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_SRC_I2S_MATR__A
, src_i2s_matr
, 0);
14853 pr_err("error %d\n", rc
);
14858 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_WR_FM_MATRIX__A
, &fm_matr
, 0);
14860 pr_err("error %d\n", rc
);
14863 fm_matr
&= (u16
) ~AUD_DEM_WR_FM_MATRIX__M
;
14864 switch (mixer
->matrix_fm
) {
14865 case DRX_AUD_FM_MATRIX_NO_MATRIX
:
14866 fm_matr
|= AUD_DEM_WR_FM_MATRIX_NO_MATRIX
;
14868 case DRX_AUD_FM_MATRIX_GERMAN
:
14869 fm_matr
|= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX
;
14871 case DRX_AUD_FM_MATRIX_KOREAN
:
14872 fm_matr
|= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX
;
14874 case DRX_AUD_FM_MATRIX_SOUND_A
:
14875 fm_matr
|= AUD_DEM_WR_FM_MATRIX_SOUND_A
;
14877 case DRX_AUD_FM_MATRIX_SOUND_B
:
14878 fm_matr
|= AUD_DEM_WR_FM_MATRIX_SOUND_B
;
14884 /* Only write if ASS is off */
14885 if (ext_attr
->aud_data
.auto_sound
== DRX_AUD_AUTO_SOUND_OFF
) {
14886 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_FM_MATRIX__A
, fm_matr
, 0);
14888 pr_err("error %d\n", rc
);
14893 /* update the data structure with hardware state */
14894 ext_attr
->aud_data
.mixer
= *mixer
;
14901 /*============================================================================*/
14903 * \brief Set AV Sync settings
14904 * \param demod instance of demodulator
14905 * \param pointer to DRXICfgAVSync_t
14910 aud_ctrl_set_cfg_av_sync(struct drx_demod_instance
*demod
, enum drx_cfg_aud_av_sync
*av_sync
)
14912 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14913 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14915 u16 w_aud_vid_sync
= 0;
14917 if (av_sync
== NULL
)
14920 dev_addr
= demod
->my_i2c_dev_addr
;
14921 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14924 if (ext_attr
->aud_data
.audio_is_active
== false) {
14925 rc
= power_up_aud(demod
, true);
14927 pr_err("error %d\n", rc
);
14930 ext_attr
->aud_data
.audio_is_active
= true;
14933 /* audio/video synchronisation */
14934 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_AV_SYNC__A
, &w_aud_vid_sync
, 0);
14936 pr_err("error %d\n", rc
);
14940 w_aud_vid_sync
&= (u16
) ~AUD_DSP_WR_AV_SYNC_AV_ON__M
;
14942 if (*av_sync
== DRX_AUD_AVSYNC_OFF
)
14943 w_aud_vid_sync
|= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE
;
14945 w_aud_vid_sync
|= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE
;
14947 w_aud_vid_sync
&= (u16
) ~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M
;
14949 switch (*av_sync
) {
14950 case DRX_AUD_AVSYNC_NTSC
:
14951 w_aud_vid_sync
|= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC
;
14953 case DRX_AUD_AVSYNC_MONOCHROME
:
14954 w_aud_vid_sync
|= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME
;
14956 case DRX_AUD_AVSYNC_PAL_SECAM
:
14957 w_aud_vid_sync
|= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM
;
14959 case DRX_AUD_AVSYNC_OFF
:
14966 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_AV_SYNC__A
, w_aud_vid_sync
, 0);
14968 pr_err("error %d\n", rc
);
14976 /*============================================================================*/
14978 * \brief Get AV Sync settings
14979 * \param demod instance of demodulator
14980 * \param pointer to DRXICfgAVSync_t
14985 aud_ctrl_get_cfg_av_sync(struct drx_demod_instance
*demod
, enum drx_cfg_aud_av_sync
*av_sync
)
14987 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
14988 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
14990 u16 w_aud_vid_sync
= 0;
14992 if (av_sync
== NULL
)
14995 dev_addr
= demod
->my_i2c_dev_addr
;
14996 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
14999 if (ext_attr
->aud_data
.audio_is_active
== false) {
15000 rc
= power_up_aud(demod
, true);
15002 pr_err("error %d\n", rc
);
15005 ext_attr
->aud_data
.audio_is_active
= true;
15008 /* audio/video synchronisation */
15009 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_AV_SYNC__A
, &w_aud_vid_sync
, 0);
15011 pr_err("error %d\n", rc
);
15015 if ((w_aud_vid_sync
& AUD_DSP_WR_AV_SYNC_AV_ON__M
) ==
15016 AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE
) {
15017 *av_sync
= DRX_AUD_AVSYNC_OFF
;
15021 switch (w_aud_vid_sync
& AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M
) {
15022 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC
:
15023 *av_sync
= DRX_AUD_AVSYNC_NTSC
;
15025 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME
:
15026 *av_sync
= DRX_AUD_AVSYNC_MONOCHROME
;
15028 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM
:
15029 *av_sync
= DRX_AUD_AVSYNC_PAL_SECAM
;
15040 /*============================================================================*/
15042 * \brief Get deviation mode
15043 * \param demod instance of demodulator
15044 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15048 aud_ctrl_get_cfg_dev(struct drx_demod_instance
*demod
, enum drx_cfg_aud_deviation
*dev
)
15056 rc
= aud_get_modus(demod
, &r_modus
);
15058 pr_err("error %d\n", rc
);
15062 switch (r_modus
& AUD_DEM_WR_MODUS_MOD_HDEV_A__M
) {
15063 case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL
:
15064 *dev
= DRX_AUD_DEVIATION_NORMAL
;
15066 case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION
:
15067 *dev
= DRX_AUD_DEVIATION_HIGH
;
15078 /*============================================================================*/
15080 * \brief Get deviation mode
15081 * \param demod instance of demodulator
15082 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15086 aud_ctrl_set_cfg_dev(struct drx_demod_instance
*demod
, enum drx_cfg_aud_deviation
*dev
)
15088 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
15089 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
15097 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
15098 dev_addr
= demod
->my_i2c_dev_addr
;
15100 rc
= aud_get_modus(demod
, &r_modus
);
15102 pr_err("error %d\n", rc
);
15108 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_HDEV_A__M
;
15111 case DRX_AUD_DEVIATION_NORMAL
:
15112 w_modus
|= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL
;
15114 case DRX_AUD_DEVIATION_HIGH
:
15115 w_modus
|= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION
;
15121 /* now update the modus register */
15122 if (w_modus
!= r_modus
) {
15123 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_MODUS__A
, w_modus
, 0);
15125 pr_err("error %d\n", rc
);
15129 /* store in drxk data struct */
15130 ext_attr
->aud_data
.deviation
= *dev
;
15137 /*============================================================================*/
15139 * \brief Get Prescaler settings
15140 * \param demod instance of demodulator
15141 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15145 aud_ctrl_get_cfg_prescale(struct drx_demod_instance
*demod
, struct drx_cfg_aud_prescale
*presc
)
15147 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
15148 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
15150 u16 r_max_fm_deviation
= 0;
15151 u16 r_nicam_prescaler
= 0;
15156 dev_addr
= demod
->my_i2c_dev_addr
;
15157 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
15160 if (ext_attr
->aud_data
.audio_is_active
== false) {
15161 rc
= power_up_aud(demod
, true);
15163 pr_err("error %d\n", rc
);
15166 ext_attr
->aud_data
.audio_is_active
= true;
15169 /* read register data */
15170 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_NICAM_PRESC__A
, &r_nicam_prescaler
, 0);
15172 pr_err("error %d\n", rc
);
15175 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DSP_WR_FM_PRESC__A
, &r_max_fm_deviation
, 0);
15177 pr_err("error %d\n", rc
);
15181 /* calculate max FM deviation */
15182 r_max_fm_deviation
>>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B
;
15183 if (r_max_fm_deviation
> 0) {
15184 presc
->fm_deviation
= 3600UL + (r_max_fm_deviation
>> 1);
15185 presc
->fm_deviation
/= r_max_fm_deviation
;
15187 presc
->fm_deviation
= 380; /* kHz */
15190 /* calculate NICAM gain from pre-scaler */
15192 nicam_gain = 20 * ( log10( preScaler / 16) )
15193 = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
15195 because log1_times100() cannot return negative numbers
15196 = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
15198 for 0.1dB resolution:
15200 nicam_gain = 200 * ( log10( preScaler / 16) )
15201 = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
15202 = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
15205 r_nicam_prescaler
>>= 8;
15206 if (r_nicam_prescaler
<= 1)
15207 presc
->nicam_gain
= -241;
15209 presc
->nicam_gain
= (s16
)(((s32
)(log1_times100(10 * r_nicam_prescaler
* r_nicam_prescaler
)) - (s32
)(log1_times100(10 * 16 * 16))));
15216 /*============================================================================*/
15218 * \brief Set Prescaler settings
15219 * \param demod instance of demodulator
15220 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15224 aud_ctrl_set_cfg_prescale(struct drx_demod_instance
*demod
, struct drx_cfg_aud_prescale
*presc
)
15226 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
15227 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
15229 u16 w_max_fm_deviation
= 0;
15230 u16 nicam_prescaler
;
15235 dev_addr
= demod
->my_i2c_dev_addr
;
15236 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
15239 if (ext_attr
->aud_data
.audio_is_active
== false) {
15240 rc
= power_up_aud(demod
, true);
15242 pr_err("error %d\n", rc
);
15245 ext_attr
->aud_data
.audio_is_active
= true;
15248 /* setting of max FM deviation */
15249 w_max_fm_deviation
= (u16
) (frac(3600UL, presc
->fm_deviation
, 0));
15250 w_max_fm_deviation
<<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B
;
15251 if (w_max_fm_deviation
>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION
)
15252 w_max_fm_deviation
= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION
;
15254 /* NICAM Prescaler */
15255 if ((presc
->nicam_gain
>= -241) && (presc
->nicam_gain
<= 180)) {
15258 prescaler = 16 * 10^( gd_b / 20 )
15260 minval of gd_b = -20*log( 16 ) = -24.1dB
15262 negative numbers not allowed for d_b2lin_times100, so
15264 prescaler = 16 * 10^( gd_b / 20 )
15265 = 10^( (gd_b / 20) + log10(16) )
15266 = 10^( (gd_b + 20log10(16)) / 20 )
15270 = 10^( G0.1dB + 200log10(16)) / 200 )
15273 nicam_prescaler
= (u16
)
15274 ((d_b2lin_times100(presc
->nicam_gain
+ 241UL) + 50UL) / 100UL);
15277 if (nicam_prescaler
> 127)
15278 nicam_prescaler
= 127;
15280 /* shift before writing to register */
15281 nicam_prescaler
<<= 8;
15285 /* end of setting NICAM Prescaler */
15287 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_NICAM_PRESC__A
, nicam_prescaler
, 0);
15289 pr_err("error %d\n", rc
);
15292 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_FM_PRESC__A
, w_max_fm_deviation
, 0);
15294 pr_err("error %d\n", rc
);
15298 ext_attr
->aud_data
.prescale
= *presc
;
15305 /*============================================================================*/
15308 * \param demod instance of demodulator
15309 * \param pointer to struct drx_aud_beep * \return int.
15312 static int aud_ctrl_beep(struct drx_demod_instance
*demod
, struct drx_aud_beep
*beep
)
15314 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
15315 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
15324 dev_addr
= demod
->my_i2c_dev_addr
;
15325 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
15328 if (ext_attr
->aud_data
.audio_is_active
== false) {
15329 rc
= power_up_aud(demod
, true);
15331 pr_err("error %d\n", rc
);
15334 ext_attr
->aud_data
.audio_is_active
= true;
15337 if ((beep
->volume
> 0) || (beep
->volume
< -127))
15340 if (beep
->frequency
> 3000)
15343 volume
= (u16
) beep
->volume
+ 127;
15344 the_beep
|= volume
<< AUD_DSP_WR_BEEPER_BEEP_VOLUME__B
;
15346 frequency
= ((u32
) beep
->frequency
) * 23 / 500;
15347 if (frequency
> AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M
)
15348 frequency
= AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M
;
15349 the_beep
|= (u16
) frequency
;
15351 if (beep
->mute
== true)
15354 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_BEEPER__A
, the_beep
, 0);
15356 pr_err("error %d\n", rc
);
15365 /*============================================================================*/
15367 * \brief Set an audio standard
15368 * \param demod instance of demodulator
15369 * \param pointer to enum drx_aud_standard * \return int.
15373 aud_ctrl_set_standard(struct drx_demod_instance
*demod
, enum drx_aud_standard
*standard
)
15375 struct i2c_device_addr
*dev_addr
= NULL
;
15376 struct drxj_data
*ext_attr
= NULL
;
15377 enum drx_standard current_standard
= DRX_STANDARD_UNKNOWN
;
15379 u16 w_standard
= 0;
15383 bool mute_buffer
= false;
15384 s16 volume_buffer
= 0;
15387 if (standard
== NULL
)
15390 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
15391 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
15394 if (ext_attr
->aud_data
.audio_is_active
== false) {
15395 rc
= power_up_aud(demod
, false);
15397 pr_err("error %d\n", rc
);
15400 ext_attr
->aud_data
.audio_is_active
= true;
15403 /* reset RDS data availability flag */
15404 ext_attr
->aud_data
.rds_data_present
= false;
15406 /* we need to mute from here to avoid noise during standard switching */
15407 mute_buffer
= ext_attr
->aud_data
.volume
.mute
;
15408 volume_buffer
= ext_attr
->aud_data
.volume
.volume
;
15410 ext_attr
->aud_data
.volume
.mute
= true;
15411 /* restore data structure from DRX ExtAttr, call volume first to mute */
15412 rc
= aud_ctrl_set_cfg_volume(demod
, &ext_attr
->aud_data
.volume
);
15414 pr_err("error %d\n", rc
);
15417 rc
= aud_ctrl_set_cfg_carrier(demod
, &ext_attr
->aud_data
.carriers
);
15419 pr_err("error %d\n", rc
);
15422 rc
= aud_ctrl_set_cfg_ass_thres(demod
, &ext_attr
->aud_data
.ass_thresholds
);
15424 pr_err("error %d\n", rc
);
15427 rc
= aud_ctr_setl_cfg_auto_sound(demod
, &ext_attr
->aud_data
.auto_sound
);
15429 pr_err("error %d\n", rc
);
15432 rc
= aud_ctrl_set_cfg_mixer(demod
, &ext_attr
->aud_data
.mixer
);
15434 pr_err("error %d\n", rc
);
15437 rc
= aud_ctrl_set_cfg_av_sync(demod
, &ext_attr
->aud_data
.av_sync
);
15439 pr_err("error %d\n", rc
);
15442 rc
= aud_ctrl_set_cfg_output_i2s(demod
, &ext_attr
->aud_data
.i2sdata
);
15444 pr_err("error %d\n", rc
);
15448 /* get prescaler from presets */
15449 rc
= aud_ctrl_set_cfg_prescale(demod
, &ext_attr
->aud_data
.prescale
);
15451 pr_err("error %d\n", rc
);
15455 rc
= aud_get_modus(demod
, &r_modus
);
15457 pr_err("error %d\n", rc
);
15463 switch (*standard
) {
15464 case DRX_AUD_STANDARD_AUTO
:
15465 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO
;
15467 case DRX_AUD_STANDARD_BTSC
:
15468 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO
;
15469 if (ext_attr
->aud_data
.btsc_detect
== DRX_BTSC_MONO_AND_SAP
)
15470 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP
;
15472 case DRX_AUD_STANDARD_A2
:
15473 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA
;
15475 case DRX_AUD_STANDARD_EIAJ
:
15476 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J
;
15478 case DRX_AUD_STANDARD_FM_STEREO
:
15479 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO
;
15481 case DRX_AUD_STANDARD_BG_FM
:
15482 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM
;
15484 case DRX_AUD_STANDARD_D_K1
:
15485 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1
;
15487 case DRX_AUD_STANDARD_D_K2
:
15488 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2
;
15490 case DRX_AUD_STANDARD_D_K3
:
15491 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3
;
15493 case DRX_AUD_STANDARD_BG_NICAM_FM
:
15494 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM
;
15496 case DRX_AUD_STANDARD_L_NICAM_AM
:
15497 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM
;
15499 case DRX_AUD_STANDARD_I_NICAM_FM
:
15500 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM
;
15502 case DRX_AUD_STANDARD_D_K_NICAM_FM
:
15503 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM
;
15505 case DRX_AUD_STANDARD_UNKNOWN
:
15506 w_standard
= AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO
;
15512 if (*standard
== DRX_AUD_STANDARD_AUTO
) {
15513 /* we need the current standard here */
15514 current_standard
= ext_attr
->standard
;
15516 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M
;
15518 if ((current_standard
== DRX_STANDARD_PAL_SECAM_L
) || (current_standard
== DRX_STANDARD_PAL_SECAM_LP
))
15519 w_modus
|= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM
);
15521 w_modus
|= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K
);
15523 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M
;
15524 if (current_standard
== DRX_STANDARD_NTSC
)
15525 w_modus
|= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC
);
15527 w_modus
|= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA
);
15531 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_FMRADIO__M
;
15533 /* just get hardcoded deemphasis and activate here */
15534 if (ext_attr
->aud_data
.deemph
== DRX_AUD_FM_DEEMPH_50US
)
15535 w_modus
|= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U
);
15537 w_modus
|= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U
);
15539 w_modus
&= (u16
) ~AUD_DEM_WR_MODUS_MOD_BTSC__M
;
15540 if (ext_attr
->aud_data
.btsc_detect
== DRX_BTSC_STEREO
)
15541 w_modus
|= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO
);
15543 w_modus
|= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP
);
15545 if (w_modus
!= r_modus
) {
15546 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_MODUS__A
, w_modus
, 0);
15548 pr_err("error %d\n", rc
);
15553 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DEM_WR_STANDARD_SEL__A
, w_standard
, 0);
15555 pr_err("error %d\n", rc
);
15559 /**************************************************************************/
15560 /* NOT calling aud_ctrl_set_cfg_volume to avoid interfering standard */
15561 /* detection, need to keep things very minimal here, but keep audio */
15562 /* buffers intact */
15563 /**************************************************************************/
15564 ext_attr
->aud_data
.volume
.mute
= mute_buffer
;
15565 if (ext_attr
->aud_data
.volume
.mute
== false) {
15566 w_volume
|= (u16
) ((volume_buffer
+ AUD_VOLUME_ZERO_DB
) <<
15567 AUD_DSP_WR_VOLUME_VOL_MAIN__B
);
15568 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, AUD_DSP_WR_VOLUME__A
, w_volume
, 0);
15570 pr_err("error %d\n", rc
);
15575 /* write standard selected */
15576 ext_attr
->aud_data
.audio_standard
= *standard
;
15583 /*============================================================================*/
15585 * \brief Get the current audio standard
15586 * \param demod instance of demodulator
15587 * \param pointer to enum drx_aud_standard * \return int.
15591 aud_ctrl_get_standard(struct drx_demod_instance
*demod
, enum drx_aud_standard
*standard
)
15593 struct i2c_device_addr
*dev_addr
= NULL
;
15594 struct drxj_data
*ext_attr
= NULL
;
15598 if (standard
== NULL
)
15601 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
15602 dev_addr
= (struct i2c_device_addr
*)demod
->my_i2c_dev_addr
;
15605 if (ext_attr
->aud_data
.audio_is_active
== false) {
15606 rc
= power_up_aud(demod
, true);
15608 pr_err("error %d\n", rc
);
15611 ext_attr
->aud_data
.audio_is_active
= true;
15614 *standard
= DRX_AUD_STANDARD_UNKNOWN
;
15616 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, AUD_DEM_RD_STANDARD_RES__A
, &r_data
, 0);
15618 pr_err("error %d\n", rc
);
15622 /* return OK if the detection is not ready yet */
15623 if (r_data
>= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE
) {
15624 *standard
= DRX_AUD_STANDARD_NOT_READY
;
15628 /* detection done, return correct standard */
15630 /* no standard detected */
15631 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD
:
15632 *standard
= DRX_AUD_STANDARD_UNKNOWN
;
15634 /* standard is KOREA(A2) */
15635 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM
:
15636 *standard
= DRX_AUD_STANDARD_A2
;
15638 /* standard is EIA-J (Japan) */
15639 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J
:
15640 *standard
= DRX_AUD_STANDARD_EIAJ
;
15642 /* standard is BTSC-stereo */
15643 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO
:
15644 *standard
= DRX_AUD_STANDARD_BTSC
;
15646 /* standard is BTSC-mono (SAP) */
15647 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP
:
15648 *standard
= DRX_AUD_STANDARD_BTSC
;
15650 /* standard is FM radio */
15651 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO
:
15652 *standard
= DRX_AUD_STANDARD_FM_STEREO
;
15654 /* standard is BG FM */
15655 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM
:
15656 *standard
= DRX_AUD_STANDARD_BG_FM
;
15658 /* standard is DK-1 FM */
15659 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM
:
15660 *standard
= DRX_AUD_STANDARD_D_K1
;
15662 /* standard is DK-2 FM */
15663 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM
:
15664 *standard
= DRX_AUD_STANDARD_D_K2
;
15666 /* standard is DK-3 FM */
15667 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM
:
15668 *standard
= DRX_AUD_STANDARD_D_K3
;
15670 /* standard is BG-NICAM FM */
15671 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM
:
15672 *standard
= DRX_AUD_STANDARD_BG_NICAM_FM
;
15674 /* standard is L-NICAM AM */
15675 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM
:
15676 *standard
= DRX_AUD_STANDARD_L_NICAM_AM
;
15678 /* standard is I-NICAM FM */
15679 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM
:
15680 *standard
= DRX_AUD_STANDARD_I_NICAM_FM
;
15682 /* standard is DK-NICAM FM */
15683 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM
:
15684 *standard
= DRX_AUD_STANDARD_D_K_NICAM_FM
;
15687 *standard
= DRX_AUD_STANDARD_UNKNOWN
;
15696 /*============================================================================*/
15698 * \brief Retreive lock status in case of FM standard
15699 * \param demod instance of demodulator
15700 * \param pointer to lock status
15705 fm_lock_status(struct drx_demod_instance
*demod
, enum drx_lock_status
*lock_stat
)
15707 struct drx_aud_status status
;
15710 /* Check detection of audio carriers */
15711 rc
= aud_ctrl_get_carrier_detect_status(demod
, &status
);
15713 pr_err("error %d\n", rc
);
15717 /* locked if either primary or secondary carrier is detected */
15718 if ((status
.carrier_a
== true) || (status
.carrier_b
== true))
15719 *lock_stat
= DRX_LOCKED
;
15721 *lock_stat
= DRX_NOT_LOCKED
;
15729 /*============================================================================*/
15731 * \brief retreive signal quality in case of FM standard
15732 * \param demod instance of demodulator
15733 * \param pointer to signal quality
15736 * Only the quality indicator field is will be supplied.
15737 * This will either be 0% or 100%, nothing in between.
15741 fm_sig_quality(struct drx_demod_instance
*demod
, struct drx_sig_quality
*sig_quality
)
15743 enum drx_lock_status lock_status
= DRX_NOT_LOCKED
;
15746 rc
= fm_lock_status(demod
, &lock_status
);
15748 pr_err("error %d\n", rc
);
15751 if (lock_status
== DRX_LOCKED
)
15752 sig_quality
->indicator
= 100;
15754 sig_quality
->indicator
= 0;
15762 /*===========================================================================*/
15763 /*== END AUDIO DATAPATH FUNCTIONS ==*/
15764 /*===========================================================================*/
15766 /*============================================================================*/
15767 /*============================================================================*/
15768 /*== OOB DATAPATH FUNCTIONS ==*/
15769 /*============================================================================*/
15770 /*============================================================================*/
15772 * \fn int get_oob_lock_status ()
15773 * \brief Get OOB lock status.
15774 * \param dev_addr I2C address
15775 \ oob_lock OOB lock status.
15778 * Gets OOB lock status
15782 get_oob_lock_status(struct drx_demod_instance
*demod
,
15783 struct i2c_device_addr
*dev_addr
, enum drx_lock_status
*oob_lock
)
15785 struct drxjscu_cmd scu_cmd
;
15788 u16 oob_lock_state
;
15790 *oob_lock
= DRX_NOT_LOCKED
;
15792 scu_cmd
.command
= SCU_RAM_COMMAND_STANDARD_OOB
|
15793 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK
;
15794 scu_cmd
.result_len
= 2;
15795 scu_cmd
.result
= cmd_result
;
15796 scu_cmd
.parameter_len
= 0;
15798 rc
= scu_command(dev_addr
, &scu_cmd
);
15800 pr_err("error %d\n", rc
);
15804 if (scu_cmd
.result
[1] < 0x4000) {
15805 /* 0x00 NOT LOCKED */
15806 *oob_lock
= DRX_NOT_LOCKED
;
15807 } else if (scu_cmd
.result
[1] < 0x8000) {
15808 /* 0x40 DEMOD LOCKED */
15809 *oob_lock
= DRXJ_OOB_SYNC_LOCK
;
15810 } else if (scu_cmd
.result
[1] < 0xC000) {
15811 /* 0x80 DEMOD + OOB LOCKED (system lock) */
15812 oob_lock_state
= scu_cmd
.result
[1] & 0x00FF;
15814 if (oob_lock_state
& 0x0008)
15815 *oob_lock
= DRXJ_OOB_SYNC_LOCK
;
15816 else if ((oob_lock_state
& 0x0002) && (oob_lock_state
& 0x0001))
15817 *oob_lock
= DRXJ_OOB_AGC_LOCK
;
15819 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
15820 *oob_lock
= DRX_NEVER_LOCK
;
15823 /* *oob_lock = scu_cmd.result[1]; */
15831 * \fn int get_oob_symbol_rate_offset ()
15832 * \brief Get OOB Symbol rate offset. Unit is [ppm]
15833 * \param dev_addr I2C address
15834 * \ Symbol Rate Offset OOB parameter.
15837 * Gets OOB frequency offset
15841 get_oob_symbol_rate_offset(struct i2c_device_addr
*dev_addr
, s32
*symbol_rate_offset
)
15843 /* offset = -{(timing_offset/2^19)*(symbol_rate/12,656250MHz)}*10^6 [ppm] */
15844 /* offset = -{(timing_offset/2^19)*(symbol_rate/12656250)}*10^6 [ppm] */
15845 /* after reconfiguration: */
15846 /* offset = -{(timing_offset*symbol_rate)/(2^19*12656250)}*10^6 [ppm] */
15847 /* shift symbol rate left by 5 without lossing information */
15848 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
15849 /* shift 10^6 left by 6 without loosing information */
15850 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
15851 /* trim 12656250/15625 = 810 */
15852 /* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*810)} [ppm] */
15853 /* offset = -[(symbol_rate * 2^-5)*(timing_offset)/(2^8)]/810 [ppm] */
15855 s32 timing_offset
= 0;
15856 u32 unsigned_timing_offset
= 0;
15857 s32 division_factor
= 810;
15859 u32 symbol_rate
= 0;
15860 bool negative
= false;
15862 *symbol_rate_offset
= 0;
15863 /* read data rate */
15864 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ORX_RF_RX_DATA_RATE__A
, &data
, 0);
15866 pr_err("error %d\n", rc
);
15869 switch (data
& SCU_RAM_ORX_RF_RX_DATA_RATE__M
) {
15870 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC
:
15871 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC
:
15872 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT
:
15873 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT
:
15874 symbol_rate
= 1024000; /* bps */
15876 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC
:
15877 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC
:
15878 symbol_rate
= 772000; /* bps */
15880 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC
:
15881 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC
:
15882 symbol_rate
= 1544000; /* bps */
15888 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_CON_CTI_DTI_R__A
, &data
, 0);
15890 pr_err("error %d\n", rc
);
15893 /* convert data to positive and keep information about sign */
15894 if ((data
& 0x8000) == 0x8000) {
15895 if (data
== 0x8000)
15896 unsigned_timing_offset
= 32768;
15898 unsigned_timing_offset
= 0x00007FFF & (u32
) (-data
);
15901 unsigned_timing_offset
= (u32
) data
;
15903 symbol_rate
= symbol_rate
>> 5;
15904 unsigned_timing_offset
= (unsigned_timing_offset
* symbol_rate
);
15905 unsigned_timing_offset
= frac(unsigned_timing_offset
, 256, FRAC_ROUND
);
15906 unsigned_timing_offset
= frac(unsigned_timing_offset
,
15907 division_factor
, FRAC_ROUND
);
15909 timing_offset
= (s32
) unsigned_timing_offset
;
15911 timing_offset
= -(s32
) unsigned_timing_offset
;
15913 *symbol_rate_offset
= timing_offset
;
15921 * \fn int get_oob_freq_offset ()
15922 * \brief Get OOB lock status.
15923 * \param dev_addr I2C address
15924 * \ freq_offset OOB frequency offset.
15927 * Gets OOB frequency offset
15931 get_oob_freq_offset(struct drx_demod_instance
*demod
, s32
*freq_offset
)
15933 struct drx_common_attr
*common_attr
= (struct drx_common_attr
*) (NULL
);
15934 struct i2c_device_addr
*dev_addr
= NULL
;
15938 u16 symbol_rate_reg
= 0;
15939 u32 symbol_rate
= 0;
15940 s32 coarse_freq_offset
= 0;
15941 s32 fine_freq_offset
= 0;
15943 s32 coarse_sign
= 1;
15946 u32 temp_freq_offset
= 0;
15948 /* check arguments */
15949 if ((demod
== NULL
) || (freq_offset
== NULL
))
15952 dev_addr
= demod
->my_i2c_dev_addr
;
15953 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
15957 /* read sign (spectrum inversion) */
15958 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_FWP_IQM_FRQ_W__A
, &rot
, 0);
15960 pr_err("error %d\n", rc
);
15964 /* read frequency offset */
15965 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ORX_FRQ_OFFSET__A
, &data
, 0);
15967 pr_err("error %d\n", rc
);
15970 /* find COARSE frequency offset */
15971 /* coarse_freq_offset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
15972 if (data
& 0x8000) {
15973 data
= (0xffff - data
+ 1);
15976 mult32(data
, (common_attr
->sys_clock_freq
* 1000) / 6, &data64hi
,
15978 temp_freq_offset
= (((data64lo
>> 21) & 0x7ff) | (data64hi
<< 11));
15980 /* get value in KHz */
15981 coarse_freq_offset
= coarse_sign
* frac(temp_freq_offset
, 1000, FRAC_ROUND
); /* KHz */
15982 /* read data rate */
15983 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ORX_RF_RX_DATA_RATE__A
, &symbol_rate_reg
, 0);
15985 pr_err("error %d\n", rc
);
15988 switch (symbol_rate_reg
& SCU_RAM_ORX_RF_RX_DATA_RATE__M
) {
15989 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC
:
15990 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC
:
15991 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT
:
15992 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT
:
15993 symbol_rate
= 1024000;
15995 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC
:
15996 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC
:
15997 symbol_rate
= 772000;
15999 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC
:
16000 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC
:
16001 symbol_rate
= 1544000;
16007 /* find FINE frequency offset */
16008 /* fine_freq_offset = ( (CORRECTION_VALUE*symbol_rate) >> 18 ); */
16009 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_CON_CPH_FRQ_R__A
, &data
, 0);
16011 pr_err("error %d\n", rc
);
16014 /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
16015 fine_freq_offset
= (symbol_rate
>> 5);
16016 if (data
& 0x8000) {
16017 fine_freq_offset
*= 0xffff - data
+ 1; /* Hz */
16020 fine_freq_offset
*= data
; /* Hz */
16022 /* Left to divide with 8192 (2^13) */
16023 fine_freq_offset
= frac(fine_freq_offset
, 8192, FRAC_ROUND
);
16024 /* and to divide with 1000 to get KHz */
16025 fine_freq_offset
= fine_sign
* frac(fine_freq_offset
, 1000, FRAC_ROUND
); /* KHz */
16027 if ((rot
& 0x8000) == 0x8000)
16028 *freq_offset
= -(coarse_freq_offset
+ fine_freq_offset
);
16030 *freq_offset
= (coarse_freq_offset
+ fine_freq_offset
);
16038 * \fn int get_oob_frequency ()
16039 * \brief Get OOB frequency (Unit:KHz).
16040 * \param dev_addr I2C address
16041 * \ frequency OOB frequency parameters.
16044 * Gets OOB frequency
16048 get_oob_frequency(struct drx_demod_instance
*demod
, s32
*frequency
)
16050 struct i2c_device_addr
*dev_addr
= NULL
;
16053 s32 freq_offset
= 0;
16056 dev_addr
= demod
->my_i2c_dev_addr
;
16058 *frequency
= 0; /* KHz */
16060 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A
, &data
, 0);
16062 pr_err("error %d\n", rc
);
16066 freq
= (s32
) ((s32
) data
* 50 + 50000L);
16068 rc
= get_oob_freq_offset(demod
, &freq_offset
);
16070 pr_err("error %d\n", rc
);
16074 *frequency
= freq
+ freq_offset
;
16082 * \fn int get_oobmer ()
16083 * \brief Get OOB MER.
16084 * \param dev_addr I2C address
16085 \ MER OOB parameter in dB.
16088 * Gets OOB MER. Table for MER is in Programming guide.
16091 static int get_oobmer(struct i2c_device_addr
*dev_addr
, u32
*mer
)
16098 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_EQU_MER_MER_R__A
, &data
, 0);
16100 pr_err("error %d\n", rc
);
16104 case 0: /* fall through */
16141 case 13: /* fall through */
16145 case 15: /* fall through */
16149 case 17: /* fall through */
16153 case 19: /* fall through */
16157 case 21: /* fall through */
16161 case 23: /* fall through */
16162 case 24: /* fall through */
16166 case 26: /* fall through */
16167 case 27: /* fall through */
16171 case 29: /* fall through */
16172 case 30: /* fall through */
16173 case 31: /* fall through */
16177 case 33: /* fall through */
16178 case 34: /* fall through */
16179 case 35: /* fall through */
16183 case 37: /* fall through */
16184 case 38: /* fall through */
16185 case 39: /* fall through */
16189 case 41: /* fall through */
16190 case 42: /* fall through */
16191 case 43: /* fall through */
16192 case 44: /* fall through */
16196 case 46: /* fall through */
16197 case 47: /* fall through */
16198 case 48: /* fall through */
16199 case 49: /* fall through */
16200 case 50: /* fall through */
16203 case 51: /* fall through */
16204 case 52: /* fall through */
16205 case 53: /* fall through */
16206 case 54: /* fall through */
16207 case 55: /* fall through */
16208 case 56: /* fall through */
16212 case 58: /* fall through */
16213 case 59: /* fall through */
16214 case 60: /* fall through */
16215 case 61: /* fall through */
16216 case 62: /* fall through */
16231 * \fn int set_orx_nsu_aox()
16232 * \brief Configure OrxNsuAox for OOB
16233 * \param demod instance of demodulator.
16237 static int set_orx_nsu_aox(struct drx_demod_instance
*demod
, bool active
)
16239 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
16243 /* Configure NSU_AOX */
16244 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_NSU_AOX_STDBY_W__A
, &data
, 0);
16246 pr_err("error %d\n", rc
);
16250 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
));
16252 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
);
16253 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_NSU_AOX_STDBY_W__A
, data
, 0);
16255 pr_err("error %d\n", rc
);
16265 * \fn int ctrl_set_oob()
16266 * \brief Set OOB channel to be used.
16267 * \param demod instance of demodulator
16268 * \param oob_param OOB parameters for channel setting.
16269 * \frequency should be in KHz
16272 * Accepts only. Returns error otherwise.
16273 * Demapper value is written after scu_command START
16274 * because START command causes COMM_EXEC transition
16275 * from 0 to 1 which causes all registers to be
16276 * overwritten with initial value
16280 /* Nyquist filter impulse response */
16281 #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 */
16282 #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 */
16283 #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) */
16285 /* Coefficients for the nyquist fitler (total: 27 taps) */
16286 #define NYQFILTERLEN 27
16289 static int ctrl_set_oob(struct drx_demod_instance
*demod
, struct drxoob
*oob_param
)
16292 s32 freq
= 0; /* KHz */
16293 struct i2c_device_addr
*dev_addr
= NULL
;
16294 struct drxj_data
*ext_attr
= NULL
;
16296 bool mirror_freq_spect_oob
= false;
16297 u16 trk_filter_value
= 0;
16298 struct drxjscu_cmd scu_cmd
;
16299 u16 set_param_parameters
[3];
16300 u16 cmd_result
[2] = { 0, 0 };
16301 s16 nyquist_coeffs
[4][(NYQFILTERLEN
+ 1) / 2] = {
16302 IMPULSE_COSINE_ALPHA_0_3
, /* Target Mode 0 */
16303 IMPULSE_COSINE_ALPHA_0_3
, /* Target Mode 1 */
16304 IMPULSE_COSINE_ALPHA_0_5
, /* Target Mode 2 */
16305 IMPULSE_COSINE_ALPHA_RO_0_5
/* Target Mode 3 */
16307 u8 mode_val
[4] = { 2, 2, 0, 1 };
16308 u8 pfi_coeffs
[4][6] = {
16309 {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) */
16310 {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) */
16311 {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) */
16312 {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) */
16316 dev_addr
= demod
->my_i2c_dev_addr
;
16317 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
16318 mirror_freq_spect_oob
= ext_attr
->mirror_freq_spect_oob
;
16320 /* Check parameters */
16321 if (oob_param
== NULL
) {
16322 /* power off oob module */
16323 scu_cmd
.command
= SCU_RAM_COMMAND_STANDARD_OOB
16324 | SCU_RAM_COMMAND_CMD_DEMOD_STOP
;
16325 scu_cmd
.parameter_len
= 0;
16326 scu_cmd
.result_len
= 1;
16327 scu_cmd
.result
= cmd_result
;
16328 rc
= scu_command(dev_addr
, &scu_cmd
);
16330 pr_err("error %d\n", rc
);
16333 rc
= set_orx_nsu_aox(demod
, false);
16335 pr_err("error %d\n", rc
);
16338 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_COMM_EXEC__A
, ORX_COMM_EXEC_STOP
, 0);
16340 pr_err("error %d\n", rc
);
16344 ext_attr
->oob_power_on
= false;
16348 freq
= oob_param
->frequency
;
16349 if ((freq
< 70000) || (freq
> 130000))
16351 freq
= (freq
- 50000) / 50;
16356 u16
*trk_filtercfg
= ext_attr
->oob_trk_filter_cfg
;
16358 index
= (u16
) ((freq
- 400) / 200);
16359 remainder
= (u16
) ((freq
- 400) % 200);
16361 trk_filtercfg
[index
] - (trk_filtercfg
[index
] -
16362 trk_filtercfg
[index
+
16363 1]) / 10 * remainder
/
16370 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_COMM_EXEC__A
, ORX_COMM_EXEC_STOP
, 0);
16372 pr_err("error %d\n", rc
);
16375 scu_cmd
.command
= SCU_RAM_COMMAND_STANDARD_OOB
16376 | SCU_RAM_COMMAND_CMD_DEMOD_STOP
;
16377 scu_cmd
.parameter_len
= 0;
16378 scu_cmd
.result_len
= 1;
16379 scu_cmd
.result
= cmd_result
;
16380 rc
= scu_command(dev_addr
, &scu_cmd
);
16382 pr_err("error %d\n", rc
);
16388 scu_cmd
.command
= SCU_RAM_COMMAND_STANDARD_OOB
16389 | SCU_RAM_COMMAND_CMD_DEMOD_RESET
;
16390 scu_cmd
.parameter_len
= 0;
16391 scu_cmd
.result_len
= 1;
16392 scu_cmd
.result
= cmd_result
;
16393 rc
= scu_command(dev_addr
, &scu_cmd
);
16395 pr_err("error %d\n", rc
);
16401 /* set frequency, spectrum inversion and data rate */
16402 scu_cmd
.command
= SCU_RAM_COMMAND_STANDARD_OOB
16403 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV
;
16404 scu_cmd
.parameter_len
= 3;
16405 /* 1-data rate;2-frequency */
16406 switch (oob_param
->standard
) {
16407 case DRX_OOB_MODE_A
:
16409 /* signal is transmitted inverted */
16410 ((oob_param
->spectrum_inverted
== true) &
16411 /* and tuner is not mirroring the signal */
16412 (!mirror_freq_spect_oob
)) |
16414 /* signal is transmitted noninverted */
16415 ((oob_param
->spectrum_inverted
== false) &
16416 /* and tuner is mirroring the signal */
16417 (mirror_freq_spect_oob
))
16419 set_param_parameters
[0] =
16420 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC
;
16422 set_param_parameters
[0] =
16423 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC
;
16425 case DRX_OOB_MODE_B_GRADE_A
:
16427 /* signal is transmitted inverted */
16428 ((oob_param
->spectrum_inverted
== true) &
16429 /* and tuner is not mirroring the signal */
16430 (!mirror_freq_spect_oob
)) |
16432 /* signal is transmitted noninverted */
16433 ((oob_param
->spectrum_inverted
== false) &
16434 /* and tuner is mirroring the signal */
16435 (mirror_freq_spect_oob
))
16437 set_param_parameters
[0] =
16438 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC
;
16440 set_param_parameters
[0] =
16441 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC
;
16443 case DRX_OOB_MODE_B_GRADE_B
:
16446 /* signal is transmitted inverted */
16447 ((oob_param
->spectrum_inverted
== true) &
16448 /* and tuner is not mirroring the signal */
16449 (!mirror_freq_spect_oob
)) |
16451 /* signal is transmitted noninverted */
16452 ((oob_param
->spectrum_inverted
== false) &
16453 /* and tuner is mirroring the signal */
16454 (mirror_freq_spect_oob
))
16456 set_param_parameters
[0] =
16457 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC
;
16459 set_param_parameters
[0] =
16460 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC
;
16463 set_param_parameters
[1] = (u16
) (freq
& 0xFFFF);
16464 set_param_parameters
[2] = trk_filter_value
;
16465 scu_cmd
.parameter
= set_param_parameters
;
16466 scu_cmd
.result_len
= 1;
16467 scu_cmd
.result
= cmd_result
;
16468 mode_index
= mode_val
[(set_param_parameters
[0] & 0xC0) >> 6];
16469 rc
= scu_command(dev_addr
, &scu_cmd
);
16471 pr_err("error %d\n", rc
);
16475 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, 0xFABA, 0);
16477 pr_err("error %d\n", rc
);
16479 } /* Write magic word to enable pdr reg write */
16480 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);
16482 pr_err("error %d\n", rc
);
16485 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);
16487 pr_err("error %d\n", rc
);
16490 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_TOP_COMM_KEY__A
, 0x0000, 0);
16492 pr_err("error %d\n", rc
);
16494 } /* Write magic word to disable pdr reg write */
16496 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_TOP_COMM_KEY__A
, 0, 0);
16498 pr_err("error %d\n", rc
);
16501 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_FWP_AAG_LEN_W__A
, 16000, 0);
16503 pr_err("error %d\n", rc
);
16506 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_FWP_AAG_THR_W__A
, 40, 0);
16508 pr_err("error %d\n", rc
);
16513 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_DDC_OFO_SET_W__A
, ORX_DDC_OFO_SET_W__PRE
, 0);
16515 pr_err("error %d\n", rc
);
16520 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_NSU_AOX_LOPOW_W__A
, ext_attr
->oob_lo_pow
, 0);
16522 pr_err("error %d\n", rc
);
16526 /* initialization for target mode */
16527 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_TARGET_MODE__A
, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT
, 0);
16529 pr_err("error %d\n", rc
);
16532 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_FREQ_GAIN_CORR__A
, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS
, 0);
16534 pr_err("error %d\n", rc
);
16538 /* Reset bits for timing and freq. recovery */
16539 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_RST_CPH__A
, 0x0001, 0);
16541 pr_err("error %d\n", rc
);
16544 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_RST_CTI__A
, 0x0002, 0);
16546 pr_err("error %d\n", rc
);
16549 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_RST_KRN__A
, 0x0004, 0);
16551 pr_err("error %d\n", rc
);
16554 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_RST_KRP__A
, 0x0008, 0);
16556 pr_err("error %d\n", rc
);
16560 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
16561 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_AGN_LOCK_TH__A
, 2048 >> 3, 0);
16563 pr_err("error %d\n", rc
);
16566 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_AGN_LOCK_TOTH__A
, (u16
)(-2048), 0);
16568 pr_err("error %d\n", rc
);
16571 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_AGN_ONLOCK_TTH__A
, 8, 0);
16573 pr_err("error %d\n", rc
);
16576 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_AGN_UNLOCK_TTH__A
, (u16
)(-8), 0);
16578 pr_err("error %d\n", rc
);
16581 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_AGN_LOCK_MASK__A
, 1, 0);
16583 pr_err("error %d\n", rc
);
16587 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
16588 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_DGN_LOCK_TH__A
, 10, 0);
16590 pr_err("error %d\n", rc
);
16593 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_DGN_LOCK_TOTH__A
, (u16
)(-2048), 0);
16595 pr_err("error %d\n", rc
);
16598 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_DGN_ONLOCK_TTH__A
, 8, 0);
16600 pr_err("error %d\n", rc
);
16603 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_DGN_UNLOCK_TTH__A
, (u16
)(-8), 0);
16605 pr_err("error %d\n", rc
);
16608 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_DGN_LOCK_MASK__A
, 1 << 1, 0);
16610 pr_err("error %d\n", rc
);
16614 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
16615 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_FRQ_LOCK_TH__A
, 17, 0);
16617 pr_err("error %d\n", rc
);
16620 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_FRQ_LOCK_TOTH__A
, (u16
)(-2048), 0);
16622 pr_err("error %d\n", rc
);
16625 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A
, 8, 0);
16627 pr_err("error %d\n", rc
);
16630 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A
, (u16
)(-8), 0);
16632 pr_err("error %d\n", rc
);
16635 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_FRQ_LOCK_MASK__A
, 1 << 2, 0);
16637 pr_err("error %d\n", rc
);
16641 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
16642 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_PHA_LOCK_TH__A
, 3000, 0);
16644 pr_err("error %d\n", rc
);
16647 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_PHA_LOCK_TOTH__A
, (u16
)(-2048), 0);
16649 pr_err("error %d\n", rc
);
16652 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_PHA_ONLOCK_TTH__A
, 8, 0);
16654 pr_err("error %d\n", rc
);
16657 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_PHA_UNLOCK_TTH__A
, (u16
)(-8), 0);
16659 pr_err("error %d\n", rc
);
16662 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_PHA_LOCK_MASK__A
, 1 << 3, 0);
16664 pr_err("error %d\n", rc
);
16668 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
16669 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_TIM_LOCK_TH__A
, 400, 0);
16671 pr_err("error %d\n", rc
);
16674 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_TIM_LOCK_TOTH__A
, (u16
)(-2048), 0);
16676 pr_err("error %d\n", rc
);
16679 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_TIM_ONLOCK_TTH__A
, 8, 0);
16681 pr_err("error %d\n", rc
);
16684 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_TIM_UNLOCK_TTH__A
, (u16
)(-8), 0);
16686 pr_err("error %d\n", rc
);
16689 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_TIM_LOCK_MASK__A
, 1 << 4, 0);
16691 pr_err("error %d\n", rc
);
16695 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
16696 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_EQU_LOCK_TH__A
, 20, 0);
16698 pr_err("error %d\n", rc
);
16701 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_EQU_LOCK_TOTH__A
, (u16
)(-2048), 0);
16703 pr_err("error %d\n", rc
);
16706 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_EQU_ONLOCK_TTH__A
, 4, 0);
16708 pr_err("error %d\n", rc
);
16711 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_EQU_UNLOCK_TTH__A
, (u16
)(-4), 0);
16713 pr_err("error %d\n", rc
);
16716 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_ORX_EQU_LOCK_MASK__A
, 1 << 5, 0);
16718 pr_err("error %d\n", rc
);
16722 /* PRE-Filter coefficients (PFI) */
16723 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);
16725 pr_err("error %d\n", rc
);
16728 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_TOP_MDE_W__A
, mode_index
, 0);
16730 pr_err("error %d\n", rc
);
16734 /* NYQUIST-Filter coefficients (NYQ) */
16735 for (i
= 0; i
< (NYQFILTERLEN
+ 1) / 2; i
++) {
16736 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_FWP_NYQ_ADR_W__A
, i
, 0);
16738 pr_err("error %d\n", rc
);
16741 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_FWP_NYQ_COF_RW__A
, nyquist_coeffs
[mode_index
][i
], 0);
16743 pr_err("error %d\n", rc
);
16747 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_FWP_NYQ_ADR_W__A
, 31, 0);
16749 pr_err("error %d\n", rc
);
16752 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_COMM_EXEC__A
, ORX_COMM_EXEC_ACTIVE
, 0);
16754 pr_err("error %d\n", rc
);
16760 scu_cmd
.command
= SCU_RAM_COMMAND_STANDARD_OOB
16761 | SCU_RAM_COMMAND_CMD_DEMOD_START
;
16762 scu_cmd
.parameter_len
= 0;
16763 scu_cmd
.result_len
= 1;
16764 scu_cmd
.result
= cmd_result
;
16765 rc
= scu_command(dev_addr
, &scu_cmd
);
16767 pr_err("error %d\n", rc
);
16771 rc
= set_orx_nsu_aox(demod
, true);
16773 pr_err("error %d\n", rc
);
16776 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_NSU_AOX_STHR_W__A
, ext_attr
->oob_pre_saw
, 0);
16778 pr_err("error %d\n", rc
);
16782 ext_attr
->oob_power_on
= true;
16790 * \fn int ctrl_get_oob()
16791 * \brief Set modulation standard to be used.
16792 * \param demod instance of demodulator
16793 * \param oob_status OOB status parameters.
16797 ctrl_get_oob(struct drx_demod_instance
*demod
, struct drxoob_status
*oob_status
)
16800 struct i2c_device_addr
*dev_addr
= NULL
;
16801 struct drxj_data
*ext_attr
= NULL
;
16804 dev_addr
= demod
->my_i2c_dev_addr
;
16805 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
16807 /* check arguments */
16808 if (oob_status
== NULL
)
16811 if (!ext_attr
->oob_power_on
)
16814 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_DDC_OFO_SET_W__A
, &data
, 0);
16816 pr_err("error %d\n", rc
);
16819 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_NSU_TUN_RFGAIN_W__A
, &data
, 0);
16821 pr_err("error %d\n", rc
);
16824 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_FWP_AAG_THR_W__A
, &data
, 0);
16826 pr_err("error %d\n", rc
);
16829 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ORX_DGN_KI__A
, &data
, 0);
16831 pr_err("error %d\n", rc
);
16834 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_FWP_SRC_DGN_W__A
, &data
, 0);
16836 pr_err("error %d\n", rc
);
16840 rc
= get_oob_lock_status(demod
, dev_addr
, &oob_status
->lock
);
16842 pr_err("error %d\n", rc
);
16845 rc
= get_oob_frequency(demod
, &oob_status
->frequency
);
16847 pr_err("error %d\n", rc
);
16850 rc
= get_oobmer(dev_addr
, &oob_status
->mer
);
16852 pr_err("error %d\n", rc
);
16855 rc
= get_oob_symbol_rate_offset(dev_addr
, &oob_status
->symbol_rate_offset
);
16857 pr_err("error %d\n", rc
);
16867 * \fn int ctrl_set_cfg_oob_pre_saw()
16868 * \brief Configure PreSAW treshold value
16869 * \param cfg_data Pointer to configuration parameter
16870 * \return Error code
16873 ctrl_set_cfg_oob_pre_saw(struct drx_demod_instance
*demod
, u16
*cfg_data
)
16875 struct i2c_device_addr
*dev_addr
= NULL
;
16876 struct drxj_data
*ext_attr
= NULL
;
16879 if (cfg_data
== NULL
)
16882 dev_addr
= demod
->my_i2c_dev_addr
;
16883 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
16885 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_NSU_AOX_STHR_W__A
, *cfg_data
, 0);
16887 pr_err("error %d\n", rc
);
16890 ext_attr
->oob_pre_saw
= *cfg_data
;
16897 * \fn int ctrl_get_cfg_oob_pre_saw()
16898 * \brief Configure PreSAW treshold value
16899 * \param cfg_data Pointer to configuration parameter
16900 * \return Error code
16903 ctrl_get_cfg_oob_pre_saw(struct drx_demod_instance
*demod
, u16
*cfg_data
)
16905 struct drxj_data
*ext_attr
= NULL
;
16907 if (cfg_data
== NULL
)
16910 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
16912 *cfg_data
= ext_attr
->oob_pre_saw
;
16918 * \fn int ctrl_set_cfg_oob_lo_power()
16919 * \brief Configure LO Power value
16920 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
16923 ctrl_set_cfg_oob_lo_power(struct drx_demod_instance
*demod
, enum drxj_cfg_oob_lo_power
*cfg_data
)
16925 struct i2c_device_addr
*dev_addr
= NULL
;
16926 struct drxj_data
*ext_attr
= NULL
;
16929 if (cfg_data
== NULL
)
16932 dev_addr
= demod
->my_i2c_dev_addr
;
16933 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
16935 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, ORX_NSU_AOX_LOPOW_W__A
, *cfg_data
, 0);
16937 pr_err("error %d\n", rc
);
16940 ext_attr
->oob_lo_pow
= *cfg_data
;
16947 * \fn int ctrl_get_cfg_oob_lo_power()
16948 * \brief Configure LO Power value
16949 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
16952 ctrl_get_cfg_oob_lo_power(struct drx_demod_instance
*demod
, enum drxj_cfg_oob_lo_power
*cfg_data
)
16954 struct drxj_data
*ext_attr
= NULL
;
16956 if (cfg_data
== NULL
)
16959 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
16961 *cfg_data
= ext_attr
->oob_lo_pow
;
16966 /*============================================================================*/
16967 /*== END OOB DATAPATH FUNCTIONS ==*/
16968 /*============================================================================*/
16970 /*=============================================================================
16971 ===== MC command related functions ==========================================
16972 ===========================================================================*/
16974 /*=============================================================================
16975 ===== ctrl_set_channel() ==========================================================
16976 ===========================================================================*/
16978 * \fn int ctrl_set_channel()
16979 * \brief Select a new transmission channel.
16980 * \param demod instance of demod.
16981 * \param channel Pointer to channel data.
16984 * In case the tuner module is not used and in case of NTSC/FM the pogrammer
16985 * must tune the tuner to the centre frequency of the NTSC/FM channel.
16989 ctrl_set_channel(struct drx_demod_instance
*demod
, struct drx_channel
*channel
)
16992 s32 tuner_freq_offset
= 0;
16993 s32 intermediate_freq
= 0;
16994 struct drxj_data
*ext_attr
= NULL
;
16995 struct i2c_device_addr
*dev_addr
= NULL
;
16996 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
16997 struct drx_common_attr
*common_attr
= NULL
;
16998 #ifndef DRXJ_VSB_ONLY
16999 u32 min_symbol_rate
= 0;
17000 u32 max_symbol_rate
= 0;
17001 int bandwidth_temp
= 0;
17004 /*== check arguments ======================================================*/
17005 if ((demod
== NULL
) || (channel
== NULL
))
17008 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
17009 dev_addr
= demod
->my_i2c_dev_addr
;
17010 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
17011 standard
= ext_attr
->standard
;
17013 /* check valid standards */
17014 switch (standard
) {
17015 case DRX_STANDARD_8VSB
:
17016 #ifndef DRXJ_VSB_ONLY
17017 case DRX_STANDARD_ITU_A
:
17018 case DRX_STANDARD_ITU_B
:
17019 case DRX_STANDARD_ITU_C
:
17020 #endif /* DRXJ_VSB_ONLY */
17022 case DRX_STANDARD_NTSC
:
17023 case DRX_STANDARD_FM
:
17024 case DRX_STANDARD_PAL_SECAM_BG
:
17025 case DRX_STANDARD_PAL_SECAM_DK
:
17026 case DRX_STANDARD_PAL_SECAM_I
:
17027 case DRX_STANDARD_PAL_SECAM_L
:
17028 case DRX_STANDARD_PAL_SECAM_LP
:
17031 case DRX_STANDARD_UNKNOWN
:
17036 /* check bandwidth QAM annex B, NTSC and 8VSB */
17037 if ((standard
== DRX_STANDARD_ITU_B
) ||
17038 (standard
== DRX_STANDARD_8VSB
) ||
17039 (standard
== DRX_STANDARD_NTSC
)) {
17040 switch (channel
->bandwidth
) {
17041 case DRX_BANDWIDTH_6MHZ
:
17042 case DRX_BANDWIDTH_UNKNOWN
: /* fall through */
17043 channel
->bandwidth
= DRX_BANDWIDTH_6MHZ
;
17045 case DRX_BANDWIDTH_8MHZ
: /* fall through */
17046 case DRX_BANDWIDTH_7MHZ
: /* fall through */
17052 if (standard
== DRX_STANDARD_PAL_SECAM_BG
) {
17053 switch (channel
->bandwidth
) {
17054 case DRX_BANDWIDTH_7MHZ
: /* fall through */
17055 case DRX_BANDWIDTH_8MHZ
:
17058 case DRX_BANDWIDTH_6MHZ
: /* fall through */
17059 case DRX_BANDWIDTH_UNKNOWN
: /* fall through */
17064 /* check bandwidth PAL/SECAM */
17065 if ((standard
== DRX_STANDARD_PAL_SECAM_BG
) ||
17066 (standard
== DRX_STANDARD_PAL_SECAM_DK
) ||
17067 (standard
== DRX_STANDARD_PAL_SECAM_I
) ||
17068 (standard
== DRX_STANDARD_PAL_SECAM_L
) ||
17069 (standard
== DRX_STANDARD_PAL_SECAM_LP
)) {
17070 switch (channel
->bandwidth
) {
17071 case DRX_BANDWIDTH_8MHZ
:
17072 case DRX_BANDWIDTH_UNKNOWN
: /* fall through */
17073 channel
->bandwidth
= DRX_BANDWIDTH_8MHZ
;
17075 case DRX_BANDWIDTH_6MHZ
: /* fall through */
17076 case DRX_BANDWIDTH_7MHZ
: /* fall through */
17083 /* For QAM annex A and annex C:
17084 -check symbolrate and constellation
17085 -derive bandwidth from symbolrate (input bandwidth is ignored)
17087 #ifndef DRXJ_VSB_ONLY
17088 if ((standard
== DRX_STANDARD_ITU_A
) ||
17089 (standard
== DRX_STANDARD_ITU_C
)) {
17090 struct drxuio_cfg uio_cfg
= { DRX_UIO1
, DRX_UIO_MODE_FIRMWARE_SAW
};
17091 int bw_rolloff_factor
= 0;
17093 bw_rolloff_factor
= (standard
== DRX_STANDARD_ITU_A
) ? 115 : 113;
17094 min_symbol_rate
= DRXJ_QAM_SYMBOLRATE_MIN
;
17095 max_symbol_rate
= DRXJ_QAM_SYMBOLRATE_MAX
;
17096 /* config SMA_TX pin to SAW switch mode */
17097 rc
= ctrl_set_uio_cfg(demod
, &uio_cfg
);
17099 pr_err("error %d\n", rc
);
17103 if (channel
->symbolrate
< min_symbol_rate
||
17104 channel
->symbolrate
> max_symbol_rate
) {
17108 switch (channel
->constellation
) {
17109 case DRX_CONSTELLATION_QAM16
: /* fall through */
17110 case DRX_CONSTELLATION_QAM32
: /* fall through */
17111 case DRX_CONSTELLATION_QAM64
: /* fall through */
17112 case DRX_CONSTELLATION_QAM128
: /* fall through */
17113 case DRX_CONSTELLATION_QAM256
:
17114 bandwidth_temp
= channel
->symbolrate
* bw_rolloff_factor
;
17115 bandwidth
= bandwidth_temp
/ 100;
17117 if ((bandwidth_temp
% 100) >= 50)
17120 if (bandwidth
<= 6100000) {
17121 channel
->bandwidth
= DRX_BANDWIDTH_6MHZ
;
17122 } else if ((bandwidth
> 6100000)
17123 && (bandwidth
<= 7100000)) {
17124 channel
->bandwidth
= DRX_BANDWIDTH_7MHZ
;
17125 } else if (bandwidth
> 7100000) {
17126 channel
->bandwidth
= DRX_BANDWIDTH_8MHZ
;
17134 /* For QAM annex B:
17135 -check constellation
17137 if (standard
== DRX_STANDARD_ITU_B
) {
17138 switch (channel
->constellation
) {
17139 case DRX_CONSTELLATION_AUTO
:
17140 case DRX_CONSTELLATION_QAM256
:
17141 case DRX_CONSTELLATION_QAM64
:
17147 switch (channel
->interleavemode
) {
17148 case DRX_INTERLEAVEMODE_I128_J1
:
17149 case DRX_INTERLEAVEMODE_I128_J1_V2
:
17150 case DRX_INTERLEAVEMODE_I128_J2
:
17151 case DRX_INTERLEAVEMODE_I64_J2
:
17152 case DRX_INTERLEAVEMODE_I128_J3
:
17153 case DRX_INTERLEAVEMODE_I32_J4
:
17154 case DRX_INTERLEAVEMODE_I128_J4
:
17155 case DRX_INTERLEAVEMODE_I16_J8
:
17156 case DRX_INTERLEAVEMODE_I128_J5
:
17157 case DRX_INTERLEAVEMODE_I8_J16
:
17158 case DRX_INTERLEAVEMODE_I128_J6
:
17159 case DRX_INTERLEAVEMODE_I128_J7
:
17160 case DRX_INTERLEAVEMODE_I128_J8
:
17161 case DRX_INTERLEAVEMODE_I12_J17
:
17162 case DRX_INTERLEAVEMODE_I5_J4
:
17163 case DRX_INTERLEAVEMODE_B52_M240
:
17164 case DRX_INTERLEAVEMODE_B52_M720
:
17165 case DRX_INTERLEAVEMODE_UNKNOWN
:
17166 case DRX_INTERLEAVEMODE_AUTO
:
17173 if ((ext_attr
->uio_sma_tx_mode
) == DRX_UIO_MODE_FIRMWARE_SAW
) {
17174 /* SAW SW, user UIO is used for switchable SAW */
17175 struct drxuio_data uio1
= { DRX_UIO1
, false };
17177 switch (channel
->bandwidth
) {
17178 case DRX_BANDWIDTH_8MHZ
:
17181 case DRX_BANDWIDTH_7MHZ
:
17182 uio1
.value
= false;
17184 case DRX_BANDWIDTH_6MHZ
:
17185 uio1
.value
= false;
17187 case DRX_BANDWIDTH_UNKNOWN
:
17192 rc
= ctrl_uio_write(demod
, &uio1
);
17194 pr_err("error %d\n", rc
);
17198 #endif /* DRXJ_VSB_ONLY */
17199 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_COMM_EXEC__A
, SCU_COMM_EXEC_ACTIVE
, 0);
17201 pr_err("error %d\n", rc
);
17205 tuner_freq_offset
= 0;
17206 intermediate_freq
= demod
->my_common_attr
->intermediate_freq
;
17208 /*== Setup demod for specific standard ====================================*/
17209 switch (standard
) {
17210 case DRX_STANDARD_8VSB
:
17211 if (channel
->mirror
== DRX_MIRROR_AUTO
)
17212 ext_attr
->mirror
= DRX_MIRROR_NO
;
17214 ext_attr
->mirror
= channel
->mirror
;
17215 rc
= set_vsb(demod
);
17217 pr_err("error %d\n", rc
);
17220 rc
= set_frequency(demod
, channel
, tuner_freq_offset
);
17222 pr_err("error %d\n", rc
);
17227 case DRX_STANDARD_NTSC
: /* fallthrough */
17228 case DRX_STANDARD_FM
: /* fallthrough */
17229 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
17230 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
17231 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
17232 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
17233 case DRX_STANDARD_PAL_SECAM_LP
:
17234 if (channel
->mirror
== DRX_MIRROR_AUTO
)
17235 ext_attr
->mirror
= DRX_MIRROR_NO
;
17237 ext_attr
->mirror
= channel
->mirror
;
17238 rc
= set_atv_channel(demod
, tuner_freq_offset
, channel
, standard
);
17240 pr_err("error %d\n", rc
);
17245 #ifndef DRXJ_VSB_ONLY
17246 case DRX_STANDARD_ITU_A
: /* fallthrough */
17247 case DRX_STANDARD_ITU_B
: /* fallthrough */
17248 case DRX_STANDARD_ITU_C
:
17249 rc
= set_qam_channel(demod
, channel
, tuner_freq_offset
);
17251 pr_err("error %d\n", rc
);
17256 case DRX_STANDARD_UNKNOWN
:
17261 /* flag the packet error counter reset */
17262 ext_attr
->reset_pkt_err_acc
= true;
17270 /*=============================================================================
17271 ===== ctrl_get_channel() ==========================================================
17272 ===========================================================================*/
17274 * \fn int ctrl_get_channel()
17275 * \brief Retreive parameters of current transmission channel.
17276 * \param demod Pointer to demod instance.
17277 * \param channel Pointer to channel data.
17281 ctrl_get_channel(struct drx_demod_instance
*demod
, struct drx_channel
*channel
)
17283 struct i2c_device_addr
*dev_addr
= NULL
;
17284 struct drxj_data
*ext_attr
= NULL
;
17286 enum drx_lock_status lock_status
= DRX_NOT_LOCKED
;
17287 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
17288 struct drx_common_attr
*common_attr
= NULL
;
17289 s32 intermediate_freq
= 0;
17290 s32 ctl_freq_offset
= 0;
17291 u32 iqm_rc_rate_lo
= 0;
17292 u32 adc_frequency
= 0;
17293 #ifndef DRXJ_VSB_ONLY
17294 int bandwidth_temp
= 0;
17298 /* check arguments */
17299 if ((demod
== NULL
) || (channel
== NULL
))
17302 dev_addr
= demod
->my_i2c_dev_addr
;
17303 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
17304 standard
= ext_attr
->standard
;
17305 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
17307 /* initialize channel fields */
17308 channel
->mirror
= DRX_MIRROR_UNKNOWN
;
17309 channel
->hierarchy
= DRX_HIERARCHY_UNKNOWN
;
17310 channel
->priority
= DRX_PRIORITY_UNKNOWN
;
17311 channel
->coderate
= DRX_CODERATE_UNKNOWN
;
17312 channel
->guard
= DRX_GUARD_UNKNOWN
;
17313 channel
->fftmode
= DRX_FFTMODE_UNKNOWN
;
17314 channel
->classification
= DRX_CLASSIFICATION_UNKNOWN
;
17315 channel
->bandwidth
= DRX_BANDWIDTH_UNKNOWN
;
17316 channel
->constellation
= DRX_CONSTELLATION_UNKNOWN
;
17317 channel
->symbolrate
= 0;
17318 channel
->interleavemode
= DRX_INTERLEAVEMODE_UNKNOWN
;
17319 channel
->carrier
= DRX_CARRIER_UNKNOWN
;
17320 channel
->framemode
= DRX_FRAMEMODE_UNKNOWN
;
17321 /* channel->interleaver = DRX_INTERLEAVER_UNKNOWN;*/
17322 channel
->ldpc
= DRX_LDPC_UNKNOWN
;
17324 intermediate_freq
= common_attr
->intermediate_freq
;
17326 /* check lock status */
17327 rc
= ctrl_lock_status(demod
, &lock_status
);
17329 pr_err("error %d\n", rc
);
17332 if ((lock_status
== DRX_LOCKED
) || (lock_status
== DRXJ_DEMOD_LOCK
)) {
17333 rc
= drxj_dap_atomic_read_reg32(dev_addr
, IQM_RC_RATE_LO__A
, &iqm_rc_rate_lo
, 0);
17335 pr_err("error %d\n", rc
);
17338 adc_frequency
= (common_attr
->sys_clock_freq
* 1000) / 3;
17340 channel
->symbolrate
=
17341 frac28(adc_frequency
, (iqm_rc_rate_lo
+ (1 << 23))) >> 7;
17343 switch (standard
) {
17344 case DRX_STANDARD_8VSB
:
17345 channel
->bandwidth
= DRX_BANDWIDTH_6MHZ
;
17346 /* get the channel frequency */
17347 rc
= get_ctl_freq_offset(demod
, &ctl_freq_offset
);
17349 pr_err("error %d\n", rc
);
17352 channel
->frequency
-= ctl_freq_offset
;
17353 /* get the channel constellation */
17354 channel
->constellation
= DRX_CONSTELLATION_AUTO
;
17356 #ifndef DRXJ_VSB_ONLY
17357 case DRX_STANDARD_ITU_A
:
17358 case DRX_STANDARD_ITU_B
:
17359 case DRX_STANDARD_ITU_C
:
17361 /* get the channel frequency */
17362 rc
= get_ctl_freq_offset(demod
, &ctl_freq_offset
);
17364 pr_err("error %d\n", rc
);
17367 channel
->frequency
-= ctl_freq_offset
;
17369 if (standard
== DRX_STANDARD_ITU_B
) {
17370 channel
->bandwidth
= DRX_BANDWIDTH_6MHZ
;
17374 u32 roll_off
= 113; /* default annex C */
17376 if (standard
== DRX_STANDARD_ITU_A
)
17380 channel
->symbolrate
* roll_off
;
17381 bandwidth
= bandwidth_temp
/ 100;
17383 if ((bandwidth_temp
% 100) >= 50)
17386 if (bandwidth
<= 6000000) {
17387 channel
->bandwidth
=
17388 DRX_BANDWIDTH_6MHZ
;
17389 } else if ((bandwidth
> 6000000)
17390 && (bandwidth
<= 7000000)) {
17391 channel
->bandwidth
=
17392 DRX_BANDWIDTH_7MHZ
;
17393 } else if (bandwidth
> 7000000) {
17394 channel
->bandwidth
=
17395 DRX_BANDWIDTH_8MHZ
;
17397 } /* if (standard == DRX_STANDARD_ITU_B) */
17400 struct drxjscu_cmd cmd_scu
= { 0, 0, 0, NULL
, NULL
};
17401 u16 cmd_result
[3] = { 0, 0, 0 };
17404 SCU_RAM_COMMAND_STANDARD_QAM
|
17405 SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM
;
17406 cmd_scu
.parameter_len
= 0;
17407 cmd_scu
.result_len
= 3;
17408 cmd_scu
.parameter
= NULL
;
17409 cmd_scu
.result
= cmd_result
;
17410 rc
= scu_command(dev_addr
, &cmd_scu
);
17412 pr_err("error %d\n", rc
);
17416 channel
->interleavemode
=
17417 (enum drx_interleave_mode
) (cmd_scu
.
17421 switch (ext_attr
->constellation
) {
17422 case DRX_CONSTELLATION_QAM256
:
17423 channel
->constellation
=
17424 DRX_CONSTELLATION_QAM256
;
17426 case DRX_CONSTELLATION_QAM128
:
17427 channel
->constellation
=
17428 DRX_CONSTELLATION_QAM128
;
17430 case DRX_CONSTELLATION_QAM64
:
17431 channel
->constellation
=
17432 DRX_CONSTELLATION_QAM64
;
17434 case DRX_CONSTELLATION_QAM32
:
17435 channel
->constellation
=
17436 DRX_CONSTELLATION_QAM32
;
17438 case DRX_CONSTELLATION_QAM16
:
17439 channel
->constellation
=
17440 DRX_CONSTELLATION_QAM16
;
17443 channel
->constellation
=
17444 DRX_CONSTELLATION_UNKNOWN
;
17450 case DRX_STANDARD_NTSC
: /* fall trough */
17451 case DRX_STANDARD_PAL_SECAM_BG
:
17452 case DRX_STANDARD_PAL_SECAM_DK
:
17453 case DRX_STANDARD_PAL_SECAM_I
:
17454 case DRX_STANDARD_PAL_SECAM_L
:
17455 case DRX_STANDARD_PAL_SECAM_LP
:
17456 case DRX_STANDARD_FM
:
17457 rc
= get_atv_channel(demod
, channel
, standard
);
17459 pr_err("error %d\n", rc
);
17463 case DRX_STANDARD_UNKNOWN
: /* fall trough */
17466 } /* switch ( standard ) */
17468 if (lock_status
== DRX_LOCKED
)
17469 channel
->mirror
= ext_attr
->mirror
;
17471 /* if ( lock_status == DRX_LOCKED ) */
17478 /*=============================================================================
17479 ===== SigQuality() ==========================================================
17480 ===========================================================================*/
17483 mer2indicator(u16 mer
, u16 min_mer
, u16 threshold_mer
, u16 max_mer
)
17487 if (mer
< min_mer
) {
17489 } else if (mer
< threshold_mer
) {
17490 if ((threshold_mer
- min_mer
) != 0)
17491 indicator
= 25 * (mer
- min_mer
) / (threshold_mer
- min_mer
);
17492 } else if (mer
< max_mer
) {
17493 if ((max_mer
- threshold_mer
) != 0)
17494 indicator
= 25 + 75 * (mer
- threshold_mer
) / (max_mer
- threshold_mer
);
17505 * \fn int ctrl_sig_quality()
17506 * \brief Retreive signal quality form device.
17507 * \param devmod Pointer to demodulator instance.
17508 * \param sig_quality Pointer to signal quality data.
17510 * \retval 0 sig_quality contains valid data.
17511 * \retval -EINVAL sig_quality is NULL.
17512 * \retval -EIO Erroneous data, sig_quality contains invalid data.
17516 ctrl_sig_quality(struct drx_demod_instance
*demod
, struct drx_sig_quality
*sig_quality
)
17518 struct i2c_device_addr
*dev_addr
= NULL
;
17519 struct drxj_data
*ext_attr
= NULL
;
17521 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
17522 enum drx_lock_status lock_status
= DRX_NOT_LOCKED
;
17525 u16 threshold_mer
= 0;
17527 /* Check arguments */
17528 if ((sig_quality
== NULL
) || (demod
== NULL
))
17531 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
17532 standard
= ext_attr
->standard
;
17534 /* get basic information */
17535 dev_addr
= demod
->my_i2c_dev_addr
;
17536 rc
= ctrl_lock_status(demod
, &lock_status
);
17538 pr_err("error %d\n", rc
);
17541 switch (standard
) {
17542 case DRX_STANDARD_8VSB
:
17543 #ifdef DRXJ_SIGNAL_ACCUM_ERR
17544 rc
= get_acc_pkt_err(demod
, &sig_quality
->packet_error
);
17546 pr_err("error %d\n", rc
);
17550 rc
= get_vsb_post_rs_pck_err(dev_addr
, &sig_quality
->packet_error
);
17552 pr_err("error %d\n", rc
);
17556 if (lock_status
!= DRXJ_DEMOD_LOCK
&& lock_status
!= DRX_LOCKED
) {
17557 sig_quality
->post_viterbi_ber
= 500000;
17558 sig_quality
->MER
= 20;
17559 sig_quality
->pre_viterbi_ber
= 0;
17561 /* PostViterbi is compute in steps of 10^(-6) */
17562 rc
= get_vs_bpre_viterbi_ber(dev_addr
, &sig_quality
->pre_viterbi_ber
);
17564 pr_err("error %d\n", rc
);
17567 rc
= get_vs_bpost_viterbi_ber(dev_addr
, &sig_quality
->post_viterbi_ber
);
17569 pr_err("error %d\n", rc
);
17572 rc
= get_vsbmer(dev_addr
, &sig_quality
->MER
);
17574 pr_err("error %d\n", rc
);
17580 threshold_mer
= 145;
17581 sig_quality
->post_reed_solomon_ber
= 0;
17582 sig_quality
->scale_factor_ber
= 1000000;
17583 sig_quality
->indicator
=
17584 mer2indicator(sig_quality
->MER
, min_mer
, threshold_mer
,
17587 #ifndef DRXJ_VSB_ONLY
17588 case DRX_STANDARD_ITU_A
:
17589 case DRX_STANDARD_ITU_B
:
17590 case DRX_STANDARD_ITU_C
:
17591 rc
= ctrl_get_qam_sig_quality(demod
, sig_quality
);
17593 pr_err("error %d\n", rc
);
17596 if (lock_status
!= DRXJ_DEMOD_LOCK
&& lock_status
!= DRX_LOCKED
) {
17597 switch (ext_attr
->constellation
) {
17598 case DRX_CONSTELLATION_QAM256
:
17599 sig_quality
->MER
= 210;
17601 case DRX_CONSTELLATION_QAM128
:
17602 sig_quality
->MER
= 180;
17604 case DRX_CONSTELLATION_QAM64
:
17605 sig_quality
->MER
= 150;
17607 case DRX_CONSTELLATION_QAM32
:
17608 sig_quality
->MER
= 120;
17610 case DRX_CONSTELLATION_QAM16
:
17611 sig_quality
->MER
= 90;
17614 sig_quality
->MER
= 0;
17619 switch (ext_attr
->constellation
) {
17620 case DRX_CONSTELLATION_QAM256
:
17622 threshold_mer
= 270;
17625 case DRX_CONSTELLATION_QAM64
:
17627 threshold_mer
= 210;
17630 case DRX_CONSTELLATION_QAM128
:
17631 case DRX_CONSTELLATION_QAM32
:
17632 case DRX_CONSTELLATION_QAM16
:
17637 sig_quality
->indicator
=
17638 mer2indicator(sig_quality
->MER
, min_mer
, threshold_mer
,
17643 case DRX_STANDARD_PAL_SECAM_BG
:
17644 case DRX_STANDARD_PAL_SECAM_DK
:
17645 case DRX_STANDARD_PAL_SECAM_I
:
17646 case DRX_STANDARD_PAL_SECAM_L
:
17647 case DRX_STANDARD_PAL_SECAM_LP
:
17648 case DRX_STANDARD_NTSC
:
17649 rc
= atv_sig_quality(demod
, sig_quality
);
17651 pr_err("error %d\n", rc
);
17655 case DRX_STANDARD_FM
:
17656 rc
= fm_sig_quality(demod
, sig_quality
);
17658 pr_err("error %d\n", rc
);
17672 /*============================================================================*/
17675 * \fn int ctrl_lock_status()
17676 * \brief Retreive lock status .
17677 * \param dev_addr Pointer to demodulator device address.
17678 * \param lock_stat Pointer to lock status structure.
17683 ctrl_lock_status(struct drx_demod_instance
*demod
, enum drx_lock_status
*lock_stat
)
17685 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
17686 struct drxj_data
*ext_attr
= NULL
;
17687 struct i2c_device_addr
*dev_addr
= NULL
;
17688 struct drxjscu_cmd cmd_scu
= { /* command */ 0,
17689 /* parameter_len */ 0,
17690 /* result_len */ 0,
17691 /* *parameter */ NULL
,
17695 u16 cmd_result
[2] = { 0, 0 };
17696 u16 demod_lock
= SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED
;
17698 /* check arguments */
17699 if ((demod
== NULL
) || (lock_stat
== NULL
))
17702 dev_addr
= demod
->my_i2c_dev_addr
;
17703 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
17704 standard
= ext_attr
->standard
;
17706 *lock_stat
= DRX_NOT_LOCKED
;
17708 /* define the SCU command code */
17709 switch (standard
) {
17710 case DRX_STANDARD_8VSB
:
17711 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_VSB
|
17712 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK
;
17715 #ifndef DRXJ_VSB_ONLY
17716 case DRX_STANDARD_ITU_A
:
17717 case DRX_STANDARD_ITU_B
:
17718 case DRX_STANDARD_ITU_C
:
17719 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_QAM
|
17720 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK
;
17724 case DRX_STANDARD_NTSC
:
17725 case DRX_STANDARD_PAL_SECAM_BG
:
17726 case DRX_STANDARD_PAL_SECAM_DK
:
17727 case DRX_STANDARD_PAL_SECAM_I
:
17728 case DRX_STANDARD_PAL_SECAM_L
:
17729 case DRX_STANDARD_PAL_SECAM_LP
:
17730 cmd_scu
.command
= SCU_RAM_COMMAND_STANDARD_ATV
|
17731 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK
;
17733 case DRX_STANDARD_FM
:
17734 return fm_lock_status(demod
, lock_stat
);
17736 case DRX_STANDARD_UNKNOWN
: /* fallthrough */
17741 /* define the SCU command paramters and execute the command */
17742 cmd_scu
.parameter_len
= 0;
17743 cmd_scu
.result_len
= 2;
17744 cmd_scu
.parameter
= NULL
;
17745 cmd_scu
.result
= cmd_result
;
17746 rc
= scu_command(dev_addr
, &cmd_scu
);
17748 pr_err("error %d\n", rc
);
17752 /* set the lock status */
17753 if (cmd_scu
.result
[1] < demod_lock
) {
17754 /* 0x0000 NOT LOCKED */
17755 *lock_stat
= DRX_NOT_LOCKED
;
17756 } else if (cmd_scu
.result
[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED
) {
17757 *lock_stat
= DRXJ_DEMOD_LOCK
;
17758 } else if (cmd_scu
.result
[1] <
17759 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK
) {
17760 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
17761 *lock_stat
= DRX_LOCKED
;
17763 /* 0xC000 NEVER LOCKED */
17764 /* (system will never be able to lock to the signal) */
17765 *lock_stat
= DRX_NEVER_LOCK
;
17773 /*============================================================================*/
17777 * \fn int ctrl_constel()
17778 * \brief Retreive a constellation point via I2C.
17779 * \param demod Pointer to demodulator instance.
17780 * \param complex_nr Pointer to the structure in which to store the
17781 constellation point.
17785 ctrl_constel(struct drx_demod_instance
*demod
, struct drx_complex
*complex_nr
)
17788 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
17789 /**< active standard */
17791 /* check arguments */
17792 if ((demod
== NULL
) || (complex_nr
== NULL
))
17795 /* read device info */
17796 standard
= ((struct drxj_data
*) demod
->my_ext_attr
)->standard
;
17798 /* Read constellation point */
17799 switch (standard
) {
17800 case DRX_STANDARD_8VSB
:
17801 rc
= ctrl_get_vsb_constel(demod
, complex_nr
);
17803 pr_err("error %d\n", rc
);
17807 #ifndef DRXJ_VSB_ONLY
17808 case DRX_STANDARD_ITU_A
: /* fallthrough */
17809 case DRX_STANDARD_ITU_B
: /* fallthrough */
17810 case DRX_STANDARD_ITU_C
:
17811 rc
= ctrl_get_qam_constel(demod
, complex_nr
);
17813 pr_err("error %d\n", rc
);
17818 case DRX_STANDARD_UNKNOWN
:
17829 /*============================================================================*/
17832 * \fn int ctrl_set_standard()
17833 * \brief Set modulation standard to be used.
17834 * \param standard Modulation standard.
17837 * Setup stuff for the desired demodulation standard.
17838 * Disable and power down the previous selected demodulation standard
17842 ctrl_set_standard(struct drx_demod_instance
*demod
, enum drx_standard
*standard
)
17844 struct drxj_data
*ext_attr
= NULL
;
17846 enum drx_standard prev_standard
;
17848 /* check arguments */
17849 if ((standard
== NULL
) || (demod
== NULL
))
17852 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
17853 prev_standard
= ext_attr
->standard
;
17856 Stop and power down previous standard
17858 switch (prev_standard
) {
17859 #ifndef DRXJ_VSB_ONLY
17860 case DRX_STANDARD_ITU_A
: /* fallthrough */
17861 case DRX_STANDARD_ITU_B
: /* fallthrough */
17862 case DRX_STANDARD_ITU_C
:
17863 rc
= power_down_qam(demod
, false);
17865 pr_err("error %d\n", rc
);
17870 case DRX_STANDARD_8VSB
:
17871 rc
= power_down_vsb(demod
, false);
17873 pr_err("error %d\n", rc
);
17878 case DRX_STANDARD_NTSC
: /* fallthrough */
17879 case DRX_STANDARD_FM
: /* fallthrough */
17880 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
17881 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
17882 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
17883 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
17884 case DRX_STANDARD_PAL_SECAM_LP
:
17885 rc
= power_down_atv(demod
, prev_standard
, false);
17887 pr_err("error %d\n", rc
);
17892 case DRX_STANDARD_UNKNOWN
:
17895 case DRX_STANDARD_AUTO
: /* fallthrough */
17901 Initialize channel independent registers
17902 Power up new standard
17904 ext_attr
->standard
= *standard
;
17906 switch (*standard
) {
17907 #ifndef DRXJ_VSB_ONLY
17908 case DRX_STANDARD_ITU_A
: /* fallthrough */
17909 case DRX_STANDARD_ITU_B
: /* fallthrough */
17910 case DRX_STANDARD_ITU_C
:
17913 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_VERSION_HI__A
, &dummy
, 0);
17915 pr_err("error %d\n", rc
);
17921 case DRX_STANDARD_8VSB
:
17922 rc
= set_vsb_leak_n_gain(demod
);
17924 pr_err("error %d\n", rc
);
17929 case DRX_STANDARD_NTSC
: /* fallthrough */
17930 case DRX_STANDARD_FM
: /* fallthrough */
17931 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
17932 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
17933 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
17934 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
17935 case DRX_STANDARD_PAL_SECAM_LP
:
17936 rc
= set_atv_standard(demod
, standard
);
17938 pr_err("error %d\n", rc
);
17941 rc
= power_up_atv(demod
, *standard
);
17943 pr_err("error %d\n", rc
);
17949 ext_attr
->standard
= DRX_STANDARD_UNKNOWN
;
17956 /* Don't know what the standard is now ... try again */
17957 ext_attr
->standard
= DRX_STANDARD_UNKNOWN
;
17962 /*============================================================================*/
17965 * \fn int ctrl_get_standard()
17966 * \brief Get modulation standard currently used to demodulate.
17967 * \param standard Modulation standard.
17970 * Returns 8VSB, NTSC, QAM only.
17974 ctrl_get_standard(struct drx_demod_instance
*demod
, enum drx_standard
*standard
)
17976 struct drxj_data
*ext_attr
= NULL
;
17978 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
17980 /* check arguments */
17981 if (standard
== NULL
)
17984 *standard
= ext_attr
->standard
;
17987 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_VERSION_HI__A
, &dummy
, 0);
17989 pr_err("error %d\n", rc
);
17999 /*============================================================================*/
18002 * \fn int ctrl_get_cfg_symbol_clock_offset()
18003 * \brief Get frequency offsets of STR.
18004 * \param pointer to s32.
18009 ctrl_get_cfg_symbol_clock_offset(struct drx_demod_instance
*demod
, s32
*rate_offset
)
18011 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
18013 struct drxj_data
*ext_attr
= NULL
;
18015 /* check arguments */
18016 if (rate_offset
== NULL
)
18019 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
18020 standard
= ext_attr
->standard
;
18022 switch (standard
) {
18023 case DRX_STANDARD_8VSB
: /* fallthrough */
18024 #ifndef DRXJ_VSB_ONLY
18025 case DRX_STANDARD_ITU_A
: /* fallthrough */
18026 case DRX_STANDARD_ITU_B
: /* fallthrough */
18027 case DRX_STANDARD_ITU_C
:
18029 rc
= get_str_freq_offset(demod
, rate_offset
);
18031 pr_err("error %d\n", rc
);
18035 case DRX_STANDARD_NTSC
:
18036 case DRX_STANDARD_UNKNOWN
:
18047 /*============================================================================*/
18049 static void drxj_reset_mode(struct drxj_data
*ext_attr
)
18051 /* Initialize default AFE configuartion for QAM */
18052 if (ext_attr
->has_lna
) {
18053 /* IF AGC off, PGA active */
18054 #ifndef DRXJ_VSB_ONLY
18055 ext_attr
->qam_if_agc_cfg
.standard
= DRX_STANDARD_ITU_B
;
18056 ext_attr
->qam_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_OFF
;
18057 ext_attr
->qam_pga_cfg
= 140 + (11 * 13);
18059 ext_attr
->vsb_if_agc_cfg
.standard
= DRX_STANDARD_8VSB
;
18060 ext_attr
->vsb_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_OFF
;
18061 ext_attr
->vsb_pga_cfg
= 140 + (11 * 13);
18063 /* IF AGC on, PGA not active */
18064 #ifndef DRXJ_VSB_ONLY
18065 ext_attr
->qam_if_agc_cfg
.standard
= DRX_STANDARD_ITU_B
;
18066 ext_attr
->qam_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
18067 ext_attr
->qam_if_agc_cfg
.min_output_level
= 0;
18068 ext_attr
->qam_if_agc_cfg
.max_output_level
= 0x7FFF;
18069 ext_attr
->qam_if_agc_cfg
.speed
= 3;
18070 ext_attr
->qam_if_agc_cfg
.top
= 1297;
18071 ext_attr
->qam_pga_cfg
= 140;
18073 ext_attr
->vsb_if_agc_cfg
.standard
= DRX_STANDARD_8VSB
;
18074 ext_attr
->vsb_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
18075 ext_attr
->vsb_if_agc_cfg
.min_output_level
= 0;
18076 ext_attr
->vsb_if_agc_cfg
.max_output_level
= 0x7FFF;
18077 ext_attr
->vsb_if_agc_cfg
.speed
= 3;
18078 ext_attr
->vsb_if_agc_cfg
.top
= 1024;
18079 ext_attr
->vsb_pga_cfg
= 140;
18081 /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
18082 /* mc has not used them */
18083 #ifndef DRXJ_VSB_ONLY
18084 ext_attr
->qam_rf_agc_cfg
.standard
= DRX_STANDARD_ITU_B
;
18085 ext_attr
->qam_rf_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
18086 ext_attr
->qam_rf_agc_cfg
.min_output_level
= 0;
18087 ext_attr
->qam_rf_agc_cfg
.max_output_level
= 0x7FFF;
18088 ext_attr
->qam_rf_agc_cfg
.speed
= 3;
18089 ext_attr
->qam_rf_agc_cfg
.top
= 9500;
18090 ext_attr
->qam_rf_agc_cfg
.cut_off_current
= 4000;
18091 ext_attr
->qam_pre_saw_cfg
.standard
= DRX_STANDARD_ITU_B
;
18092 ext_attr
->qam_pre_saw_cfg
.reference
= 0x07;
18093 ext_attr
->qam_pre_saw_cfg
.use_pre_saw
= true;
18095 /* Initialize default AFE configuartion for VSB */
18096 ext_attr
->vsb_rf_agc_cfg
.standard
= DRX_STANDARD_8VSB
;
18097 ext_attr
->vsb_rf_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
18098 ext_attr
->vsb_rf_agc_cfg
.min_output_level
= 0;
18099 ext_attr
->vsb_rf_agc_cfg
.max_output_level
= 0x7FFF;
18100 ext_attr
->vsb_rf_agc_cfg
.speed
= 3;
18101 ext_attr
->vsb_rf_agc_cfg
.top
= 9500;
18102 ext_attr
->vsb_rf_agc_cfg
.cut_off_current
= 4000;
18103 ext_attr
->vsb_pre_saw_cfg
.standard
= DRX_STANDARD_8VSB
;
18104 ext_attr
->vsb_pre_saw_cfg
.reference
= 0x07;
18105 ext_attr
->vsb_pre_saw_cfg
.use_pre_saw
= true;
18108 /* Initialize default AFE configuartion for ATV */
18109 ext_attr
->atv_rf_agc_cfg
.standard
= DRX_STANDARD_NTSC
;
18110 ext_attr
->atv_rf_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
18111 ext_attr
->atv_rf_agc_cfg
.top
= 9500;
18112 ext_attr
->atv_rf_agc_cfg
.cut_off_current
= 4000;
18113 ext_attr
->atv_rf_agc_cfg
.speed
= 3;
18114 ext_attr
->atv_if_agc_cfg
.standard
= DRX_STANDARD_NTSC
;
18115 ext_attr
->atv_if_agc_cfg
.ctrl_mode
= DRX_AGC_CTRL_AUTO
;
18116 ext_attr
->atv_if_agc_cfg
.speed
= 3;
18117 ext_attr
->atv_if_agc_cfg
.top
= 2400;
18118 ext_attr
->atv_pre_saw_cfg
.reference
= 0x0007;
18119 ext_attr
->atv_pre_saw_cfg
.use_pre_saw
= true;
18120 ext_attr
->atv_pre_saw_cfg
.standard
= DRX_STANDARD_NTSC
;
18125 * \fn int ctrl_power_mode()
18126 * \brief Set the power mode of the device to the specified power mode
18127 * \param demod Pointer to demodulator instance.
18128 * \param mode Pointer to new power mode.
18130 * \retval 0 Success
18131 * \retval -EIO I2C error or other failure
18132 * \retval -EINVAL Invalid mode argument.
18137 ctrl_power_mode(struct drx_demod_instance
*demod
, enum drx_power_mode
*mode
)
18139 struct drx_common_attr
*common_attr
= (struct drx_common_attr
*) NULL
;
18140 struct drxj_data
*ext_attr
= (struct drxj_data
*) NULL
;
18141 struct i2c_device_addr
*dev_addr
= (struct i2c_device_addr
*)NULL
;
18143 u16 sio_cc_pwd_mode
= 0;
18145 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
18146 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
18147 dev_addr
= demod
->my_i2c_dev_addr
;
18149 /* Check arguments */
18153 /* If already in requested power mode, do nothing */
18154 if (common_attr
->current_power_mode
== *mode
)
18159 case DRXJ_POWER_DOWN_MAIN_PATH
:
18160 sio_cc_pwd_mode
= SIO_CC_PWD_MODE_LEVEL_NONE
;
18162 case DRXJ_POWER_DOWN_CORE
:
18163 sio_cc_pwd_mode
= SIO_CC_PWD_MODE_LEVEL_CLOCK
;
18165 case DRXJ_POWER_DOWN_PLL
:
18166 sio_cc_pwd_mode
= SIO_CC_PWD_MODE_LEVEL_PLL
;
18168 case DRX_POWER_DOWN
:
18169 sio_cc_pwd_mode
= SIO_CC_PWD_MODE_LEVEL_OSC
;
18172 /* Unknow sleep mode */
18177 /* Check if device needs to be powered up */
18178 if ((common_attr
->current_power_mode
!= DRX_POWER_UP
)) {
18179 rc
= power_up_device(demod
);
18181 pr_err("error %d\n", rc
);
18186 if ((*mode
== DRX_POWER_UP
)) {
18187 /* Restore analog & pin configuartion */
18189 /* Initialize default AFE configuartion for VSB */
18190 drxj_reset_mode(ext_attr
);
18192 /* Power down to requested mode */
18193 /* Backup some register settings */
18194 /* Set pins with possible pull-ups connected to them in input mode */
18195 /* Analog power down */
18196 /* ADC power down */
18197 /* Power down device */
18198 /* stop all comm_exec */
18200 Stop and power down previous standard
18203 switch (ext_attr
->standard
) {
18204 case DRX_STANDARD_ITU_A
:
18205 case DRX_STANDARD_ITU_B
:
18206 case DRX_STANDARD_ITU_C
:
18207 rc
= power_down_qam(demod
, true);
18209 pr_err("error %d\n", rc
);
18213 case DRX_STANDARD_8VSB
:
18214 rc
= power_down_vsb(demod
, true);
18216 pr_err("error %d\n", rc
);
18220 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
18221 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
18222 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
18223 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
18224 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
18225 case DRX_STANDARD_NTSC
: /* fallthrough */
18226 case DRX_STANDARD_FM
:
18227 rc
= power_down_atv(demod
, ext_attr
->standard
, true);
18229 pr_err("error %d\n", rc
);
18233 case DRX_STANDARD_UNKNOWN
:
18236 case DRX_STANDARD_AUTO
: /* fallthrough */
18241 if (*mode
!= DRXJ_POWER_DOWN_MAIN_PATH
) {
18242 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_CC_PWD_MODE__A
, sio_cc_pwd_mode
, 0);
18244 pr_err("error %d\n", rc
);
18247 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_CC_UPDATE__A
, SIO_CC_UPDATE_KEY
, 0);
18249 pr_err("error %d\n", rc
);
18253 /* Initialize HI, wakeup key especially before put IC to sleep */
18254 rc
= init_hi(demod
);
18256 pr_err("error %d\n", rc
);
18260 ext_attr
->hi_cfg_ctrl
|= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ
;
18261 rc
= hi_cfg_command(demod
);
18263 pr_err("error %d\n", rc
);
18267 ext_attr
->standard
= DRX_STANDARD_UNKNOWN
;
18270 common_attr
->current_power_mode
= *mode
;
18278 /*============================================================================*/
18281 * \fn int ctrl_probe_device()
18282 * \brief Probe device, check if it is present
18283 * \param demod Pointer to demodulator instance.
18285 * \retval 0 a drx39xxj device has been detected.
18286 * \retval -EIO no drx39xxj device detected.
18288 * This funtion can be caled before open() and after close().
18292 static int ctrl_probe_device(struct drx_demod_instance
*demod
)
18294 enum drx_power_mode org_power_mode
= DRX_POWER_UP
;
18295 int ret_status
= 0;
18296 struct drx_common_attr
*common_attr
= (struct drx_common_attr
*) (NULL
);
18299 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
18301 if (common_attr
->is_opened
== false
18302 || common_attr
->current_power_mode
!= DRX_POWER_UP
) {
18303 struct i2c_device_addr
*dev_addr
= NULL
;
18304 enum drx_power_mode power_mode
= DRX_POWER_UP
;
18307 dev_addr
= demod
->my_i2c_dev_addr
;
18309 /* Remeber original power mode */
18310 org_power_mode
= common_attr
->current_power_mode
;
18312 if (demod
->my_common_attr
->is_opened
== false) {
18313 rc
= power_up_device(demod
);
18315 pr_err("error %d\n", rc
);
18318 common_attr
->current_power_mode
= DRX_POWER_UP
;
18320 /* Wake-up device, feedback from device */
18321 rc
= ctrl_power_mode(demod
, &power_mode
);
18323 pr_err("error %d\n", rc
);
18327 /* Initialize HI, wakeup key especially */
18328 rc
= init_hi(demod
);
18330 pr_err("error %d\n", rc
);
18334 /* Check device id */
18335 rc
= DRXJ_DAP
.read_reg32func(dev_addr
, SIO_TOP_JTAGID_LO__A
, &jtag
, 0);
18337 pr_err("error %d\n", rc
);
18340 jtag
= (jtag
>> 12) & 0xFFFF;
18342 case 0x3931: /* fallthrough */
18343 case 0x3932: /* fallthrough */
18344 case 0x3933: /* fallthrough */
18345 case 0x3934: /* fallthrough */
18346 case 0x3941: /* fallthrough */
18347 case 0x3942: /* fallthrough */
18348 case 0x3943: /* fallthrough */
18349 case 0x3944: /* fallthrough */
18350 case 0x3945: /* fallthrough */
18352 /* ok , do nothing */
18359 /* Device was not opened, return to orginal powermode,
18360 feedback from device */
18361 rc
= ctrl_power_mode(demod
, &org_power_mode
);
18363 pr_err("error %d\n", rc
);
18367 /* dummy read to make this function fail in case device
18368 suddenly disappears after a succesful drx_open */
18371 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_VERSION_HI__A
, &dummy
, 0);
18373 pr_err("error %d\n", rc
);
18382 common_attr
->current_power_mode
= org_power_mode
;
18387 /*============================================================================*/
18388 /*== CTRL Set/Get Config related functions ===================================*/
18389 /*============================================================================*/
18392 /*===== SigStrength() =========================================================*/
18394 * \fn int ctrl_sig_strength()
18395 * \brief Retrieve signal strength.
18396 * \param devmod Pointer to demodulator instance.
18397 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
18399 * \retval 0 sig_strength contains valid data.
18400 * \retval -EINVAL sig_strength is NULL.
18401 * \retval -EIO Erroneous data, sig_strength contains invalid data.
18405 ctrl_sig_strength(struct drx_demod_instance
*demod
, u16
*sig_strength
)
18407 struct drxj_data
*ext_attr
= NULL
;
18408 enum drx_standard standard
= DRX_STANDARD_UNKNOWN
;
18411 /* Check arguments */
18412 if ((sig_strength
== NULL
) || (demod
== NULL
))
18415 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
18416 standard
= ext_attr
->standard
;
18419 /* Signal strength indication for each standard */
18420 switch (standard
) {
18421 case DRX_STANDARD_8VSB
: /* fallthrough */
18422 #ifndef DRXJ_VSB_ONLY
18423 case DRX_STANDARD_ITU_A
: /* fallthrough */
18424 case DRX_STANDARD_ITU_B
: /* fallthrough */
18425 case DRX_STANDARD_ITU_C
:
18427 rc
= get_sig_strength(demod
, sig_strength
);
18429 pr_err("error %d\n", rc
);
18433 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
18434 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
18435 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
18436 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
18437 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
18438 case DRX_STANDARD_NTSC
: /* fallthrough */
18439 case DRX_STANDARD_FM
:
18440 rc
= get_atv_sig_strength(demod
, sig_strength
);
18442 pr_err("error %d\n", rc
);
18446 case DRX_STANDARD_UNKNOWN
: /* fallthrough */
18452 /* find out if signal strength is calculated in the same way for all standards */
18458 /*============================================================================*/
18460 * \fn int ctrl_get_cfg_oob_misc()
18461 * \brief Get current state information of OOB.
18462 * \param pointer to struct drxj_cfg_oob_misc.
18467 ctrl_get_cfg_oob_misc(struct drx_demod_instance
*demod
, struct drxj_cfg_oob_misc
*misc
)
18469 struct i2c_device_addr
*dev_addr
= NULL
;
18474 u16 digital_agc_mant
= 0U;
18475 u16 digital_agc_exp
= 0U;
18477 /* check arguments */
18481 dev_addr
= demod
->my_i2c_dev_addr
;
18484 /* check if the same registers are used for all standards (QAM/VSB/ATV) */
18485 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_NSU_TUN_IFGAIN_W__A
, &misc
->agc
.IFAGC
, 0);
18487 pr_err("error %d\n", rc
);
18490 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_NSU_TUN_RFGAIN_W__A
, &misc
->agc
.RFAGC
, 0);
18492 pr_err("error %d\n", rc
);
18495 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, ORX_FWP_SRC_DGN_W__A
, &data
, 0);
18497 pr_err("error %d\n", rc
);
18501 digital_agc_mant
= data
& ORX_FWP_SRC_DGN_W_MANT__M
;
18502 digital_agc_exp
= (data
& ORX_FWP_SRC_DGN_W_EXP__M
)
18503 >> ORX_FWP_SRC_DGN_W_EXP__B
;
18504 misc
->agc
.digital_agc
= digital_agc_mant
<< digital_agc_exp
;
18506 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ORX_SCU_LOCK__A
, &lock
, 0);
18508 pr_err("error %d\n", rc
);
18512 misc
->ana_gain_lock
= ((lock
& 0x0001) ? true : false);
18513 misc
->dig_gain_lock
= ((lock
& 0x0002) ? true : false);
18514 misc
->freq_lock
= ((lock
& 0x0004) ? true : false);
18515 misc
->phase_lock
= ((lock
& 0x0008) ? true : false);
18516 misc
->sym_timing_lock
= ((lock
& 0x0010) ? true : false);
18517 misc
->eq_lock
= ((lock
& 0x0020) ? true : false);
18519 rc
= drxj_dap_scu_atomic_read_reg16(dev_addr
, SCU_RAM_ORX_SCU_STATE__A
, &state
, 0);
18521 pr_err("error %d\n", rc
);
18524 misc
->state
= (state
>> 8) & 0xff;
18532 * \fn int ctrl_get_cfg_vsb_misc()
18533 * \brief Get current state information of OOB.
18534 * \param pointer to struct drxj_cfg_oob_misc.
18539 ctrl_get_cfg_vsb_misc(struct drx_demod_instance
*demod
, struct drxj_cfg_vsb_misc
*misc
)
18541 struct i2c_device_addr
*dev_addr
= NULL
;
18544 /* check arguments */
18548 dev_addr
= demod
->my_i2c_dev_addr
;
18550 rc
= get_vsb_symb_err(dev_addr
, &misc
->symb_error
);
18552 pr_err("error %d\n", rc
);
18561 /*============================================================================*/
18564 * \fn int ctrl_set_cfg_agc_if()
18565 * \brief Set IF AGC.
18566 * \param demod demod instance
18567 * \param agc_settings If agc configuration
18571 * Dispatch handling to standard specific function.
18575 ctrl_set_cfg_agc_if(struct drx_demod_instance
*demod
, struct drxj_cfg_agc
*agc_settings
)
18577 /* check arguments */
18578 if (agc_settings
== NULL
)
18581 switch (agc_settings
->ctrl_mode
) {
18582 case DRX_AGC_CTRL_AUTO
: /* fallthrough */
18583 case DRX_AGC_CTRL_USER
: /* fallthrough */
18584 case DRX_AGC_CTRL_OFF
: /* fallthrough */
18591 switch (agc_settings
->standard
) {
18592 case DRX_STANDARD_8VSB
: /* fallthrough */
18593 #ifndef DRXJ_VSB_ONLY
18594 case DRX_STANDARD_ITU_A
: /* fallthrough */
18595 case DRX_STANDARD_ITU_B
: /* fallthrough */
18596 case DRX_STANDARD_ITU_C
:
18599 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
18600 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
18601 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
18602 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
18603 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
18604 case DRX_STANDARD_NTSC
: /* fallthrough */
18605 case DRX_STANDARD_FM
:
18607 return set_agc_if(demod
, agc_settings
, true);
18608 case DRX_STANDARD_UNKNOWN
:
18616 /*============================================================================*/
18619 * \fn int ctrl_get_cfg_agc_if()
18620 * \brief Retrieve IF AGC settings.
18621 * \param demod demod instance
18622 * \param agc_settings If agc configuration
18626 * Dispatch handling to standard specific function.
18630 ctrl_get_cfg_agc_if(struct drx_demod_instance
*demod
, struct drxj_cfg_agc
*agc_settings
)
18632 /* check arguments */
18633 if (agc_settings
== NULL
)
18637 switch (agc_settings
->standard
) {
18638 case DRX_STANDARD_8VSB
: /* fallthrough */
18639 #ifndef DRXJ_VSB_ONLY
18640 case DRX_STANDARD_ITU_A
: /* fallthrough */
18641 case DRX_STANDARD_ITU_B
: /* fallthrough */
18642 case DRX_STANDARD_ITU_C
:
18645 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
18646 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
18647 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
18648 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
18649 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
18650 case DRX_STANDARD_NTSC
: /* fallthrough */
18651 case DRX_STANDARD_FM
:
18653 return get_agc_if(demod
, agc_settings
);
18654 case DRX_STANDARD_UNKNOWN
:
18662 /*============================================================================*/
18665 * \fn int ctrl_set_cfg_agc_rf()
18666 * \brief Set RF AGC.
18667 * \param demod demod instance
18668 * \param agc_settings rf agc configuration
18672 * Dispatch handling to standard specific function.
18676 ctrl_set_cfg_agc_rf(struct drx_demod_instance
*demod
, struct drxj_cfg_agc
*agc_settings
)
18678 /* check arguments */
18679 if (agc_settings
== NULL
)
18682 switch (agc_settings
->ctrl_mode
) {
18683 case DRX_AGC_CTRL_AUTO
: /* fallthrough */
18684 case DRX_AGC_CTRL_USER
: /* fallthrough */
18685 case DRX_AGC_CTRL_OFF
:
18692 switch (agc_settings
->standard
) {
18693 case DRX_STANDARD_8VSB
: /* fallthrough */
18694 #ifndef DRXJ_VSB_ONLY
18695 case DRX_STANDARD_ITU_A
: /* fallthrough */
18696 case DRX_STANDARD_ITU_B
: /* fallthrough */
18697 case DRX_STANDARD_ITU_C
:
18699 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
18700 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
18701 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
18702 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
18703 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
18704 case DRX_STANDARD_NTSC
: /* fallthrough */
18705 case DRX_STANDARD_FM
:
18706 return set_agc_rf(demod
, agc_settings
, true);
18707 case DRX_STANDARD_UNKNOWN
:
18715 /*============================================================================*/
18718 * \fn int ctrl_get_cfg_agc_rf()
18719 * \brief Retrieve RF AGC settings.
18720 * \param demod demod instance
18721 * \param agc_settings Rf agc configuration
18725 * Dispatch handling to standard specific function.
18729 ctrl_get_cfg_agc_rf(struct drx_demod_instance
*demod
, struct drxj_cfg_agc
*agc_settings
)
18731 /* check arguments */
18732 if (agc_settings
== NULL
)
18736 switch (agc_settings
->standard
) {
18737 case DRX_STANDARD_8VSB
: /* fallthrough */
18738 #ifndef DRXJ_VSB_ONLY
18739 case DRX_STANDARD_ITU_A
: /* fallthrough */
18740 case DRX_STANDARD_ITU_B
: /* fallthrough */
18741 case DRX_STANDARD_ITU_C
:
18743 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
18744 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
18745 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
18746 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
18747 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
18748 case DRX_STANDARD_NTSC
: /* fallthrough */
18749 case DRX_STANDARD_FM
:
18750 return get_agc_rf(demod
, agc_settings
);
18751 case DRX_STANDARD_UNKNOWN
:
18759 /*============================================================================*/
18762 * \fn int ctrl_get_cfg_agc_internal()
18763 * \brief Retrieve internal AGC value.
18764 * \param demod demod instance
18769 * Dispatch handling to standard specific function.
18773 ctrl_get_cfg_agc_internal(struct drx_demod_instance
*demod
, u16
*agc_internal
)
18775 struct i2c_device_addr
*dev_addr
= NULL
;
18777 enum drx_lock_status lock_status
= DRX_NOT_LOCKED
;
18778 struct drxj_data
*ext_attr
= NULL
;
18779 u16 iqm_cf_scale_sh
= 0;
18780 u16 iqm_cf_power
= 0;
18781 u16 iqm_cf_amp
= 0;
18782 u16 iqm_cf_gain
= 0;
18784 /* check arguments */
18785 if (agc_internal
== NULL
)
18787 dev_addr
= demod
->my_i2c_dev_addr
;
18788 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
18790 rc
= ctrl_lock_status(demod
, &lock_status
);
18792 pr_err("error %d\n", rc
);
18795 if (lock_status
!= DRXJ_DEMOD_LOCK
&& lock_status
!= DRX_LOCKED
) {
18801 switch (ext_attr
->standard
) {
18802 case DRX_STANDARD_8VSB
:
18805 #ifndef DRXJ_VSB_ONLY
18806 case DRX_STANDARD_ITU_A
:
18807 case DRX_STANDARD_ITU_B
:
18808 case DRX_STANDARD_ITU_C
:
18809 switch (ext_attr
->constellation
) {
18810 case DRX_CONSTELLATION_QAM256
:
18811 case DRX_CONSTELLATION_QAM128
:
18812 case DRX_CONSTELLATION_QAM32
:
18813 case DRX_CONSTELLATION_QAM16
:
18816 case DRX_CONSTELLATION_QAM64
:
18828 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_CF_POW__A
, &iqm_cf_power
, 0);
18830 pr_err("error %d\n", rc
);
18833 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_CF_SCALE_SH__A
, &iqm_cf_scale_sh
, 0);
18835 pr_err("error %d\n", rc
);
18838 rc
= DRXJ_DAP
.read_reg16func(dev_addr
, IQM_CF_AMP__A
, &iqm_cf_amp
, 0);
18840 pr_err("error %d\n", rc
);
18843 /* IQM_CF_PWR_CORRECTION_dB = 3;
18844 P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
18845 /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
18846 -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
18847 +6*7+10*log10(1+0.115/4); */
18848 /* PadcdB = P4dB +3 -6 +60; dBmV */
18849 *agc_internal
= (u16
) (log1_times100(iqm_cf_power
)
18850 - 2 * log1_times100(iqm_cf_amp
)
18851 - iqm_cf_gain
- 120 * iqm_cf_scale_sh
+ 781);
18858 /*============================================================================*/
18862 * \fn int ctrl_set_cfg_pre_saw()
18863 * \brief Set Pre-saw reference.
18864 * \param demod demod instance
18869 * Dispatch handling to standard specific function.
18873 ctrl_set_cfg_pre_saw(struct drx_demod_instance
*demod
, struct drxj_cfg_pre_saw
*pre_saw
)
18875 struct i2c_device_addr
*dev_addr
= NULL
;
18876 struct drxj_data
*ext_attr
= NULL
;
18879 dev_addr
= demod
->my_i2c_dev_addr
;
18880 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
18882 /* check arguments */
18883 if ((pre_saw
== NULL
) || (pre_saw
->reference
> IQM_AF_PDREF__M
)
18888 /* Only if standard is currently active */
18889 if ((ext_attr
->standard
== pre_saw
->standard
) ||
18890 (DRXJ_ISQAMSTD(ext_attr
->standard
) &&
18891 DRXJ_ISQAMSTD(pre_saw
->standard
)) ||
18892 (DRXJ_ISATVSTD(ext_attr
->standard
) &&
18893 DRXJ_ISATVSTD(pre_saw
->standard
))) {
18894 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_PDREF__A
, pre_saw
->reference
, 0);
18896 pr_err("error %d\n", rc
);
18901 /* Store pre-saw settings */
18902 switch (pre_saw
->standard
) {
18903 case DRX_STANDARD_8VSB
:
18904 ext_attr
->vsb_pre_saw_cfg
= *pre_saw
;
18906 #ifndef DRXJ_VSB_ONLY
18907 case DRX_STANDARD_ITU_A
: /* fallthrough */
18908 case DRX_STANDARD_ITU_B
: /* fallthrough */
18909 case DRX_STANDARD_ITU_C
:
18910 ext_attr
->qam_pre_saw_cfg
= *pre_saw
;
18914 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
18915 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
18916 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
18917 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
18918 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
18919 case DRX_STANDARD_NTSC
: /* fallthrough */
18920 case DRX_STANDARD_FM
:
18921 ext_attr
->atv_pre_saw_cfg
= *pre_saw
;
18933 /*============================================================================*/
18936 * \fn int ctrl_set_cfg_afe_gain()
18937 * \brief Set AFE Gain.
18938 * \param demod demod instance
18943 * Dispatch handling to standard specific function.
18947 ctrl_set_cfg_afe_gain(struct drx_demod_instance
*demod
, struct drxj_cfg_afe_gain
*afe_gain
)
18949 struct i2c_device_addr
*dev_addr
= NULL
;
18950 struct drxj_data
*ext_attr
= NULL
;
18954 /* check arguments */
18955 if (afe_gain
== NULL
)
18958 dev_addr
= demod
->my_i2c_dev_addr
;
18959 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
18961 switch (afe_gain
->standard
) {
18962 case DRX_STANDARD_8VSB
: /* fallthrough */
18963 #ifndef DRXJ_VSB_ONLY
18964 case DRX_STANDARD_ITU_A
: /* fallthrough */
18965 case DRX_STANDARD_ITU_B
: /* fallthrough */
18966 case DRX_STANDARD_ITU_C
:
18974 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
18975 So I (PJ) think interface requires choice between auto, user mode */
18977 if (afe_gain
->gain
>= 329)
18979 else if (afe_gain
->gain
<= 147)
18982 gain
= (afe_gain
->gain
- 140 + 6) / 13;
18984 /* Only if standard is currently active */
18985 if (ext_attr
->standard
== afe_gain
->standard
) {
18986 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, IQM_AF_PGA_GAIN__A
, gain
, 0);
18988 pr_err("error %d\n", rc
);
18993 /* Store AFE Gain settings */
18994 switch (afe_gain
->standard
) {
18995 case DRX_STANDARD_8VSB
:
18996 ext_attr
->vsb_pga_cfg
= gain
* 13 + 140;
18998 #ifndef DRXJ_VSB_ONLY
18999 case DRX_STANDARD_ITU_A
: /* fallthrough */
19000 case DRX_STANDARD_ITU_B
: /* fallthrough */
19001 case DRX_STANDARD_ITU_C
:
19002 ext_attr
->qam_pga_cfg
= gain
* 13 + 140;
19014 /*============================================================================*/
19018 * \fn int ctrl_get_cfg_pre_saw()
19019 * \brief Get Pre-saw reference setting.
19020 * \param demod demod instance
19025 * Dispatch handling to standard specific function.
19029 ctrl_get_cfg_pre_saw(struct drx_demod_instance
*demod
, struct drxj_cfg_pre_saw
*pre_saw
)
19031 struct drxj_data
*ext_attr
= NULL
;
19033 /* check arguments */
19034 if (pre_saw
== NULL
)
19037 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
19039 switch (pre_saw
->standard
) {
19040 case DRX_STANDARD_8VSB
:
19041 *pre_saw
= ext_attr
->vsb_pre_saw_cfg
;
19043 #ifndef DRXJ_VSB_ONLY
19044 case DRX_STANDARD_ITU_A
: /* fallthrough */
19045 case DRX_STANDARD_ITU_B
: /* fallthrough */
19046 case DRX_STANDARD_ITU_C
:
19047 *pre_saw
= ext_attr
->qam_pre_saw_cfg
;
19050 case DRX_STANDARD_PAL_SECAM_BG
: /* fallthrough */
19051 case DRX_STANDARD_PAL_SECAM_DK
: /* fallthrough */
19052 case DRX_STANDARD_PAL_SECAM_I
: /* fallthrough */
19053 case DRX_STANDARD_PAL_SECAM_L
: /* fallthrough */
19054 case DRX_STANDARD_PAL_SECAM_LP
: /* fallthrough */
19055 case DRX_STANDARD_NTSC
:
19056 ext_attr
->atv_pre_saw_cfg
.standard
= DRX_STANDARD_NTSC
;
19057 *pre_saw
= ext_attr
->atv_pre_saw_cfg
;
19059 case DRX_STANDARD_FM
:
19060 ext_attr
->atv_pre_saw_cfg
.standard
= DRX_STANDARD_FM
;
19061 *pre_saw
= ext_attr
->atv_pre_saw_cfg
;
19071 /*============================================================================*/
19074 * \fn int ctrl_get_cfg_afe_gain()
19075 * \brief Get AFE Gain.
19076 * \param demod demod instance
19081 * Dispatch handling to standard specific function.
19085 ctrl_get_cfg_afe_gain(struct drx_demod_instance
*demod
, struct drxj_cfg_afe_gain
*afe_gain
)
19087 struct drxj_data
*ext_attr
= NULL
;
19089 /* check arguments */
19090 if (afe_gain
== NULL
)
19093 ext_attr
= demod
->my_ext_attr
;
19095 switch (afe_gain
->standard
) {
19096 case DRX_STANDARD_8VSB
:
19097 afe_gain
->gain
= ext_attr
->vsb_pga_cfg
;
19099 #ifndef DRXJ_VSB_ONLY
19100 case DRX_STANDARD_ITU_A
: /* fallthrough */
19101 case DRX_STANDARD_ITU_B
: /* fallthrough */
19102 case DRX_STANDARD_ITU_C
:
19103 afe_gain
->gain
= ext_attr
->qam_pga_cfg
;
19113 /*============================================================================*/
19116 * \fn int ctrl_get_fec_meas_seq_count()
19117 * \brief Get FEC measurement sequnce number.
19118 * \param demod demod instance
19123 * Dispatch handling to standard specific function.
19127 ctrl_get_fec_meas_seq_count(struct drx_demod_instance
*demod
, u16
*fec_meas_seq_count
)
19130 /* check arguments */
19131 if (fec_meas_seq_count
== NULL
)
19134 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_FEC_MEAS_COUNT__A
, fec_meas_seq_count
, 0);
19136 pr_err("error %d\n", rc
);
19145 /*============================================================================*/
19148 * \fn int ctrl_get_accum_cr_rs_cw_err()
19149 * \brief Get accumulative corrected RS codeword number.
19150 * \param demod demod instance
19155 * Dispatch handling to standard specific function.
19159 ctrl_get_accum_cr_rs_cw_err(struct drx_demod_instance
*demod
, u32
*accum_cr_rs_cw_err
)
19162 if (accum_cr_rs_cw_err
== NULL
)
19165 rc
= DRXJ_DAP
.read_reg32func(demod
->my_i2c_dev_addr
, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A
, accum_cr_rs_cw_err
, 0);
19167 pr_err("error %d\n", rc
);
19177 * \fn int ctrl_set_cfg()
19178 * \brief Set 'some' configuration of the device.
19179 * \param devmod Pointer to demodulator instance.
19180 * \param config Pointer to configuration parameters (type and data).
19184 static int ctrl_set_cfg(struct drx_demod_instance
*demod
, struct drx_cfg
*config
)
19188 if (config
== NULL
)
19193 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_VERSION_HI__A
, &dummy
, 0);
19195 pr_err("error %d\n", rc
);
19199 switch (config
->cfg_type
) {
19200 case DRX_CFG_MPEG_OUTPUT
:
19201 return ctrl_set_cfg_mpeg_output(demod
,
19202 (struct drx_cfg_mpeg_output
*) config
->
19204 case DRX_CFG_PINS_SAFE_MODE
:
19205 return ctrl_set_cfg_pdr_safe_mode(demod
, (bool *)config
->cfg_data
);
19206 case DRXJ_CFG_AGC_RF
:
19207 return ctrl_set_cfg_agc_rf(demod
, (struct drxj_cfg_agc
*) config
->cfg_data
);
19208 case DRXJ_CFG_AGC_IF
:
19209 return ctrl_set_cfg_agc_if(demod
, (struct drxj_cfg_agc
*) config
->cfg_data
);
19210 case DRXJ_CFG_PRE_SAW
:
19211 return ctrl_set_cfg_pre_saw(demod
,
19212 (struct drxj_cfg_pre_saw
*) config
->cfg_data
);
19213 case DRXJ_CFG_AFE_GAIN
:
19214 return ctrl_set_cfg_afe_gain(demod
,
19215 (struct drxj_cfg_afe_gain
*) config
->cfg_data
);
19216 case DRXJ_CFG_SMART_ANT
:
19217 return ctrl_set_cfg_smart_ant(demod
,
19218 (struct drxj_cfg_smart_ant
*) (config
->
19220 case DRXJ_CFG_RESET_PACKET_ERR
:
19221 return ctrl_set_cfg_reset_pkt_err(demod
);
19223 case DRXJ_CFG_OOB_PRE_SAW
:
19224 return ctrl_set_cfg_oob_pre_saw(demod
, (u16
*)(config
->cfg_data
));
19225 case DRXJ_CFG_OOB_LO_POW
:
19226 return ctrl_set_cfg_oob_lo_power(demod
,
19227 (enum drxj_cfg_oob_lo_power
*) (config
->
19229 case DRXJ_CFG_ATV_MISC
:
19230 return ctrl_set_cfg_atv_misc(demod
,
19231 (struct drxj_cfg_atv_misc
*) config
->cfg_data
);
19232 case DRXJ_CFG_ATV_EQU_COEF
:
19233 return ctrl_set_cfg_atv_equ_coef(demod
,
19234 (struct drxj_cfg_atv_equ_coef
*) config
->
19236 case DRXJ_CFG_ATV_OUTPUT
:
19237 return ctrl_set_cfg_atv_output(demod
,
19238 (struct drxj_cfg_atv_output
*) config
->
19241 case DRXJ_CFG_MPEG_OUTPUT_MISC
:
19242 return ctrl_set_cfg_mpeg_output_misc(demod
,
19243 (struct drxj_cfg_mpeg_output_misc
*)
19245 #ifndef DRXJ_EXCLUDE_AUDIO
19246 case DRX_CFG_AUD_VOLUME
:
19247 return aud_ctrl_set_cfg_volume(demod
,
19248 (struct drx_cfg_aud_volume
*) config
->
19250 case DRX_CFG_I2S_OUTPUT
:
19251 return aud_ctrl_set_cfg_output_i2s(demod
,
19252 (struct drx_cfg_i2s_output
*) config
->
19254 case DRX_CFG_AUD_AUTOSOUND
:
19255 return aud_ctr_setl_cfg_auto_sound(demod
, (enum drx_cfg_aud_auto_sound
*)
19257 case DRX_CFG_AUD_ASS_THRES
:
19258 return aud_ctrl_set_cfg_ass_thres(demod
, (struct drx_cfg_aud_ass_thres
*)
19260 case DRX_CFG_AUD_CARRIER
:
19261 return aud_ctrl_set_cfg_carrier(demod
,
19262 (struct drx_cfg_aud_carriers
*) config
->
19264 case DRX_CFG_AUD_DEVIATION
:
19265 return aud_ctrl_set_cfg_dev(demod
,
19266 (enum drx_cfg_aud_deviation
*) config
->
19268 case DRX_CFG_AUD_PRESCALE
:
19269 return aud_ctrl_set_cfg_prescale(demod
,
19270 (struct drx_cfg_aud_prescale
*) config
->
19272 case DRX_CFG_AUD_MIXER
:
19273 return aud_ctrl_set_cfg_mixer(demod
,
19274 (struct drx_cfg_aud_mixer
*) config
->cfg_data
);
19275 case DRX_CFG_AUD_AVSYNC
:
19276 return aud_ctrl_set_cfg_av_sync(demod
,
19277 (enum drx_cfg_aud_av_sync
*) config
->
19290 /*============================================================================*/
19293 * \fn int ctrl_get_cfg()
19294 * \brief Get 'some' configuration of the device.
19295 * \param devmod Pointer to demodulator instance.
19296 * \param config Pointer to configuration parameters (type and data).
19300 static int ctrl_get_cfg(struct drx_demod_instance
*demod
, struct drx_cfg
*config
)
19304 if (config
== NULL
)
19309 rc
= DRXJ_DAP
.read_reg16func(demod
->my_i2c_dev_addr
, SCU_RAM_VERSION_HI__A
, &dummy
, 0);
19311 pr_err("error %d\n", rc
);
19316 switch (config
->cfg_type
) {
19317 case DRX_CFG_MPEG_OUTPUT
:
19318 return ctrl_get_cfg_mpeg_output(demod
,
19319 (struct drx_cfg_mpeg_output
*) config
->
19321 case DRX_CFG_PINS_SAFE_MODE
:
19322 return ctrl_get_cfg_pdr_safe_mode(demod
, (bool *)config
->cfg_data
);
19323 case DRXJ_CFG_AGC_RF
:
19324 return ctrl_get_cfg_agc_rf(demod
, (struct drxj_cfg_agc
*) config
->cfg_data
);
19325 case DRXJ_CFG_AGC_IF
:
19326 return ctrl_get_cfg_agc_if(demod
, (struct drxj_cfg_agc
*) config
->cfg_data
);
19327 case DRXJ_CFG_AGC_INTERNAL
:
19328 return ctrl_get_cfg_agc_internal(demod
, (u16
*)config
->cfg_data
);
19329 case DRXJ_CFG_PRE_SAW
:
19330 return ctrl_get_cfg_pre_saw(demod
,
19331 (struct drxj_cfg_pre_saw
*) config
->cfg_data
);
19332 case DRXJ_CFG_AFE_GAIN
:
19333 return ctrl_get_cfg_afe_gain(demod
,
19334 (struct drxj_cfg_afe_gain
*) config
->cfg_data
);
19335 case DRXJ_CFG_ACCUM_CR_RS_CW_ERR
:
19336 return ctrl_get_accum_cr_rs_cw_err(demod
, (u32
*)config
->cfg_data
);
19337 case DRXJ_CFG_FEC_MERS_SEQ_COUNT
:
19338 return ctrl_get_fec_meas_seq_count(demod
, (u16
*)config
->cfg_data
);
19339 case DRXJ_CFG_VSB_MISC
:
19340 return ctrl_get_cfg_vsb_misc(demod
,
19341 (struct drxj_cfg_vsb_misc
*) config
->cfg_data
);
19342 case DRXJ_CFG_SYMBOL_CLK_OFFSET
:
19343 return ctrl_get_cfg_symbol_clock_offset(demod
,
19344 (s32
*)config
->cfg_data
);
19346 case DRXJ_CFG_OOB_MISC
:
19347 return ctrl_get_cfg_oob_misc(demod
,
19348 (struct drxj_cfg_oob_misc
*) config
->cfg_data
);
19349 case DRXJ_CFG_OOB_PRE_SAW
:
19350 return ctrl_get_cfg_oob_pre_saw(demod
, (u16
*)(config
->cfg_data
));
19351 case DRXJ_CFG_OOB_LO_POW
:
19352 return ctrl_get_cfg_oob_lo_power(demod
,
19353 (enum drxj_cfg_oob_lo_power
*) (config
->
19355 case DRXJ_CFG_ATV_EQU_COEF
:
19356 return ctrl_get_cfg_atv_equ_coef(demod
,
19357 (struct drxj_cfg_atv_equ_coef
*) config
->
19359 case DRXJ_CFG_ATV_MISC
:
19360 return ctrl_get_cfg_atv_misc(demod
,
19361 (struct drxj_cfg_atv_misc
*) config
->cfg_data
);
19362 case DRXJ_CFG_ATV_OUTPUT
:
19363 return ctrl_get_cfg_atv_output(demod
,
19364 (struct drxj_cfg_atv_output
*) config
->
19366 case DRXJ_CFG_ATV_AGC_STATUS
:
19367 return ctrl_get_cfg_atv_agc_status(demod
,
19368 (struct drxj_cfg_atv_agc_status
*) config
->
19371 case DRXJ_CFG_MPEG_OUTPUT_MISC
:
19372 return ctrl_get_cfg_mpeg_output_misc(demod
,
19373 (struct drxj_cfg_mpeg_output_misc
*)
19375 case DRXJ_CFG_HW_CFG
:
19376 return ctrl_get_cfg_hw_cfg(demod
,
19377 (struct drxj_cfg_hw_cfg
*) config
->cfg_data
);
19378 #ifndef DRXJ_EXCLUDE_AUDIO
19379 case DRX_CFG_AUD_VOLUME
:
19380 return aud_ctrl_get_cfg_volume(demod
,
19381 (struct drx_cfg_aud_volume
*) config
->
19383 case DRX_CFG_I2S_OUTPUT
:
19384 return aud_ctrl_get_cfg_output_i2s(demod
,
19385 (struct drx_cfg_i2s_output
*) config
->
19388 case DRX_CFG_AUD_RDS
:
19389 return aud_ctrl_get_cfg_rds(demod
,
19390 (struct drx_cfg_aud_rds
*) config
->cfg_data
);
19391 case DRX_CFG_AUD_AUTOSOUND
:
19392 return aud_ctrl_get_cfg_auto_sound(demod
,
19393 (enum drx_cfg_aud_auto_sound
*) config
->
19395 case DRX_CFG_AUD_ASS_THRES
:
19396 return aud_ctrl_get_cfg_ass_thres(demod
,
19397 (struct drx_cfg_aud_ass_thres
*) config
->
19399 case DRX_CFG_AUD_CARRIER
:
19400 return aud_ctrl_get_cfg_carrier(demod
,
19401 (struct drx_cfg_aud_carriers
*) config
->
19403 case DRX_CFG_AUD_DEVIATION
:
19404 return aud_ctrl_get_cfg_dev(demod
,
19405 (enum drx_cfg_aud_deviation
*) config
->
19407 case DRX_CFG_AUD_PRESCALE
:
19408 return aud_ctrl_get_cfg_prescale(demod
,
19409 (struct drx_cfg_aud_prescale
*) config
->
19411 case DRX_CFG_AUD_MIXER
:
19412 return aud_ctrl_get_cfg_mixer(demod
,
19413 (struct drx_cfg_aud_mixer
*) config
->cfg_data
);
19414 case DRX_CFG_AUD_AVSYNC
:
19415 return aud_ctrl_get_cfg_av_sync(demod
,
19416 (enum drx_cfg_aud_av_sync
*) config
->
19430 /*=============================================================================
19431 ===== EXPORTED FUNCTIONS ====================================================*/
19433 static int drx_ctrl_u_code(struct drx_demod_instance
*demod
,
19434 struct drxu_code_info
*mc_info
,
19435 enum drxu_code_action action
);
19439 * \brief Open the demod instance, configure device, configure drxdriver
19440 * \return Status_t Return status.
19442 * drxj_open() can be called with a NULL ucode image => no ucode upload.
19443 * This means that drxj_open() must NOT contain SCU commands or, in general,
19444 * rely on SCU or AUD ucode to be present.
19448 int drxj_open(struct drx_demod_instance
*demod
)
19450 struct i2c_device_addr
*dev_addr
= NULL
;
19451 struct drxj_data
*ext_attr
= NULL
;
19452 struct drx_common_attr
*common_attr
= NULL
;
19453 u32 driver_version
= 0;
19454 struct drxu_code_info ucode_info
;
19455 struct drx_cfg_mpeg_output cfg_mpeg_output
;
19459 if ((demod
== NULL
) ||
19460 (demod
->my_common_attr
== NULL
) ||
19461 (demod
->my_ext_attr
== NULL
) ||
19462 (demod
->my_i2c_dev_addr
== NULL
) ||
19463 (demod
->my_common_attr
->is_opened
)) {
19467 /* Check arguments */
19468 if (demod
->my_ext_attr
== NULL
)
19471 dev_addr
= demod
->my_i2c_dev_addr
;
19472 ext_attr
= (struct drxj_data
*) demod
->my_ext_attr
;
19473 common_attr
= (struct drx_common_attr
*) demod
->my_common_attr
;
19475 rc
= power_up_device(demod
);
19477 pr_err("error %d\n", rc
);
19480 common_attr
->current_power_mode
= DRX_POWER_UP
;
19482 /* has to be in front of setIqmAf and setOrxNsuAox */
19483 rc
= get_device_capabilities(demod
);
19485 pr_err("error %d\n", rc
);
19489 /* Soft reset of sys- and osc-clockdomain */
19490 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);
19492 pr_err("error %d\n", rc
);
19495 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SIO_CC_UPDATE__A
, SIO_CC_UPDATE_KEY
, 0);
19497 pr_err("error %d\n", rc
);
19502 /* TODO first make sure that everything keeps working before enabling this */
19503 /* PowerDownAnalogBlocks() */
19504 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);
19506 pr_err("error %d\n", rc
);
19510 rc
= set_iqm_af(demod
, false);
19512 pr_err("error %d\n", rc
);
19515 rc
= set_orx_nsu_aox(demod
, false);
19517 pr_err("error %d\n", rc
);
19521 rc
= init_hi(demod
);
19523 pr_err("error %d\n", rc
);
19527 /* disable mpegoutput pins */
19528 cfg_mpeg_output
.enable_mpeg_output
= false;
19529 rc
= ctrl_set_cfg_mpeg_output(demod
, &cfg_mpeg_output
);
19531 pr_err("error %d\n", rc
);
19534 /* Stop AUD Inform SetAudio it will need to do all setting */
19535 rc
= power_down_aud(demod
);
19537 pr_err("error %d\n", rc
);
19541 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_COMM_EXEC__A
, SCU_COMM_EXEC_STOP
, 0);
19543 pr_err("error %d\n", rc
);
19547 /* Upload microcode */
19548 if (common_attr
->microcode_file
!= NULL
) {
19549 /* Dirty trick to use common ucode upload & verify,
19550 pretend device is already open */
19551 common_attr
->is_opened
= true;
19552 ucode_info
.mc_file
= common_attr
->microcode_file
;
19554 if (DRX_ISPOWERDOWNMODE(demod
->my_common_attr
->current_power_mode
)) {
19555 pr_err("Should powerup before loading the firmware.");
19559 rc
= drx_ctrl_u_code(demod
, &ucode_info
, UCODE_UPLOAD
);
19561 pr_err("error %d while uploading the firmware\n", rc
);
19564 if (common_attr
->verify_microcode
== true) {
19565 rc
= drx_ctrl_u_code(demod
, &ucode_info
, UCODE_VERIFY
);
19567 pr_err("error %d while verifying the firmware\n",
19572 common_attr
->is_opened
= false;
19575 /* Run SCU for a little while to initialize microcode version numbers */
19576 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_COMM_EXEC__A
, SCU_COMM_EXEC_ACTIVE
, 0);
19578 pr_err("error %d\n", rc
);
19582 /* Initialize scan timeout */
19583 common_attr
->scan_demod_lock_timeout
= DRXJ_SCAN_TIMEOUT
;
19584 common_attr
->scan_desired_lock
= DRX_LOCKED
;
19586 drxj_reset_mode(ext_attr
);
19587 ext_attr
->standard
= DRX_STANDARD_UNKNOWN
;
19589 rc
= smart_ant_init(demod
);
19591 pr_err("error %d\n", rc
);
19595 /* Stamp driver version number in SCU data RAM in BCD code
19596 Done to enable field application engineers to retreive drxdriver version
19597 via I2C from SCU RAM
19599 driver_version
= (VERSION_MAJOR
/ 100) % 10;
19600 driver_version
<<= 4;
19601 driver_version
+= (VERSION_MAJOR
/ 10) % 10;
19602 driver_version
<<= 4;
19603 driver_version
+= (VERSION_MAJOR
% 10);
19604 driver_version
<<= 4;
19605 driver_version
+= (VERSION_MINOR
% 10);
19606 driver_version
<<= 4;
19607 driver_version
+= (VERSION_PATCH
/ 1000) % 10;
19608 driver_version
<<= 4;
19609 driver_version
+= (VERSION_PATCH
/ 100) % 10;
19610 driver_version
<<= 4;
19611 driver_version
+= (VERSION_PATCH
/ 10) % 10;
19612 driver_version
<<= 4;
19613 driver_version
+= (VERSION_PATCH
% 10);
19614 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_DRIVER_VER_HI__A
, (u16
)(driver_version
>> 16), 0);
19616 pr_err("error %d\n", rc
);
19619 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_RAM_DRIVER_VER_LO__A
, (u16
)(driver_version
& 0xFFFF), 0);
19621 pr_err("error %d\n", rc
);
19625 /* refresh the audio data structure with default */
19626 ext_attr
->aud_data
= drxj_default_aud_data_g
;
19628 demod
->my_common_attr
->is_opened
= true;
19631 common_attr
->is_opened
= false;
19635 /*============================================================================*/
19638 * \brief Close the demod instance, power down the device
19639 * \return Status_t Return status.
19642 int drxj_close(struct drx_demod_instance
*demod
)
19644 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
19646 enum drx_power_mode power_mode
= DRX_POWER_UP
;
19648 if ((demod
== NULL
) ||
19649 (demod
->my_common_attr
== NULL
) ||
19650 (demod
->my_ext_attr
== NULL
) ||
19651 (demod
->my_i2c_dev_addr
== NULL
) ||
19652 (!demod
->my_common_attr
->is_opened
)) {
19657 rc
= ctrl_power_mode(demod
, &power_mode
);
19659 pr_err("error %d\n", rc
);
19663 rc
= DRXJ_DAP
.write_reg16func(dev_addr
, SCU_COMM_EXEC__A
, SCU_COMM_EXEC_ACTIVE
, 0);
19665 pr_err("error %d\n", rc
);
19668 power_mode
= DRX_POWER_DOWN
;
19669 rc
= ctrl_power_mode(demod
, &power_mode
);
19671 pr_err("error %d\n", rc
);
19675 DRX_ATTR_ISOPENED(demod
) = false;
19679 DRX_ATTR_ISOPENED(demod
) = false;
19685 * Microcode related functions
19689 * drx_u_code_compute_crc - Compute CRC of block of microcode data.
19690 * @block_data: Pointer to microcode data.
19691 * @nr_words: Size of microcode block (number of 16 bits words).
19693 * returns The computed CRC residue.
19695 static u16
drx_u_code_compute_crc(u8
*block_data
, u16 nr_words
)
19702 while (i
< nr_words
) {
19703 crc_word
|= (u32
)be16_to_cpu(*(u32
*)(block_data
));
19704 for (j
= 0; j
< 16; j
++) {
19707 crc_word
^= 0x80050000UL
;
19708 carry
= crc_word
& 0x80000000UL
;
19711 block_data
+= (sizeof(u16
));
19713 return (u16
)(crc_word
>> 16);
19717 * drx_check_firmware - checks if the loaded firmware is valid
19719 * @demod: demod structure
19720 * @mc_data: pointer to the start of the firmware
19721 * @size: firmware size
19723 static int drx_check_firmware(struct drx_demod_instance
*demod
, u8
*mc_data
,
19726 struct drxu_code_block_hdr block_hdr
;
19728 unsigned count
= 2 * sizeof(u16
);
19729 u32 mc_dev_type
, mc_version
, mc_base_version
;
19730 u16 mc_nr_of_blks
= be16_to_cpu(*(u32
*)(mc_data
+ sizeof(u16
)));
19733 * Scan microcode blocks first for version info
19734 * and firmware check
19737 /* Clear version block */
19738 DRX_ATTR_MCRECORD(demod
).aux_type
= 0;
19739 DRX_ATTR_MCRECORD(demod
).mc_dev_type
= 0;
19740 DRX_ATTR_MCRECORD(demod
).mc_version
= 0;
19741 DRX_ATTR_MCRECORD(demod
).mc_base_version
= 0;
19743 for (i
= 0; i
< mc_nr_of_blks
; i
++) {
19744 if (count
+ 3 * sizeof(u16
) + sizeof(u32
) > size
)
19747 /* Process block header */
19748 block_hdr
.addr
= be32_to_cpu(*(u32
*)(mc_data
+ count
));
19749 count
+= sizeof(u32
);
19750 block_hdr
.size
= be16_to_cpu(*(u32
*)(mc_data
+ count
));
19751 count
+= sizeof(u16
);
19752 block_hdr
.flags
= be16_to_cpu(*(u32
*)(mc_data
+ count
));
19753 count
+= sizeof(u16
);
19754 block_hdr
.CRC
= be16_to_cpu(*(u32
*)(mc_data
+ count
));
19755 count
+= sizeof(u16
);
19757 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
19758 count
, block_hdr
.addr
, block_hdr
.size
, block_hdr
.flags
,
19761 if (block_hdr
.flags
& 0x8) {
19762 u8
*auxblk
= ((void *)mc_data
) + block_hdr
.addr
;
19765 if (block_hdr
.addr
+ sizeof(u16
) > size
)
19768 auxtype
= be16_to_cpu(*(u32
*)(auxblk
));
19770 /* Aux block. Check type */
19771 if (DRX_ISMCVERTYPE(auxtype
)) {
19772 if (block_hdr
.addr
+ 2 * sizeof(u16
) + 2 * sizeof (u32
) > size
)
19775 auxblk
+= sizeof(u16
);
19776 mc_dev_type
= be32_to_cpu(*(u32
*)(auxblk
));
19777 auxblk
+= sizeof(u32
);
19778 mc_version
= be32_to_cpu(*(u32
*)(auxblk
));
19779 auxblk
+= sizeof(u32
);
19780 mc_base_version
= be32_to_cpu(*(u32
*)(auxblk
));
19782 DRX_ATTR_MCRECORD(demod
).aux_type
= auxtype
;
19783 DRX_ATTR_MCRECORD(demod
).mc_dev_type
= mc_dev_type
;
19784 DRX_ATTR_MCRECORD(demod
).mc_version
= mc_version
;
19785 DRX_ATTR_MCRECORD(demod
).mc_base_version
= mc_base_version
;
19787 pr_info("Firmware dev %x, ver %x, base ver %x\n",
19788 mc_dev_type
, mc_version
, mc_base_version
);
19791 } else if (count
+ block_hdr
.size
* sizeof(u16
) > size
)
19794 count
+= block_hdr
.size
* sizeof(u16
);
19798 pr_err("Firmware is truncated at pos %u/%u\n", count
, size
);
19803 * drx_ctrl_u_code - Handle microcode upload or verify.
19804 * @dev_addr: Address of device.
19805 * @mc_info: Pointer to information about microcode data.
19806 * @action: Either UCODE_UPLOAD or UCODE_VERIFY
19808 * This function returns:
19810 * - In case of UCODE_UPLOAD: code is successfully uploaded.
19811 * - In case of UCODE_VERIFY: image on device is equal to
19812 * image provided to this control function.
19814 * - In case of UCODE_UPLOAD: I2C error.
19815 * - In case of UCODE_VERIFY: I2C error or image on device
19816 * is not equal to image provided to this control function.
19818 * - Invalid arguments.
19819 * - Provided image is corrupt
19821 static int drx_ctrl_u_code(struct drx_demod_instance
*demod
,
19822 struct drxu_code_info
*mc_info
,
19823 enum drxu_code_action action
)
19825 struct i2c_device_addr
*dev_addr
= demod
->my_i2c_dev_addr
;
19828 u16 mc_nr_of_blks
= 0;
19829 u16 mc_magic_word
= 0;
19830 const u8
*mc_data_init
= NULL
;
19831 u8
*mc_data
= NULL
;
19833 char *mc_file
= mc_info
->mc_file
;
19835 /* Check arguments */
19836 if (!mc_info
|| !mc_file
)
19839 if (!demod
->firmware
) {
19840 const struct firmware
*fw
= NULL
;
19842 rc
= request_firmware(&fw
, mc_file
, demod
->i2c
->dev
.parent
);
19844 pr_err("Couldn't read firmware %s\n", mc_file
);
19847 demod
->firmware
= fw
;
19849 if (demod
->firmware
->size
< 2 * sizeof(u16
)) {
19851 pr_err("Firmware is too short!\n");
19855 pr_info("Firmware %s, size %zu\n",
19856 mc_file
, demod
->firmware
->size
);
19859 mc_data_init
= demod
->firmware
->data
;
19860 size
= demod
->firmware
->size
;
19862 mc_data
= (void *)mc_data_init
;
19864 mc_magic_word
= be16_to_cpu(*(u32
*)(mc_data
));
19865 mc_data
+= sizeof(u16
);
19866 mc_nr_of_blks
= be16_to_cpu(*(u32
*)(mc_data
));
19867 mc_data
+= sizeof(u16
);
19869 if ((mc_magic_word
!= DRX_UCODE_MAGIC_WORD
) || (mc_nr_of_blks
== 0)) {
19871 pr_err("Firmware magic word doesn't match\n");
19875 if (action
== UCODE_UPLOAD
) {
19876 rc
= drx_check_firmware(demod
, (u8
*)mc_data_init
, size
);
19879 pr_info("Uploading firmware %s\n", mc_file
);
19881 pr_info("Verifying if firmware upload was ok.\n");
19884 /* Process microcode blocks */
19885 for (i
= 0; i
< mc_nr_of_blks
; i
++) {
19886 struct drxu_code_block_hdr block_hdr
;
19887 u16 mc_block_nr_bytes
= 0;
19889 /* Process block header */
19890 block_hdr
.addr
= be32_to_cpu(*(u32
*)(mc_data
));
19891 mc_data
+= sizeof(u32
);
19892 block_hdr
.size
= be16_to_cpu(*(u32
*)(mc_data
));
19893 mc_data
+= sizeof(u16
);
19894 block_hdr
.flags
= be16_to_cpu(*(u32
*)(mc_data
));
19895 mc_data
+= sizeof(u16
);
19896 block_hdr
.CRC
= be16_to_cpu(*(u32
*)(mc_data
));
19897 mc_data
+= sizeof(u16
);
19899 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
19900 (unsigned)(mc_data
- mc_data_init
), block_hdr
.addr
,
19901 block_hdr
.size
, block_hdr
.flags
, block_hdr
.CRC
);
19903 /* Check block header on:
19904 - data larger than 64Kb
19905 - if CRC enabled check CRC
19907 if ((block_hdr
.size
> 0x7FFF) ||
19908 (((block_hdr
.flags
& DRX_UCODE_CRC_FLAG
) != 0) &&
19909 (block_hdr
.CRC
!= drx_u_code_compute_crc(mc_data
, block_hdr
.size
)))
19913 pr_err("firmware CRC is wrong\n");
19917 if (!block_hdr
.size
)
19920 mc_block_nr_bytes
= block_hdr
.size
* ((u16
) sizeof(u16
));
19922 /* Perform the desired action */
19924 case UCODE_UPLOAD
: /* Upload microcode */
19925 if (demod
->my_access_funct
->write_block_func(dev_addr
,
19928 mc_data
, 0x0000)) {
19930 pr_err("error writing firmware at pos %u\n",
19931 (unsigned)(mc_data
- mc_data_init
));
19935 case UCODE_VERIFY
: { /* Verify uploaded microcode */
19937 u8 mc_data_buffer
[DRX_UCODE_MAX_BUF_SIZE
];
19938 u32 bytes_to_comp
= 0;
19939 u32 bytes_left
= mc_block_nr_bytes
;
19940 u32 curr_addr
= block_hdr
.addr
;
19941 u8
*curr_ptr
= mc_data
;
19943 while (bytes_left
!= 0) {
19944 if (bytes_left
> DRX_UCODE_MAX_BUF_SIZE
)
19945 bytes_to_comp
= DRX_UCODE_MAX_BUF_SIZE
;
19947 bytes_to_comp
= bytes_left
;
19949 if (demod
->my_access_funct
->
19950 read_block_func(dev_addr
,
19952 (u16
)bytes_to_comp
,
19953 (u8
*)mc_data_buffer
,
19955 pr_err("error reading firmware at pos %u\n",
19956 (unsigned)(mc_data
- mc_data_init
));
19960 result
= memcmp(curr_ptr
, mc_data_buffer
,
19964 pr_err("error verifying firmware at pos %u\n",
19965 (unsigned)(mc_data
- mc_data_init
));
19969 curr_addr
+= ((dr_xaddr_t
)(bytes_to_comp
/ 2));
19970 curr_ptr
=&(curr_ptr
[bytes_to_comp
]);
19971 bytes_left
-=((u32
) bytes_to_comp
);
19980 mc_data
+= mc_block_nr_bytes
;
19986 release_firmware(demod
->firmware
);
19987 demod
->firmware
= NULL
;
19993 * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
19995 * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
19998 static int drx39xxj_set_powerstate(struct dvb_frontend
*fe
, int enable
)
20000 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20001 struct drx_demod_instance
*demod
= state
->demod
;
20003 enum drx_power_mode power_mode
;
20006 power_mode
= DRX_POWER_UP
;
20008 power_mode
= DRX_POWER_DOWN
;
20010 result
= ctrl_power_mode(demod
, &power_mode
);
20012 pr_err("Power state change failed\n");
20016 state
->powered_up
= enable
;
20020 static int drx39xxj_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
20022 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20023 struct drx_demod_instance
*demod
= state
->demod
;
20025 enum drx_lock_status lock_status
;
20029 result
= ctrl_lock_status(demod
, &lock_status
);
20031 pr_err("drx39xxj: could not get lock status!\n");
20035 switch (lock_status
) {
20036 case DRX_NEVER_LOCK
:
20038 pr_err("drx says NEVER_LOCK\n");
20040 case DRX_NOT_LOCKED
:
20043 case DRX_LOCK_STATE_1
:
20044 case DRX_LOCK_STATE_2
:
20045 case DRX_LOCK_STATE_3
:
20046 case DRX_LOCK_STATE_4
:
20047 case DRX_LOCK_STATE_5
:
20048 case DRX_LOCK_STATE_6
:
20049 case DRX_LOCK_STATE_7
:
20050 case DRX_LOCK_STATE_8
:
20051 case DRX_LOCK_STATE_9
:
20052 *status
= FE_HAS_SIGNAL
20053 | FE_HAS_CARRIER
| FE_HAS_VITERBI
| FE_HAS_SYNC
;
20056 *status
= FE_HAS_SIGNAL
20058 | FE_HAS_VITERBI
| FE_HAS_SYNC
| FE_HAS_LOCK
;
20061 pr_err("Lock state unknown %d\n", lock_status
);
20067 static int drx39xxj_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
20069 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20070 struct drx_demod_instance
*demod
= state
->demod
;
20072 struct drx_sig_quality sig_quality
;
20074 result
= ctrl_sig_quality(demod
, &sig_quality
);
20076 pr_err("drx39xxj: could not get ber!\n");
20081 *ber
= sig_quality
.post_reed_solomon_ber
;
20085 static int drx39xxj_read_signal_strength(struct dvb_frontend
*fe
,
20088 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20089 struct drx_demod_instance
*demod
= state
->demod
;
20091 struct drx_sig_quality sig_quality
;
20093 result
= ctrl_sig_quality(demod
, &sig_quality
);
20095 pr_err("drx39xxj: could not get signal strength!\n");
20100 /* 1-100% scaled to 0-65535 */
20101 *strength
= (sig_quality
.indicator
* 65535 / 100);
20105 static int drx39xxj_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
20107 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20108 struct drx_demod_instance
*demod
= state
->demod
;
20110 struct drx_sig_quality sig_quality
;
20112 result
= ctrl_sig_quality(demod
, &sig_quality
);
20114 pr_err("drx39xxj: could not read snr!\n");
20119 *snr
= sig_quality
.MER
;
20123 static int drx39xxj_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
20125 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20126 struct drx_demod_instance
*demod
= state
->demod
;
20128 struct drx_sig_quality sig_quality
;
20130 result
= ctrl_sig_quality(demod
, &sig_quality
);
20132 pr_err("drx39xxj: could not get uc blocks!\n");
20137 *ucblocks
= sig_quality
.packet_error
;
20141 static int drx39xxj_set_frontend(struct dvb_frontend
*fe
)
20146 struct dtv_frontend_properties
*p
= &fe
->dtv_property_cache
;
20147 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20148 struct drx_demod_instance
*demod
= state
->demod
;
20149 enum drx_standard standard
= DRX_STANDARD_8VSB
;
20150 struct drx_channel channel
;
20152 struct drxuio_data uio_data
;
20153 static const struct drx_channel def_channel
= {
20155 /* bandwidth */ DRX_BANDWIDTH_6MHZ
,
20156 /* mirror */ DRX_MIRROR_NO
,
20157 /* constellation */ DRX_CONSTELLATION_AUTO
,
20158 /* hierarchy */ DRX_HIERARCHY_UNKNOWN
,
20159 /* priority */ DRX_PRIORITY_UNKNOWN
,
20160 /* coderate */ DRX_CODERATE_UNKNOWN
,
20161 /* guard */ DRX_GUARD_UNKNOWN
,
20162 /* fftmode */ DRX_FFTMODE_UNKNOWN
,
20163 /* classification */ DRX_CLASSIFICATION_AUTO
,
20164 /* symbolrate */ 5057000,
20165 /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN
,
20166 /* ldpc */ DRX_LDPC_UNKNOWN
,
20167 /* carrier */ DRX_CARRIER_UNKNOWN
,
20168 /* frame mode */ DRX_FRAMEMODE_UNKNOWN
20170 u32 constellation
= DRX_CONSTELLATION_AUTO
;
20172 /* Bring the demod out of sleep */
20173 drx39xxj_set_powerstate(fe
, 1);
20175 if (fe
->ops
.tuner_ops
.set_params
) {
20178 if (fe
->ops
.i2c_gate_ctrl
)
20179 fe
->ops
.i2c_gate_ctrl(fe
, 1);
20181 /* Set tuner to desired frequency and standard */
20182 fe
->ops
.tuner_ops
.set_params(fe
);
20184 /* Use the tuner's IF */
20185 if (fe
->ops
.tuner_ops
.get_if_frequency
) {
20186 fe
->ops
.tuner_ops
.get_if_frequency(fe
, &int_freq
);
20187 demod
->my_common_attr
->intermediate_freq
= int_freq
/ 1000;
20190 if (fe
->ops
.i2c_gate_ctrl
)
20191 fe
->ops
.i2c_gate_ctrl(fe
, 0);
20194 switch (p
->delivery_system
) {
20196 standard
= DRX_STANDARD_8VSB
;
20198 case SYS_DVBC_ANNEX_B
:
20199 standard
= DRX_STANDARD_ITU_B
;
20201 switch (p
->modulation
) {
20203 constellation
= DRX_CONSTELLATION_QAM64
;
20206 constellation
= DRX_CONSTELLATION_QAM256
;
20209 constellation
= DRX_CONSTELLATION_AUTO
;
20217 if (standard
!= state
->current_standard
|| state
->powered_up
== 0) {
20218 /* Set the standard (will be powered up if necessary */
20219 result
= ctrl_set_standard(demod
, &standard
);
20221 pr_err("Failed to set standard! result=%02x\n",
20225 state
->powered_up
= 1;
20226 state
->current_standard
= standard
;
20229 /* set channel parameters */
20230 channel
= def_channel
;
20231 channel
.frequency
= p
->frequency
/ 1000;
20232 channel
.bandwidth
= DRX_BANDWIDTH_6MHZ
;
20233 channel
.constellation
= constellation
;
20235 /* program channel */
20236 result
= ctrl_set_channel(demod
, &channel
);
20238 pr_err("Failed to set channel!\n");
20241 /* Just for giggles, let's shut off the LNA again.... */
20242 uio_data
.uio
= DRX_UIO1
;
20243 uio_data
.value
= false;
20244 result
= ctrl_uio_write(demod
, &uio_data
);
20246 pr_err("Failed to disable LNA!\n");
20250 for (i
= 0; i
< 2000; i
++) {
20251 fe_status_t status
;
20252 drx39xxj_read_status(fe
, &status
);
20253 pr_dbg("i=%d status=%d\n", i
, status
);
20262 static int drx39xxj_sleep(struct dvb_frontend
*fe
)
20264 /* power-down the demodulator */
20265 return drx39xxj_set_powerstate(fe
, 0);
20268 static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend
*fe
, int enable
)
20270 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20271 struct drx_demod_instance
*demod
= state
->demod
;
20272 bool i2c_gate_state
;
20276 pr_dbg("i2c gate call: enable=%d state=%d\n", enable
,
20277 state
->i2c_gate_open
);
20281 i2c_gate_state
= true;
20283 i2c_gate_state
= false;
20285 if (state
->i2c_gate_open
== enable
) {
20286 /* We're already in the desired state */
20290 result
= ctrl_i2c_bridge(demod
, &i2c_gate_state
);
20292 pr_err("drx39xxj: could not open i2c gate [%d]\n",
20296 state
->i2c_gate_open
= enable
;
20301 static int drx39xxj_init(struct dvb_frontend
*fe
)
20303 /* Bring the demod out of sleep */
20304 drx39xxj_set_powerstate(fe
, 1);
20309 static int drx39xxj_get_tune_settings(struct dvb_frontend
*fe
,
20310 struct dvb_frontend_tune_settings
*tune
)
20312 tune
->min_delay_ms
= 1000;
20316 static void drx39xxj_release(struct dvb_frontend
*fe
)
20318 struct drx39xxj_state
*state
= fe
->demodulator_priv
;
20319 struct drx_demod_instance
*demod
= state
->demod
;
20321 kfree(demod
->my_ext_attr
);
20322 kfree(demod
->my_common_attr
);
20323 kfree(demod
->my_i2c_dev_addr
);
20324 if (demod
->firmware
)
20325 release_firmware(demod
->firmware
);
20330 static struct dvb_frontend_ops drx39xxj_ops
;
20332 struct dvb_frontend
*drx39xxj_attach(struct i2c_adapter
*i2c
)
20334 struct drx39xxj_state
*state
= NULL
;
20336 struct i2c_device_addr
*demod_addr
= NULL
;
20337 struct drx_common_attr
*demod_comm_attr
= NULL
;
20338 struct drxj_data
*demod_ext_attr
= NULL
;
20339 struct drx_demod_instance
*demod
= NULL
;
20340 struct drxuio_cfg uio_cfg
;
20341 struct drxuio_data uio_data
;
20344 /* allocate memory for the internal state */
20345 state
= kzalloc(sizeof(struct drx39xxj_state
), GFP_KERNEL
);
20349 demod
= kmalloc(sizeof(struct drx_demod_instance
), GFP_KERNEL
);
20353 demod_addr
= kmalloc(sizeof(struct i2c_device_addr
), GFP_KERNEL
);
20354 if (demod_addr
== NULL
)
20356 memcpy(demod_addr
, &drxj_default_addr_g
,
20357 sizeof(struct i2c_device_addr
));
20359 demod_comm_attr
= kmalloc(sizeof(struct drx_common_attr
), GFP_KERNEL
);
20360 if (demod_comm_attr
== NULL
)
20362 memcpy(demod_comm_attr
, &drxj_default_comm_attr_g
,
20363 sizeof(struct drx_common_attr
));
20365 demod_ext_attr
= kmalloc(sizeof(struct drxj_data
), GFP_KERNEL
);
20366 if (demod_ext_attr
== NULL
)
20368 memcpy(demod_ext_attr
, &drxj_data_g
, sizeof(struct drxj_data
));
20370 /* setup the state */
20372 state
->demod
= demod
;
20374 /* setup the demod data */
20375 memcpy(demod
, &drxj_default_demod_g
, sizeof(struct drx_demod_instance
));
20377 demod
->my_i2c_dev_addr
= demod_addr
;
20378 demod
->my_common_attr
= demod_comm_attr
;
20379 demod
->my_i2c_dev_addr
->user_data
= state
;
20380 demod
->my_common_attr
->microcode_file
= DRX39XX_MAIN_FIRMWARE
;
20381 demod
->my_common_attr
->verify_microcode
= true;
20382 demod
->my_common_attr
->intermediate_freq
= 5000;
20383 demod
->my_ext_attr
= demod_ext_attr
;
20384 ((struct drxj_data
*)demod_ext_attr
)->uio_sma_tx_mode
= DRX_UIO_MODE_READWRITE
;
20387 result
= drxj_open(demod
);
20389 pr_err("DRX open failed! Aborting\n");
20393 /* Turn off the LNA */
20394 uio_cfg
.uio
= DRX_UIO1
;
20395 uio_cfg
.mode
= DRX_UIO_MODE_READWRITE
;
20396 /* Configure user-I/O #3: enable read/write */
20397 result
= ctrl_set_uio_cfg(demod
, &uio_cfg
);
20399 pr_err("Failed to setup LNA GPIO!\n");
20403 uio_data
.uio
= DRX_UIO1
;
20404 uio_data
.value
= false;
20405 result
= ctrl_uio_write(demod
, &uio_data
);
20407 pr_err("Failed to disable LNA!\n");
20411 /* create dvb_frontend */
20412 memcpy(&state
->frontend
.ops
, &drx39xxj_ops
,
20413 sizeof(struct dvb_frontend_ops
));
20415 state
->frontend
.demodulator_priv
= state
;
20416 return &state
->frontend
;
20419 kfree(demod_ext_attr
);
20420 kfree(demod_comm_attr
);
20427 EXPORT_SYMBOL(drx39xxj_attach
);
20429 static struct dvb_frontend_ops drx39xxj_ops
= {
20430 .delsys
= { SYS_ATSC
, SYS_DVBC_ANNEX_B
},
20432 .name
= "Micronas DRX39xxj family Frontend",
20433 .frequency_stepsize
= 62500,
20434 .frequency_min
= 51000000,
20435 .frequency_max
= 858000000,
20436 .caps
= FE_CAN_QAM_64
| FE_CAN_QAM_256
| FE_CAN_8VSB
20439 .init
= drx39xxj_init
,
20440 .i2c_gate_ctrl
= drx39xxj_i2c_gate_ctrl
,
20441 .sleep
= drx39xxj_sleep
,
20442 .set_frontend
= drx39xxj_set_frontend
,
20443 .get_tune_settings
= drx39xxj_get_tune_settings
,
20444 .read_status
= drx39xxj_read_status
,
20445 .read_ber
= drx39xxj_read_ber
,
20446 .read_signal_strength
= drx39xxj_read_signal_strength
,
20447 .read_snr
= drx39xxj_read_snr
,
20448 .read_ucblocks
= drx39xxj_read_ucblocks
,
20449 .release
= drx39xxj_release
,
20452 MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
20453 MODULE_AUTHOR("Devin Heitmueller");
20454 MODULE_LICENSE("GPL");
20455 MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE
);