Merge remote-tracking branches 'asoc/topic/mc13783', 'asoc/topic/msm8916', 'asoc...
[linux-2.6-block.git] / drivers / media / dvb-frontends / drx39xyj / drxj.c
CommitLineData
ca3355a9
DH
1/*
2 Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
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
16 permission.
17
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.
ca3355a9 29
63713517
MCC
30 DRXJ specific implementation of DRX driver
31 authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
19013747
MCC
32
33 The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was
34 written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
35
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.
40
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
44
45 GNU General Public License for more details.
46
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.
38b2df95
DH
50*/
51
38b2df95
DH
52/*-----------------------------------------------------------------------------
53INCLUDE FILES
54----------------------------------------------------------------------------*/
55
935c6654 56#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
068e94ea 57
19013747
MCC
58#include <linux/module.h>
59#include <linux/init.h>
60#include <linux/string.h>
61#include <linux/slab.h>
90d9c3e1 62#include <asm/div64.h>
19013747
MCC
63
64#include "dvb_frontend.h"
65#include "drx39xxj.h"
66
38b2df95
DH
67#include "drxj.h"
68#include "drxj_map.h"
69
38b2df95
DH
70/*============================================================================*/
71/*=== DEFINES ================================================================*/
72/*============================================================================*/
73
19013747
MCC
74#define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
75
34eb9751 76/*
43a431e4 77* \brief Maximum u32 value.
38b2df95
DH
78*/
79#ifndef MAX_U32
43a431e4 80#define MAX_U32 ((u32) (0xFFFFFFFFL))
38b2df95
DH
81#endif
82
83/* Customer configurable hardware settings, etc */
84#ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
85#define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
86#endif
87
88#ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
89#define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
90#endif
91
92#ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
93#define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
94#endif
95
96#ifndef OOB_CRX_DRIVE_STRENGTH
97#define OOB_CRX_DRIVE_STRENGTH 0x02
98#endif
99
100#ifndef OOB_DRX_DRIVE_STRENGTH
101#define OOB_DRX_DRIVE_STRENGTH 0x02
102#endif
34eb9751
MCC
103/*** START DJCOMBO patches to DRXJ registermap constants *********************/
104/*** registermap 200706071303 from drxj **************************************/
38b2df95
DH
105#define ATV_TOP_CR_AMP_TH_FM 0x0
106#define ATV_TOP_CR_AMP_TH_L 0xA
107#define ATV_TOP_CR_AMP_TH_LP 0xA
108#define ATV_TOP_CR_AMP_TH_BG 0x8
109#define ATV_TOP_CR_AMP_TH_DK 0x8
110#define ATV_TOP_CR_AMP_TH_I 0x8
111#define ATV_TOP_CR_CONT_CR_D_MN 0x18
112#define ATV_TOP_CR_CONT_CR_D_FM 0x0
113#define ATV_TOP_CR_CONT_CR_D_L 0x20
114#define ATV_TOP_CR_CONT_CR_D_LP 0x20
115#define ATV_TOP_CR_CONT_CR_D_BG 0x18
116#define ATV_TOP_CR_CONT_CR_D_DK 0x18
117#define ATV_TOP_CR_CONT_CR_D_I 0x18
118#define ATV_TOP_CR_CONT_CR_I_MN 0x80
119#define ATV_TOP_CR_CONT_CR_I_FM 0x0
120#define ATV_TOP_CR_CONT_CR_I_L 0x80
121#define ATV_TOP_CR_CONT_CR_I_LP 0x80
122#define ATV_TOP_CR_CONT_CR_I_BG 0x80
123#define ATV_TOP_CR_CONT_CR_I_DK 0x80
124#define ATV_TOP_CR_CONT_CR_I_I 0x80
125#define ATV_TOP_CR_CONT_CR_P_MN 0x4
126#define ATV_TOP_CR_CONT_CR_P_FM 0x0
127#define ATV_TOP_CR_CONT_CR_P_L 0x4
128#define ATV_TOP_CR_CONT_CR_P_LP 0x4
129#define ATV_TOP_CR_CONT_CR_P_BG 0x4
130#define ATV_TOP_CR_CONT_CR_P_DK 0x4
131#define ATV_TOP_CR_CONT_CR_P_I 0x4
132#define ATV_TOP_CR_OVM_TH_MN 0xA0
133#define ATV_TOP_CR_OVM_TH_FM 0x0
134#define ATV_TOP_CR_OVM_TH_L 0xA0
135#define ATV_TOP_CR_OVM_TH_LP 0xA0
136#define ATV_TOP_CR_OVM_TH_BG 0xA0
137#define ATV_TOP_CR_OVM_TH_DK 0xA0
138#define ATV_TOP_CR_OVM_TH_I 0xA0
139#define ATV_TOP_EQU0_EQU_C0_FM 0x0
140#define ATV_TOP_EQU0_EQU_C0_L 0x3
141#define ATV_TOP_EQU0_EQU_C0_LP 0x3
142#define ATV_TOP_EQU0_EQU_C0_BG 0x7
143#define ATV_TOP_EQU0_EQU_C0_DK 0x0
144#define ATV_TOP_EQU0_EQU_C0_I 0x3
145#define ATV_TOP_EQU1_EQU_C1_FM 0x0
146#define ATV_TOP_EQU1_EQU_C1_L 0x1F6
147#define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
148#define ATV_TOP_EQU1_EQU_C1_BG 0x197
149#define ATV_TOP_EQU1_EQU_C1_DK 0x198
150#define ATV_TOP_EQU1_EQU_C1_I 0x1F6
151#define ATV_TOP_EQU2_EQU_C2_FM 0x0
152#define ATV_TOP_EQU2_EQU_C2_L 0x28
153#define ATV_TOP_EQU2_EQU_C2_LP 0x28
154#define ATV_TOP_EQU2_EQU_C2_BG 0xC5
155#define ATV_TOP_EQU2_EQU_C2_DK 0xB0
156#define ATV_TOP_EQU2_EQU_C2_I 0x28
157#define ATV_TOP_EQU3_EQU_C3_FM 0x0
158#define ATV_TOP_EQU3_EQU_C3_L 0x192
159#define ATV_TOP_EQU3_EQU_C3_LP 0x192
160#define ATV_TOP_EQU3_EQU_C3_BG 0x12E
161#define ATV_TOP_EQU3_EQU_C3_DK 0x18E
162#define ATV_TOP_EQU3_EQU_C3_I 0x192
163#define ATV_TOP_STD_MODE_MN 0x0
164#define ATV_TOP_STD_MODE_FM 0x1
165#define ATV_TOP_STD_MODE_L 0x0
166#define ATV_TOP_STD_MODE_LP 0x0
167#define ATV_TOP_STD_MODE_BG 0x0
168#define ATV_TOP_STD_MODE_DK 0x0
169#define ATV_TOP_STD_MODE_I 0x0
170#define ATV_TOP_STD_VID_POL_MN 0x0
171#define ATV_TOP_STD_VID_POL_FM 0x0
172#define ATV_TOP_STD_VID_POL_L 0x2
173#define ATV_TOP_STD_VID_POL_LP 0x2
174#define ATV_TOP_STD_VID_POL_BG 0x0
175#define ATV_TOP_STD_VID_POL_DK 0x0
176#define ATV_TOP_STD_VID_POL_I 0x0
177#define ATV_TOP_VID_AMP_MN 0x380
178#define ATV_TOP_VID_AMP_FM 0x0
179#define ATV_TOP_VID_AMP_L 0xF50
180#define ATV_TOP_VID_AMP_LP 0xF50
181#define ATV_TOP_VID_AMP_BG 0x380
182#define ATV_TOP_VID_AMP_DK 0x394
183#define ATV_TOP_VID_AMP_I 0x3D8
184#define IQM_CF_OUT_ENA_OFDM__M 0x4
185#define IQM_FS_ADJ_SEL_B_QAM 0x1
186#define IQM_FS_ADJ_SEL_B_OFF 0x0
187#define IQM_FS_ADJ_SEL_B_VSB 0x2
188#define IQM_RC_ADJ_SEL_B_OFF 0x0
189#define IQM_RC_ADJ_SEL_B_QAM 0x1
190#define IQM_RC_ADJ_SEL_B_VSB 0x2
34eb9751 191/*** END DJCOMBO patches to DRXJ registermap *********************************/
38b2df95
DH
192
193#include "drx_driver_version.h"
194
7ef66759 195/* #define DRX_DEBUG */
38b2df95
DH
196#ifdef DRX_DEBUG
197#include <stdio.h>
198#endif
199
200/*-----------------------------------------------------------------------------
201ENUMS
202----------------------------------------------------------------------------*/
203
204/*-----------------------------------------------------------------------------
205DEFINES
206----------------------------------------------------------------------------*/
207#ifndef DRXJ_WAKE_UP_KEY
57afe2f0 208#define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
38b2df95
DH
209#endif
210
34eb9751 211/*
38b2df95 212* \def DRXJ_DEF_I2C_ADDR
69bb7ab6 213* \brief Default I2C address of a demodulator instance.
38b2df95
DH
214*/
215#define DRXJ_DEF_I2C_ADDR (0x52)
216
34eb9751 217/*
38b2df95
DH
218* \def DRXJ_DEF_DEMOD_DEV_ID
219* \brief Default device identifier of a demodultor instance.
220*/
221#define DRXJ_DEF_DEMOD_DEV_ID (1)
222
34eb9751 223/*
38b2df95
DH
224* \def DRXJ_SCAN_TIMEOUT
225* \brief Timeout value for waiting on demod lock during channel scan (millisec).
226*/
227#define DRXJ_SCAN_TIMEOUT 1000
228
34eb9751 229/*
38b2df95
DH
230* \def HI_I2C_DELAY
231* \brief HI timing delay for I2C timing (in nano seconds)
232*
233* Used to compute HI_CFG_DIV
234*/
235#define HI_I2C_DELAY 42
236
34eb9751 237/*
38b2df95
DH
238* \def HI_I2C_BRIDGE_DELAY
239* \brief HI timing delay for I2C timing (in nano seconds)
240*
241* Used to compute HI_CFG_BDL
242*/
243#define HI_I2C_BRIDGE_DELAY 750
244
34eb9751 245/*
38b2df95
DH
246* \brief Time Window for MER and SER Measurement in Units of Segment duration.
247*/
248#define VSB_TOP_MEASUREMENT_PERIOD 64
249#define SYMBOLS_PER_SEGMENT 832
250
34eb9751 251/*
38b2df95
DH
252* \brief bit rate and segment rate constants used for SER and BER.
253*/
254/* values taken from the QAM microcode */
255#define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
256#define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
257#define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
258#define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
259#define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
260#define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
261#define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
262#define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
34eb9751 263/*
38b2df95
DH
264* \brief Min supported symbolrates.
265*/
266#ifndef DRXJ_QAM_SYMBOLRATE_MIN
267#define DRXJ_QAM_SYMBOLRATE_MIN (520000)
268#endif
269
34eb9751 270/*
38b2df95
DH
271* \brief Max supported symbolrates.
272*/
273#ifndef DRXJ_QAM_SYMBOLRATE_MAX
274#define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
275#endif
276
34eb9751 277/*
38b2df95
DH
278* \def DRXJ_QAM_MAX_WAITTIME
279* \brief Maximal wait time for QAM auto constellation in ms
280*/
281#ifndef DRXJ_QAM_MAX_WAITTIME
282#define DRXJ_QAM_MAX_WAITTIME 900
283#endif
284
285#ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
286#define DRXJ_QAM_FEC_LOCK_WAITTIME 150
287#endif
288
289#ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
290#define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
291#endif
292
34eb9751 293/*
38b2df95
DH
294* \def SCU status and results
295* \brief SCU
296*/
297#define DRX_SCU_READY 0
443f18d0
MCC
298#define DRXJ_MAX_WAITTIME 100 /* ms */
299#define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
300#define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
38b2df95 301
34eb9751 302/*
38b2df95
DH
303* \def DRX_AUD_MAX_DEVIATION
304* \brief Needed for calculation of prescale feature in AUD
305*/
306#ifndef DRXJ_AUD_MAX_FM_DEVIATION
443f18d0 307#define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
38b2df95
DH
308#endif
309
34eb9751 310/*
38b2df95
DH
311* \brief Needed for calculation of NICAM prescale feature in AUD
312*/
313#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
443f18d0 314#define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
38b2df95
DH
315#endif
316
34eb9751 317/*
38b2df95
DH
318* \brief Needed for calculation of NICAM prescale feature in AUD
319*/
320#ifndef DRXJ_AUD_MAX_WAITTIME
443f18d0 321#define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
38b2df95
DH
322#endif
323
324/* ATV config changed flags */
7ef66759
MCC
325#define DRXJ_ATV_CHANGED_COEF (0x00000001UL)
326#define DRXJ_ATV_CHANGED_PEAK_FLT (0x00000008UL)
327#define DRXJ_ATV_CHANGED_NOISE_FLT (0x00000010UL)
328#define DRXJ_ATV_CHANGED_OUTPUT (0x00000020UL)
329#define DRXJ_ATV_CHANGED_SIF_ATT (0x00000040UL)
38b2df95
DH
330
331/* UIO define */
332#define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
333#define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
334
b240eacd
MCC
335/*
336 * MICROCODE RELATED DEFINES
337 */
338
69bb7ab6 339/* Magic word for checking correct Endianness of microcode data */
b240eacd
MCC
340#define DRX_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L'))
341
342/* CRC flag in ucode header, flags field. */
343#define DRX_UCODE_CRC_FLAG (0x0001)
344
345/*
346 * Maximum size of buffer used to verify the microcode.
347 * Must be an even number
348 */
349#define DRX_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
350
351#if DRX_UCODE_MAX_BUF_SIZE & 1
352#error DRX_UCODE_MAX_BUF_SIZE must be an even number
353#endif
354
355/*
356 * Power mode macros
357 */
358
359#define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
360 (mode == DRX_POWER_MODE_10) || \
361 (mode == DRX_POWER_MODE_11) || \
362 (mode == DRX_POWER_MODE_12) || \
363 (mode == DRX_POWER_MODE_13) || \
364 (mode == DRX_POWER_MODE_14) || \
365 (mode == DRX_POWER_MODE_15) || \
366 (mode == DRX_POWER_MODE_16) || \
367 (mode == DRX_POWER_DOWN))
368
38b2df95
DH
369/* Pin safe mode macro */
370#define DRXJ_PIN_SAFE_MODE 0x0000
371/*============================================================================*/
372/*=== GLOBAL VARIABLEs =======================================================*/
373/*============================================================================*/
34eb9751 374/*
38b2df95
DH
375*/
376
34eb9751 377/*
38b2df95
DH
378* \brief Temporary register definitions.
379* (register definitions that are not yet available in register master)
380*/
381
34eb9751 382/*****************************************************************************/
38b2df95
DH
383/* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
384/* RAM adresses directly. This must be READ ONLY to avoid problems. */
385/* Writing to the interface adresses is more than only writing the RAM */
386/* locations */
34eb9751
MCC
387/*****************************************************************************/
388/*
38b2df95
DH
389* \brief RAM location of MODUS registers
390*/
391#define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
392#define AUD_DEM_RAM_MODUS_HI__M 0xF000
393
394#define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
395#define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
396
34eb9751 397/*
38b2df95
DH
398* \brief RAM location of I2S config registers
399*/
400#define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
401#define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
402
34eb9751 403/*
38b2df95
DH
404* \brief RAM location of DCO config registers
405*/
406#define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
407#define AUD_DEM_RAM_DCO_B_LO__A 0x1020462
408#define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
409#define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
410
34eb9751 411/*
38b2df95
DH
412* \brief RAM location of Threshold registers
413*/
414#define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
415#define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
416#define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
417
34eb9751 418/*
38b2df95
DH
419* \brief RAM location of Carrier Threshold registers
420*/
421#define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
422#define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
423
34eb9751 424/*
38b2df95
DH
425* \brief FM Matrix register fix
426*/
7ef66759 427#ifdef AUD_DEM_WR_FM_MATRIX__A
38b2df95
DH
428#undef AUD_DEM_WR_FM_MATRIX__A
429#endif
430#define AUD_DEM_WR_FM_MATRIX__A 0x105006F
431
432/*============================================================================*/
34eb9751 433/*
38b2df95
DH
434* \brief Defines required for audio
435*/
436#define AUD_VOLUME_ZERO_DB 115
437#define AUD_VOLUME_DB_MIN -60
438#define AUD_VOLUME_DB_MAX 12
439#define AUD_CARRIER_STRENGTH_QP_0DB 0x4000
440#define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 421
441#define AUD_MAX_AVC_REF_LEVEL 15
442#define AUD_I2S_FREQUENCY_MAX 48000UL
443#define AUD_I2S_FREQUENCY_MIN 12000UL
444#define AUD_RDS_ARRAY_SIZE 18
445
34eb9751 446/*
38b2df95
DH
447* \brief Needed for calculation of prescale feature in AUD
448*/
449#ifndef DRX_AUD_MAX_FM_DEVIATION
443f18d0 450#define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
38b2df95
DH
451#endif
452
34eb9751 453/*
38b2df95
DH
454* \brief Needed for calculation of NICAM prescale feature in AUD
455*/
456#ifndef DRX_AUD_MAX_NICAM_PRESCALE
443f18d0 457#define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
38b2df95
DH
458#endif
459
38b2df95
DH
460/*============================================================================*/
461/* Values for I2S Master/Slave pin configurations */
462#define SIO_PDR_I2S_CL_CFG_MODE__MASTER 0x0004
463#define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER 0x0008
464#define SIO_PDR_I2S_CL_CFG_MODE__SLAVE 0x0004
465#define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE 0x0000
466
467#define SIO_PDR_I2S_DA_CFG_MODE__MASTER 0x0003
468#define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER 0x0008
469#define SIO_PDR_I2S_DA_CFG_MODE__SLAVE 0x0003
470#define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE 0x0008
471
472#define SIO_PDR_I2S_WS_CFG_MODE__MASTER 0x0004
473#define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER 0x0008
474#define SIO_PDR_I2S_WS_CFG_MODE__SLAVE 0x0004
475#define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE 0x0000
476
477/*============================================================================*/
478/*=== REGISTER ACCESS MACROS =================================================*/
479/*============================================================================*/
480
34eb9751 481/*
38b2df95
DH
482* This macro is used to create byte arrays for block writes.
483* Block writes speed up I2C traffic between host and demod.
484* The macro takes care of the required byte order in a 16 bits word.
485* x -> lowbyte(x), highbyte(x)
486*/
7ef66759 487#define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
63713517 488 ((u8)((((u16)x)>>8)&0xFF))
34eb9751 489/*
38b2df95
DH
490* This macro is used to convert byte array to 16 bit register value for block read.
491* Block read speed up I2C traffic between host and demod.
492* The macro takes care of the required byte order in a 16 bits word.
493*/
7ef66759 494#define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
38b2df95
DH
495
496/*============================================================================*/
497/*=== MISC DEFINES ===========================================================*/
498/*============================================================================*/
499
500/*============================================================================*/
501/*=== HI COMMAND RELATED DEFINES =============================================*/
502/*============================================================================*/
503
34eb9751 504/*
38b2df95
DH
505* \brief General maximum number of retries for ucode command interfaces
506*/
507#define DRXJ_MAX_RETRIES (100)
508
509/*============================================================================*/
510/*=== STANDARD RELATED MACROS ================================================*/
511/*============================================================================*/
512
adc0e258 513#define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
7ef66759
MCC
514 (std == DRX_STANDARD_PAL_SECAM_DK) || \
515 (std == DRX_STANDARD_PAL_SECAM_I) || \
516 (std == DRX_STANDARD_PAL_SECAM_L) || \
517 (std == DRX_STANDARD_PAL_SECAM_LP) || \
518 (std == DRX_STANDARD_NTSC) || \
22892268 519 (std == DRX_STANDARD_FM))
38b2df95 520
adc0e258 521#define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
7ef66759
MCC
522 (std == DRX_STANDARD_ITU_B) || \
523 (std == DRX_STANDARD_ITU_C) || \
524 (std == DRX_STANDARD_ITU_D))
38b2df95 525
38b2df95
DH
526/*-----------------------------------------------------------------------------
527GLOBAL VARIABLES
528----------------------------------------------------------------------------*/
529/*
530 * DRXJ DAP structures
531 */
532
244c0e06 533static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
1bfc9e15 534 u32 addr,
43a431e4 535 u16 datasize,
1bfc9e15 536 u8 *data, u32 flags);
443f18d0 537
443f18d0 538
57afe2f0 539static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
540 u32 waddr,
541 u32 raddr,
43a431e4 542 u16 wdata, u16 *rdata);
443f18d0 543
57afe2f0 544static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
545 u32 addr,
546 u16 *data, u32 flags);
443f18d0 547
244c0e06 548static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
549 u32 addr,
550 u32 *data, u32 flags);
443f18d0 551
244c0e06 552static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
1bfc9e15 553 u32 addr,
43a431e4 554 u16 datasize,
1bfc9e15 555 u8 *data, u32 flags);
443f18d0 556
57afe2f0 557static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
558 u32 addr,
559 u16 data, u32 flags);
443f18d0 560
244c0e06 561static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
562 u32 addr,
563 u32 data, u32 flags);
38b2df95 564
01473146 565static struct drxj_data drxj_data_g = {
57afe2f0
MCC
566 false, /* has_lna : true if LNA (aka PGA) present */
567 false, /* has_oob : true if OOB supported */
568 false, /* has_ntsc: true if NTSC supported */
569 false, /* has_btsc: true if BTSC supported */
570 false, /* has_smatx: true if SMA_TX pin is available */
571 false, /* has_smarx: true if SMA_RX pin is available */
572 false, /* has_gpio : true if GPIO pin is available */
573 false, /* has_irqn : true if IRQN pin is available */
443f18d0
MCC
574 0, /* mfx A1/A2/A... */
575
576 /* tuner settings */
73f7065b 577 false, /* tuner mirrors RF signal */
443f18d0
MCC
578 /* standard/channel settings */
579 DRX_STANDARD_UNKNOWN, /* current standard */
580 DRX_CONSTELLATION_AUTO, /* constellation */
581 0, /* frequency in KHz */
57afe2f0 582 DRX_BANDWIDTH_UNKNOWN, /* curr_bandwidth */
443f18d0
MCC
583 DRX_MIRROR_NO, /* mirror */
584
585 /* signal quality information: */
586 /* default values taken from the QAM Programming guide */
57afe2f0
MCC
587 /* fec_bits_desired should not be less than 4000000 */
588 4000000, /* fec_bits_desired */
589 5, /* fec_vd_plen */
590 4, /* qam_vd_prescale */
443f18d0 591 0xFFFF, /* qamVDPeriod */
57afe2f0
MCC
592 204 * 8, /* fec_rs_plen annex A */
593 1, /* fec_rs_prescale */
594 FEC_RS_MEASUREMENT_PERIOD, /* fec_rs_period */
595 true, /* reset_pkt_err_acc */
e33f2193 596 0, /* pkt_err_acc_start */
443f18d0
MCC
597
598 /* HI configuration */
57afe2f0
MCC
599 0, /* hi_cfg_timing_div */
600 0, /* hi_cfg_bridge_delay */
601 0, /* hi_cfg_wake_up_key */
602 0, /* hi_cfg_ctrl */
443f18d0 603 0, /* HICfgTimeout */
2c149601 604 /* UIO configuration */
57afe2f0
MCC
605 DRX_UIO_MODE_DISABLE, /* uio_sma_rx_mode */
606 DRX_UIO_MODE_DISABLE, /* uio_sma_tx_mode */
443f18d0 607 DRX_UIO_MODE_DISABLE, /* uioASELMode */
57afe2f0 608 DRX_UIO_MODE_DISABLE, /* uio_irqn_mode */
443f18d0 609 /* FS setting */
57afe2f0
MCC
610 0UL, /* iqm_fs_rate_ofs */
611 false, /* pos_image */
443f18d0 612 /* RC setting */
57afe2f0 613 0UL, /* iqm_rc_rate_ofs */
443f18d0 614 /* AUD information */
73f7065b
MCC
615/* false, * flagSetAUDdone */
616/* false, * detectedRDS */
617/* true, * flagASDRequest */
618/* false, * flagHDevClear */
619/* false, * flagHDevSet */
43a431e4 620/* (u16) 0xFFF, * rdsLastCount */
38b2df95 621
2c149601 622 /* ATV configuration */
443f18d0
MCC
623 0UL, /* flags cfg changes */
624 /* shadow of ATV_TOP_EQU0__A */
625 {-5,
626 ATV_TOP_EQU0_EQU_C0_FM,
627 ATV_TOP_EQU0_EQU_C0_L,
628 ATV_TOP_EQU0_EQU_C0_LP,
629 ATV_TOP_EQU0_EQU_C0_BG,
630 ATV_TOP_EQU0_EQU_C0_DK,
631 ATV_TOP_EQU0_EQU_C0_I},
632 /* shadow of ATV_TOP_EQU1__A */
633 {-50,
634 ATV_TOP_EQU1_EQU_C1_FM,
635 ATV_TOP_EQU1_EQU_C1_L,
636 ATV_TOP_EQU1_EQU_C1_LP,
637 ATV_TOP_EQU1_EQU_C1_BG,
638 ATV_TOP_EQU1_EQU_C1_DK,
639 ATV_TOP_EQU1_EQU_C1_I},
640 /* shadow of ATV_TOP_EQU2__A */
641 {210,
642 ATV_TOP_EQU2_EQU_C2_FM,
643 ATV_TOP_EQU2_EQU_C2_L,
644 ATV_TOP_EQU2_EQU_C2_LP,
645 ATV_TOP_EQU2_EQU_C2_BG,
646 ATV_TOP_EQU2_EQU_C2_DK,
647 ATV_TOP_EQU2_EQU_C2_I},
648 /* shadow of ATV_TOP_EQU3__A */
649 {-160,
650 ATV_TOP_EQU3_EQU_C3_FM,
651 ATV_TOP_EQU3_EQU_C3_L,
652 ATV_TOP_EQU3_EQU_C3_LP,
653 ATV_TOP_EQU3_EQU_C3_BG,
654 ATV_TOP_EQU3_EQU_C3_DK,
655 ATV_TOP_EQU3_EQU_C3_I},
73f7065b 656 false, /* flag: true=bypass */
443f18d0
MCC
657 ATV_TOP_VID_PEAK__PRE, /* shadow of ATV_TOP_VID_PEAK__A */
658 ATV_TOP_NOISE_TH__PRE, /* shadow of ATV_TOP_NOISE_TH__A */
73f7065b
MCC
659 true, /* flag CVBS ouput enable */
660 false, /* flag SIF ouput enable */
443f18d0 661 DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
57afe2f0 662 { /* qam_rf_agc_cfg */
443f18d0 663 DRX_STANDARD_ITU_B, /* standard */
57afe2f0
MCC
664 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
665 0, /* output_level */
666 0, /* min_output_level */
667 0xFFFF, /* max_output_level */
443f18d0
MCC
668 0x0000, /* speed */
669 0x0000, /* top */
670 0x0000 /* c.o.c. */
671 },
57afe2f0 672 { /* qam_if_agc_cfg */
443f18d0 673 DRX_STANDARD_ITU_B, /* standard */
57afe2f0
MCC
674 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
675 0, /* output_level */
676 0, /* min_output_level */
677 0xFFFF, /* max_output_level */
443f18d0
MCC
678 0x0000, /* speed */
679 0x0000, /* top (don't care) */
680 0x0000 /* c.o.c. (don't care) */
681 },
57afe2f0 682 { /* vsb_rf_agc_cfg */
443f18d0 683 DRX_STANDARD_8VSB, /* standard */
57afe2f0
MCC
684 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
685 0, /* output_level */
686 0, /* min_output_level */
687 0xFFFF, /* max_output_level */
443f18d0
MCC
688 0x0000, /* speed */
689 0x0000, /* top (don't care) */
690 0x0000 /* c.o.c. (don't care) */
691 },
57afe2f0 692 { /* vsb_if_agc_cfg */
443f18d0 693 DRX_STANDARD_8VSB, /* standard */
57afe2f0
MCC
694 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
695 0, /* output_level */
696 0, /* min_output_level */
697 0xFFFF, /* max_output_level */
443f18d0
MCC
698 0x0000, /* speed */
699 0x0000, /* top (don't care) */
700 0x0000 /* c.o.c. (don't care) */
701 },
57afe2f0
MCC
702 0, /* qam_pga_cfg */
703 0, /* vsb_pga_cfg */
704 { /* qam_pre_saw_cfg */
443f18d0
MCC
705 DRX_STANDARD_ITU_B, /* standard */
706 0, /* reference */
57afe2f0 707 false /* use_pre_saw */
443f18d0 708 },
57afe2f0 709 { /* vsb_pre_saw_cfg */
443f18d0
MCC
710 DRX_STANDARD_8VSB, /* standard */
711 0, /* reference */
57afe2f0 712 false /* use_pre_saw */
443f18d0
MCC
713 },
714
715 /* Version information */
38b2df95 716#ifndef _CH_
443f18d0
MCC
717 {
718 "01234567890", /* human readable version microcode */
719 "01234567890" /* human readable version device specific code */
720 },
721 {
1bfc9e15 722 { /* struct drx_version for microcode */
443f18d0
MCC
723 DRX_MODULE_UNKNOWN,
724 (char *)(NULL),
725 0,
726 0,
727 0,
728 (char *)(NULL)
729 },
1bfc9e15 730 { /* struct drx_version for device specific code */
443f18d0
MCC
731 DRX_MODULE_UNKNOWN,
732 (char *)(NULL),
733 0,
734 0,
735 0,
736 (char *)(NULL)
737 }
738 },
739 {
1bfc9e15
MCC
740 { /* struct drx_version_list for microcode */
741 (struct drx_version *) (NULL),
742 (struct drx_version_list *) (NULL)
443f18d0 743 },
1bfc9e15
MCC
744 { /* struct drx_version_list for device specific code */
745 (struct drx_version *) (NULL),
746 (struct drx_version_list *) (NULL)
443f18d0
MCC
747 }
748 },
38b2df95 749#endif
57afe2f0 750 false, /* smart_ant_inverted */
443f18d0
MCC
751 /* Tracking filter setting for OOB */
752 {
753 12000,
754 9300,
755 6600,
756 5280,
757 3700,
758 3000,
759 2000,
760 0},
57afe2f0
MCC
761 false, /* oob_power_on */
762 0, /* mpeg_ts_static_bitrate */
763 false, /* disable_te_ihandling */
764 false, /* bit_reverse_mpeg_outout */
765 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO, /* mpeg_output_clock_rate */
766 DRXJ_MPEG_START_WIDTH_1CLKCYC, /* mpeg_start_width */
443f18d0
MCC
767
768 /* Pre SAW & Agc configuration for ATV */
769 {
770 DRX_STANDARD_NTSC, /* standard */
771 7, /* reference */
57afe2f0 772 true /* use_pre_saw */
443f18d0
MCC
773 },
774 { /* ATV RF-AGC */
775 DRX_STANDARD_NTSC, /* standard */
57afe2f0
MCC
776 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
777 0, /* output_level */
778 0, /* min_output_level (d.c.) */
779 0, /* max_output_level (d.c.) */
443f18d0
MCC
780 3, /* speed */
781 9500, /* top */
782 4000 /* cut-off current */
783 },
784 { /* ATV IF-AGC */
785 DRX_STANDARD_NTSC, /* standard */
57afe2f0
MCC
786 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
787 0, /* output_level */
788 0, /* min_output_level (d.c.) */
789 0, /* max_output_level (d.c.) */
443f18d0
MCC
790 3, /* speed */
791 2400, /* top */
792 0 /* c.o.c. (d.c.) */
793 },
794 140, /* ATV PGA config */
57afe2f0 795 0, /* curr_symbol_rate */
443f18d0 796
57afe2f0
MCC
797 false, /* pdr_safe_mode */
798 SIO_PDR_GPIO_CFG__PRE, /* pdr_safe_restore_val_gpio */
799 SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
800 SIO_PDR_SMA_RX_CFG__PRE, /* pdr_safe_restore_val_sma_rx */
801 SIO_PDR_SMA_TX_CFG__PRE, /* pdr_safe_restore_val_sma_tx */
443f18d0 802
57afe2f0
MCC
803 4, /* oob_pre_saw */
804 DRXJ_OOB_LO_POW_MINUS10DB, /* oob_lo_pow */
443f18d0 805 {
57afe2f0 806 false /* aud_data, only first member */
443f18d0 807 },
38b2df95
DH
808};
809
34eb9751 810/*
57afe2f0 811* \var drxj_default_addr_g
38b2df95
DH
812* \brief Default I2C address and device identifier.
813*/
01473146 814static struct i2c_device_addr drxj_default_addr_g = {
443f18d0
MCC
815 DRXJ_DEF_I2C_ADDR, /* i2c address */
816 DRXJ_DEF_DEMOD_DEV_ID /* device id */
38b2df95
DH
817};
818
34eb9751 819/*
57afe2f0 820* \var drxj_default_comm_attr_g
38b2df95
DH
821* \brief Default common attributes of a drxj demodulator instance.
822*/
01473146 823static struct drx_common_attr drxj_default_comm_attr_g = {
b48293db 824 NULL, /* ucode file */
73f7065b 825 true, /* ucode verify switch */
443f18d0
MCC
826 {0}, /* version record */
827
828 44000, /* IF in kHz in case no tuner instance is used */
829 (151875 - 0), /* system clock frequency in kHz */
830 0, /* oscillator frequency kHz */
831 0, /* oscillator deviation in ppm, signed */
73f7065b 832 false, /* If true mirror frequency spectrum */
443f18d0
MCC
833 {
834 /* MPEG output configuration */
73f7065b
MCC
835 true, /* If true, enable MPEG ouput */
836 false, /* If true, insert RS byte */
a5e7a67f 837 false, /* If true, parallel out otherwise serial */
73f7065b
MCC
838 false, /* If true, invert DATA signals */
839 false, /* If true, invert ERR signal */
840 false, /* If true, invert STR signals */
841 false, /* If true, invert VAL signals */
842 false, /* If true, invert CLK signals */
843 true, /* If true, static MPEG clockrate will
443f18d0
MCC
844 be used, otherwise clockrate will
845 adapt to the bitrate of the TS */
846 19392658UL, /* Maximum bitrate in b/s in case
847 static clockrate is selected */
848 DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
849 },
69bb7ab6 850 /* Initilisations below can be omitted, they require no user input and
73f7065b 851 are initialy 0, NULL or false. The compiler will initialize them to these
69bb7ab6 852 values when omitted. */
57afe2f0 853 false, /* is_opened */
443f18d0
MCC
854
855 /* SCAN */
856 NULL, /* no scan params yet */
857 0, /* current scan index */
858 0, /* next scan frequency */
73f7065b 859 false, /* scan ready flag */
443f18d0
MCC
860 0, /* max channels to scan */
861 0, /* nr of channels scanned */
862 NULL, /* default scan function */
863 NULL, /* default context pointer */
864 0, /* millisec to wait for demod lock */
865 DRXJ_DEMOD_LOCK, /* desired lock */
73f7065b 866 false,
443f18d0
MCC
867
868 /* Power management */
869 DRX_POWER_UP,
870
871 /* Tuner */
872 1, /* nr of I2C port to wich tuner is */
873 0L, /* minimum RF input frequency, in kHz */
874 0L, /* maximum RF input frequency, in kHz */
73f7065b
MCC
875 false, /* Rf Agc Polarity */
876 false, /* If Agc Polarity */
877 false, /* tuner slow mode */
443f18d0
MCC
878
879 { /* current channel (all 0) */
880 0UL /* channel.frequency */
881 },
882 DRX_STANDARD_UNKNOWN, /* current standard */
883 DRX_STANDARD_UNKNOWN, /* previous standard */
57afe2f0
MCC
884 DRX_STANDARD_UNKNOWN, /* di_cache_standard */
885 false, /* use_bootloader */
443f18d0
MCC
886 0UL, /* capabilities */
887 0 /* mfx */
38b2df95
DH
888};
889
34eb9751 890/*
57afe2f0 891* \var drxj_default_demod_g
38b2df95
DH
892* \brief Default drxj demodulator instance.
893*/
01473146 894static struct drx_demod_instance drxj_default_demod_g = {
57afe2f0
MCC
895 &drxj_default_addr_g, /* i2c address & device id */
896 &drxj_default_comm_attr_g, /* demod common attributes */
897 &drxj_data_g /* demod device specific attributes */
38b2df95
DH
898};
899
34eb9751 900/*
38b2df95
DH
901* \brief Default audio data structure for DRK demodulator instance.
902*
903* This structure is DRXK specific.
904*
905*/
c4cfb293 906static struct drx_aud_data drxj_default_aud_data_g = {
57afe2f0
MCC
907 false, /* audio_is_active */
908 DRX_AUD_STANDARD_AUTO, /* audio_standard */
38b2df95 909
443f18d0
MCC
910 /* i2sdata */
911 {
57afe2f0 912 false, /* output_enable */
443f18d0
MCC
913 48000, /* frequency */
914 DRX_I2S_MODE_MASTER, /* mode */
57afe2f0 915 DRX_I2S_WORDLENGTH_32, /* word_length */
443f18d0
MCC
916 DRX_I2S_POLARITY_RIGHT, /* polarity */
917 DRX_I2S_FORMAT_WS_WITH_DATA /* format */
918 },
919 /* volume */
920 {
73f7065b 921 true, /* mute; */
443f18d0 922 0, /* volume */
57afe2f0
MCC
923 DRX_AUD_AVC_OFF, /* avc_mode */
924 0, /* avc_ref_level */
925 DRX_AUD_AVC_MAX_GAIN_12DB, /* avc_max_gain */
926 DRX_AUD_AVC_MAX_ATTEN_24DB, /* avc_max_atten */
927 0, /* strength_left */
928 0 /* strength_right */
443f18d0 929 },
57afe2f0
MCC
930 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
931 /* ass_thresholds */
443f18d0
MCC
932 {
933 440, /* A2 */
934 12, /* BTSC */
935 700, /* NICAM */
936 },
937 /* carrier */
938 {
939 /* a */
940 {
941 42, /* thres */
942 DRX_NO_CARRIER_NOISE, /* opt */
943 0, /* shift */
944 0 /* dco */
945 },
946 /* b */
947 {
948 42, /* thres */
949 DRX_NO_CARRIER_MUTE, /* opt */
950 0, /* shift */
951 0 /* dco */
952 },
953
954 },
955 /* mixer */
956 {
57afe2f0
MCC
957 DRX_AUD_SRC_STEREO_OR_A, /* source_i2s */
958 DRX_AUD_I2S_MATRIX_STEREO, /* matrix_i2s */
959 DRX_AUD_FM_MATRIX_SOUND_A /* matrix_fm */
443f18d0
MCC
960 },
961 DRX_AUD_DEVIATION_NORMAL, /* deviation */
57afe2f0 962 DRX_AUD_AVSYNC_OFF, /* av_sync */
443f18d0
MCC
963
964 /* prescale */
965 {
57afe2f0
MCC
966 DRX_AUD_MAX_FM_DEVIATION, /* fm_deviation */
967 DRX_AUD_MAX_NICAM_PRESCALE /* nicam_gain */
443f18d0
MCC
968 },
969 DRX_AUD_FM_DEEMPH_75US, /* deemph */
57afe2f0
MCC
970 DRX_BTSC_STEREO, /* btsc_detect */
971 0, /* rds_data_counter */
972 false /* rds_data_present */
38b2df95
DH
973};
974
38b2df95
DH
975/*-----------------------------------------------------------------------------
976STRUCTURES
977----------------------------------------------------------------------------*/
60d3603b 978struct drxjeq_stat {
57afe2f0
MCC
979 u16 eq_mse;
980 u8 eq_mode;
981 u8 eq_ctrl;
63713517
MCC
982 u8 eq_stat;
983};
38b2df95
DH
984
985/* HI command */
60d3603b 986struct drxj_hi_cmd {
43a431e4
MCC
987 u16 cmd;
988 u16 param1;
989 u16 param2;
990 u16 param3;
991 u16 param4;
992 u16 param5;
63713517
MCC
993 u16 param6;
994};
38b2df95 995
38b2df95
DH
996/*============================================================================*/
997/*=== MICROCODE RELATED STRUCTURES ===========================================*/
998/*============================================================================*/
999
34eb9751 1000/*
b240eacd
MCC
1001 * struct drxu_code_block_hdr - Structure of the microcode block headers
1002 *
1003 * @addr: Destination address of the data in this block
1004 * @size: Size of the block data following this header counted in
1005 * 16 bits words
1006 * @CRC: CRC value of the data block, only valid if CRC flag is
1007 * set.
1008 */
60d3603b 1009struct drxu_code_block_hdr {
43a431e4
MCC
1010 u32 addr;
1011 u16 size;
b240eacd 1012 u16 flags;
63713517
MCC
1013 u16 CRC;
1014};
38b2df95
DH
1015
1016/*-----------------------------------------------------------------------------
1017FUNCTIONS
1018----------------------------------------------------------------------------*/
1019/* Some prototypes */
61263c75 1020static int
57afe2f0 1021hi_command(struct i2c_device_addr *dev_addr,
60d3603b 1022 const struct drxj_hi_cmd *cmd, u16 *result);
38b2df95 1023
61263c75 1024static int
1bfc9e15 1025ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
38b2df95 1026
61263c75 1027static int
1bfc9e15 1028ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
38b2df95 1029
1bfc9e15 1030static int power_down_aud(struct drx_demod_instance *demod);
38b2df95 1031
61263c75 1032static int
b3ce3a83 1033ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
38b2df95 1034
61263c75 1035static int
b3ce3a83 1036ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
38b2df95 1037
38b2df95
DH
1038/*============================================================================*/
1039/*============================================================================*/
1040/*== HELPER FUNCTIONS ==*/
1041/*============================================================================*/
1042/*============================================================================*/
1043
38b2df95
DH
1044
1045/*============================================================================*/
1046
1047/*
57afe2f0 1048* \fn u32 frac28(u32 N, u32 D)
38b2df95
DH
1049* \brief Compute: (1<<28)*N/D
1050* \param N 32 bits
1051* \param D 32 bits
1052* \return (1<<28)*N/D
1053* This function is used to avoid floating-point calculations as they may
1054* not be present on the target platform.
1055
57afe2f0 1056* frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
38b2df95
DH
1057* fraction used for setting the Frequency Shifter registers.
1058* N and D can hold numbers up to width: 28-bits.
1059* The 4 bits integer part and the 28 bits fractional part are calculated.
1060
1061* Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1062
1063* N: 0...(1<<28)-1 = 268435454
1064* D: 0...(1<<28)-1
1065* Q: 0...(1<<32)-1
1066*/
57afe2f0 1067static u32 frac28(u32 N, u32 D)
38b2df95 1068{
443f18d0 1069 int i = 0;
43a431e4
MCC
1070 u32 Q1 = 0;
1071 u32 R0 = 0;
443f18d0
MCC
1072
1073 R0 = (N % D) << 4; /* 32-28 == 4 shifts possible at max */
1074 Q1 = N / D; /* integer part, only the 4 least significant bits
1075 will be visible in the result */
1076
1077 /* division using radix 16, 7 nibbles in the result */
1078 for (i = 0; i < 7; i++) {
1079 Q1 = (Q1 << 4) | R0 / D;
1080 R0 = (R0 % D) << 4;
1081 }
1082 /* rounding */
1083 if ((R0 >> 3) >= D)
1084 Q1++;
1085
1086 return Q1;
38b2df95
DH
1087}
1088
34eb9751 1089/*
57afe2f0 1090* \fn u32 log1_times100( u32 x)
38b2df95
DH
1091* \brief Compute: 100*log10(x)
1092* \param x 32 bits
1093* \return 100*log10(x)
1094*
1095* 100*log10(x)
1096* = 100*(log2(x)/log2(10)))
1097* = (100*(2^15)*log2(x))/((2^15)*log2(10))
1098* = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1099* = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1100* = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1101*
1102* where y = 2^k and 1<= (x/y) < 2
1103*/
1104
57afe2f0 1105static u32 log1_times100(u32 x)
38b2df95 1106{
43a431e4 1107 static const u8 scale = 15;
57afe2f0 1108 static const u8 index_width = 5;
443f18d0
MCC
1109 /*
1110 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1111 0 <= n < ((1<<INDEXWIDTH)+1)
1112 */
1113
43a431e4 1114 static const u32 log2lut[] = {
443f18d0
MCC
1115 0, /* 0.000000 */
1116 290941, /* 290941.300628 */
1117 573196, /* 573196.476418 */
1118 847269, /* 847269.179851 */
1119 1113620, /* 1113620.489452 */
1120 1372674, /* 1372673.576986 */
1121 1624818, /* 1624817.752104 */
1122 1870412, /* 1870411.981536 */
1123 2109788, /* 2109787.962654 */
1124 2343253, /* 2343252.817465 */
1125 2571091, /* 2571091.461923 */
1126 2793569, /* 2793568.696416 */
1127 3010931, /* 3010931.055901 */
1128 3223408, /* 3223408.452106 */
1129 3431216, /* 3431215.635215 */
1130 3634553, /* 3634553.498355 */
1131 3833610, /* 3833610.244726 */
1132 4028562, /* 4028562.434393 */
1133 4219576, /* 4219575.925308 */
1134 4406807, /* 4406806.721144 */
1135 4590402, /* 4590401.736809 */
1136 4770499, /* 4770499.491025 */
1137 4947231, /* 4947230.734179 */
1138 5120719, /* 5120719.018555 */
1139 5291081, /* 5291081.217197 */
1140 5458428, /* 5458427.996830 */
1141 5622864, /* 5622864.249668 */
1142 5784489, /* 5784489.488298 */
1143 5943398, /* 5943398.207380 */
1144 6099680, /* 6099680.215452 */
1145 6253421, /* 6253420.939751 */
1146 6404702, /* 6404701.706649 */
1147 6553600, /* 6553600.000000 */
1148 };
1149
43a431e4
MCC
1150 u8 i = 0;
1151 u32 y = 0;
1152 u32 d = 0;
1153 u32 k = 0;
1154 u32 r = 0;
443f18d0
MCC
1155
1156 if (x == 0)
64e49cb9 1157 return 0;
443f18d0
MCC
1158
1159 /* Scale x (normalize) */
1160 /* computing y in log(x/y) = log(x) - log(y) */
43a431e4 1161 if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
443f18d0 1162 for (k = scale; k > 0; k--) {
43a431e4 1163 if (x & (((u32) 1) << scale))
443f18d0
MCC
1164 break;
1165 x <<= 1;
1166 }
1167 } else {
1168 for (k = scale; k < 31; k++) {
43a431e4 1169 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
443f18d0
MCC
1170 break;
1171 x >>= 1;
1172 }
1173 }
1174 /*
1175 Now x has binary point between bit[scale] and bit[scale-1]
1176 and 1.0 <= x < 2.0 */
1177
69bb7ab6 1178 /* correction for division: log(x) = log(x/y)+log(y) */
43a431e4 1179 y = k * ((((u32) 1) << scale) * 200);
443f18d0
MCC
1180
1181 /* remove integer part */
43a431e4 1182 x &= ((((u32) 1) << scale) - 1);
443f18d0 1183 /* get index */
57afe2f0 1184 i = (u8) (x >> (scale - index_width));
443f18d0 1185 /* compute delta (x-a) */
57afe2f0 1186 d = x & ((((u32) 1) << (scale - index_width)) - 1);
443f18d0
MCC
1187 /* compute log, multiplication ( d* (.. )) must be within range ! */
1188 y += log2lut[i] +
57afe2f0 1189 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
443f18d0
MCC
1190 /* Conver to log10() */
1191 y /= 108853; /* (log2(10) << scale) */
1192 r = (y >> 1);
1193 /* rounding */
63713517 1194 if (y & ((u32)1))
443f18d0
MCC
1195 r++;
1196
64e49cb9 1197 return r;
38b2df95
DH
1198
1199}
1200
34eb9751 1201/*
57afe2f0 1202* \fn u32 frac_times1e6( u16 N, u32 D)
38b2df95
DH
1203* \brief Compute: (N/D) * 1000000.
1204* \param N nominator 16-bits.
1205* \param D denominator 32-bits.
43a431e4 1206* \return u32
38b2df95
DH
1207* \retval ((N/D) * 1000000), 32 bits
1208*
1209* No check on D=0!
1210*/
57afe2f0 1211static u32 frac_times1e6(u32 N, u32 D)
38b2df95 1212{
43a431e4
MCC
1213 u32 remainder = 0;
1214 u32 frac = 0;
38b2df95 1215
443f18d0
MCC
1216 /*
1217 frac = (N * 1000000) / D
1218 To let it fit in a 32 bits computation:
1219 frac = (N * (1000000 >> 4)) / (D >> 4)
1220 This would result in a problem in case D < 16 (div by 0).
1221 So we do it more elaborate as shown below.
1222 */
43a431e4 1223 frac = (((u32) N) * (1000000 >> 4)) / D;
443f18d0 1224 frac <<= 4;
43a431e4 1225 remainder = (((u32) N) * (1000000 >> 4)) % D;
443f18d0
MCC
1226 remainder <<= 4;
1227 frac += remainder / D;
1228 remainder = remainder % D;
63713517 1229 if ((remainder * 2) > D)
443f18d0 1230 frac++;
443f18d0 1231
64e49cb9 1232 return frac;
38b2df95
DH
1233}
1234
1235/*============================================================================*/
1236
38b2df95 1237
34eb9751 1238/*
38b2df95
DH
1239* \brief Values for NICAM prescaler gain. Computed from dB to integer
1240* and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1241*
1242*/
01d7d436
MCC
1243#if 0
1244/* Currently, unused as we lack support for analog TV */
63713517
MCC
1245static const u16 nicam_presc_table_val[43] = {
1246 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
443f18d0
MCC
1247 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1248 18, 20, 23, 25, 28, 32, 36, 40, 45,
1249 51, 57, 64, 71, 80, 90, 101, 113, 127
1250};
01d7d436 1251#endif
38b2df95
DH
1252
1253/*============================================================================*/
1254/*== END HELPER FUNCTIONS ==*/
1255/*============================================================================*/
1256
38b2df95
DH
1257/*============================================================================*/
1258/*============================================================================*/
1259/*== DRXJ DAP FUNCTIONS ==*/
1260/*============================================================================*/
1261/*============================================================================*/
1262
1263/*
1264 This layer takes care of some device specific register access protocols:
1265 -conversion to short address format
1266 -access to audio block
1267 This layer is placed between the drx_dap_fasi and the rest of the drxj
1268 specific implementation. This layer can use address map knowledge whereas
1269 dap_fasi may not use memory map knowledge.
1270
1271 * For audio currently only 16 bits read and write register access is
1272 supported. More is not needed. RMW and 32 or 8 bit access on audio
1273 registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1274 single/multi master) will be ignored.
1275
38b2df95
DH
1276 TODO: check ignoring single/multimaster is ok for AUD access ?
1277*/
1278
22892268 1279#define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
443f18d0 1280#define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
38b2df95
DH
1281/*============================================================================*/
1282
34eb9751 1283/*
1bfc9e15 1284* \fn bool is_handled_by_aud_tr_if( u32 addr )
38b2df95
DH
1285* \brief Check if this address is handled by the audio token ring interface.
1286* \param addr
73f7065b
MCC
1287* \return bool
1288* \retval true Yes, handled by audio token ring interface
1289* \retval false No, not handled by audio token ring interface
38b2df95
DH
1290*
1291*/
1292static
1bfc9e15 1293bool is_handled_by_aud_tr_if(u32 addr)
38b2df95 1294{
73f7065b 1295 bool retval = false;
38b2df95 1296
443f18d0
MCC
1297 if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1298 (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1299 (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
73f7065b 1300 retval = true;
443f18d0 1301 }
38b2df95 1302
64e49cb9 1303 return retval;
38b2df95
DH
1304}
1305
1306/*============================================================================*/
1307
73b3fc3d
MCC
1308int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
1309 u16 w_count,
1310 u8 *wData,
1311 struct i2c_device_addr *r_dev_addr,
1312 u16 r_count, u8 *r_data)
1313{
1314 struct drx39xxj_state *state;
1315 struct i2c_msg msg[2];
1316 unsigned int num_msgs;
1317
1318 if (w_dev_addr == NULL) {
1319 /* Read only */
1320 state = r_dev_addr->user_data;
1321 msg[0].addr = r_dev_addr->i2c_addr >> 1;
1322 msg[0].flags = I2C_M_RD;
1323 msg[0].buf = r_data;
1324 msg[0].len = r_count;
1325 num_msgs = 1;
1326 } else if (r_dev_addr == NULL) {
1327 /* Write only */
1328 state = w_dev_addr->user_data;
1329 msg[0].addr = w_dev_addr->i2c_addr >> 1;
1330 msg[0].flags = 0;
1331 msg[0].buf = wData;
1332 msg[0].len = w_count;
1333 num_msgs = 1;
1334 } else {
1335 /* Both write and read */
1336 state = w_dev_addr->user_data;
1337 msg[0].addr = w_dev_addr->i2c_addr >> 1;
1338 msg[0].flags = 0;
1339 msg[0].buf = wData;
1340 msg[0].len = w_count;
1341 msg[1].addr = r_dev_addr->i2c_addr >> 1;
1342 msg[1].flags = I2C_M_RD;
1343 msg[1].buf = r_data;
1344 msg[1].len = r_count;
1345 num_msgs = 2;
1346 }
1347
1348 if (state->i2c == NULL) {
1349 pr_err("i2c was zero, aborting\n");
1350 return 0;
1351 }
1352 if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {
1353 pr_warn("drx3933: I2C write/read failed\n");
1354 return -EREMOTEIO;
1355 }
1356
73b3fc3d 1357#ifdef DJH_DEBUG
1ad77b5c
SK
1358 if (w_dev_addr == NULL || r_dev_addr == NULL)
1359 return 0;
73b3fc3d 1360
1ad77b5c
SK
1361 state = w_dev_addr->user_data;
1362
1363 if (state->i2c == NULL)
1364 return 0;
1365
1366 msg[0].addr = w_dev_addr->i2c_addr;
1367 msg[0].flags = 0;
1368 msg[0].buf = wData;
1369 msg[0].len = w_count;
1370 msg[1].addr = r_dev_addr->i2c_addr;
1371 msg[1].flags = I2C_M_RD;
1372 msg[1].buf = r_data;
1373 msg[1].len = r_count;
1374 num_msgs = 2;
73b3fc3d 1375
6c955b8b 1376 pr_debug("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
73b3fc3d
MCC
1377 w_dev_addr->i2c_addr, state->i2c, w_count, r_count);
1378
1379 if (i2c_transfer(state->i2c, msg, 2) != 2) {
1380 pr_warn("drx3933: I2C write/read failed\n");
1381 return -EREMOTEIO;
1382 }
1383#endif
1384 return 0;
1385}
1386
1387/*============================================================================*/
1388
34eb9751 1389/*****************************
73b3fc3d
MCC
1390*
1391* int drxdap_fasi_read_block (
1392* struct i2c_device_addr *dev_addr, -- address of I2C device
1393* u32 addr, -- address of chip register/memory
1394* u16 datasize, -- number of bytes to read
1395* u8 *data, -- data to receive
1396* u32 flags) -- special device flags
1397*
1398* Read block data from chip address. Because the chip is word oriented,
1399* the number of bytes to read must be even.
1400*
1401* Make sure that the buffer to receive the data is large enough.
1402*
1403* Although this function expects an even number of bytes, it is still byte
1404* oriented, and the data read back is NOT translated to the endianness of
1405* the target platform.
1406*
1407* Output:
1408* - 0 if reading was successful
1409* in that case: data read is in *data.
1410* - -EIO if anything went wrong
1411*
1412******************************/
1413
1414static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
1415 u32 addr,
1416 u16 datasize,
1417 u8 *data, u32 flags)
1418{
1419 u8 buf[4];
1420 u16 bufx;
1421 int rc;
1422 u16 overhead_size = 0;
1423
1424 /* Check parameters ******************************************************* */
1425 if (dev_addr == NULL)
1426 return -EINVAL;
1427
1428 overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
1429 (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
1430
1431 if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
1432 ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
1433 DRXDAP_FASI_LONG_FORMAT(addr)) ||
1434 (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
1435 ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {
1436 return -EINVAL;
1437 }
1438
1439 /* ReadModifyWrite & mode flag bits are not allowed */
1440 flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);
1441#if DRXDAP_SINGLE_MASTER
1442 flags |= DRXDAP_FASI_SINGLE_MASTER;
1443#endif
1444
1445 /* Read block from I2C **************************************************** */
1446 do {
1447 u16 todo = (datasize < DRXDAP_MAX_RCHUNKSIZE ?
1448 datasize : DRXDAP_MAX_RCHUNKSIZE);
1449
1450 bufx = 0;
1451
1452 addr &= ~DRXDAP_FASI_FLAGS;
1453 addr |= flags;
1454
1455#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1456 /* short format address preferred but long format otherwise */
1457 if (DRXDAP_FASI_LONG_FORMAT(addr)) {
1458#endif
1459#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1460 buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
1461 buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
1462 buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
1463 buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
1464#endif
1465#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1466 } else {
1467#endif
1468#if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)
1469 buf[bufx++] = (u8) ((addr << 1) & 0xFF);
1470 buf[bufx++] =
1471 (u8) (((addr >> 16) & 0x0F) |
1472 ((addr >> 18) & 0xF0));
1473#endif
1474#if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1475 }
1476#endif
1477
1478#if DRXDAP_SINGLE_MASTER
1479 /*
1480 * In single master mode, split the read and write actions.
1481 * No special action is needed for write chunks here.
1482 */
db5657c5
MCC
1483 rc = drxbsp_i2c_write_read(dev_addr, bufx, buf,
1484 NULL, 0, NULL);
73b3fc3d 1485 if (rc == 0)
db5657c5 1486 rc = drxbsp_i2c_write_read(NULL, 0, NULL, dev_addr, todo, data);
73b3fc3d
MCC
1487#else
1488 /* In multi master mode, do everything in one RW action */
1489 rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
1490 data);
1491#endif
1492 data += todo;
1493 addr += (todo >> 1);
1494 datasize -= todo;
1495 } while (datasize && rc == 0);
1496
1497 return rc;
1498}
1499
1500
34eb9751 1501/*****************************
73b3fc3d
MCC
1502*
1503* int drxdap_fasi_read_reg16 (
1504* struct i2c_device_addr *dev_addr, -- address of I2C device
1505* u32 addr, -- address of chip register/memory
1506* u16 *data, -- data to receive
1507* u32 flags) -- special device flags
1508*
1509* Read one 16-bit register or memory location. The data received back is
1510* converted back to the target platform's endianness.
1511*
1512* Output:
1513* - 0 if reading was successful
1514* in that case: read data is at *data
1515* - -EIO if anything went wrong
1516*
1517******************************/
1518
1519static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
1520 u32 addr,
1521 u16 *data, u32 flags)
1522{
1523 u8 buf[sizeof(*data)];
1524 int rc;
1525
1526 if (!data)
1527 return -EINVAL;
1528
1529 rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
1530 *data = buf[0] + (((u16) buf[1]) << 8);
1531 return rc;
1532}
1533
34eb9751 1534/*****************************
73b3fc3d
MCC
1535*
1536* int drxdap_fasi_read_reg32 (
1537* struct i2c_device_addr *dev_addr, -- address of I2C device
1538* u32 addr, -- address of chip register/memory
1539* u32 *data, -- data to receive
1540* u32 flags) -- special device flags
1541*
1542* Read one 32-bit register or memory location. The data received back is
1543* converted back to the target platform's endianness.
1544*
1545* Output:
1546* - 0 if reading was successful
1547* in that case: read data is at *data
1548* - -EIO if anything went wrong
1549*
1550******************************/
1551
1552static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
1553 u32 addr,
1554 u32 *data, u32 flags)
1555{
1556 u8 buf[sizeof(*data)];
1557 int rc;
1558
1559 if (!data)
1560 return -EINVAL;
1561
1562 rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
1563 *data = (((u32) buf[0]) << 0) +
1564 (((u32) buf[1]) << 8) +
1565 (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
1566 return rc;
1567}
1568
34eb9751 1569/*****************************
73b3fc3d
MCC
1570*
1571* int drxdap_fasi_write_block (
1572* struct i2c_device_addr *dev_addr, -- address of I2C device
1573* u32 addr, -- address of chip register/memory
1574* u16 datasize, -- number of bytes to read
1575* u8 *data, -- data to receive
1576* u32 flags) -- special device flags
1577*
1578* Write block data to chip address. Because the chip is word oriented,
1579* the number of bytes to write must be even.
1580*
1581* Although this function expects an even number of bytes, it is still byte
1582* oriented, and the data being written is NOT translated from the endianness of
1583* the target platform.
1584*
1585* Output:
1586* - 0 if writing was successful
1587* - -EIO if anything went wrong
1588*
1589******************************/
1590
1591static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
1592 u32 addr,
1593 u16 datasize,
1594 u8 *data, u32 flags)
1595{
1596 u8 buf[DRXDAP_MAX_WCHUNKSIZE];
1597 int st = -EIO;
1598 int first_err = 0;
1599 u16 overhead_size = 0;
1600 u16 block_size = 0;
1601
1602 /* Check parameters ******************************************************* */
1603 if (dev_addr == NULL)
1604 return -EINVAL;
1605
1606 overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
1607 (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
1608
1609 if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
1610 ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
1611 DRXDAP_FASI_LONG_FORMAT(addr)) ||
1612 (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
1613 ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))
1614 return -EINVAL;
1615
1616 flags &= DRXDAP_FASI_FLAGS;
1617 flags &= ~DRXDAP_FASI_MODEFLAGS;
1618#if DRXDAP_SINGLE_MASTER
1619 flags |= DRXDAP_FASI_SINGLE_MASTER;
1620#endif
1621
1622 /* Write block to I2C ***************************************************** */
1623 block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;
1624 do {
1625 u16 todo = 0;
1626 u16 bufx = 0;
1627
1628 /* Buffer device address */
1629 addr &= ~DRXDAP_FASI_FLAGS;
1630 addr |= flags;
1631#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1632 /* short format address preferred but long format otherwise */
1633 if (DRXDAP_FASI_LONG_FORMAT(addr)) {
1634#endif
1635#if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)
1636 buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
1637 buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
1638 buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
1639 buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
1640#endif
1641#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1642 } else {
1643#endif
1644#if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)
1645 buf[bufx++] = (u8) ((addr << 1) & 0xFF);
1646 buf[bufx++] =
1647 (u8) (((addr >> 16) & 0x0F) |
1648 ((addr >> 18) & 0xF0));
1649#endif
1650#if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1651 }
1652#endif
1653
1654 /*
1655 In single master mode block_size can be 0. In such a case this I2C
1656 sequense will be visible: (1) write address {i2c addr,
1657 4 bytes chip address} (2) write data {i2c addr, 4 bytes data }
1658 (3) write address (4) write data etc...
69bb7ab6 1659 Address must be rewriten because HI is reset after data transport and
73b3fc3d
MCC
1660 expects an address.
1661 */
1662 todo = (block_size < datasize ? block_size : datasize);
1663 if (todo == 0) {
1664 u16 overhead_size_i2c_addr = 0;
1665 u16 data_block_size = 0;
1666
1667 overhead_size_i2c_addr =
1668 (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);
1669 data_block_size =
1670 (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;
1671
1672 /* write device address */
1673 st = drxbsp_i2c_write_read(dev_addr,
1674 (u16) (bufx),
1675 buf,
1676 (struct i2c_device_addr *)(NULL),
1677 0, (u8 *)(NULL));
1678
1679 if ((st != 0) && (first_err == 0)) {
1680 /* at the end, return the first error encountered */
1681 first_err = st;
1682 }
1683 bufx = 0;
1684 todo =
1685 (data_block_size <
1686 datasize ? data_block_size : datasize);
1687 }
1688 memcpy(&buf[bufx], data, todo);
1689 /* write (address if can do and) data */
1690 st = drxbsp_i2c_write_read(dev_addr,
1691 (u16) (bufx + todo),
1692 buf,
1693 (struct i2c_device_addr *)(NULL),
1694 0, (u8 *)(NULL));
1695
1696 if ((st != 0) && (first_err == 0)) {
1697 /* at the end, return the first error encountered */
1698 first_err = st;
1699 }
1700 datasize -= todo;
1701 data += todo;
1702 addr += (todo >> 1);
1703 } while (datasize);
1704
1705 return first_err;
1706}
1707
34eb9751 1708/*****************************
73b3fc3d
MCC
1709*
1710* int drxdap_fasi_write_reg16 (
1711* struct i2c_device_addr *dev_addr, -- address of I2C device
1712* u32 addr, -- address of chip register/memory
1713* u16 data, -- data to send
1714* u32 flags) -- special device flags
1715*
1716* Write one 16-bit register or memory location. The data being written is
1717* converted from the target platform's endianness to little endian.
1718*
1719* Output:
1720* - 0 if writing was successful
1721* - -EIO if anything went wrong
1722*
1723******************************/
1724
1725static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
1726 u32 addr,
1727 u16 data, u32 flags)
1728{
1729 u8 buf[sizeof(data)];
1730
1731 buf[0] = (u8) ((data >> 0) & 0xFF);
1732 buf[1] = (u8) ((data >> 8) & 0xFF);
1733
1734 return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
1735}
1736
34eb9751 1737/*****************************
73b3fc3d
MCC
1738*
1739* int drxdap_fasi_read_modify_write_reg16 (
1740* struct i2c_device_addr *dev_addr, -- address of I2C device
1741* u32 waddr, -- address of chip register/memory
1742* u32 raddr, -- chip address to read back from
1743* u16 wdata, -- data to send
1744* u16 *rdata) -- data to receive back
1745*
1746* Write 16-bit data, then read back the original contents of that location.
1747* Requires long addressing format to be allowed.
1748*
1749* Before sending data, the data is converted to little endian. The
1750* data received back is converted back to the target platform's endianness.
1751*
1752* WARNING: This function is only guaranteed to work if there is one
1753* master on the I2C bus.
1754*
1755* Output:
1756* - 0 if reading was successful
1757* in that case: read back data is at *rdata
1758* - -EIO if anything went wrong
1759*
1760******************************/
1761
1762static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1763 u32 waddr,
1764 u32 raddr,
1765 u16 wdata, u16 *rdata)
1766{
1767 int rc = -EIO;
1768
1769#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1770 if (rdata == NULL)
1771 return -EINVAL;
1772
1773 rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);
1774 if (rc == 0)
1775 rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);
1776#endif
1777
1778 return rc;
1779}
1780
34eb9751 1781/*****************************
73b3fc3d
MCC
1782*
1783* int drxdap_fasi_write_reg32 (
1784* struct i2c_device_addr *dev_addr, -- address of I2C device
1785* u32 addr, -- address of chip register/memory
1786* u32 data, -- data to send
1787* u32 flags) -- special device flags
1788*
1789* Write one 32-bit register or memory location. The data being written is
1790* converted from the target platform's endianness to little endian.
1791*
1792* Output:
1793* - 0 if writing was successful
1794* - -EIO if anything went wrong
1795*
1796******************************/
1797
1798static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
1799 u32 addr,
1800 u32 data, u32 flags)
1801{
1802 u8 buf[sizeof(data)];
1803
1804 buf[0] = (u8) ((data >> 0) & 0xFF);
1805 buf[1] = (u8) ((data >> 8) & 0xFF);
1806 buf[2] = (u8) ((data >> 16) & 0xFF);
1807 buf[3] = (u8) ((data >> 24) & 0xFF);
1808
1809 return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
1810}
1811
38b2df95
DH
1812/*============================================================================*/
1813
34eb9751 1814/*
57afe2f0 1815* \fn int drxj_dap_rm_write_reg16short
38b2df95 1816* \brief Read modify write 16 bits audio register using short format only.
57afe2f0 1817* \param dev_addr
38b2df95
DH
1818* \param waddr Address to write to
1819* \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1820* \param wdata Data to write
1821* \param rdata Buffer for data to read
61263c75 1822* \return int
9482354f
MCC
1823* \retval 0 Succes
1824* \retval -EIO Timeout, I2C error, illegal bank
38b2df95
DH
1825*
1826* 16 bits register read modify write access using short addressing format only.
1827* Requires knowledge of the registermap, thus device dependent.
1828* Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1829*
1830*/
1831
1832/* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
57afe2f0 1833 See comments drxj_dap_read_modify_write_reg16 */
7ef66759 1834#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
57afe2f0 1835static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
1836 u32 waddr,
1837 u32 raddr,
43a431e4 1838 u16 wdata, u16 *rdata)
38b2df95 1839{
61263c75 1840 int rc;
443f18d0 1841
63713517 1842 if (rdata == NULL)
9482354f 1843 return -EINVAL;
443f18d0
MCC
1844
1845 /* Set RMW flag */
80bff4b0 1846 rc = drxdap_fasi_write_reg16(dev_addr,
38b2df95 1847 SIO_HI_RA_RAM_S0_FLG_ACC__A,
443f18d0 1848 SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
38b2df95 1849 0x0000);
9482354f 1850 if (rc == 0) {
443f18d0 1851 /* Write new data: triggers RMW */
80bff4b0 1852 rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
443f18d0
MCC
1853 0x0000);
1854 }
9482354f 1855 if (rc == 0) {
443f18d0 1856 /* Read old data */
80bff4b0 1857 rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
443f18d0
MCC
1858 0x0000);
1859 }
9482354f 1860 if (rc == 0) {
443f18d0 1861 /* Reset RMW flag */
80bff4b0 1862 rc = drxdap_fasi_write_reg16(dev_addr,
443f18d0
MCC
1863 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1864 0, 0x0000);
1865 }
38b2df95 1866
443f18d0 1867 return rc;
38b2df95
DH
1868}
1869#endif
1870
1871/*============================================================================*/
1872
57afe2f0 1873static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
1874 u32 waddr,
1875 u32 raddr,
43a431e4 1876 u16 wdata, u16 *rdata)
38b2df95 1877{
443f18d0
MCC
1878 /* TODO: correct short/long addressing format decision,
1879 now long format has higher prio then short because short also
1880 needs virt bnks (not impl yet) for certain audio registers */
7ef66759 1881#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
80bff4b0 1882 return drxdap_fasi_read_modify_write_reg16(dev_addr,
443f18d0
MCC
1883 waddr,
1884 raddr, wdata, rdata);
38b2df95 1885#else
57afe2f0 1886 return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
38b2df95
DH
1887#endif
1888}
1889
38b2df95
DH
1890
1891/*============================================================================*/
1892
34eb9751 1893/*
57afe2f0 1894* \fn int drxj_dap_read_aud_reg16
38b2df95 1895* \brief Read 16 bits audio register
57afe2f0 1896* \param dev_addr
38b2df95
DH
1897* \param addr
1898* \param data
61263c75 1899* \return int
9482354f
MCC
1900* \retval 0 Succes
1901* \retval -EIO Timeout, I2C error, illegal bank
38b2df95
DH
1902*
1903* 16 bits register read access via audio token ring interface.
1904*
1905*/
57afe2f0 1906static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15 1907 u32 addr, u16 *data)
443f18d0 1908{
57afe2f0
MCC
1909 u32 start_timer = 0;
1910 u32 current_timer = 0;
1911 u32 delta_timer = 0;
1912 u16 tr_status = 0;
9482354f 1913 int stat = -EIO;
443f18d0
MCC
1914
1915 /* No read possible for bank 3, return with error */
1916 if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
9482354f 1917 stat = -EINVAL;
443f18d0 1918 } else {
1bfc9e15 1919 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
443f18d0
MCC
1920
1921 /* Force reset write bit */
57afe2f0 1922 addr &= (~write_bit);
443f18d0
MCC
1923
1924 /* Set up read */
d7b0631e 1925 start_timer = jiffies_to_msecs(jiffies);
443f18d0
MCC
1926 do {
1927 /* RMW to aud TR IF until request is granted or timeout */
57afe2f0 1928 stat = drxj_dap_read_modify_write_reg16(dev_addr,
443f18d0
MCC
1929 addr,
1930 SIO_HI_RA_RAM_S0_RMWBUF__A,
57afe2f0 1931 0x0000, &tr_status);
443f18d0 1932
9482354f 1933 if (stat != 0)
443f18d0 1934 break;
443f18d0 1935
d7b0631e 1936 current_timer = jiffies_to_msecs(jiffies);
57afe2f0
MCC
1937 delta_timer = current_timer - start_timer;
1938 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
9482354f 1939 stat = -EIO;
443f18d0 1940 break;
259f380e 1941 }
443f18d0 1942
57afe2f0 1943 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
443f18d0 1944 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
57afe2f0 1945 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
443f18d0
MCC
1946 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1947 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1948
1949 /* Wait for read ready status or timeout */
9482354f 1950 if (stat == 0) {
d7b0631e 1951 start_timer = jiffies_to_msecs(jiffies);
443f18d0 1952
57afe2f0 1953 while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
443f18d0 1954 AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
57afe2f0 1955 stat = drxj_dap_read_reg16(dev_addr,
443f18d0 1956 AUD_TOP_TR_CTR__A,
57afe2f0 1957 &tr_status, 0x0000);
9482354f 1958 if (stat != 0)
443f18d0 1959 break;
443f18d0 1960
d7b0631e 1961 current_timer = jiffies_to_msecs(jiffies);
57afe2f0
MCC
1962 delta_timer = current_timer - start_timer;
1963 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
9482354f 1964 stat = -EIO;
443f18d0 1965 break;
259f380e 1966 }
443f18d0
MCC
1967 } /* while ( ... ) */
1968 }
38b2df95 1969
443f18d0 1970 /* Read value */
9482354f 1971 if (stat == 0)
57afe2f0 1972 stat = drxj_dap_read_modify_write_reg16(dev_addr,
443f18d0
MCC
1973 AUD_TOP_TR_RD_REG__A,
1974 SIO_HI_RA_RAM_S0_RMWBUF__A,
1975 0x0000, data);
443f18d0 1976 return stat;
38b2df95
DH
1977}
1978
1979/*============================================================================*/
1980
57afe2f0 1981static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
1982 u32 addr,
1983 u16 *data, u32 flags)
38b2df95 1984{
9482354f 1985 int stat = -EIO;
38b2df95 1986
443f18d0 1987 /* Check param */
63713517 1988 if ((dev_addr == NULL) || (data == NULL))
9482354f 1989 return -EINVAL;
38b2df95 1990
63713517 1991 if (is_handled_by_aud_tr_if(addr))
57afe2f0 1992 stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
63713517 1993 else
244c0e06 1994 stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);
443f18d0
MCC
1995
1996 return stat;
38b2df95 1997}
38b2df95
DH
1998/*============================================================================*/
1999
34eb9751 2000/*
57afe2f0 2001* \fn int drxj_dap_write_aud_reg16
38b2df95 2002* \brief Write 16 bits audio register
57afe2f0 2003* \param dev_addr
38b2df95
DH
2004* \param addr
2005* \param data
61263c75 2006* \return int
9482354f
MCC
2007* \retval 0 Succes
2008* \retval -EIO Timeout, I2C error, illegal bank
38b2df95
DH
2009*
2010* 16 bits register write access via audio token ring interface.
2011*
2012*/
57afe2f0 2013static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15 2014 u32 addr, u16 data)
38b2df95 2015{
9482354f 2016 int stat = -EIO;
38b2df95 2017
443f18d0
MCC
2018 /* No write possible for bank 2, return with error */
2019 if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
9482354f 2020 stat = -EINVAL;
443f18d0 2021 } else {
57afe2f0
MCC
2022 u32 start_timer = 0;
2023 u32 current_timer = 0;
2024 u32 delta_timer = 0;
2025 u16 tr_status = 0;
1bfc9e15 2026 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
38b2df95 2027
443f18d0 2028 /* Force write bit */
57afe2f0 2029 addr |= write_bit;
d7b0631e 2030 start_timer = jiffies_to_msecs(jiffies);
443f18d0
MCC
2031 do {
2032 /* RMW to aud TR IF until request is granted or timeout */
57afe2f0 2033 stat = drxj_dap_read_modify_write_reg16(dev_addr,
443f18d0
MCC
2034 addr,
2035 SIO_HI_RA_RAM_S0_RMWBUF__A,
57afe2f0 2036 data, &tr_status);
9482354f 2037 if (stat != 0)
443f18d0 2038 break;
38b2df95 2039
d7b0631e 2040 current_timer = jiffies_to_msecs(jiffies);
57afe2f0
MCC
2041 delta_timer = current_timer - start_timer;
2042 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
9482354f 2043 stat = -EIO;
443f18d0 2044 break;
259f380e 2045 }
38b2df95 2046
57afe2f0 2047 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
443f18d0 2048 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
57afe2f0 2049 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
443f18d0 2050 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
38b2df95 2051
443f18d0
MCC
2052 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
2053
2054 return stat;
38b2df95
DH
2055}
2056
2057/*============================================================================*/
2058
57afe2f0 2059static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
2060 u32 addr,
2061 u16 data, u32 flags)
38b2df95 2062{
9482354f 2063 int stat = -EIO;
38b2df95 2064
443f18d0 2065 /* Check param */
63713517 2066 if (dev_addr == NULL)
9482354f 2067 return -EINVAL;
38b2df95 2068
63713517 2069 if (is_handled_by_aud_tr_if(addr))
57afe2f0 2070 stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
63713517 2071 else
80bff4b0 2072 stat = drxdap_fasi_write_reg16(dev_addr,
63713517 2073 addr, data, flags);
38b2df95 2074
443f18d0 2075 return stat;
38b2df95
DH
2076}
2077
2078/*============================================================================*/
2079
38b2df95
DH
2080/* Free data ram in SIO HI */
2081#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2082#define SIO_HI_RA_RAM_USR_END__A 0x420060
2083
2084#define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2085#define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2086#define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2087#define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2088
34eb9751 2089/*
57afe2f0 2090* \fn int drxj_dap_atomic_read_write_block()
38b2df95 2091* \brief Basic access routine for atomic read or write access
57afe2f0 2092* \param dev_addr pointer to i2c dev address
38b2df95
DH
2093* \param addr destination/source address
2094* \param datasize size of data buffer in bytes
2095* \param data pointer to data buffer
61263c75 2096* \return int
9482354f
MCC
2097* \retval 0 Succes
2098* \retval -EIO Timeout, I2C error, illegal bank
38b2df95
DH
2099*
2100*/
2101static
57afe2f0 2102int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
1bfc9e15 2103 u32 addr,
43a431e4 2104 u16 datasize,
57afe2f0 2105 u8 *data, bool read_flag)
443f18d0 2106{
60d3603b 2107 struct drxj_hi_cmd hi_cmd;
068e94ea 2108 int rc;
43a431e4
MCC
2109 u16 word;
2110 u16 dummy = 0;
2111 u16 i = 0;
443f18d0
MCC
2112
2113 /* Parameter check */
63713517 2114 if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
9482354f 2115 return -EINVAL;
38b2df95 2116
443f18d0 2117 /* Set up HI parameters to read or write n bytes */
57afe2f0
MCC
2118 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2119 hi_cmd.param1 =
43a431e4 2120 (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
443f18d0 2121 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
57afe2f0 2122 hi_cmd.param2 =
43a431e4 2123 (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
57afe2f0 2124 hi_cmd.param3 = (u16) ((datasize / 2) - 1);
63713517 2125 if (!read_flag)
57afe2f0 2126 hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
63713517 2127 else
57afe2f0 2128 hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
57afe2f0 2129 hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
443f18d0 2130 DRXDAP_FASI_ADDR2BANK(addr));
57afe2f0 2131 hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
443f18d0 2132
259f380e 2133 if (!read_flag) {
443f18d0
MCC
2134 /* write data to buffer */
2135 for (i = 0; i < (datasize / 2); i++) {
2136
43a431e4
MCC
2137 word = ((u16) data[2 * i]);
2138 word += (((u16) data[(2 * i) + 1]) << 8);
57afe2f0 2139 drxj_dap_write_reg16(dev_addr,
22892268 2140 (DRXJ_HI_ATOMIC_BUF_START + i),
443f18d0
MCC
2141 word, 0);
2142 }
2143 }
38b2df95 2144
068e94ea 2145 rc = hi_command(dev_addr, &hi_cmd, &dummy);
9482354f 2146 if (rc != 0) {
068e94ea
MCC
2147 pr_err("error %d\n", rc);
2148 goto rw_error;
2149 }
443f18d0 2150
259f380e 2151 if (read_flag) {
443f18d0
MCC
2152 /* read data from buffer */
2153 for (i = 0; i < (datasize / 2); i++) {
57afe2f0 2154 drxj_dap_read_reg16(dev_addr,
22892268 2155 (DRXJ_HI_ATOMIC_BUF_START + i),
443f18d0 2156 &word, 0);
43a431e4
MCC
2157 data[2 * i] = (u8) (word & 0xFF);
2158 data[(2 * i) + 1] = (u8) (word >> 8);
443f18d0
MCC
2159 }
2160 }
38b2df95 2161
9482354f 2162 return 0;
38b2df95 2163
443f18d0 2164rw_error:
30741871 2165 return rc;
38b2df95
DH
2166
2167}
2168
2169/*============================================================================*/
2170
34eb9751 2171/*
57afe2f0 2172* \fn int drxj_dap_atomic_read_reg32()
38b2df95
DH
2173* \brief Atomic read of 32 bits words
2174*/
2175static
57afe2f0 2176int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
2177 u32 addr,
2178 u32 *data, u32 flags)
38b2df95 2179{
4182438e 2180 u8 buf[sizeof(*data)] = { 0 };
9482354f 2181 int rc = -EIO;
43a431e4 2182 u32 word = 0;
38b2df95 2183
63713517 2184 if (!data)
9482354f 2185 return -EINVAL;
38b2df95 2186
57afe2f0 2187 rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
63713517 2188 sizeof(*data), buf, true);
38b2df95 2189
b1d0a596
MCC
2190 if (rc < 0)
2191 return 0;
2192
43a431e4 2193 word = (u32) buf[3];
443f18d0 2194 word <<= 8;
43a431e4 2195 word |= (u32) buf[2];
443f18d0 2196 word <<= 8;
43a431e4 2197 word |= (u32) buf[1];
443f18d0 2198 word <<= 8;
43a431e4 2199 word |= (u32) buf[0];
38b2df95 2200
443f18d0 2201 *data = word;
38b2df95 2202
443f18d0 2203 return rc;
38b2df95
DH
2204}
2205
38b2df95
DH
2206/*============================================================================*/
2207
38b2df95
DH
2208/*============================================================================*/
2209/*== END DRXJ DAP FUNCTIONS ==*/
2210/*============================================================================*/
2211
2212/*============================================================================*/
2213/*============================================================================*/
2214/*== HOST INTERFACE FUNCTIONS ==*/
2215/*============================================================================*/
2216/*============================================================================*/
2217
34eb9751 2218/*
57afe2f0 2219* \fn int hi_cfg_command()
38b2df95
DH
2220* \brief Configure HI with settings stored in the demod structure.
2221* \param demod Demodulator.
61263c75 2222* \return int.
38b2df95
DH
2223*
2224* This routine was created because to much orthogonal settings have
2225* been put into one HI API function (configure). Especially the I2C bridge
2226* enable/disable should not need re-configuration of the HI.
2227*
2228*/
1bfc9e15 2229static int hi_cfg_command(const struct drx_demod_instance *demod)
38b2df95 2230{
b3ce3a83 2231 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
60d3603b 2232 struct drxj_hi_cmd hi_cmd;
43a431e4 2233 u16 result = 0;
068e94ea 2234 int rc;
38b2df95 2235
b3ce3a83 2236 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 2237
57afe2f0
MCC
2238 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2239 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2240 hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2241 hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2242 hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2243 hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2244 hi_cmd.param6 = ext_attr->hi_cfg_transmit;
38b2df95 2245
068e94ea 2246 rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
9482354f 2247 if (rc != 0) {
068e94ea
MCC
2248 pr_err("error %d\n", rc);
2249 goto rw_error;
2250 }
38b2df95 2251
443f18d0 2252 /* Reset power down flag (set one call only) */
57afe2f0 2253 ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
38b2df95 2254
9482354f 2255 return 0;
38b2df95 2256
443f18d0 2257rw_error:
30741871 2258 return rc;
38b2df95
DH
2259}
2260
34eb9751 2261/*
57afe2f0 2262* \fn int hi_command()
38b2df95 2263* \brief Configure HI with settings stored in the demod structure.
57afe2f0 2264* \param dev_addr I2C address.
38b2df95
DH
2265* \param cmd HI command.
2266* \param result HI command result.
61263c75 2267* \return int.
38b2df95
DH
2268*
2269* Sends command to HI
2270*
2271*/
61263c75 2272static int
60d3603b 2273hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
38b2df95 2274{
57afe2f0
MCC
2275 u16 wait_cmd = 0;
2276 u16 nr_retries = 0;
73f7065b 2277 bool powerdown_cmd = false;
068e94ea 2278 int rc;
38b2df95 2279
443f18d0
MCC
2280 /* Write parameters */
2281 switch (cmd->cmd) {
38b2df95 2282
443f18d0
MCC
2283 case SIO_HI_RA_RAM_CMD_CONFIG:
2284 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
244c0e06 2285 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
9482354f 2286 if (rc != 0) {
068e94ea
MCC
2287 pr_err("error %d\n", rc);
2288 goto rw_error;
2289 }
244c0e06 2290 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
9482354f 2291 if (rc != 0) {
068e94ea
MCC
2292 pr_err("error %d\n", rc);
2293 goto rw_error;
2294 }
244c0e06 2295 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
9482354f 2296 if (rc != 0) {
068e94ea
MCC
2297 pr_err("error %d\n", rc);
2298 goto rw_error;
2299 }
244c0e06 2300 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
9482354f 2301 if (rc != 0) {
068e94ea
MCC
2302 pr_err("error %d\n", rc);
2303 goto rw_error;
2304 }
443f18d0
MCC
2305 /* fallthrough */
2306 case SIO_HI_RA_RAM_CMD_BRDCTRL:
244c0e06 2307 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
9482354f 2308 if (rc != 0) {
068e94ea
MCC
2309 pr_err("error %d\n", rc);
2310 goto rw_error;
2311 }
244c0e06 2312 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
9482354f 2313 if (rc != 0) {
068e94ea
MCC
2314 pr_err("error %d\n", rc);
2315 goto rw_error;
2316 }
443f18d0
MCC
2317 /* fallthrough */
2318 case SIO_HI_RA_RAM_CMD_NULL:
2319 /* No parameters */
2320 break;
38b2df95 2321
443f18d0 2322 default:
9482354f 2323 return -EINVAL;
443f18d0
MCC
2324 break;
2325 }
2326
2327 /* Write command */
244c0e06 2328 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
9482354f 2329 if (rc != 0) {
068e94ea
MCC
2330 pr_err("error %d\n", rc);
2331 goto rw_error;
2332 }
443f18d0 2333
63713517 2334 if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
d7b0631e 2335 msleep(1);
38b2df95 2336
443f18d0 2337 /* Detect power down to ommit reading result */
73f7065b 2338 powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
443f18d0
MCC
2339 (((cmd->
2340 param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2341 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
259f380e 2342 if (!powerdown_cmd) {
443f18d0
MCC
2343 /* Wait until command rdy */
2344 do {
57afe2f0
MCC
2345 nr_retries++;
2346 if (nr_retries > DRXJ_MAX_RETRIES) {
63713517 2347 pr_err("timeout\n");
443f18d0 2348 goto rw_error;
259f380e 2349 }
443f18d0 2350
244c0e06 2351 rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
9482354f 2352 if (rc != 0) {
068e94ea
MCC
2353 pr_err("error %d\n", rc);
2354 goto rw_error;
2355 }
57afe2f0 2356 } while (wait_cmd != 0);
443f18d0
MCC
2357
2358 /* Read result */
244c0e06 2359 rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
9482354f 2360 if (rc != 0) {
068e94ea
MCC
2361 pr_err("error %d\n", rc);
2362 goto rw_error;
2363 }
443f18d0
MCC
2364
2365 }
73f7065b 2366 /* if ( powerdown_cmd == true ) */
9482354f 2367 return 0;
38b2df95 2368rw_error:
30741871 2369 return rc;
38b2df95
DH
2370}
2371
34eb9751 2372/*
1bfc9e15 2373* \fn int init_hi( const struct drx_demod_instance *demod )
38b2df95
DH
2374* \brief Initialise and configurate HI.
2375* \param demod pointer to demod data.
61263c75 2376* \return int Return status.
9482354f
MCC
2377* \retval 0 Success.
2378* \retval -EIO Failure.
38b2df95
DH
2379*
2380* Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2381* Need to store configuration in driver because of the way I2C
2382* bridging is controlled.
2383*
2384*/
1bfc9e15 2385static int init_hi(const struct drx_demod_instance *demod)
38b2df95 2386{
b3ce3a83 2387 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
1bfc9e15 2388 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
22892268 2389 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
068e94ea 2390 int rc;
443f18d0 2391
b3ce3a83 2392 ext_attr = (struct drxj_data *) demod->my_ext_attr;
1bfc9e15 2393 common_attr = (struct drx_common_attr *) demod->my_common_attr;
57afe2f0 2394 dev_addr = demod->my_i2c_dev_addr;
443f18d0
MCC
2395
2396 /* PATCH for bug 5003, HI ucode v3.1.0 */
244c0e06 2397 rc = drxj_dap_write_reg16(dev_addr, 0x4301D7, 0x801, 0);
9482354f 2398 if (rc != 0) {
068e94ea
MCC
2399 pr_err("error %d\n", rc);
2400 goto rw_error;
2401 }
38b2df95 2402
443f18d0
MCC
2403 /* Timing div, 250ns/Psys */
2404 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
57afe2f0
MCC
2405 ext_attr->hi_cfg_timing_div =
2406 (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
443f18d0 2407 /* Clipping */
63713517 2408 if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
57afe2f0 2409 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
443f18d0
MCC
2410 /* Bridge delay, uses oscilator clock */
2411 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2412 /* SDA brdige delay */
57afe2f0
MCC
2413 ext_attr->hi_cfg_bridge_delay =
2414 (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
443f18d0
MCC
2415 1000;
2416 /* Clipping */
63713517 2417 if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
57afe2f0 2418 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
443f18d0 2419 /* SCL bridge delay, same as SDA for now */
57afe2f0 2420 ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
443f18d0
MCC
2421 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2422 /* Wakeup key, setting the read flag (as suggest in the documentation) does
2423 not always result into a working solution (barebones worked VI2C failed).
2424 Not setting the bit works in all cases . */
57afe2f0 2425 ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
443f18d0 2426 /* port/bridge/power down ctrl */
57afe2f0 2427 ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
443f18d0 2428 /* transit mode time out delay and watch dog divider */
57afe2f0 2429 ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
443f18d0 2430
068e94ea 2431 rc = hi_cfg_command(demod);
9482354f 2432 if (rc != 0) {
068e94ea
MCC
2433 pr_err("error %d\n", rc);
2434 goto rw_error;
2435 }
443f18d0 2436
9482354f 2437 return 0;
443f18d0
MCC
2438
2439rw_error:
30741871 2440 return rc;
443f18d0 2441}
38b2df95
DH
2442
2443/*============================================================================*/
2444/*== END HOST INTERFACE FUNCTIONS ==*/
2445/*============================================================================*/
2446
2447/*============================================================================*/
2448/*============================================================================*/
2449/*== AUXILIARY FUNCTIONS ==*/
2450/*============================================================================*/
2451/*============================================================================*/
2452
34eb9751 2453/*
57afe2f0 2454* \fn int get_device_capabilities()
38b2df95
DH
2455* \brief Get and store device capabilities.
2456* \param demod Pointer to demodulator instance.
61263c75 2457* \return int.
9482354f
MCC
2458* \return 0 Success
2459* \retval -EIO Failure
38b2df95
DH
2460*
2461* Depending on pulldowns on MDx pins the following internals are set:
57afe2f0
MCC
2462* * common_attr->osc_clock_freq
2463* * ext_attr->has_lna
2464* * ext_attr->has_ntsc
2465* * ext_attr->has_btsc
2466* * ext_attr->has_oob
38b2df95
DH
2467*
2468*/
1bfc9e15 2469static int get_device_capabilities(struct drx_demod_instance *demod)
38b2df95 2470{
1bfc9e15 2471 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
b3ce3a83 2472 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
22892268 2473 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
57afe2f0
MCC
2474 u16 sio_pdr_ohw_cfg = 0;
2475 u32 sio_top_jtagid_lo = 0;
43a431e4 2476 u16 bid = 0;
068e94ea 2477 int rc;
443f18d0 2478
1bfc9e15 2479 common_attr = (struct drx_common_attr *) demod->my_common_attr;
b3ce3a83 2480 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0 2481 dev_addr = demod->my_i2c_dev_addr;
443f18d0 2482
244c0e06 2483 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 2484 if (rc != 0) {
068e94ea
MCC
2485 pr_err("error %d\n", rc);
2486 goto rw_error;
2487 }
244c0e06 2488 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
9482354f 2489 if (rc != 0) {
068e94ea
MCC
2490 pr_err("error %d\n", rc);
2491 goto rw_error;
2492 }
244c0e06 2493 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
9482354f 2494 if (rc != 0) {
068e94ea
MCC
2495 pr_err("error %d\n", rc);
2496 goto rw_error;
2497 }
443f18d0 2498
57afe2f0 2499 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
443f18d0
MCC
2500 case 0:
2501 /* ignore (bypass ?) */
2502 break;
2503 case 1:
2504 /* 27 MHz */
57afe2f0 2505 common_attr->osc_clock_freq = 27000;
443f18d0
MCC
2506 break;
2507 case 2:
2508 /* 20.25 MHz */
57afe2f0 2509 common_attr->osc_clock_freq = 20250;
443f18d0
MCC
2510 break;
2511 case 3:
2512 /* 4 MHz */
57afe2f0 2513 common_attr->osc_clock_freq = 4000;
443f18d0
MCC
2514 break;
2515 default:
9482354f 2516 return -EIO;
443f18d0
MCC
2517 }
2518
2519 /*
2520 Determine device capabilities
2521 Based on pinning v47
2522 */
244c0e06 2523 rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
9482354f 2524 if (rc != 0) {
068e94ea
MCC
2525 pr_err("error %d\n", rc);
2526 goto rw_error;
2527 }
57afe2f0 2528 ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
443f18d0 2529
57afe2f0 2530 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
443f18d0 2531 case 0x31:
244c0e06 2532 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 2533 if (rc != 0) {
068e94ea
MCC
2534 pr_err("error %d\n", rc);
2535 goto rw_error;
2536 }
244c0e06 2537 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
9482354f 2538 if (rc != 0) {
068e94ea
MCC
2539 pr_err("error %d\n", rc);
2540 goto rw_error;
2541 }
443f18d0 2542 bid = (bid >> 10) & 0xf;
244c0e06 2543 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
9482354f 2544 if (rc != 0) {
068e94ea
MCC
2545 pr_err("error %d\n", rc);
2546 goto rw_error;
2547 }
443f18d0 2548
57afe2f0
MCC
2549 ext_attr->has_lna = true;
2550 ext_attr->has_ntsc = false;
2551 ext_attr->has_btsc = false;
2552 ext_attr->has_oob = false;
2553 ext_attr->has_smatx = true;
2554 ext_attr->has_smarx = false;
2555 ext_attr->has_gpio = false;
2556 ext_attr->has_irqn = false;
443f18d0
MCC
2557 break;
2558 case 0x33:
57afe2f0
MCC
2559 ext_attr->has_lna = false;
2560 ext_attr->has_ntsc = false;
2561 ext_attr->has_btsc = false;
2562 ext_attr->has_oob = false;
2563 ext_attr->has_smatx = true;
2564 ext_attr->has_smarx = false;
2565 ext_attr->has_gpio = false;
2566 ext_attr->has_irqn = false;
443f18d0
MCC
2567 break;
2568 case 0x45:
57afe2f0
MCC
2569 ext_attr->has_lna = true;
2570 ext_attr->has_ntsc = true;
2571 ext_attr->has_btsc = false;
2572 ext_attr->has_oob = false;
2573 ext_attr->has_smatx = true;
2574 ext_attr->has_smarx = true;
2575 ext_attr->has_gpio = true;
2576 ext_attr->has_irqn = false;
443f18d0
MCC
2577 break;
2578 case 0x46:
57afe2f0
MCC
2579 ext_attr->has_lna = false;
2580 ext_attr->has_ntsc = true;
2581 ext_attr->has_btsc = false;
2582 ext_attr->has_oob = false;
2583 ext_attr->has_smatx = true;
2584 ext_attr->has_smarx = true;
2585 ext_attr->has_gpio = true;
2586 ext_attr->has_irqn = false;
443f18d0
MCC
2587 break;
2588 case 0x41:
57afe2f0
MCC
2589 ext_attr->has_lna = true;
2590 ext_attr->has_ntsc = true;
2591 ext_attr->has_btsc = true;
2592 ext_attr->has_oob = false;
2593 ext_attr->has_smatx = true;
2594 ext_attr->has_smarx = true;
2595 ext_attr->has_gpio = true;
2596 ext_attr->has_irqn = false;
443f18d0
MCC
2597 break;
2598 case 0x43:
57afe2f0
MCC
2599 ext_attr->has_lna = false;
2600 ext_attr->has_ntsc = true;
2601 ext_attr->has_btsc = true;
2602 ext_attr->has_oob = false;
2603 ext_attr->has_smatx = true;
2604 ext_attr->has_smarx = true;
2605 ext_attr->has_gpio = true;
2606 ext_attr->has_irqn = false;
443f18d0
MCC
2607 break;
2608 case 0x32:
57afe2f0
MCC
2609 ext_attr->has_lna = true;
2610 ext_attr->has_ntsc = false;
2611 ext_attr->has_btsc = false;
2612 ext_attr->has_oob = true;
2613 ext_attr->has_smatx = true;
2614 ext_attr->has_smarx = true;
2615 ext_attr->has_gpio = true;
2616 ext_attr->has_irqn = true;
443f18d0
MCC
2617 break;
2618 case 0x34:
57afe2f0
MCC
2619 ext_attr->has_lna = false;
2620 ext_attr->has_ntsc = true;
2621 ext_attr->has_btsc = true;
2622 ext_attr->has_oob = true;
2623 ext_attr->has_smatx = true;
2624 ext_attr->has_smarx = true;
2625 ext_attr->has_gpio = true;
2626 ext_attr->has_irqn = true;
443f18d0
MCC
2627 break;
2628 case 0x42:
57afe2f0
MCC
2629 ext_attr->has_lna = true;
2630 ext_attr->has_ntsc = true;
2631 ext_attr->has_btsc = true;
2632 ext_attr->has_oob = true;
2633 ext_attr->has_smatx = true;
2634 ext_attr->has_smarx = true;
2635 ext_attr->has_gpio = true;
2636 ext_attr->has_irqn = true;
443f18d0
MCC
2637 break;
2638 case 0x44:
57afe2f0
MCC
2639 ext_attr->has_lna = false;
2640 ext_attr->has_ntsc = true;
2641 ext_attr->has_btsc = true;
2642 ext_attr->has_oob = true;
2643 ext_attr->has_smatx = true;
2644 ext_attr->has_smarx = true;
2645 ext_attr->has_gpio = true;
2646 ext_attr->has_irqn = true;
443f18d0
MCC
2647 break;
2648 default:
2649 /* Unknown device variant */
9482354f 2650 return -EIO;
443f18d0
MCC
2651 break;
2652 }
2653
9482354f 2654 return 0;
38b2df95 2655rw_error:
30741871 2656 return rc;
38b2df95
DH
2657}
2658
34eb9751 2659/*
57afe2f0 2660* \fn int power_up_device()
38b2df95
DH
2661* \brief Power up device.
2662* \param demod Pointer to demodulator instance.
61263c75 2663* \return int.
9482354f
MCC
2664* \return 0 Success
2665* \retval -EIO Failure, I2C or max retries reached
38b2df95
DH
2666*
2667*/
2668
2669#ifndef DRXJ_MAX_RETRIES_POWERUP
2670#define DRXJ_MAX_RETRIES_POWERUP 10
2671#endif
2672
1bfc9e15 2673static int power_up_device(struct drx_demod_instance *demod)
443f18d0 2674{
22892268 2675 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
43a431e4 2676 u8 data = 0;
57afe2f0
MCC
2677 u16 retry_count = 0;
2678 struct i2c_device_addr wake_up_addr;
443f18d0 2679
57afe2f0
MCC
2680 dev_addr = demod->my_i2c_dev_addr;
2681 wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2682 wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2683 wake_up_addr.user_data = dev_addr->user_data;
068e94ea
MCC
2684 /*
2685 * I2C access may fail in this case: no ack
2686 * dummy write must be used to wake uop device, dummy read must be used to
2687 * reset HI state machine (avoiding actual writes)
2688 */
443f18d0
MCC
2689 do {
2690 data = 0;
57afe2f0 2691 drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
22892268
MCC
2692 (struct i2c_device_addr *)(NULL), 0,
2693 (u8 *)(NULL));
d7b0631e 2694 msleep(10);
57afe2f0
MCC
2695 retry_count++;
2696 } while ((drxbsp_i2c_write_read
22892268 2697 ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
443f18d0 2698 &data)
9482354f 2699 != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
443f18d0
MCC
2700
2701 /* Need some recovery time .... */
d7b0631e 2702 msleep(10);
443f18d0 2703
63713517 2704 if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
9482354f 2705 return -EIO;
38b2df95 2706
9482354f 2707 return 0;
38b2df95
DH
2708}
2709
2710/*----------------------------------------------------------------------------*/
2711/* MPEG Output Configuration Functions - begin */
2712/*----------------------------------------------------------------------------*/
34eb9751 2713/*
57afe2f0 2714* \fn int ctrl_set_cfg_mpeg_output()
38b2df95
DH
2715* \brief Set MPEG output configuration of the device.
2716* \param devmod Pointer to demodulator instance.
57afe2f0 2717* \param cfg_data Pointer to mpeg output configuaration.
61263c75 2718* \return int.
38b2df95
DH
2719*
2720* Configure MPEG output parameters.
2721*
2722*/
61263c75 2723static int
1bfc9e15 2724ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
57afe2f0 2725{
22892268 2726 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
b3ce3a83 2727 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
1bfc9e15 2728 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
068e94ea 2729 int rc;
57afe2f0
MCC
2730 u16 fec_oc_reg_mode = 0;
2731 u16 fec_oc_reg_ipr_mode = 0;
2732 u16 fec_oc_reg_ipr_invert = 0;
2733 u32 max_bit_rate = 0;
2734 u32 rcn_rate = 0;
2735 u32 nr_bits = 0;
2736 u16 sio_pdr_md_cfg = 0;
443f18d0 2737 /* data mask for the output data byte */
57afe2f0 2738 u16 invert_data_mask =
443f18d0
MCC
2739 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2740 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2741 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2742 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
068e94ea 2743
443f18d0 2744 /* check arguments */
63713517 2745 if ((demod == NULL) || (cfg_data == NULL))
9482354f 2746 return -EINVAL;
38b2df95 2747
57afe2f0 2748 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 2749 ext_attr = (struct drxj_data *) demod->my_ext_attr;
1bfc9e15 2750 common_attr = (struct drx_common_attr *) demod->my_common_attr;
443f18d0 2751
57afe2f0 2752 if (cfg_data->enable_mpeg_output == true) {
443f18d0
MCC
2753 /* quick and dirty patch to set MPEG incase current std is not
2754 producing MPEG */
57afe2f0 2755 switch (ext_attr->standard) {
443f18d0
MCC
2756 case DRX_STANDARD_8VSB:
2757 case DRX_STANDARD_ITU_A:
2758 case DRX_STANDARD_ITU_B:
2759 case DRX_STANDARD_ITU_C:
2760 break;
2761 default:
9482354f 2762 return 0;
443f18d0
MCC
2763 }
2764
244c0e06 2765 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
9482354f 2766 if (rc != 0) {
068e94ea
MCC
2767 pr_err("error %d\n", rc);
2768 goto rw_error;
2769 }
57afe2f0 2770 switch (ext_attr->standard) {
443f18d0 2771 case DRX_STANDARD_8VSB:
244c0e06 2772 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
9482354f 2773 if (rc != 0) {
068e94ea
MCC
2774 pr_err("error %d\n", rc);
2775 goto rw_error;
2776 } /* 2048 bytes fifo ram */
244c0e06 2777 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
9482354f 2778 if (rc != 0) {
068e94ea
MCC
2779 pr_err("error %d\n", rc);
2780 goto rw_error;
2781 }
244c0e06 2782 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
9482354f 2783 if (rc != 0) {
068e94ea
MCC
2784 pr_err("error %d\n", rc);
2785 goto rw_error;
2786 }
244c0e06 2787 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
9482354f 2788 if (rc != 0) {
068e94ea
MCC
2789 pr_err("error %d\n", rc);
2790 goto rw_error;
2791 }
244c0e06 2792 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
9482354f 2793 if (rc != 0) {
068e94ea
MCC
2794 pr_err("error %d\n", rc);
2795 goto rw_error;
2796 }
244c0e06 2797 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
9482354f 2798 if (rc != 0) {
068e94ea
MCC
2799 pr_err("error %d\n", rc);
2800 goto rw_error;
2801 }
443f18d0 2802 /* Low Water Mark for synchronization */
244c0e06 2803 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
9482354f 2804 if (rc != 0) {
068e94ea
MCC
2805 pr_err("error %d\n", rc);
2806 goto rw_error;
2807 }
443f18d0 2808 /* High Water Mark for synchronization */
244c0e06 2809 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
9482354f 2810 if (rc != 0) {
068e94ea
MCC
2811 pr_err("error %d\n", rc);
2812 goto rw_error;
2813 }
443f18d0
MCC
2814 break;
2815 case DRX_STANDARD_ITU_A:
2816 case DRX_STANDARD_ITU_C:
57afe2f0 2817 switch (ext_attr->constellation) {
443f18d0 2818 case DRX_CONSTELLATION_QAM256:
57afe2f0 2819 nr_bits = 8;
443f18d0
MCC
2820 break;
2821 case DRX_CONSTELLATION_QAM128:
57afe2f0 2822 nr_bits = 7;
443f18d0
MCC
2823 break;
2824 case DRX_CONSTELLATION_QAM64:
57afe2f0 2825 nr_bits = 6;
443f18d0
MCC
2826 break;
2827 case DRX_CONSTELLATION_QAM32:
57afe2f0 2828 nr_bits = 5;
443f18d0
MCC
2829 break;
2830 case DRX_CONSTELLATION_QAM16:
57afe2f0 2831 nr_bits = 4;
443f18d0
MCC
2832 break;
2833 default:
9482354f 2834 return -EIO;
57afe2f0
MCC
2835 } /* ext_attr->constellation */
2836 /* max_bit_rate = symbol_rate * nr_bits * coef */
443f18d0 2837 /* coef = 188/204 */
57afe2f0
MCC
2838 max_bit_rate =
2839 (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
06eeefe8
MCC
2840 /* pass through as b/c Annex A/c need following settings */
2841 /* fall-through */
443f18d0 2842 case DRX_STANDARD_ITU_B:
244c0e06 2843 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
9482354f 2844 if (rc != 0) {
068e94ea
MCC
2845 pr_err("error %d\n", rc);
2846 goto rw_error;
2847 }
244c0e06 2848 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
9482354f 2849 if (rc != 0) {
068e94ea
MCC
2850 pr_err("error %d\n", rc);
2851 goto rw_error;
2852 }
244c0e06 2853 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
9482354f 2854 if (rc != 0) {
068e94ea
MCC
2855 pr_err("error %d\n", rc);
2856 goto rw_error;
2857 }
244c0e06 2858 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
9482354f 2859 if (rc != 0) {
068e94ea
MCC
2860 pr_err("error %d\n", rc);
2861 goto rw_error;
2862 }
244c0e06 2863 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
9482354f 2864 if (rc != 0) {
068e94ea
MCC
2865 pr_err("error %d\n", rc);
2866 goto rw_error;
2867 }
57afe2f0 2868 if (cfg_data->static_clk == true) {
244c0e06 2869 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
9482354f 2870 if (rc != 0) {
068e94ea
MCC
2871 pr_err("error %d\n", rc);
2872 goto rw_error;
2873 }
443f18d0 2874 } else {
244c0e06 2875 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
9482354f 2876 if (rc != 0) {
068e94ea
MCC
2877 pr_err("error %d\n", rc);
2878 goto rw_error;
2879 }
2880 }
244c0e06 2881 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
9482354f 2882 if (rc != 0) {
068e94ea
MCC
2883 pr_err("error %d\n", rc);
2884 goto rw_error;
2885 }
244c0e06 2886 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
9482354f 2887 if (rc != 0) {
068e94ea
MCC
2888 pr_err("error %d\n", rc);
2889 goto rw_error;
443f18d0 2890 }
443f18d0
MCC
2891 break;
2892 default:
2893 break;
2894 } /* swtich (standard) */
2895
2896 /* Check insertion of the Reed-Solomon parity bytes */
244c0e06 2897 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
9482354f 2898 if (rc != 0) {
068e94ea
MCC
2899 pr_err("error %d\n", rc);
2900 goto rw_error;
2901 }
244c0e06 2902 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
9482354f 2903 if (rc != 0) {
068e94ea
MCC
2904 pr_err("error %d\n", rc);
2905 goto rw_error;
2906 }
57afe2f0 2907 if (cfg_data->insert_rs_byte == true) {
443f18d0 2908 /* enable parity symbol forward */
57afe2f0 2909 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
443f18d0 2910 /* MVAL disable during parity bytes */
57afe2f0
MCC
2911 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2912 switch (ext_attr->standard) {
443f18d0 2913 case DRX_STANDARD_8VSB:
57afe2f0 2914 rcn_rate = 0x004854D3;
443f18d0
MCC
2915 break;
2916 case DRX_STANDARD_ITU_B:
57afe2f0
MCC
2917 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2918 switch (ext_attr->constellation) {
443f18d0 2919 case DRX_CONSTELLATION_QAM256:
57afe2f0 2920 rcn_rate = 0x008945E7;
443f18d0
MCC
2921 break;
2922 case DRX_CONSTELLATION_QAM64:
57afe2f0 2923 rcn_rate = 0x005F64D4;
443f18d0
MCC
2924 break;
2925 default:
9482354f 2926 return -EIO;
443f18d0
MCC
2927 }
2928 break;
2929 case DRX_STANDARD_ITU_A:
2930 case DRX_STANDARD_ITU_C:
57afe2f0
MCC
2931 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2932 rcn_rate =
2933 (frac28
2934 (max_bit_rate,
2935 (u32) (common_attr->sys_clock_freq / 8))) /
443f18d0
MCC
2936 188;
2937 break;
2938 default:
9482354f 2939 return -EIO;
57afe2f0
MCC
2940 } /* ext_attr->standard */
2941 } else { /* insert_rs_byte == false */
443f18d0
MCC
2942
2943 /* disable parity symbol forward */
57afe2f0 2944 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
443f18d0 2945 /* MVAL enable during parity bytes */
57afe2f0
MCC
2946 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2947 switch (ext_attr->standard) {
443f18d0 2948 case DRX_STANDARD_8VSB:
57afe2f0 2949 rcn_rate = 0x0041605C;
443f18d0
MCC
2950 break;
2951 case DRX_STANDARD_ITU_B:
57afe2f0
MCC
2952 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2953 switch (ext_attr->constellation) {
443f18d0 2954 case DRX_CONSTELLATION_QAM256:
57afe2f0 2955 rcn_rate = 0x0082D6A0;
443f18d0
MCC
2956 break;
2957 case DRX_CONSTELLATION_QAM64:
57afe2f0 2958 rcn_rate = 0x005AEC1A;
443f18d0
MCC
2959 break;
2960 default:
9482354f 2961 return -EIO;
443f18d0
MCC
2962 }
2963 break;
2964 case DRX_STANDARD_ITU_A:
2965 case DRX_STANDARD_ITU_C:
57afe2f0
MCC
2966 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2967 rcn_rate =
2968 (frac28
2969 (max_bit_rate,
2970 (u32) (common_attr->sys_clock_freq / 8))) /
443f18d0
MCC
2971 204;
2972 break;
2973 default:
9482354f 2974 return -EIO;
57afe2f0 2975 } /* ext_attr->standard */
443f18d0
MCC
2976 }
2977
69bb7ab6 2978 if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> clear ipr_mode[0] */
57afe2f0 2979 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
443f18d0 2980 } else { /* MPEG data output is serial -> set ipr_mode[0] */
57afe2f0 2981 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
443f18d0
MCC
2982 }
2983
2984 /* Control slective inversion of output bits */
63713517 2985 if (cfg_data->invert_data == true)
57afe2f0 2986 fec_oc_reg_ipr_invert |= invert_data_mask;
63713517 2987 else
57afe2f0 2988 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
443f18d0 2989
63713517 2990 if (cfg_data->invert_err == true)
57afe2f0 2991 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
63713517 2992 else
57afe2f0 2993 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
443f18d0 2994
63713517 2995 if (cfg_data->invert_str == true)
57afe2f0 2996 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
63713517 2997 else
57afe2f0 2998 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
443f18d0 2999
63713517 3000 if (cfg_data->invert_val == true)
57afe2f0 3001 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
63713517 3002 else
57afe2f0 3003 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
443f18d0 3004
63713517 3005 if (cfg_data->invert_clk == true)
57afe2f0 3006 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
63713517 3007 else
57afe2f0 3008 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
443f18d0 3009
41b5cc0c 3010
57afe2f0
MCC
3011 if (cfg_data->static_clk == true) { /* Static mode */
3012 u32 dto_rate = 0;
3013 u32 bit_rate = 0;
3014 u16 fec_oc_dto_burst_len = 0;
3015 u16 fec_oc_dto_period = 0;
443f18d0 3016
57afe2f0 3017 fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
443f18d0 3018
57afe2f0 3019 switch (ext_attr->standard) {
443f18d0 3020 case DRX_STANDARD_8VSB:
57afe2f0 3021 fec_oc_dto_period = 4;
63713517 3022 if (cfg_data->insert_rs_byte == true)
57afe2f0 3023 fec_oc_dto_burst_len = 208;
443f18d0
MCC
3024 break;
3025 case DRX_STANDARD_ITU_A:
3026 {
57afe2f0
MCC
3027 u32 symbol_rate_th = 6400000;
3028 if (cfg_data->insert_rs_byte == true) {
3029 fec_oc_dto_burst_len = 204;
3030 symbol_rate_th = 5900000;
443f18d0 3031 }
57afe2f0
MCC
3032 if (ext_attr->curr_symbol_rate >=
3033 symbol_rate_th) {
3034 fec_oc_dto_period = 0;
443f18d0 3035 } else {
57afe2f0 3036 fec_oc_dto_period = 1;
443f18d0
MCC
3037 }
3038 }
3039 break;
3040 case DRX_STANDARD_ITU_B:
57afe2f0 3041 fec_oc_dto_period = 1;
63713517 3042 if (cfg_data->insert_rs_byte == true)
57afe2f0 3043 fec_oc_dto_burst_len = 128;
443f18d0
MCC
3044 break;
3045 case DRX_STANDARD_ITU_C:
57afe2f0 3046 fec_oc_dto_period = 1;
63713517 3047 if (cfg_data->insert_rs_byte == true)
57afe2f0 3048 fec_oc_dto_burst_len = 204;
443f18d0
MCC
3049 break;
3050 default:
9482354f 3051 return -EIO;
443f18d0 3052 }
57afe2f0
MCC
3053 bit_rate =
3054 common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
443f18d0 3055 2);
57afe2f0
MCC
3056 dto_rate =
3057 frac28(bit_rate, common_attr->sys_clock_freq * 1000);
3058 dto_rate >>= 3;
244c0e06 3059 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
9482354f 3060 if (rc != 0) {
068e94ea
MCC
3061 pr_err("error %d\n", rc);
3062 goto rw_error;
3063 }
244c0e06 3064 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_LO__A, (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), 0);
9482354f 3065 if (rc != 0) {
068e94ea
MCC
3066 pr_err("error %d\n", rc);
3067 goto rw_error;
3068 }
244c0e06 3069 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M, 0);
9482354f 3070 if (rc != 0) {
068e94ea
MCC
3071 pr_err("error %d\n", rc);
3072 goto rw_error;
3073 }
244c0e06 3074 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M, 0);
9482354f 3075 if (rc != 0) {
068e94ea
MCC
3076 pr_err("error %d\n", rc);
3077 goto rw_error;
3078 }
244c0e06 3079 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
9482354f 3080 if (rc != 0) {
068e94ea
MCC
3081 pr_err("error %d\n", rc);
3082 goto rw_error;
3083 }
63713517
MCC
3084 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3085 fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
244c0e06 3086 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
9482354f 3087 if (rc != 0) {
068e94ea
MCC
3088 pr_err("error %d\n", rc);
3089 goto rw_error;
3090 }
443f18d0
MCC
3091 } else { /* Dynamic mode */
3092
244c0e06 3093 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
9482354f 3094 if (rc != 0) {
068e94ea
MCC
3095 pr_err("error %d\n", rc);
3096 goto rw_error;
3097 }
244c0e06 3098 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
9482354f 3099 if (rc != 0) {
068e94ea
MCC
3100 pr_err("error %d\n", rc);
3101 goto rw_error;
3102 }
443f18d0
MCC
3103 }
3104
244c0e06 3105 rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
9482354f 3106 if (rc != 0) {
068e94ea
MCC
3107 pr_err("error %d\n", rc);
3108 goto rw_error;
3109 }
443f18d0
MCC
3110
3111 /* Write appropriate registers with requested configuration */
244c0e06 3112 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
9482354f 3113 if (rc != 0) {
068e94ea
MCC
3114 pr_err("error %d\n", rc);
3115 goto rw_error;
3116 }
244c0e06 3117 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
9482354f 3118 if (rc != 0) {
068e94ea
MCC
3119 pr_err("error %d\n", rc);
3120 goto rw_error;
3121 }
244c0e06 3122 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
9482354f 3123 if (rc != 0) {
068e94ea
MCC
3124 pr_err("error %d\n", rc);
3125 goto rw_error;
3126 }
443f18d0
MCC
3127
3128 /* enabling for both parallel and serial now */
3129 /* Write magic word to enable pdr reg write */
244c0e06 3130 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
9482354f 3131 if (rc != 0) {
068e94ea
MCC
3132 pr_err("error %d\n", rc);
3133 goto rw_error;
3134 }
443f18d0 3135 /* Set MPEG TS pads to outputmode */
244c0e06 3136 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
9482354f 3137 if (rc != 0) {
068e94ea
MCC
3138 pr_err("error %d\n", rc);
3139 goto rw_error;
3140 }
244c0e06 3141 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
9482354f 3142 if (rc != 0) {
068e94ea
MCC
3143 pr_err("error %d\n", rc);
3144 goto rw_error;
3145 }
244c0e06 3146 rc = drxj_dap_write_reg16(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);
9482354f 3147 if (rc != 0) {
068e94ea
MCC
3148 pr_err("error %d\n", rc);
3149 goto rw_error;
3150 }
244c0e06 3151 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
9482354f 3152 if (rc != 0) {
068e94ea
MCC
3153 pr_err("error %d\n", rc);
3154 goto rw_error;
3155 }
57afe2f0 3156 sio_pdr_md_cfg =
443f18d0
MCC
3157 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3158 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
244c0e06 3159 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3160 if (rc != 0) {
068e94ea
MCC
3161 pr_err("error %d\n", rc);
3162 goto rw_error;
3163 }
69bb7ab6 3164 if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> set MD1 to MD7 to output mode */
57afe2f0 3165 sio_pdr_md_cfg =
443f18d0
MCC
3166 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3167 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3168 SIO_PDR_MD0_CFG_MODE__B;
244c0e06 3169 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3170 if (rc != 0) {
068e94ea
MCC
3171 pr_err("error %d\n", rc);
3172 goto rw_error;
3173 }
244c0e06 3174 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3175 if (rc != 0) {
068e94ea
MCC
3176 pr_err("error %d\n", rc);
3177 goto rw_error;
3178 }
244c0e06 3179 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3180 if (rc != 0) {
068e94ea
MCC
3181 pr_err("error %d\n", rc);
3182 goto rw_error;
3183 }
244c0e06 3184 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3185 if (rc != 0) {
068e94ea
MCC
3186 pr_err("error %d\n", rc);
3187 goto rw_error;
3188 }
244c0e06 3189 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3190 if (rc != 0) {
068e94ea
MCC
3191 pr_err("error %d\n", rc);
3192 goto rw_error;
3193 }
244c0e06 3194 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3195 if (rc != 0) {
068e94ea
MCC
3196 pr_err("error %d\n", rc);
3197 goto rw_error;
3198 }
244c0e06 3199 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3200 if (rc != 0) {
068e94ea
MCC
3201 pr_err("error %d\n", rc);
3202 goto rw_error;
3203 }
244c0e06 3204 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3205 if (rc != 0) {
068e94ea
MCC
3206 pr_err("error %d\n", rc);
3207 goto rw_error;
3208 }
443f18d0 3209 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
244c0e06 3210 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
9482354f 3211 if (rc != 0) {
068e94ea
MCC
3212 pr_err("error %d\n", rc);
3213 goto rw_error;
3214 }
244c0e06 3215 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
9482354f 3216 if (rc != 0) {
068e94ea
MCC
3217 pr_err("error %d\n", rc);
3218 goto rw_error;
3219 }
244c0e06 3220 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
9482354f 3221 if (rc != 0) {
068e94ea
MCC
3222 pr_err("error %d\n", rc);
3223 goto rw_error;
3224 }
244c0e06 3225 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
9482354f 3226 if (rc != 0) {
068e94ea
MCC
3227 pr_err("error %d\n", rc);
3228 goto rw_error;
3229 }
244c0e06 3230 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
9482354f 3231 if (rc != 0) {
068e94ea
MCC
3232 pr_err("error %d\n", rc);
3233 goto rw_error;
3234 }
244c0e06 3235 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
9482354f 3236 if (rc != 0) {
068e94ea
MCC
3237 pr_err("error %d\n", rc);
3238 goto rw_error;
3239 }
244c0e06 3240 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
9482354f 3241 if (rc != 0) {
068e94ea
MCC
3242 pr_err("error %d\n", rc);
3243 goto rw_error;
3244 }
443f18d0
MCC
3245 }
3246 /* Enable Monitor Bus output over MPEG pads and ctl input */
244c0e06 3247 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
9482354f 3248 if (rc != 0) {
068e94ea
MCC
3249 pr_err("error %d\n", rc);
3250 goto rw_error;
3251 }
443f18d0 3252 /* Write nomagic word to enable pdr reg write */
244c0e06 3253 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3254 if (rc != 0) {
068e94ea
MCC
3255 pr_err("error %d\n", rc);
3256 goto rw_error;
3257 }
443f18d0
MCC
3258 } else {
3259 /* Write magic word to enable pdr reg write */
244c0e06 3260 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
9482354f 3261 if (rc != 0) {
068e94ea
MCC
3262 pr_err("error %d\n", rc);
3263 goto rw_error;
3264 }
443f18d0 3265 /* Set MPEG TS pads to inputmode */
244c0e06 3266 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
9482354f 3267 if (rc != 0) {
068e94ea
MCC
3268 pr_err("error %d\n", rc);
3269 goto rw_error;
3270 }
244c0e06 3271 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
9482354f 3272 if (rc != 0) {
068e94ea
MCC
3273 pr_err("error %d\n", rc);
3274 goto rw_error;
3275 }
244c0e06 3276 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
9482354f 3277 if (rc != 0) {
068e94ea
MCC
3278 pr_err("error %d\n", rc);
3279 goto rw_error;
3280 }
244c0e06 3281 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
9482354f 3282 if (rc != 0) {
068e94ea
MCC
3283 pr_err("error %d\n", rc);
3284 goto rw_error;
3285 }
244c0e06 3286 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
9482354f 3287 if (rc != 0) {
068e94ea
MCC
3288 pr_err("error %d\n", rc);
3289 goto rw_error;
3290 }
244c0e06 3291 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
9482354f 3292 if (rc != 0) {
068e94ea
MCC
3293 pr_err("error %d\n", rc);
3294 goto rw_error;
3295 }
244c0e06 3296 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
9482354f 3297 if (rc != 0) {
068e94ea
MCC
3298 pr_err("error %d\n", rc);
3299 goto rw_error;
3300 }
244c0e06 3301 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
9482354f 3302 if (rc != 0) {
068e94ea
MCC
3303 pr_err("error %d\n", rc);
3304 goto rw_error;
3305 }
244c0e06 3306 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
9482354f 3307 if (rc != 0) {
068e94ea
MCC
3308 pr_err("error %d\n", rc);
3309 goto rw_error;
3310 }
244c0e06 3311 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
9482354f 3312 if (rc != 0) {
068e94ea
MCC
3313 pr_err("error %d\n", rc);
3314 goto rw_error;
3315 }
244c0e06 3316 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
9482354f 3317 if (rc != 0) {
068e94ea
MCC
3318 pr_err("error %d\n", rc);
3319 goto rw_error;
3320 }
244c0e06 3321 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
9482354f 3322 if (rc != 0) {
068e94ea
MCC
3323 pr_err("error %d\n", rc);
3324 goto rw_error;
3325 }
443f18d0 3326 /* Enable Monitor Bus output over MPEG pads and ctl input */
244c0e06 3327 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
9482354f 3328 if (rc != 0) {
068e94ea
MCC
3329 pr_err("error %d\n", rc);
3330 goto rw_error;
3331 }
443f18d0 3332 /* Write nomagic word to enable pdr reg write */
244c0e06 3333 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3334 if (rc != 0) {
068e94ea
MCC
3335 pr_err("error %d\n", rc);
3336 goto rw_error;
3337 }
443f18d0
MCC
3338 }
3339
3340 /* save values for restore after re-acquire */
57afe2f0 3341 common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
443f18d0 3342
9482354f 3343 return 0;
38b2df95 3344rw_error:
30741871 3345 return rc;
38b2df95
DH
3346}
3347
3348/*----------------------------------------------------------------------------*/
3349
38b2df95
DH
3350
3351/*----------------------------------------------------------------------------*/
3352/* MPEG Output Configuration Functions - end */
3353/*----------------------------------------------------------------------------*/
3354
3355/*----------------------------------------------------------------------------*/
2c149601 3356/* miscellaneous configurations - begin */
38b2df95
DH
3357/*----------------------------------------------------------------------------*/
3358
34eb9751 3359/*
57afe2f0 3360* \fn int set_mpegtei_handling()
38b2df95
DH
3361* \brief Activate MPEG TEI handling settings.
3362* \param devmod Pointer to demodulator instance.
61263c75 3363* \return int.
38b2df95
DH
3364*
3365* This routine should be called during a set channel of QAM/VSB
3366*
3367*/
1bfc9e15 3368static int set_mpegtei_handling(struct drx_demod_instance *demod)
38b2df95 3369{
b3ce3a83 3370 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
22892268 3371 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
068e94ea 3372 int rc;
57afe2f0
MCC
3373 u16 fec_oc_dpr_mode = 0;
3374 u16 fec_oc_snc_mode = 0;
3375 u16 fec_oc_ems_mode = 0;
443f18d0 3376
57afe2f0 3377 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 3378 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0 3379
244c0e06 3380 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
9482354f 3381 if (rc != 0) {
068e94ea
MCC
3382 pr_err("error %d\n", rc);
3383 goto rw_error;
3384 }
244c0e06 3385 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
9482354f 3386 if (rc != 0) {
068e94ea
MCC
3387 pr_err("error %d\n", rc);
3388 goto rw_error;
3389 }
244c0e06 3390 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
9482354f 3391 if (rc != 0) {
068e94ea
MCC
3392 pr_err("error %d\n", rc);
3393 goto rw_error;
3394 }
443f18d0
MCC
3395
3396 /* reset to default, allow TEI bit to be changed */
57afe2f0
MCC
3397 fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3398 fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
443f18d0 3399 FEC_OC_SNC_MODE_CORR_DISABLE__M));
57afe2f0 3400 fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
443f18d0 3401
259f380e 3402 if (ext_attr->disable_te_ihandling) {
443f18d0 3403 /* do not change TEI bit */
57afe2f0
MCC
3404 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3405 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
443f18d0 3406 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
57afe2f0 3407 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
443f18d0
MCC
3408 }
3409
244c0e06 3410 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
9482354f 3411 if (rc != 0) {
068e94ea
MCC
3412 pr_err("error %d\n", rc);
3413 goto rw_error;
3414 }
244c0e06 3415 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
9482354f 3416 if (rc != 0) {
068e94ea
MCC
3417 pr_err("error %d\n", rc);
3418 goto rw_error;
3419 }
244c0e06 3420 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
9482354f 3421 if (rc != 0) {
068e94ea
MCC
3422 pr_err("error %d\n", rc);
3423 goto rw_error;
3424 }
443f18d0 3425
9482354f 3426 return 0;
38b2df95 3427rw_error:
30741871 3428 return rc;
38b2df95
DH
3429}
3430
3431/*----------------------------------------------------------------------------*/
34eb9751 3432/*
57afe2f0 3433* \fn int bit_reverse_mpeg_output()
38b2df95
DH
3434* \brief Set MPEG output bit-endian settings.
3435* \param devmod Pointer to demodulator instance.
61263c75 3436* \return int.
38b2df95
DH
3437*
3438* This routine should be called during a set channel of QAM/VSB
3439*
3440*/
1bfc9e15 3441static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
38b2df95 3442{
b3ce3a83 3443 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
22892268 3444 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
068e94ea 3445 int rc;
57afe2f0 3446 u16 fec_oc_ipr_mode = 0;
38b2df95 3447
57afe2f0 3448 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 3449 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 3450
244c0e06 3451 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
9482354f 3452 if (rc != 0) {
068e94ea
MCC
3453 pr_err("error %d\n", rc);
3454 goto rw_error;
3455 }
38b2df95 3456
443f18d0 3457 /* reset to default (normal bit order) */
57afe2f0 3458 fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
38b2df95 3459
63713517 3460 if (ext_attr->bit_reverse_mpeg_outout)
57afe2f0 3461 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
38b2df95 3462
244c0e06 3463 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
9482354f 3464 if (rc != 0) {
068e94ea
MCC
3465 pr_err("error %d\n", rc);
3466 goto rw_error;
3467 }
38b2df95 3468
9482354f 3469 return 0;
38b2df95 3470rw_error:
30741871 3471 return rc;
38b2df95
DH
3472}
3473
38b2df95 3474/*----------------------------------------------------------------------------*/
34eb9751 3475/*
57afe2f0 3476* \fn int set_mpeg_start_width()
38b2df95
DH
3477* \brief Set MPEG start width.
3478* \param devmod Pointer to demodulator instance.
61263c75 3479* \return int.
38b2df95
DH
3480*
3481* This routine should be called during a set channel of QAM/VSB
3482*
3483*/
1bfc9e15 3484static int set_mpeg_start_width(struct drx_demod_instance *demod)
38b2df95 3485{
b3ce3a83 3486 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
22892268 3487 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
1bfc9e15 3488 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
068e94ea
MCC
3489 int rc;
3490 u16 fec_oc_comm_mb = 0;
38b2df95 3491
57afe2f0 3492 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 3493 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0 3494 common_attr = demod->my_common_attr;
38b2df95 3495
57afe2f0
MCC
3496 if ((common_attr->mpeg_cfg.static_clk == true)
3497 && (common_attr->mpeg_cfg.enable_parallel == false)) {
244c0e06 3498 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
9482354f 3499 if (rc != 0) {
068e94ea
MCC
3500 pr_err("error %d\n", rc);
3501 goto rw_error;
3502 }
57afe2f0 3503 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
63713517 3504 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
57afe2f0 3505 fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
244c0e06 3506 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
9482354f 3507 if (rc != 0) {
068e94ea
MCC
3508 pr_err("error %d\n", rc);
3509 goto rw_error;
3510 }
443f18d0
MCC
3511 }
3512
9482354f 3513 return 0;
38b2df95 3514rw_error:
30741871 3515 return rc;
38b2df95
DH
3516}
3517
38b2df95 3518/*----------------------------------------------------------------------------*/
2c149601 3519/* miscellaneous configurations - end */
38b2df95
DH
3520/*----------------------------------------------------------------------------*/
3521
3522/*----------------------------------------------------------------------------*/
3523/* UIO Configuration Functions - begin */
3524/*----------------------------------------------------------------------------*/
34eb9751 3525/*
57afe2f0 3526* \fn int ctrl_set_uio_cfg()
38b2df95
DH
3527* \brief Configure modus oprandi UIO.
3528* \param demod Pointer to demodulator instance.
57afe2f0 3529* \param uio_cfg Pointer to a configuration setting for a certain UIO.
61263c75 3530* \return int.
38b2df95 3531*/
1bfc9e15 3532static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
38b2df95 3533{
b3ce3a83 3534 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
068e94ea 3535 int rc;
38b2df95 3536
63713517 3537 if ((uio_cfg == NULL) || (demod == NULL))
9482354f 3538 return -EINVAL;
63713517 3539
b3ce3a83 3540 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 3541
443f18d0 3542 /* Write magic word to enable pdr reg write */
244c0e06 3543 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 3544 if (rc != 0) {
068e94ea
MCC
3545 pr_err("error %d\n", rc);
3546 goto rw_error;
3547 }
57afe2f0 3548 switch (uio_cfg->uio) {
38b2df95 3549 /*====================================================================*/
443f18d0
MCC
3550 case DRX_UIO1:
3551 /* DRX_UIO1: SMA_TX UIO-1 */
259f380e 3552 if (!ext_attr->has_smatx)
9482354f 3553 return -EIO;
57afe2f0 3554 switch (uio_cfg->mode) {
443f18d0
MCC
3555 case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
3556 case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
3557 case DRX_UIO_MODE_READWRITE:
57afe2f0 3558 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
443f18d0
MCC
3559 break;
3560 case DRX_UIO_MODE_DISABLE:
57afe2f0 3561 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
443f18d0 3562 /* pad configuration register is set 0 - input mode */
244c0e06 3563 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
9482354f 3564 if (rc != 0) {
068e94ea
MCC
3565 pr_err("error %d\n", rc);
3566 goto rw_error;
3567 }
443f18d0
MCC
3568 break;
3569 default:
9482354f 3570 return -EINVAL;
57afe2f0 3571 } /* switch ( uio_cfg->mode ) */
443f18d0 3572 break;
38b2df95 3573 /*====================================================================*/
443f18d0
MCC
3574 case DRX_UIO2:
3575 /* DRX_UIO2: SMA_RX UIO-2 */
259f380e 3576 if (!ext_attr->has_smarx)
9482354f 3577 return -EIO;
57afe2f0 3578 switch (uio_cfg->mode) {
443f18d0
MCC
3579 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3580 case DRX_UIO_MODE_READWRITE:
57afe2f0 3581 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
443f18d0
MCC
3582 break;
3583 case DRX_UIO_MODE_DISABLE:
57afe2f0 3584 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
443f18d0 3585 /* pad configuration register is set 0 - input mode */
244c0e06 3586 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
9482354f 3587 if (rc != 0) {
068e94ea
MCC
3588 pr_err("error %d\n", rc);
3589 goto rw_error;
3590 }
443f18d0
MCC
3591 break;
3592 default:
9482354f 3593 return -EINVAL;
443f18d0 3594 break;
57afe2f0 3595 } /* switch ( uio_cfg->mode ) */
443f18d0 3596 break;
38b2df95 3597 /*====================================================================*/
443f18d0
MCC
3598 case DRX_UIO3:
3599 /* DRX_UIO3: GPIO UIO-3 */
259f380e 3600 if (!ext_attr->has_gpio)
9482354f 3601 return -EIO;
57afe2f0 3602 switch (uio_cfg->mode) {
443f18d0
MCC
3603 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3604 case DRX_UIO_MODE_READWRITE:
57afe2f0 3605 ext_attr->uio_gpio_mode = uio_cfg->mode;
443f18d0
MCC
3606 break;
3607 case DRX_UIO_MODE_DISABLE:
57afe2f0 3608 ext_attr->uio_gpio_mode = uio_cfg->mode;
443f18d0 3609 /* pad configuration register is set 0 - input mode */
244c0e06 3610 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
9482354f 3611 if (rc != 0) {
068e94ea
MCC
3612 pr_err("error %d\n", rc);
3613 goto rw_error;
3614 }
443f18d0
MCC
3615 break;
3616 default:
9482354f 3617 return -EINVAL;
443f18d0 3618 break;
57afe2f0 3619 } /* switch ( uio_cfg->mode ) */
443f18d0 3620 break;
38b2df95 3621 /*====================================================================*/
443f18d0
MCC
3622 case DRX_UIO4:
3623 /* DRX_UIO4: IRQN UIO-4 */
259f380e 3624 if (!ext_attr->has_irqn)
9482354f 3625 return -EIO;
57afe2f0 3626 switch (uio_cfg->mode) {
443f18d0 3627 case DRX_UIO_MODE_READWRITE:
57afe2f0 3628 ext_attr->uio_irqn_mode = uio_cfg->mode;
443f18d0
MCC
3629 break;
3630 case DRX_UIO_MODE_DISABLE:
3631 /* pad configuration register is set 0 - input mode */
244c0e06 3632 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
9482354f 3633 if (rc != 0) {
068e94ea
MCC
3634 pr_err("error %d\n", rc);
3635 goto rw_error;
3636 }
57afe2f0 3637 ext_attr->uio_irqn_mode = uio_cfg->mode;
443f18d0
MCC
3638 break;
3639 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3640 default:
9482354f 3641 return -EINVAL;
443f18d0 3642 break;
57afe2f0 3643 } /* switch ( uio_cfg->mode ) */
443f18d0 3644 break;
38b2df95 3645 /*====================================================================*/
443f18d0 3646 default:
9482354f 3647 return -EINVAL;
57afe2f0 3648 } /* switch ( uio_cfg->uio ) */
38b2df95 3649
443f18d0 3650 /* Write magic word to disable pdr reg write */
244c0e06 3651 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3652 if (rc != 0) {
068e94ea
MCC
3653 pr_err("error %d\n", rc);
3654 goto rw_error;
3655 }
38b2df95 3656
9482354f 3657 return 0;
443f18d0 3658rw_error:
30741871 3659 return rc;
38b2df95
DH
3660}
3661
34eb9751 3662/*
b6c4065e
MCC
3663* \fn int ctrl_uio_write()
3664* \brief Write to a UIO.
38b2df95 3665* \param demod Pointer to demodulator instance.
b6c4065e 3666* \param uio_data Pointer to data container for a certain UIO.
61263c75 3667* \return int.
38b2df95 3668*/
b6c4065e
MCC
3669static int
3670ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
38b2df95 3671{
b6c4065e
MCC
3672 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3673 int rc;
3674 u16 pin_cfg_value = 0;
3675 u16 value = 0;
38b2df95 3676
b6c4065e 3677 if ((uio_data == NULL) || (demod == NULL))
9482354f 3678 return -EINVAL;
38b2df95 3679
b6c4065e 3680 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 3681
443f18d0 3682 /* Write magic word to enable pdr reg write */
244c0e06 3683 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 3684 if (rc != 0) {
068e94ea
MCC
3685 pr_err("error %d\n", rc);
3686 goto rw_error;
3687 }
57afe2f0 3688 switch (uio_data->uio) {
38b2df95 3689 /*====================================================================*/
443f18d0
MCC
3690 case DRX_UIO1:
3691 /* DRX_UIO1: SMA_TX UIO-1 */
259f380e 3692 if (!ext_attr->has_smatx)
9482354f 3693 return -EIO;
57afe2f0
MCC
3694 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3695 && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
9482354f 3696 return -EIO;
443f18d0 3697 }
57afe2f0 3698 pin_cfg_value = 0;
443f18d0 3699 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
57afe2f0 3700 pin_cfg_value |= 0x0113;
443f18d0
MCC
3701 /* io_pad_cfg_mode output mode is drive always */
3702 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3703
3704 /* write to io pad configuration register - output mode */
244c0e06 3705 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
9482354f 3706 if (rc != 0) {
068e94ea
MCC
3707 pr_err("error %d\n", rc);
3708 goto rw_error;
3709 }
443f18d0
MCC
3710
3711 /* use corresponding bit in io data output registar */
244c0e06 3712 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
9482354f 3713 if (rc != 0) {
068e94ea
MCC
3714 pr_err("error %d\n", rc);
3715 goto rw_error;
3716 }
63713517 3717 if (!uio_data->value)
443f18d0 3718 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
63713517 3719 else
443f18d0 3720 value |= 0x8000; /* write one to 15th bit - 1st UIO */
63713517 3721
443f18d0 3722 /* write back to io data output register */
244c0e06 3723 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
9482354f 3724 if (rc != 0) {
068e94ea
MCC
3725 pr_err("error %d\n", rc);
3726 goto rw_error;
3727 }
443f18d0 3728 break;
38b2df95 3729 /*======================================================================*/
443f18d0
MCC
3730 case DRX_UIO2:
3731 /* DRX_UIO2: SMA_RX UIO-2 */
259f380e 3732 if (!ext_attr->has_smarx)
9482354f 3733 return -EIO;
63713517 3734 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
9482354f 3735 return -EIO;
63713517 3736
57afe2f0 3737 pin_cfg_value = 0;
443f18d0 3738 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
57afe2f0 3739 pin_cfg_value |= 0x0113;
443f18d0
MCC
3740 /* io_pad_cfg_mode output mode is drive always */
3741 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3742
3743 /* write to io pad configuration register - output mode */
244c0e06 3744 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
9482354f 3745 if (rc != 0) {
068e94ea
MCC
3746 pr_err("error %d\n", rc);
3747 goto rw_error;
3748 }
443f18d0
MCC
3749
3750 /* use corresponding bit in io data output registar */
244c0e06 3751 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
9482354f 3752 if (rc != 0) {
068e94ea
MCC
3753 pr_err("error %d\n", rc);
3754 goto rw_error;
3755 }
63713517 3756 if (!uio_data->value)
443f18d0 3757 value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
63713517 3758 else
443f18d0 3759 value |= 0x4000; /* write one to 14th bit - 2nd UIO */
63713517 3760
443f18d0 3761 /* write back to io data output register */
244c0e06 3762 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
9482354f 3763 if (rc != 0) {
068e94ea
MCC
3764 pr_err("error %d\n", rc);
3765 goto rw_error;
3766 }
443f18d0 3767 break;
38b2df95 3768 /*====================================================================*/
443f18d0
MCC
3769 case DRX_UIO3:
3770 /* DRX_UIO3: ASEL UIO-3 */
259f380e 3771 if (!ext_attr->has_gpio)
9482354f 3772 return -EIO;
63713517 3773 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
9482354f 3774 return -EIO;
63713517 3775
57afe2f0 3776 pin_cfg_value = 0;
443f18d0 3777 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
57afe2f0 3778 pin_cfg_value |= 0x0113;
443f18d0
MCC
3779 /* io_pad_cfg_mode output mode is drive always */
3780 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3781
3782 /* write to io pad configuration register - output mode */
244c0e06 3783 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
9482354f 3784 if (rc != 0) {
068e94ea
MCC
3785 pr_err("error %d\n", rc);
3786 goto rw_error;
3787 }
443f18d0
MCC
3788
3789 /* use corresponding bit in io data output registar */
244c0e06 3790 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
9482354f 3791 if (rc != 0) {
068e94ea
MCC
3792 pr_err("error %d\n", rc);
3793 goto rw_error;
3794 }
63713517 3795 if (!uio_data->value)
443f18d0 3796 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
63713517 3797 else
443f18d0 3798 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
63713517 3799
443f18d0 3800 /* write back to io data output register */
244c0e06 3801 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
9482354f 3802 if (rc != 0) {
068e94ea
MCC
3803 pr_err("error %d\n", rc);
3804 goto rw_error;
3805 }
443f18d0 3806 break;
38b2df95 3807 /*=====================================================================*/
443f18d0
MCC
3808 case DRX_UIO4:
3809 /* DRX_UIO4: IRQN UIO-4 */
259f380e 3810 if (!ext_attr->has_irqn)
9482354f 3811 return -EIO;
443f18d0 3812
63713517 3813 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
9482354f 3814 return -EIO;
63713517 3815
57afe2f0 3816 pin_cfg_value = 0;
443f18d0 3817 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
57afe2f0 3818 pin_cfg_value |= 0x0113;
443f18d0
MCC
3819 /* io_pad_cfg_mode output mode is drive always */
3820 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3821
3822 /* write to io pad configuration register - output mode */
244c0e06 3823 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
9482354f 3824 if (rc != 0) {
068e94ea
MCC
3825 pr_err("error %d\n", rc);
3826 goto rw_error;
3827 }
443f18d0
MCC
3828
3829 /* use corresponding bit in io data output registar */
244c0e06 3830 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
9482354f 3831 if (rc != 0) {
068e94ea
MCC
3832 pr_err("error %d\n", rc);
3833 goto rw_error;
3834 }
63713517 3835 if (uio_data->value == false)
443f18d0 3836 value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
63713517 3837 else
443f18d0 3838 value |= 0x1000; /* write one to 12th bit - 4th UIO */
63713517 3839
443f18d0 3840 /* write back to io data output register */
244c0e06 3841 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
9482354f 3842 if (rc != 0) {
068e94ea
MCC
3843 pr_err("error %d\n", rc);
3844 goto rw_error;
3845 }
443f18d0 3846 break;
38b2df95 3847 /*=====================================================================*/
443f18d0 3848 default:
9482354f 3849 return -EINVAL;
57afe2f0 3850 } /* switch ( uio_data->uio ) */
38b2df95 3851
443f18d0 3852 /* Write magic word to disable pdr reg write */
244c0e06 3853 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3854 if (rc != 0) {
068e94ea
MCC
3855 pr_err("error %d\n", rc);
3856 goto rw_error;
3857 }
38b2df95 3858
9482354f 3859 return 0;
443f18d0 3860rw_error:
30741871 3861 return rc;
38b2df95
DH
3862}
3863
38b2df95
DH
3864/*---------------------------------------------------------------------------*/
3865/* UIO Configuration Functions - end */
3866/*---------------------------------------------------------------------------*/
3867
3868/*----------------------------------------------------------------------------*/
3869/* I2C Bridge Functions - begin */
3870/*----------------------------------------------------------------------------*/
34eb9751 3871/*
57afe2f0 3872* \fn int ctrl_i2c_bridge()
38b2df95
DH
3873* \brief Open or close the I2C switch to tuner.
3874* \param demod Pointer to demodulator instance.
57afe2f0 3875* \param bridge_closed Pointer to bool indication if bridge is closed not.
61263c75 3876* \return int.
38b2df95
DH
3877
3878*/
61263c75 3879static int
1bfc9e15 3880ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
38b2df95 3881{
60d3603b 3882 struct drxj_hi_cmd hi_cmd;
43a431e4 3883 u16 result = 0;
38b2df95 3884
443f18d0 3885 /* check arguments */
63713517 3886 if (bridge_closed == NULL)
9482354f 3887 return -EINVAL;
38b2df95 3888
57afe2f0
MCC
3889 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
3890 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
63713517 3891 if (*bridge_closed)
57afe2f0 3892 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
63713517 3893 else
57afe2f0 3894 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
38b2df95 3895
57afe2f0 3896 return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
38b2df95 3897}
443f18d0 3898
38b2df95
DH
3899/*----------------------------------------------------------------------------*/
3900/* I2C Bridge Functions - end */
3901/*----------------------------------------------------------------------------*/
3902
3903/*----------------------------------------------------------------------------*/
3904/* Smart antenna Functions - begin */
3905/*----------------------------------------------------------------------------*/
34eb9751 3906/*
57afe2f0 3907* \fn int smart_ant_init()
38b2df95 3908* \brief Initialize Smart Antenna.
1bfc9e15 3909* \param pointer to struct drx_demod_instance.
61263c75 3910* \return int.
38b2df95
DH
3911*
3912*/
1bfc9e15 3913static int smart_ant_init(struct drx_demod_instance *demod)
38b2df95 3914{
b3ce3a83 3915 struct drxj_data *ext_attr = NULL;
57afe2f0 3916 struct i2c_device_addr *dev_addr = NULL;
1bfc9e15 3917 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
068e94ea
MCC
3918 int rc;
3919 u16 data = 0;
443f18d0 3920
57afe2f0 3921 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 3922 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
3923
3924 /* Write magic word to enable pdr reg write */
244c0e06 3925 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 3926 if (rc != 0) {
068e94ea
MCC
3927 pr_err("error %d\n", rc);
3928 goto rw_error;
3929 }
443f18d0 3930 /* init smart antenna */
244c0e06 3931 rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
9482354f 3932 if (rc != 0) {
068e94ea
MCC
3933 pr_err("error %d\n", rc);
3934 goto rw_error;
3935 }
63713517 3936 if (ext_attr->smart_ant_inverted) {
244c0e06 3937 rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
9482354f 3938 if (rc != 0) {
63713517
MCC
3939 pr_err("error %d\n", rc);
3940 goto rw_error;
068e94ea 3941 }
63713517 3942 } else {
244c0e06 3943 rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
9482354f 3944 if (rc != 0) {
63713517
MCC
3945 pr_err("error %d\n", rc);
3946 goto rw_error;
068e94ea 3947 }
63713517 3948 }
443f18d0
MCC
3949
3950 /* config SMA_TX pin to smart antenna mode */
068e94ea 3951 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
9482354f 3952 if (rc != 0) {
068e94ea
MCC
3953 pr_err("error %d\n", rc);
3954 goto rw_error;
3955 }
244c0e06 3956 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
9482354f 3957 if (rc != 0) {
068e94ea
MCC
3958 pr_err("error %d\n", rc);
3959 goto rw_error;
3960 }
244c0e06 3961 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
9482354f 3962 if (rc != 0) {
068e94ea
MCC
3963 pr_err("error %d\n", rc);
3964 goto rw_error;
3965 }
443f18d0
MCC
3966
3967 /* Write magic word to disable pdr reg write */
244c0e06 3968 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3969 if (rc != 0) {
068e94ea
MCC
3970 pr_err("error %d\n", rc);
3971 goto rw_error;
3972 }
443f18d0 3973
9482354f 3974 return 0;
38b2df95 3975rw_error:
30741871 3976 return rc;
38b2df95
DH
3977}
3978
b3ce3a83 3979static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
38b2df95 3980{
068e94ea 3981 int rc;
068e94ea 3982 u16 cur_cmd = 0;
ceea5e2d 3983 unsigned long timeout;
38b2df95 3984
443f18d0
MCC
3985 /* Check param */
3986 if (cmd == NULL)
9482354f 3987 return -EINVAL;
38b2df95 3988
443f18d0 3989 /* Wait until SCU command interface is ready to receive command */
244c0e06 3990 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
9482354f 3991 if (rc != 0) {
068e94ea
MCC
3992 pr_err("error %d\n", rc);
3993 goto rw_error;
3994 }
63713517 3995 if (cur_cmd != DRX_SCU_READY)
9482354f 3996 return -EIO;
38b2df95 3997
57afe2f0 3998 switch (cmd->parameter_len) {
443f18d0 3999 case 5:
244c0e06 4000 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
9482354f 4001 if (rc != 0) {
068e94ea
MCC
4002 pr_err("error %d\n", rc);
4003 goto rw_error;
4004 } /* fallthrough */
443f18d0 4005 case 4:
244c0e06 4006 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
9482354f 4007 if (rc != 0) {
068e94ea
MCC
4008 pr_err("error %d\n", rc);
4009 goto rw_error;
4010 } /* fallthrough */
443f18d0 4011 case 3:
244c0e06 4012 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
9482354f 4013 if (rc != 0) {
068e94ea
MCC
4014 pr_err("error %d\n", rc);
4015 goto rw_error;
4016 } /* fallthrough */
443f18d0 4017 case 2:
244c0e06 4018 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
9482354f 4019 if (rc != 0) {
068e94ea
MCC
4020 pr_err("error %d\n", rc);
4021 goto rw_error;
4022 } /* fallthrough */
443f18d0 4023 case 1:
244c0e06 4024 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
9482354f 4025 if (rc != 0) {
068e94ea
MCC
4026 pr_err("error %d\n", rc);
4027 goto rw_error;
4028 } /* fallthrough */
443f18d0
MCC
4029 case 0:
4030 /* do nothing */
4031 break;
4032 default:
4033 /* this number of parameters is not supported */
9482354f 4034 return -EIO;
443f18d0 4035 }
244c0e06 4036 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
9482354f 4037 if (rc != 0) {
068e94ea
MCC
4038 pr_err("error %d\n", rc);
4039 goto rw_error;
4040 }
38b2df95 4041
443f18d0 4042 /* Wait until SCU has processed command */
ceea5e2d
MCC
4043 timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);
4044 while (time_is_after_jiffies(timeout)) {
244c0e06 4045 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
9482354f 4046 if (rc != 0) {
068e94ea
MCC
4047 pr_err("error %d\n", rc);
4048 goto rw_error;
4049 }
ceea5e2d
MCC
4050 if (cur_cmd == DRX_SCU_READY)
4051 break;
4052 usleep_range(1000, 2000);
4053 }
443f18d0 4054
63713517 4055 if (cur_cmd != DRX_SCU_READY)
9482354f 4056 return -EIO;
443f18d0
MCC
4057
4058 /* read results */
57afe2f0 4059 if ((cmd->result_len > 0) && (cmd->result != NULL)) {
43a431e4 4060 s16 err;
443f18d0 4061
57afe2f0 4062 switch (cmd->result_len) {
443f18d0 4063 case 4:
244c0e06 4064 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
9482354f 4065 if (rc != 0) {
068e94ea
MCC
4066 pr_err("error %d\n", rc);
4067 goto rw_error;
4068 } /* fallthrough */
443f18d0 4069 case 3:
244c0e06 4070 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
9482354f 4071 if (rc != 0) {
068e94ea
MCC
4072 pr_err("error %d\n", rc);
4073 goto rw_error;
4074 } /* fallthrough */
443f18d0 4075 case 2:
244c0e06 4076 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
9482354f 4077 if (rc != 0) {
068e94ea
MCC
4078 pr_err("error %d\n", rc);
4079 goto rw_error;
4080 } /* fallthrough */
443f18d0 4081 case 1:
244c0e06 4082 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
9482354f 4083 if (rc != 0) {
068e94ea
MCC
4084 pr_err("error %d\n", rc);
4085 goto rw_error;
4086 } /* fallthrough */
443f18d0
MCC
4087 case 0:
4088 /* do nothing */
4089 break;
4090 default:
4091 /* this number of parameters is not supported */
9482354f 4092 return -EIO;
443f18d0
MCC
4093 }
4094
4095 /* Check if an error was reported by SCU */
4096 err = cmd->result[0];
4097
4098 /* check a few fixed error codes */
43a431e4
MCC
4099 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4100 || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4101 || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4102 || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
443f18d0 4103 ) {
9482354f 4104 return -EINVAL;
443f18d0
MCC
4105 }
4106 /* here it is assumed that negative means error, and positive no error */
63713517 4107 else if (err < 0)
9482354f 4108 return -EIO;
63713517 4109 else
9482354f 4110 return 0;
443f18d0
MCC
4111 }
4112
9482354f 4113 return 0;
443f18d0
MCC
4114
4115rw_error:
30741871 4116 return rc;
38b2df95 4117}
443f18d0 4118
34eb9751 4119/*
61263c75 4120* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
38b2df95 4121* \brief Basic access routine for SCU atomic read or write access
57afe2f0 4122* \param dev_addr pointer to i2c dev address
38b2df95
DH
4123* \param addr destination/source address
4124* \param datasize size of data buffer in bytes
4125* \param data pointer to data buffer
61263c75 4126* \return int
9482354f
MCC
4127* \retval 0 Succes
4128* \retval -EIO Timeout, I2C error, illegal bank
38b2df95
DH
4129*
4130*/
4131#define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4132static
1bfc9e15 4133int 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 */
57afe2f0 4134 u8 *data, bool read_flag)
443f18d0 4135{
b3ce3a83 4136 struct drxjscu_cmd scu_cmd;
068e94ea 4137 int rc;
54c8cdd4 4138 u16 set_param_parameters[18];
57afe2f0 4139 u16 cmd_result[15];
443f18d0
MCC
4140
4141 /* Parameter check */
63713517 4142 if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
9482354f 4143 return -EINVAL;
38b2df95 4144
57afe2f0
MCC
4145 set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4146 if (read_flag) { /* read */
4147 set_param_parameters[0] = ((~(0x0080)) & datasize);
4148 scu_cmd.parameter_len = 2;
4149 scu_cmd.result_len = datasize / 2 + 2;
443f18d0
MCC
4150 } else {
4151 int i = 0;
4152
57afe2f0 4153 set_param_parameters[0] = 0x0080 | datasize;
443f18d0 4154 for (i = 0; i < (datasize / 2); i++) {
57afe2f0 4155 set_param_parameters[i + 2] =
443f18d0
MCC
4156 (data[2 * i] | (data[(2 * i) + 1] << 8));
4157 }
57afe2f0
MCC
4158 scu_cmd.parameter_len = datasize / 2 + 2;
4159 scu_cmd.result_len = 1;
443f18d0
MCC
4160 }
4161
57afe2f0 4162 scu_cmd.command =
443f18d0
MCC
4163 SCU_RAM_COMMAND_STANDARD_TOP |
4164 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
57afe2f0
MCC
4165 scu_cmd.result = cmd_result;
4166 scu_cmd.parameter = set_param_parameters;
068e94ea 4167 rc = scu_command(dev_addr, &scu_cmd);
9482354f 4168 if (rc != 0) {
068e94ea
MCC
4169 pr_err("error %d\n", rc);
4170 goto rw_error;
4171 }
443f18d0 4172
259f380e 4173 if (read_flag) {
443f18d0
MCC
4174 int i = 0;
4175 /* read data from buffer */
4176 for (i = 0; i < (datasize / 2); i++) {
57afe2f0
MCC
4177 data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4178 data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
443f18d0
MCC
4179 }
4180 }
38b2df95 4181
9482354f 4182 return 0;
38b2df95 4183
443f18d0 4184rw_error:
30741871 4185 return rc;
38b2df95
DH
4186
4187}
4188
4189/*============================================================================*/
4190
34eb9751 4191/*
61263c75 4192* \fn int DRXJ_DAP_AtomicReadReg16()
38b2df95
DH
4193* \brief Atomic read of 16 bits words
4194*/
4195static
57afe2f0 4196int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
4197 u32 addr,
4198 u16 *data, u32 flags)
38b2df95 4199{
4182438e 4200 u8 buf[2] = { 0 };
9482354f 4201 int rc = -EIO;
43a431e4 4202 u16 word = 0;
38b2df95 4203
63713517 4204 if (!data)
9482354f 4205 return -EINVAL;
38b2df95 4206
57afe2f0 4207 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
b1d0a596
MCC
4208 if (rc < 0)
4209 return rc;
38b2df95 4210
43a431e4 4211 word = (u16) (buf[0] + (buf[1] << 8));
38b2df95 4212
443f18d0 4213 *data = word;
38b2df95 4214
443f18d0 4215 return rc;
38b2df95 4216}
443f18d0 4217
38b2df95 4218/*============================================================================*/
34eb9751 4219/*
57afe2f0 4220* \fn int drxj_dap_scu_atomic_write_reg16()
38b2df95
DH
4221* \brief Atomic read of 16 bits words
4222*/
4223static
57afe2f0 4224int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
4225 u32 addr,
4226 u16 data, u32 flags)
38b2df95 4227{
43a431e4 4228 u8 buf[2];
9482354f 4229 int rc = -EIO;
38b2df95 4230
43a431e4
MCC
4231 buf[0] = (u8) (data & 0xff);
4232 buf[1] = (u8) ((data >> 8) & 0xff);
38b2df95 4233
57afe2f0 4234 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
38b2df95 4235
443f18d0 4236 return rc;
38b2df95
DH
4237}
4238
38b2df95 4239/* -------------------------------------------------------------------------- */
34eb9751 4240/*
38b2df95
DH
4241* \brief Measure result of ADC synchronisation
4242* \param demod demod instance
4243* \param count (returned) count
61263c75 4244* \return int.
9482354f
MCC
4245* \retval 0 Success
4246* \retval -EIO Failure: I2C error
38b2df95
DH
4247*
4248*/
1bfc9e15 4249static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
38b2df95 4250{
57afe2f0 4251 struct i2c_device_addr *dev_addr = NULL;
068e94ea
MCC
4252 int rc;
4253 u16 data = 0;
38b2df95 4254
57afe2f0 4255 dev_addr = demod->my_i2c_dev_addr;
38b2df95 4256
443f18d0 4257 /* Start measurement */
244c0e06 4258 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
9482354f 4259 if (rc != 0) {
068e94ea
MCC
4260 pr_err("error %d\n", rc);
4261 goto rw_error;
4262 }
244c0e06 4263 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
9482354f 4264 if (rc != 0) {
068e94ea
MCC
4265 pr_err("error %d\n", rc);
4266 goto rw_error;
4267 }
38b2df95 4268
443f18d0 4269 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
d7b0631e 4270 msleep(1);
38b2df95 4271
443f18d0 4272 *count = 0;
244c0e06 4273 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, &data, 0);
9482354f 4274 if (rc != 0) {
068e94ea
MCC
4275 pr_err("error %d\n", rc);
4276 goto rw_error;
4277 }
63713517 4278 if (data == 127)
443f18d0 4279 *count = *count + 1;
244c0e06 4280 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, &data, 0);
9482354f 4281 if (rc != 0) {
068e94ea
MCC
4282 pr_err("error %d\n", rc);
4283 goto rw_error;
4284 }
63713517 4285 if (data == 127)
443f18d0 4286 *count = *count + 1;
244c0e06 4287 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, &data, 0);
9482354f 4288 if (rc != 0) {
068e94ea
MCC
4289 pr_err("error %d\n", rc);
4290 goto rw_error;
4291 }
63713517 4292 if (data == 127)
443f18d0 4293 *count = *count + 1;
38b2df95 4294
9482354f 4295 return 0;
38b2df95 4296rw_error:
30741871 4297 return rc;
38b2df95
DH
4298}
4299
34eb9751 4300/*
38b2df95
DH
4301* \brief Synchronize analog and digital clock domains
4302* \param demod demod instance
61263c75 4303* \return int.
9482354f
MCC
4304* \retval 0 Success
4305* \retval -EIO Failure: I2C error or failure to synchronize
38b2df95
DH
4306*
4307* An IQM reset will also reset the results of this synchronization.
4308* After an IQM reset this routine needs to be called again.
4309*
4310*/
4311
1bfc9e15 4312static int adc_synchronization(struct drx_demod_instance *demod)
38b2df95 4313{
57afe2f0 4314 struct i2c_device_addr *dev_addr = NULL;
068e94ea
MCC
4315 int rc;
4316 u16 count = 0;
38b2df95 4317
57afe2f0 4318 dev_addr = demod->my_i2c_dev_addr;
38b2df95 4319
068e94ea 4320 rc = adc_sync_measurement(demod, &count);
9482354f 4321 if (rc != 0) {
068e94ea
MCC
4322 pr_err("error %d\n", rc);
4323 goto rw_error;
4324 }
38b2df95 4325
443f18d0 4326 if (count == 1) {
69bb7ab6 4327 /* Try sampling on a different edge */
57afe2f0 4328 u16 clk_neg = 0;
38b2df95 4329
244c0e06 4330 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
9482354f 4331 if (rc != 0) {
068e94ea
MCC
4332 pr_err("error %d\n", rc);
4333 goto rw_error;
4334 }
38b2df95 4335
57afe2f0 4336 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
244c0e06 4337 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
9482354f 4338 if (rc != 0) {
068e94ea
MCC
4339 pr_err("error %d\n", rc);
4340 goto rw_error;
4341 }
38b2df95 4342
068e94ea 4343 rc = adc_sync_measurement(demod, &count);
9482354f 4344 if (rc != 0) {
068e94ea
MCC
4345 pr_err("error %d\n", rc);
4346 goto rw_error;
4347 }
443f18d0 4348 }
38b2df95 4349
63713517
MCC
4350 /* TODO: implement fallback scenarios */
4351 if (count < 2)
9482354f 4352 return -EIO;
38b2df95 4353
9482354f 4354 return 0;
38b2df95 4355rw_error:
30741871 4356 return rc;
38b2df95
DH
4357}
4358
38b2df95
DH
4359/*============================================================================*/
4360/*== END AUXILIARY FUNCTIONS ==*/
4361/*============================================================================*/
4362
4363/*============================================================================*/
4364/*============================================================================*/
4365/*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
4366/*============================================================================*/
4367/*============================================================================*/
34eb9751 4368/*
57afe2f0 4369* \fn int init_agc ()
38b2df95
DH
4370* \brief Initialize AGC for all standards.
4371* \param demod instance of demodulator.
4372* \param channel pointer to channel data.
61263c75 4373* \return int.
38b2df95 4374*/
1bfc9e15 4375static int init_agc(struct drx_demod_instance *demod)
57afe2f0
MCC
4376{
4377 struct i2c_device_addr *dev_addr = NULL;
1bfc9e15 4378 struct drx_common_attr *common_attr = NULL;
b3ce3a83
MCC
4379 struct drxj_data *ext_attr = NULL;
4380 struct drxj_cfg_agc *p_agc_rf_settings = NULL;
4381 struct drxj_cfg_agc *p_agc_if_settings = NULL;
068e94ea 4382 int rc;
57afe2f0
MCC
4383 u16 ingain_tgt_max = 0;
4384 u16 clp_dir_to = 0;
4385 u16 sns_sum_max = 0;
4386 u16 clp_sum_max = 0;
4387 u16 sns_dir_to = 0;
4388 u16 ki_innergain_min = 0;
4389 u16 agc_ki = 0;
4390 u16 ki_max = 0;
4391 u16 if_iaccu_hi_tgt_min = 0;
43a431e4 4392 u16 data = 0;
e33f2193 4393 u16 agc_ki_dgain = 0;
57afe2f0
MCC
4394 u16 ki_min = 0;
4395 u16 clp_ctrl_mode = 0;
4396 u16 agc_rf = 0;
4397 u16 agc_if = 0;
068e94ea 4398
57afe2f0 4399 dev_addr = demod->my_i2c_dev_addr;
1bfc9e15 4400 common_attr = (struct drx_common_attr *) demod->my_common_attr;
b3ce3a83 4401 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0
MCC
4402
4403 switch (ext_attr->standard) {
443f18d0 4404 case DRX_STANDARD_8VSB:
57afe2f0
MCC
4405 clp_sum_max = 1023;
4406 clp_dir_to = (u16) (-9);
4407 sns_sum_max = 1023;
4408 sns_dir_to = (u16) (-9);
4409 ki_innergain_min = (u16) (-32768);
4410 ki_max = 0x032C;
e33f2193 4411 agc_ki_dgain = 0xC;
57afe2f0
MCC
4412 if_iaccu_hi_tgt_min = 2047;
4413 ki_min = 0x0117;
4414 ingain_tgt_max = 16383;
4415 clp_ctrl_mode = 0;
244c0e06 4416 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
9482354f 4417 if (rc != 0) {
068e94ea
MCC
4418 pr_err("error %d\n", rc);
4419 goto rw_error;
4420 }
244c0e06 4421 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
9482354f 4422 if (rc != 0) {
068e94ea
MCC
4423 pr_err("error %d\n", rc);
4424 goto rw_error;
4425 }
244c0e06 4426 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
9482354f 4427 if (rc != 0) {
068e94ea
MCC
4428 pr_err("error %d\n", rc);
4429 goto rw_error;
4430 }
244c0e06 4431 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
9482354f 4432 if (rc != 0) {
068e94ea
MCC
4433 pr_err("error %d\n", rc);
4434 goto rw_error;
4435 }
244c0e06 4436 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
9482354f 4437 if (rc != 0) {
068e94ea
MCC
4438 pr_err("error %d\n", rc);
4439 goto rw_error;
4440 }
244c0e06 4441 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
9482354f 4442 if (rc != 0) {
068e94ea
MCC
4443 pr_err("error %d\n", rc);
4444 goto rw_error;
4445 }
244c0e06 4446 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
9482354f 4447 if (rc != 0) {
068e94ea
MCC
4448 pr_err("error %d\n", rc);
4449 goto rw_error;
4450 }
244c0e06 4451 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
9482354f 4452 if (rc != 0) {
068e94ea
MCC
4453 pr_err("error %d\n", rc);
4454 goto rw_error;
4455 }
244c0e06 4456 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
9482354f 4457 if (rc != 0) {
068e94ea
MCC
4458 pr_err("error %d\n", rc);
4459 goto rw_error;
4460 }
244c0e06 4461 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
9482354f 4462 if (rc != 0) {
068e94ea
MCC
4463 pr_err("error %d\n", rc);
4464 goto rw_error;
4465 }
244c0e06 4466 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
9482354f 4467 if (rc != 0) {
068e94ea
MCC
4468 pr_err("error %d\n", rc);
4469 goto rw_error;
4470 }
244c0e06 4471 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
9482354f 4472 if (rc != 0) {
068e94ea
MCC
4473 pr_err("error %d\n", rc);
4474 goto rw_error;
4475 }
244c0e06 4476 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
9482354f 4477 if (rc != 0) {
068e94ea
MCC
4478 pr_err("error %d\n", rc);
4479 goto rw_error;
4480 }
57afe2f0
MCC
4481 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
4482 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
443f18d0 4483 break;
38b2df95 4484#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
4485 case DRX_STANDARD_ITU_A:
4486 case DRX_STANDARD_ITU_C:
4487 case DRX_STANDARD_ITU_B:
57afe2f0
MCC
4488 ingain_tgt_max = 5119;
4489 clp_sum_max = 1023;
4490 clp_dir_to = (u16) (-5);
4491 sns_sum_max = 127;
4492 sns_dir_to = (u16) (-3);
4493 ki_innergain_min = 0;
4494 ki_max = 0x0657;
4495 if_iaccu_hi_tgt_min = 2047;
e33f2193 4496 agc_ki_dgain = 0x7;
57afe2f0
MCC
4497 ki_min = 0x0117;
4498 clp_ctrl_mode = 0;
244c0e06 4499 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
9482354f 4500 if (rc != 0) {
068e94ea
MCC
4501 pr_err("error %d\n", rc);
4502 goto rw_error;
4503 }
244c0e06 4504 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
9482354f 4505 if (rc != 0) {
068e94ea
MCC
4506 pr_err("error %d\n", rc);
4507 goto rw_error;
4508 }
244c0e06 4509 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
9482354f 4510 if (rc != 0) {
068e94ea
MCC
4511 pr_err("error %d\n", rc);
4512 goto rw_error;
4513 }
244c0e06 4514 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
9482354f 4515 if (rc != 0) {
068e94ea
MCC
4516 pr_err("error %d\n", rc);
4517 goto rw_error;
4518 }
244c0e06 4519 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
9482354f 4520 if (rc != 0) {
068e94ea
MCC
4521 pr_err("error %d\n", rc);
4522 goto rw_error;
4523 }
244c0e06 4524 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
9482354f 4525 if (rc != 0) {
068e94ea
MCC
4526 pr_err("error %d\n", rc);
4527 goto rw_error;
4528 }
244c0e06 4529 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
9482354f 4530 if (rc != 0) {
068e94ea
MCC
4531 pr_err("error %d\n", rc);
4532 goto rw_error;
4533 }
244c0e06 4534 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
9482354f 4535 if (rc != 0) {
068e94ea
MCC
4536 pr_err("error %d\n", rc);
4537 goto rw_error;
4538 }
244c0e06 4539 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
9482354f 4540 if (rc != 0) {
068e94ea
MCC
4541 pr_err("error %d\n", rc);
4542 goto rw_error;
4543 }
244c0e06 4544 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
9482354f 4545 if (rc != 0) {
068e94ea
MCC
4546 pr_err("error %d\n", rc);
4547 goto rw_error;
4548 }
57afe2f0
MCC
4549 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
4550 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
244c0e06 4551 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
9482354f 4552 if (rc != 0) {
068e94ea
MCC
4553 pr_err("error %d\n", rc);
4554 goto rw_error;
4555 }
57afe2f0 4556
244c0e06 4557 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
9482354f 4558 if (rc != 0) {
068e94ea
MCC
4559 pr_err("error %d\n", rc);
4560 goto rw_error;
4561 }
57afe2f0 4562 agc_ki &= 0xf000;
244c0e06 4563 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
9482354f 4564 if (rc != 0) {
068e94ea
MCC
4565 pr_err("error %d\n", rc);
4566 goto rw_error;
4567 }
443f18d0 4568 break;
38b2df95 4569#endif
443f18d0 4570 default:
9482354f 4571 return -EINVAL;
443f18d0 4572 }
38b2df95 4573
443f18d0 4574 /* for new AGC interface */
244c0e06 4575 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
9482354f 4576 if (rc != 0) {
068e94ea
MCC
4577 pr_err("error %d\n", rc);
4578 goto rw_error;
4579 }
244c0e06 4580 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
9482354f 4581 if (rc != 0) {
068e94ea
MCC
4582 pr_err("error %d\n", rc);
4583 goto rw_error;
4584 } /* Gain fed from inner to outer AGC */
244c0e06 4585 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
9482354f 4586 if (rc != 0) {
068e94ea
MCC
4587 pr_err("error %d\n", rc);
4588 goto rw_error;
4589 }
244c0e06 4590 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
9482354f 4591 if (rc != 0) {
068e94ea
MCC
4592 pr_err("error %d\n", rc);
4593 goto rw_error;
4594 }
244c0e06 4595 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
9482354f 4596 if (rc != 0) {
068e94ea
MCC
4597 pr_err("error %d\n", rc);
4598 goto rw_error;
4599 } /* set to p_agc_settings->top before */
244c0e06 4600 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
9482354f 4601 if (rc != 0) {
068e94ea
MCC
4602 pr_err("error %d\n", rc);
4603 goto rw_error;
4604 }
244c0e06 4605 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
9482354f 4606 if (rc != 0) {
068e94ea
MCC
4607 pr_err("error %d\n", rc);
4608 goto rw_error;
4609 }
244c0e06 4610 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
9482354f 4611 if (rc != 0) {
068e94ea
MCC
4612 pr_err("error %d\n", rc);
4613 goto rw_error;
4614 }
244c0e06 4615 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
9482354f 4616 if (rc != 0) {
068e94ea
MCC
4617 pr_err("error %d\n", rc);
4618 goto rw_error;
4619 }
244c0e06 4620 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
9482354f 4621 if (rc != 0) {
068e94ea
MCC
4622 pr_err("error %d\n", rc);
4623 goto rw_error;
4624 }
244c0e06 4625 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
9482354f 4626 if (rc != 0) {
068e94ea
MCC
4627 pr_err("error %d\n", rc);
4628 goto rw_error;
4629 }
244c0e06 4630 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
9482354f 4631 if (rc != 0) {
068e94ea
MCC
4632 pr_err("error %d\n", rc);
4633 goto rw_error;
4634 }
244c0e06 4635 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
9482354f 4636 if (rc != 0) {
068e94ea
MCC
4637 pr_err("error %d\n", rc);
4638 goto rw_error;
4639 }
244c0e06 4640 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
9482354f 4641 if (rc != 0) {
068e94ea
MCC
4642 pr_err("error %d\n", rc);
4643 goto rw_error;
4644 }
244c0e06 4645 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
9482354f 4646 if (rc != 0) {
068e94ea
MCC
4647 pr_err("error %d\n", rc);
4648 goto rw_error;
4649 }
244c0e06 4650 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
9482354f 4651 if (rc != 0) {
068e94ea
MCC
4652 pr_err("error %d\n", rc);
4653 goto rw_error;
4654 }
244c0e06 4655 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
9482354f 4656 if (rc != 0) {
068e94ea
MCC
4657 pr_err("error %d\n", rc);
4658 goto rw_error;
4659 }
244c0e06 4660 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
9482354f 4661 if (rc != 0) {
068e94ea
MCC
4662 pr_err("error %d\n", rc);
4663 goto rw_error;
4664 }
244c0e06 4665 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
9482354f 4666 if (rc != 0) {
068e94ea
MCC
4667 pr_err("error %d\n", rc);
4668 goto rw_error;
4669 }
244c0e06 4670 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
9482354f 4671 if (rc != 0) {
068e94ea
MCC
4672 pr_err("error %d\n", rc);
4673 goto rw_error;
4674 }
244c0e06 4675 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
9482354f 4676 if (rc != 0) {
068e94ea
MCC
4677 pr_err("error %d\n", rc);
4678 goto rw_error;
4679 }
244c0e06 4680 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
9482354f 4681 if (rc != 0) {
068e94ea
MCC
4682 pr_err("error %d\n", rc);
4683 goto rw_error;
4684 }
244c0e06 4685 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
9482354f 4686 if (rc != 0) {
068e94ea
MCC
4687 pr_err("error %d\n", rc);
4688 goto rw_error;
4689 }
244c0e06 4690 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
9482354f 4691 if (rc != 0) {
068e94ea
MCC
4692 pr_err("error %d\n", rc);
4693 goto rw_error;
4694 }
244c0e06 4695 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
9482354f 4696 if (rc != 0) {
068e94ea
MCC
4697 pr_err("error %d\n", rc);
4698 goto rw_error;
4699 }
244c0e06 4700 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
9482354f 4701 if (rc != 0) {
068e94ea
MCC
4702 pr_err("error %d\n", rc);
4703 goto rw_error;
4704 }
57afe2f0
MCC
4705
4706 agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
63713517 4707 if (common_attr->tuner_rf_agc_pol == true)
57afe2f0 4708 agc_rf = 0x87ff - agc_rf;
57afe2f0
MCC
4709
4710 agc_if = 0x800;
63713517 4711 if (common_attr->tuner_if_agc_pol == true)
57afe2f0 4712 agc_rf = 0x87ff - agc_rf;
57afe2f0 4713
244c0e06 4714 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
9482354f 4715 if (rc != 0) {
068e94ea
MCC
4716 pr_err("error %d\n", rc);
4717 goto rw_error;
4718 }
244c0e06 4719 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
9482354f 4720 if (rc != 0) {
068e94ea
MCC
4721 pr_err("error %d\n", rc);
4722 goto rw_error;
4723 }
38b2df95 4724
443f18d0 4725 /* Set/restore Ki DGAIN factor */
244c0e06 4726 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 4727 if (rc != 0) {
068e94ea
MCC
4728 pr_err("error %d\n", rc);
4729 goto rw_error;
4730 }
443f18d0 4731 data &= ~SCU_RAM_AGC_KI_DGAIN__M;
e33f2193 4732 data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
244c0e06 4733 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 4734 if (rc != 0) {
068e94ea
MCC
4735 pr_err("error %d\n", rc);
4736 goto rw_error;
4737 }
38b2df95 4738
9482354f 4739 return 0;
38b2df95 4740rw_error:
30741871 4741 return rc;
38b2df95
DH
4742}
4743
34eb9751 4744/*
57afe2f0 4745* \fn int set_frequency ()
38b2df95
DH
4746* \brief Set frequency shift.
4747* \param demod instance of demodulator.
4748* \param channel pointer to channel data.
57afe2f0 4749* \param tuner_freq_offset residual frequency from tuner.
61263c75 4750* \return int.
38b2df95 4751*/
61263c75 4752static int
1bfc9e15
MCC
4753set_frequency(struct drx_demod_instance *demod,
4754 struct drx_channel *channel, s32 tuner_freq_offset)
57afe2f0 4755{
4d7bb0eb 4756 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 4757 struct drxj_data *ext_attr = demod->my_ext_attr;
068e94ea 4758 int rc;
57afe2f0
MCC
4759 s32 sampling_frequency = 0;
4760 s32 frequency_shift = 0;
4761 s32 if_freq_actual = 0;
4d7bb0eb 4762 s32 rf_freq_residual = -1 * tuner_freq_offset;
57afe2f0
MCC
4763 s32 adc_freq = 0;
4764 s32 intermediate_freq = 0;
4765 u32 iqm_fs_rate_ofs = 0;
57afe2f0
MCC
4766 bool adc_flip = true;
4767 bool select_pos_image = false;
4d7bb0eb
MCC
4768 bool rf_mirror;
4769 bool tuner_mirror;
57afe2f0
MCC
4770 bool image_to_select = true;
4771 s32 fm_frequency_shift = 0;
4772
57afe2f0
MCC
4773 rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
4774 tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
443f18d0
MCC
4775 /*
4776 Program frequency shifter
4777 No need to account for mirroring on RF
4778 */
57afe2f0 4779 switch (ext_attr->standard) {
06eeefe8
MCC
4780 case DRX_STANDARD_ITU_A:
4781 case DRX_STANDARD_ITU_C:
4782 case DRX_STANDARD_PAL_SECAM_LP:
443f18d0 4783 case DRX_STANDARD_8VSB:
57afe2f0 4784 select_pos_image = true;
443f18d0
MCC
4785 break;
4786 case DRX_STANDARD_FM:
4787 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
4788 Sound carrier is already 3Mhz above centre frequency due
4789 to tuner setting so now add an extra shift of 1MHz... */
57afe2f0 4790 fm_frequency_shift = 1000;
06eeefe8
MCC
4791 /*fall through */
4792 case DRX_STANDARD_ITU_B:
4793 case DRX_STANDARD_NTSC:
4794 case DRX_STANDARD_PAL_SECAM_BG:
4795 case DRX_STANDARD_PAL_SECAM_DK:
4796 case DRX_STANDARD_PAL_SECAM_I:
443f18d0 4797 case DRX_STANDARD_PAL_SECAM_L:
57afe2f0 4798 select_pos_image = false;
443f18d0
MCC
4799 break;
4800 default:
9482354f 4801 return -EINVAL;
443f18d0 4802 }
57afe2f0
MCC
4803 intermediate_freq = demod->my_common_attr->intermediate_freq;
4804 sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
63713517
MCC
4805 if (tuner_mirror)
4806 if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
4807 else
4808 if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
57afe2f0 4809 if (if_freq_actual > sampling_frequency / 2) {
443f18d0 4810 /* adc mirrors */
57afe2f0
MCC
4811 adc_freq = sampling_frequency - if_freq_actual;
4812 adc_flip = true;
443f18d0
MCC
4813 } else {
4814 /* adc doesn't mirror */
57afe2f0
MCC
4815 adc_freq = if_freq_actual;
4816 adc_flip = false;
443f18d0
MCC
4817 }
4818
57afe2f0
MCC
4819 frequency_shift = adc_freq;
4820 image_to_select =
4821 (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
4822 iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
443f18d0 4823
57afe2f0
MCC
4824 if (image_to_select)
4825 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
443f18d0
MCC
4826
4827 /* Program frequency shifter with tuner offset compensation */
57afe2f0 4828 /* frequency_shift += tuner_freq_offset; TODO */
244c0e06 4829 rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
9482354f 4830 if (rc != 0) {
068e94ea
MCC
4831 pr_err("error %d\n", rc);
4832 goto rw_error;
4833 }
57afe2f0
MCC
4834 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
4835 ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
443f18d0 4836
9482354f 4837 return 0;
38b2df95 4838rw_error:
30741871 4839 return rc;
38b2df95
DH
4840}
4841
34eb9751 4842/*
57afe2f0 4843* \fn int get_acc_pkt_err()
38b2df95
DH
4844* \brief Retrieve signal strength for VSB and QAM.
4845* \param demod Pointer to demod instance
57afe2f0 4846* \param packet_err Pointer to packet error
61263c75 4847* \return int.
9482354f
MCC
4848* \retval 0 sig_strength contains valid data.
4849* \retval -EINVAL sig_strength is NULL.
4850* \retval -EIO Erroneous data, sig_strength contains invalid data.
38b2df95
DH
4851*/
4852#ifdef DRXJ_SIGNAL_ACCUM_ERR
1bfc9e15 4853static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
443f18d0 4854{
068e94ea 4855 int rc;
57afe2f0
MCC
4856 static u16 pkt_err;
4857 static u16 last_pkt_err;
43a431e4 4858 u16 data = 0;
b3ce3a83 4859 struct drxj_data *ext_attr = NULL;
57afe2f0 4860 struct i2c_device_addr *dev_addr = NULL;
443f18d0 4861
b3ce3a83 4862 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0 4863 dev_addr = demod->my_i2c_dev_addr;
443f18d0 4864
244c0e06 4865 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
9482354f 4866 if (rc != 0) {
068e94ea
MCC
4867 pr_err("error %d\n", rc);
4868 goto rw_error;
4869 }
259f380e 4870 if (ext_attr->reset_pkt_err_acc) {
57afe2f0
MCC
4871 last_pkt_err = data;
4872 pkt_err = 0;
4873 ext_attr->reset_pkt_err_acc = false;
443f18d0 4874 }
38b2df95 4875
57afe2f0
MCC
4876 if (data < last_pkt_err) {
4877 pkt_err += 0xffff - last_pkt_err;
4878 pkt_err += data;
443f18d0 4879 } else {
57afe2f0 4880 pkt_err += (data - last_pkt_err);
443f18d0 4881 }
57afe2f0
MCC
4882 *packet_err = pkt_err;
4883 last_pkt_err = data;
38b2df95 4884
9482354f 4885 return 0;
38b2df95 4886rw_error:
30741871 4887 return rc;
38b2df95
DH
4888}
4889#endif
4890
38b2df95
DH
4891
4892/*============================================================================*/
4893
34eb9751 4894/*
57afe2f0 4895* \fn int set_agc_rf ()
38b2df95
DH
4896* \brief Configure RF AGC
4897* \param demod instance of demodulator.
57afe2f0 4898* \param agc_settings AGC configuration structure
61263c75 4899* \return int.
38b2df95 4900*/
61263c75 4901static int
b3ce3a83 4902set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
38b2df95 4903{
57afe2f0 4904 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83
MCC
4905 struct drxj_data *ext_attr = NULL;
4906 struct drxj_cfg_agc *p_agc_settings = NULL;
1bfc9e15 4907 struct drx_common_attr *common_attr = NULL;
068e94ea 4908 int rc;
57afe2f0
MCC
4909 drx_write_reg16func_t scu_wr16 = NULL;
4910 drx_read_reg16func_t scu_rr16 = NULL;
443f18d0 4911
1bfc9e15 4912 common_attr = (struct drx_common_attr *) demod->my_common_attr;
57afe2f0 4913 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 4914 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
4915
4916 if (atomic) {
57afe2f0
MCC
4917 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
4918 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
443f18d0 4919 } else {
244c0e06
MCC
4920 scu_rr16 = drxj_dap_read_reg16;
4921 scu_wr16 = drxj_dap_write_reg16;
443f18d0
MCC
4922 }
4923
4924 /* Configure AGC only if standard is currently active */
57afe2f0
MCC
4925 if ((ext_attr->standard == agc_settings->standard) ||
4926 (DRXJ_ISQAMSTD(ext_attr->standard) &&
4927 DRXJ_ISQAMSTD(agc_settings->standard)) ||
4928 (DRXJ_ISATVSTD(ext_attr->standard) &&
4929 DRXJ_ISATVSTD(agc_settings->standard))) {
43a431e4 4930 u16 data = 0;
443f18d0 4931
57afe2f0 4932 switch (agc_settings->ctrl_mode) {
443f18d0
MCC
4933 case DRX_AGC_CTRL_AUTO:
4934
4935 /* Enable RF AGC DAC */
244c0e06 4936 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 4937 if (rc != 0) {
068e94ea
MCC
4938 pr_err("error %d\n", rc);
4939 goto rw_error;
4940 }
443f18d0 4941 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
244c0e06 4942 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 4943 if (rc != 0) {
068e94ea
MCC
4944 pr_err("error %d\n", rc);
4945 goto rw_error;
4946 }
443f18d0
MCC
4947
4948 /* Enable SCU RF AGC loop */
068e94ea 4949 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 4950 if (rc != 0) {
068e94ea
MCC
4951 pr_err("error %d\n", rc);
4952 goto rw_error;
4953 }
443f18d0 4954 data &= ~SCU_RAM_AGC_KI_RF__M;
63713517 4955 if (ext_attr->standard == DRX_STANDARD_8VSB)
443f18d0 4956 data |= (2 << SCU_RAM_AGC_KI_RF__B);
63713517 4957 else if (DRXJ_ISQAMSTD(ext_attr->standard))
443f18d0 4958 data |= (5 << SCU_RAM_AGC_KI_RF__B);
63713517 4959 else
443f18d0 4960 data |= (4 << SCU_RAM_AGC_KI_RF__B);
443f18d0 4961
63713517 4962 if (common_attr->tuner_rf_agc_pol)
443f18d0 4963 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
63713517 4964 else
443f18d0 4965 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
068e94ea 4966 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 4967 if (rc != 0) {
068e94ea
MCC
4968 pr_err("error %d\n", rc);
4969 goto rw_error;
4970 }
443f18d0
MCC
4971
4972 /* Set speed ( using complementary reduction value ) */
068e94ea 4973 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
9482354f 4974 if (rc != 0) {
068e94ea
MCC
4975 pr_err("error %d\n", rc);
4976 goto rw_error;
4977 }
443f18d0 4978 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
63713517 4979 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);
9482354f 4980 if (rc != 0) {
068e94ea
MCC
4981 pr_err("error %d\n", rc);
4982 goto rw_error;
4983 }
443f18d0 4984
57afe2f0
MCC
4985 if (agc_settings->standard == DRX_STANDARD_8VSB)
4986 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
4987 else if (DRXJ_ISQAMSTD(agc_settings->standard))
4988 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
4989 else if (DRXJ_ISATVSTD(agc_settings->standard))
4990 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
443f18d0 4991 else
9482354f 4992 return -EINVAL;
443f18d0
MCC
4993
4994 /* Set TOP, only if IF-AGC is in AUTO mode */
57afe2f0 4995 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
068e94ea 4996 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
9482354f 4997 if (rc != 0) {
068e94ea
MCC
4998 pr_err("error %d\n", rc);
4999 goto rw_error;
5000 }
5001 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
9482354f 5002 if (rc != 0) {
068e94ea
MCC
5003 pr_err("error %d\n", rc);
5004 goto rw_error;
5005 }
443f18d0
MCC
5006 }
5007
5008 /* Cut-Off current */
068e94ea 5009 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
9482354f 5010 if (rc != 0) {
068e94ea
MCC
5011 pr_err("error %d\n", rc);
5012 goto rw_error;
5013 }
443f18d0
MCC
5014 break;
5015 case DRX_AGC_CTRL_USER:
5016
5017 /* Enable RF AGC DAC */
244c0e06 5018 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5019 if (rc != 0) {
068e94ea
MCC
5020 pr_err("error %d\n", rc);
5021 goto rw_error;
5022 }
443f18d0 5023 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
244c0e06 5024 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5025 if (rc != 0) {
068e94ea
MCC
5026 pr_err("error %d\n", rc);
5027 goto rw_error;
5028 }
443f18d0
MCC
5029
5030 /* Disable SCU RF AGC loop */
068e94ea 5031 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5032 if (rc != 0) {
068e94ea
MCC
5033 pr_err("error %d\n", rc);
5034 goto rw_error;
5035 }
443f18d0 5036 data &= ~SCU_RAM_AGC_KI_RF__M;
63713517 5037 if (common_attr->tuner_rf_agc_pol)
443f18d0 5038 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
63713517 5039 else
443f18d0 5040 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
068e94ea 5041 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5042 if (rc != 0) {
068e94ea
MCC
5043 pr_err("error %d\n", rc);
5044 goto rw_error;
5045 }
443f18d0
MCC
5046
5047 /* Write value to output pin */
068e94ea 5048 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
9482354f 5049 if (rc != 0) {
068e94ea
MCC
5050 pr_err("error %d\n", rc);
5051 goto rw_error;
5052 }
443f18d0
MCC
5053 break;
5054 case DRX_AGC_CTRL_OFF:
5055
5056 /* Disable RF AGC DAC */
244c0e06 5057 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5058 if (rc != 0) {
068e94ea
MCC
5059 pr_err("error %d\n", rc);
5060 goto rw_error;
5061 }
443f18d0 5062 data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
244c0e06 5063 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5064 if (rc != 0) {
068e94ea
MCC
5065 pr_err("error %d\n", rc);
5066 goto rw_error;
5067 }
443f18d0
MCC
5068
5069 /* Disable SCU RF AGC loop */
068e94ea 5070 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5071 if (rc != 0) {
068e94ea
MCC
5072 pr_err("error %d\n", rc);
5073 goto rw_error;
5074 }
443f18d0 5075 data &= ~SCU_RAM_AGC_KI_RF__M;
068e94ea 5076 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5077 if (rc != 0) {
068e94ea
MCC
5078 pr_err("error %d\n", rc);
5079 goto rw_error;
5080 }
443f18d0
MCC
5081 break;
5082 default:
9482354f 5083 return -EINVAL;
57afe2f0 5084 } /* switch ( agcsettings->ctrl_mode ) */
443f18d0
MCC
5085 }
5086
5087 /* Store rf agc settings */
57afe2f0 5088 switch (agc_settings->standard) {
443f18d0 5089 case DRX_STANDARD_8VSB:
57afe2f0 5090 ext_attr->vsb_rf_agc_cfg = *agc_settings;
443f18d0 5091 break;
38b2df95 5092#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
5093 case DRX_STANDARD_ITU_A:
5094 case DRX_STANDARD_ITU_B:
5095 case DRX_STANDARD_ITU_C:
57afe2f0 5096 ext_attr->qam_rf_agc_cfg = *agc_settings;
443f18d0 5097 break;
38b2df95 5098#endif
443f18d0 5099 default:
9482354f 5100 return -EIO;
443f18d0 5101 }
38b2df95 5102
9482354f 5103 return 0;
38b2df95 5104rw_error:
30741871 5105 return rc;
38b2df95
DH
5106}
5107
34eb9751 5108/*
57afe2f0 5109* \fn int set_agc_if ()
38b2df95
DH
5110* \brief Configure If AGC
5111* \param demod instance of demodulator.
57afe2f0 5112* \param agc_settings AGC configuration structure
61263c75 5113* \return int.
38b2df95 5114*/
61263c75 5115static int
b3ce3a83 5116set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
38b2df95 5117{
57afe2f0 5118 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83
MCC
5119 struct drxj_data *ext_attr = NULL;
5120 struct drxj_cfg_agc *p_agc_settings = NULL;
1bfc9e15 5121 struct drx_common_attr *common_attr = NULL;
57afe2f0
MCC
5122 drx_write_reg16func_t scu_wr16 = NULL;
5123 drx_read_reg16func_t scu_rr16 = NULL;
068e94ea 5124 int rc;
443f18d0 5125
1bfc9e15 5126 common_attr = (struct drx_common_attr *) demod->my_common_attr;
57afe2f0 5127 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 5128 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
5129
5130 if (atomic) {
57afe2f0
MCC
5131 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
5132 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
443f18d0 5133 } else {
244c0e06
MCC
5134 scu_rr16 = drxj_dap_read_reg16;
5135 scu_wr16 = drxj_dap_write_reg16;
443f18d0
MCC
5136 }
5137
5138 /* Configure AGC only if standard is currently active */
57afe2f0
MCC
5139 if ((ext_attr->standard == agc_settings->standard) ||
5140 (DRXJ_ISQAMSTD(ext_attr->standard) &&
5141 DRXJ_ISQAMSTD(agc_settings->standard)) ||
5142 (DRXJ_ISATVSTD(ext_attr->standard) &&
5143 DRXJ_ISATVSTD(agc_settings->standard))) {
43a431e4 5144 u16 data = 0;
443f18d0 5145
57afe2f0 5146 switch (agc_settings->ctrl_mode) {
443f18d0
MCC
5147 case DRX_AGC_CTRL_AUTO:
5148 /* Enable IF AGC DAC */
244c0e06 5149 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5150 if (rc != 0) {
068e94ea
MCC
5151 pr_err("error %d\n", rc);
5152 goto rw_error;
5153 }
443f18d0 5154 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
244c0e06 5155 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5156 if (rc != 0) {
068e94ea
MCC
5157 pr_err("error %d\n", rc);
5158 goto rw_error;
5159 }
443f18d0
MCC
5160
5161 /* Enable SCU IF AGC loop */
068e94ea 5162 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5163 if (rc != 0) {
068e94ea
MCC
5164 pr_err("error %d\n", rc);
5165 goto rw_error;
5166 }
443f18d0
MCC
5167 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5168 data &= ~SCU_RAM_AGC_KI_IF__M;
63713517 5169 if (ext_attr->standard == DRX_STANDARD_8VSB)
443f18d0 5170 data |= (3 << SCU_RAM_AGC_KI_IF__B);
63713517 5171 else if (DRXJ_ISQAMSTD(ext_attr->standard))
443f18d0 5172 data |= (6 << SCU_RAM_AGC_KI_IF__B);
63713517 5173 else
443f18d0 5174 data |= (5 << SCU_RAM_AGC_KI_IF__B);
443f18d0 5175
63713517 5176 if (common_attr->tuner_if_agc_pol)
443f18d0 5177 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
63713517 5178 else
443f18d0 5179 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
068e94ea 5180 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5181 if (rc != 0) {
068e94ea
MCC
5182 pr_err("error %d\n", rc);
5183 goto rw_error;
5184 }
443f18d0
MCC
5185
5186 /* Set speed (using complementary reduction value) */
068e94ea 5187 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
9482354f 5188 if (rc != 0) {
068e94ea
MCC
5189 pr_err("error %d\n", rc);
5190 goto rw_error;
5191 }
443f18d0 5192 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
068e94ea 5193 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);
9482354f 5194 if (rc != 0) {
068e94ea
MCC
5195 pr_err("error %d\n", rc);
5196 goto rw_error;
5197 }
443f18d0 5198
57afe2f0
MCC
5199 if (agc_settings->standard == DRX_STANDARD_8VSB)
5200 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
5201 else if (DRXJ_ISQAMSTD(agc_settings->standard))
5202 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
5203 else if (DRXJ_ISATVSTD(agc_settings->standard))
5204 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
443f18d0 5205 else
9482354f 5206 return -EINVAL;
443f18d0
MCC
5207
5208 /* Restore TOP */
57afe2f0 5209 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
068e94ea 5210 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
9482354f 5211 if (rc != 0) {
068e94ea
MCC
5212 pr_err("error %d\n", rc);
5213 goto rw_error;
5214 }
5215 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
9482354f 5216 if (rc != 0) {
068e94ea
MCC
5217 pr_err("error %d\n", rc);
5218 goto rw_error;
5219 }
443f18d0 5220 } else {
068e94ea 5221 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
9482354f 5222 if (rc != 0) {
068e94ea
MCC
5223 pr_err("error %d\n", rc);
5224 goto rw_error;
5225 }
5226 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
9482354f 5227 if (rc != 0) {
068e94ea
MCC
5228 pr_err("error %d\n", rc);
5229 goto rw_error;
5230 }
443f18d0
MCC
5231 }
5232 break;
5233
5234 case DRX_AGC_CTRL_USER:
5235
5236 /* Enable IF AGC DAC */
244c0e06 5237 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5238 if (rc != 0) {
068e94ea
MCC
5239 pr_err("error %d\n", rc);
5240 goto rw_error;
5241 }
443f18d0 5242 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
244c0e06 5243 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5244 if (rc != 0) {
068e94ea
MCC
5245 pr_err("error %d\n", rc);
5246 goto rw_error;
5247 }
443f18d0
MCC
5248
5249 /* Disable SCU IF AGC loop */
068e94ea 5250 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5251 if (rc != 0) {
068e94ea
MCC
5252 pr_err("error %d\n", rc);
5253 goto rw_error;
5254 }
443f18d0
MCC
5255 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5256 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
63713517 5257 if (common_attr->tuner_if_agc_pol)
443f18d0 5258 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
63713517 5259 else
443f18d0 5260 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
068e94ea 5261 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5262 if (rc != 0) {
068e94ea
MCC
5263 pr_err("error %d\n", rc);
5264 goto rw_error;
5265 }
443f18d0
MCC
5266
5267 /* Write value to output pin */
068e94ea 5268 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
9482354f 5269 if (rc != 0) {
068e94ea
MCC
5270 pr_err("error %d\n", rc);
5271 goto rw_error;
5272 }
443f18d0
MCC
5273 break;
5274
5275 case DRX_AGC_CTRL_OFF:
5276
5277 /* Disable If AGC DAC */
244c0e06 5278 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5279 if (rc != 0) {
068e94ea
MCC
5280 pr_err("error %d\n", rc);
5281 goto rw_error;
5282 }
443f18d0 5283 data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
244c0e06 5284 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5285 if (rc != 0) {
068e94ea
MCC
5286 pr_err("error %d\n", rc);
5287 goto rw_error;
5288 }
443f18d0
MCC
5289
5290 /* Disable SCU IF AGC loop */
068e94ea 5291 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5292 if (rc != 0) {
068e94ea
MCC
5293 pr_err("error %d\n", rc);
5294 goto rw_error;
5295 }
443f18d0
MCC
5296 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5297 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
068e94ea 5298 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5299 if (rc != 0) {
068e94ea
MCC
5300 pr_err("error %d\n", rc);
5301 goto rw_error;
5302 }
443f18d0
MCC
5303 break;
5304 default:
9482354f 5305 return -EINVAL;
57afe2f0 5306 } /* switch ( agcsettings->ctrl_mode ) */
443f18d0
MCC
5307
5308 /* always set the top to support configurations without if-loop */
068e94ea 5309 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
9482354f 5310 if (rc != 0) {
068e94ea
MCC
5311 pr_err("error %d\n", rc);
5312 goto rw_error;
5313 }
443f18d0
MCC
5314 }
5315
5316 /* Store if agc settings */
57afe2f0 5317 switch (agc_settings->standard) {
443f18d0 5318 case DRX_STANDARD_8VSB:
57afe2f0 5319 ext_attr->vsb_if_agc_cfg = *agc_settings;
443f18d0 5320 break;
38b2df95 5321#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
5322 case DRX_STANDARD_ITU_A:
5323 case DRX_STANDARD_ITU_B:
5324 case DRX_STANDARD_ITU_C:
57afe2f0 5325 ext_attr->qam_if_agc_cfg = *agc_settings;
443f18d0 5326 break;
38b2df95 5327#endif
443f18d0 5328 default:
9482354f 5329 return -EIO;
443f18d0 5330 }
38b2df95 5331
9482354f 5332 return 0;
38b2df95 5333rw_error:
30741871 5334 return rc;
38b2df95
DH
5335}
5336
34eb9751 5337/*
57afe2f0 5338* \fn int set_iqm_af ()
38b2df95
DH
5339* \brief Configure IQM AF registers
5340* \param demod instance of demodulator.
5341* \param active
61263c75 5342* \return int.
38b2df95 5343*/
1bfc9e15 5344static int set_iqm_af(struct drx_demod_instance *demod, bool active)
38b2df95 5345{
43a431e4 5346 u16 data = 0;
57afe2f0 5347 struct i2c_device_addr *dev_addr = NULL;
068e94ea 5348 int rc;
38b2df95 5349
57afe2f0 5350 dev_addr = demod->my_i2c_dev_addr;
38b2df95 5351
443f18d0 5352 /* Configure IQM */
244c0e06 5353 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5354 if (rc != 0) {
068e94ea
MCC
5355 pr_err("error %d\n", rc);
5356 goto rw_error;
5357 }
63713517
MCC
5358 if (!active)
5359 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));
5360 else
5361 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);
244c0e06 5362 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5363 if (rc != 0) {
068e94ea
MCC
5364 pr_err("error %d\n", rc);
5365 goto rw_error;
5366 }
443f18d0 5367
9482354f 5368 return 0;
38b2df95 5369rw_error:
30741871 5370 return rc;
38b2df95
DH
5371}
5372
5373/*============================================================================*/
5374/*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5375/*============================================================================*/
5376
5377/*============================================================================*/
5378/*============================================================================*/
5379/*== 8VSB DATAPATH FUNCTIONS ==*/
5380/*============================================================================*/
5381/*============================================================================*/
5382
34eb9751 5383/*
57afe2f0 5384* \fn int power_down_vsb ()
38b2df95
DH
5385* \brief Powr down QAM related blocks.
5386* \param demod instance of demodulator.
5387* \param channel pointer to channel data.
61263c75 5388* \return int.
38b2df95 5389*/
1bfc9e15 5390static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
443f18d0 5391{
4d7bb0eb 5392 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 5393 struct drxjscu_cmd cmd_scu = { /* command */ 0,
57afe2f0
MCC
5394 /* parameter_len */ 0,
5395 /* result_len */ 0,
443f18d0
MCC
5396 /* *parameter */ NULL,
5397 /* *result */ NULL
5398 };
1bfc9e15 5399 struct drx_cfg_mpeg_output cfg_mpeg_output;
068e94ea
MCC
5400 int rc;
5401 u16 cmd_result = 0;
443f18d0 5402
443f18d0
MCC
5403 /*
5404 STOP demodulator
5405 reset of FEC and VSB HW
5406 */
57afe2f0 5407 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
443f18d0 5408 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
57afe2f0
MCC
5409 cmd_scu.parameter_len = 0;
5410 cmd_scu.result_len = 1;
5411 cmd_scu.parameter = NULL;
5412 cmd_scu.result = &cmd_result;
068e94ea 5413 rc = scu_command(dev_addr, &cmd_scu);
9482354f 5414 if (rc != 0) {
068e94ea
MCC
5415 pr_err("error %d\n", rc);
5416 goto rw_error;
5417 }
443f18d0
MCC
5418
5419 /* stop all comm_exec */
244c0e06 5420 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9482354f 5421 if (rc != 0) {
068e94ea
MCC
5422 pr_err("error %d\n", rc);
5423 goto rw_error;
5424 }
244c0e06 5425 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
9482354f 5426 if (rc != 0) {
068e94ea
MCC
5427 pr_err("error %d\n", rc);
5428 goto rw_error;
5429 }
259f380e 5430 if (primary) {
244c0e06 5431 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9482354f 5432 if (rc != 0) {
068e94ea
MCC
5433 pr_err("error %d\n", rc);
5434 goto rw_error;
5435 }
5436 rc = set_iqm_af(demod, false);
9482354f 5437 if (rc != 0) {
068e94ea
MCC
5438 pr_err("error %d\n", rc);
5439 goto rw_error;
5440 }
443f18d0 5441 } else {
244c0e06 5442 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 5443 if (rc != 0) {
068e94ea
MCC
5444 pr_err("error %d\n", rc);
5445 goto rw_error;
5446 }
244c0e06 5447 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 5448 if (rc != 0) {
068e94ea
MCC
5449 pr_err("error %d\n", rc);
5450 goto rw_error;
5451 }
244c0e06 5452 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 5453 if (rc != 0) {
068e94ea
MCC
5454 pr_err("error %d\n", rc);
5455 goto rw_error;
5456 }
244c0e06 5457 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 5458 if (rc != 0) {
068e94ea
MCC
5459 pr_err("error %d\n", rc);
5460 goto rw_error;
5461 }
244c0e06 5462 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 5463 if (rc != 0) {
068e94ea
MCC
5464 pr_err("error %d\n", rc);
5465 goto rw_error;
5466 }
443f18d0 5467 }
38b2df95 5468
57afe2f0 5469 cfg_mpeg_output.enable_mpeg_output = false;
068e94ea 5470 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 5471 if (rc != 0) {
068e94ea
MCC
5472 pr_err("error %d\n", rc);
5473 goto rw_error;
5474 }
38b2df95 5475
9482354f 5476 return 0;
38b2df95 5477rw_error:
30741871 5478 return rc;
38b2df95 5479}
443f18d0 5480
34eb9751 5481/*
57afe2f0 5482* \fn int set_vsb_leak_n_gain ()
38b2df95
DH
5483* \brief Set ATSC demod.
5484* \param demod instance of demodulator.
61263c75 5485* \return int.
38b2df95 5486*/
1bfc9e15 5487static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
443f18d0 5488{
57afe2f0 5489 struct i2c_device_addr *dev_addr = NULL;
068e94ea 5490 int rc;
443f18d0 5491
679cfbb1 5492 static const u8 vsb_ffe_leak_gain_ram0[] = {
443f18d0
MCC
5493 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
5494 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
5495 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
5496 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
5497 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
5498 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
5499 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
5500 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
5501 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
5502 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
5503 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
5504 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
5505 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
5506 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
5507 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
5508 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
5509 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
5510 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
5511 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
5512 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
5513 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
5514 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
5515 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
5516 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
5517 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
5518 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
5519 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
5520 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
5521 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
5522 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
5523 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
5524 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
5525 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
5526 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
5527 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
5528 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
5529 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
5530 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
5531 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
5532 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
5533 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
5534 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
5535 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
5536 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
5537 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
5538 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
5539 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
5540 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
5541 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
5542 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
5543 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
5544 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
5545 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
5546 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
5547 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
5548 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
5549 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
5550 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
5551 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
5552 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
5553 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
5554 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
5555 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
5556 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
5557 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
5558 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
5559 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
5560 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
5561 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
5562 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
5563 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
5564 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
5565 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
5566 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
5567 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
5568 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
5569 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
5570 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
5571 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
5572 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
5573 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
5574 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
5575 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
5576 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
5577 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
5578 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
5579 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
5580 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
5581 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
5582 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
5583 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
5584 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
5585 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
5586 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
5587 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
5588 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
5589 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
5590 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
5591 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
5592 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
5593 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
5594 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
5595 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
5596 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
5597 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
5598 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
5599 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
5600 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
5601 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
5602 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
5603 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
5604 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
5605 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
5606 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
5607 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
5608 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
5609 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
5610 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
5611 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
5612 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
5613 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
5614 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
5615 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
5616 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
5617 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
5618 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
5619 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
5620 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
5621 };
5622
679cfbb1 5623 static const u8 vsb_ffe_leak_gain_ram1[] = {
443f18d0
MCC
5624 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
5625 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
5626 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
5627 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
5628 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
5629 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
5630 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
5631 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
5632 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
5633 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
5634 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
5635 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
5636 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
5637 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
5638 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
5639 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
5640 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
5641 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
5642 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
5643 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
5644 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
5645 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
5646 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
5647 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
5648 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
5649 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
5650 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
5651 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
5652 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
5653 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
5654 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
5655 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
5656 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
5657 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
5658 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
5659 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
5660 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
5661 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
5662 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
5663 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
5664 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
5665 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
5666 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
5667 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
5668 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
5669 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
5670 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
5671 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
5672 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
5673 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
5674 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
5675 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
5676 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
5677 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
5678 };
5679
57afe2f0 5680 dev_addr = demod->my_i2c_dev_addr;
244c0e06 5681 rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, sizeof(vsb_ffe_leak_gain_ram0), ((u8 *)vsb_ffe_leak_gain_ram0), 0);
9482354f 5682 if (rc != 0) {
068e94ea
MCC
5683 pr_err("error %d\n", rc);
5684 goto rw_error;
5685 }
244c0e06 5686 rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, sizeof(vsb_ffe_leak_gain_ram1), ((u8 *)vsb_ffe_leak_gain_ram1), 0);
9482354f 5687 if (rc != 0) {
068e94ea
MCC
5688 pr_err("error %d\n", rc);
5689 goto rw_error;
5690 }
443f18d0 5691
9482354f 5692 return 0;
38b2df95 5693rw_error:
30741871 5694 return rc;
38b2df95
DH
5695}
5696
34eb9751 5697/*
57afe2f0 5698* \fn int set_vsb()
38b2df95
DH
5699* \brief Set 8VSB demod.
5700* \param demod instance of demodulator.
61263c75 5701* \return int.
38b2df95
DH
5702*
5703*/
1bfc9e15 5704static int set_vsb(struct drx_demod_instance *demod)
443f18d0 5705{
57afe2f0 5706 struct i2c_device_addr *dev_addr = NULL;
068e94ea 5707 int rc;
1bfc9e15 5708 struct drx_common_attr *common_attr = NULL;
b3ce3a83
MCC
5709 struct drxjscu_cmd cmd_scu;
5710 struct drxj_data *ext_attr = NULL;
068e94ea
MCC
5711 u16 cmd_result = 0;
5712 u16 cmd_param = 0;
679cfbb1 5713 static const u8 vsb_taps_re[] = {
443f18d0
MCC
5714 DRXJ_16TO8(-2), /* re0 */
5715 DRXJ_16TO8(4), /* re1 */
5716 DRXJ_16TO8(1), /* re2 */
5717 DRXJ_16TO8(-4), /* re3 */
5718 DRXJ_16TO8(1), /* re4 */
5719 DRXJ_16TO8(4), /* re5 */
5720 DRXJ_16TO8(-3), /* re6 */
5721 DRXJ_16TO8(-3), /* re7 */
5722 DRXJ_16TO8(6), /* re8 */
5723 DRXJ_16TO8(1), /* re9 */
5724 DRXJ_16TO8(-9), /* re10 */
5725 DRXJ_16TO8(3), /* re11 */
5726 DRXJ_16TO8(12), /* re12 */
5727 DRXJ_16TO8(-9), /* re13 */
5728 DRXJ_16TO8(-15), /* re14 */
5729 DRXJ_16TO8(17), /* re15 */
5730 DRXJ_16TO8(19), /* re16 */
5731 DRXJ_16TO8(-29), /* re17 */
5732 DRXJ_16TO8(-22), /* re18 */
5733 DRXJ_16TO8(45), /* re19 */
5734 DRXJ_16TO8(25), /* re20 */
5735 DRXJ_16TO8(-70), /* re21 */
5736 DRXJ_16TO8(-28), /* re22 */
5737 DRXJ_16TO8(111), /* re23 */
5738 DRXJ_16TO8(30), /* re24 */
5739 DRXJ_16TO8(-201), /* re25 */
5740 DRXJ_16TO8(-31), /* re26 */
5741 DRXJ_16TO8(629) /* re27 */
5742 };
5743
57afe2f0 5744 dev_addr = demod->my_i2c_dev_addr;
1bfc9e15 5745 common_attr = (struct drx_common_attr *) demod->my_common_attr;
b3ce3a83 5746 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
5747
5748 /* stop all comm_exec */
244c0e06 5749 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9482354f 5750 if (rc != 0) {
068e94ea
MCC
5751 pr_err("error %d\n", rc);
5752 goto rw_error;
5753 }
244c0e06 5754 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
9482354f 5755 if (rc != 0) {
068e94ea
MCC
5756 pr_err("error %d\n", rc);
5757 goto rw_error;
5758 }
244c0e06 5759 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 5760 if (rc != 0) {
068e94ea
MCC
5761 pr_err("error %d\n", rc);
5762 goto rw_error;
5763 }
244c0e06 5764 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 5765 if (rc != 0) {
068e94ea
MCC
5766 pr_err("error %d\n", rc);
5767 goto rw_error;
5768 }
244c0e06 5769 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 5770 if (rc != 0) {
068e94ea
MCC
5771 pr_err("error %d\n", rc);
5772 goto rw_error;
5773 }
244c0e06 5774 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 5775 if (rc != 0) {
068e94ea
MCC
5776 pr_err("error %d\n", rc);
5777 goto rw_error;
5778 }
244c0e06 5779 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 5780 if (rc != 0) {
068e94ea
MCC
5781 pr_err("error %d\n", rc);
5782 goto rw_error;
5783 }
443f18d0
MCC
5784
5785 /* reset demodulator */
57afe2f0 5786 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
443f18d0 5787 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
57afe2f0
MCC
5788 cmd_scu.parameter_len = 0;
5789 cmd_scu.result_len = 1;
5790 cmd_scu.parameter = NULL;
5791 cmd_scu.result = &cmd_result;
068e94ea 5792 rc = scu_command(dev_addr, &cmd_scu);
9482354f 5793 if (rc != 0) {
068e94ea
MCC
5794 pr_err("error %d\n", rc);
5795 goto rw_error;
5796 }
57afe2f0 5797
244c0e06 5798 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
9482354f 5799 if (rc != 0) {
068e94ea
MCC
5800 pr_err("error %d\n", rc);
5801 goto rw_error;
5802 }
244c0e06 5803 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
9482354f 5804 if (rc != 0) {
068e94ea
MCC
5805 pr_err("error %d\n", rc);
5806 goto rw_error;
5807 }
244c0e06 5808 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
9482354f 5809 if (rc != 0) {
068e94ea
MCC
5810 pr_err("error %d\n", rc);
5811 goto rw_error;
5812 }
57afe2f0 5813 ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
244c0e06 5814 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
9482354f 5815 if (rc != 0) {
068e94ea
MCC
5816 pr_err("error %d\n", rc);
5817 goto rw_error;
5818 }
244c0e06 5819 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
9482354f 5820 if (rc != 0) {
068e94ea
MCC
5821 pr_err("error %d\n", rc);
5822 goto rw_error;
5823 }
244c0e06 5824 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
9482354f 5825 if (rc != 0) {
068e94ea
MCC
5826 pr_err("error %d\n", rc);
5827 goto rw_error;
5828 }
5829
244c0e06 5830 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
9482354f 5831 if (rc != 0) {
068e94ea
MCC
5832 pr_err("error %d\n", rc);
5833 goto rw_error;
5834 }
244c0e06 5835 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, 28, 0);
9482354f 5836 if (rc != 0) {
068e94ea
MCC
5837 pr_err("error %d\n", rc);
5838 goto rw_error;
5839 }
244c0e06 5840 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
9482354f 5841 if (rc != 0) {
068e94ea
MCC
5842 pr_err("error %d\n", rc);
5843 goto rw_error;
5844 }
244c0e06 5845 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
9482354f 5846 if (rc != 0) {
068e94ea
MCC
5847 pr_err("error %d\n", rc);
5848 goto rw_error;
5849 }
244c0e06 5850 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
9482354f 5851 if (rc != 0) {
068e94ea
MCC
5852 pr_err("error %d\n", rc);
5853 goto rw_error;
5854 }
244c0e06 5855 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
9482354f 5856 if (rc != 0) {
068e94ea
MCC
5857 pr_err("error %d\n", rc);
5858 goto rw_error;
5859 }
244c0e06 5860 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, 1393, 0);
9482354f 5861 if (rc != 0) {
068e94ea
MCC
5862 pr_err("error %d\n", rc);
5863 goto rw_error;
5864 }
244c0e06 5865 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
9482354f 5866 if (rc != 0) {
068e94ea
MCC
5867 pr_err("error %d\n", rc);
5868 goto rw_error;
5869 }
244c0e06 5870 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
9482354f 5871 if (rc != 0) {
068e94ea
MCC
5872 pr_err("error %d\n", rc);
5873 goto rw_error;
5874 }
5875
244c0e06 5876 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
9482354f 5877 if (rc != 0) {
068e94ea
MCC
5878 pr_err("error %d\n", rc);
5879 goto rw_error;
5880 }
244c0e06 5881 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
9482354f 5882 if (rc != 0) {
068e94ea
MCC
5883 pr_err("error %d\n", rc);
5884 goto rw_error;
5885 }
5886
244c0e06 5887 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
9482354f 5888 if (rc != 0) {
068e94ea
MCC
5889 pr_err("error %d\n", rc);
5890 goto rw_error;
5891 } /* set higher threshold */
244c0e06 5892 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
9482354f 5893 if (rc != 0) {
068e94ea
MCC
5894 pr_err("error %d\n", rc);
5895 goto rw_error;
5896 } /* burst detection on */
244c0e06 5897 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
9482354f 5898 if (rc != 0) {
068e94ea
MCC
5899 pr_err("error %d\n", rc);
5900 goto rw_error;
5901 } /* drop thresholds by 1 dB */
244c0e06 5902 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
9482354f 5903 if (rc != 0) {
068e94ea
MCC
5904 pr_err("error %d\n", rc);
5905 goto rw_error;
5906 } /* drop thresholds by 2 dB */
244c0e06 5907 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
9482354f 5908 if (rc != 0) {
068e94ea
MCC
5909 pr_err("error %d\n", rc);
5910 goto rw_error;
5911 } /* cma on */
244c0e06 5912 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
9482354f 5913 if (rc != 0) {
068e94ea
MCC
5914 pr_err("error %d\n", rc);
5915 goto rw_error;
5916 } /* GPIO */
443f18d0
MCC
5917
5918 /* Initialize the FEC Subsystem */
244c0e06 5919 rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
9482354f 5920 if (rc != 0) {
068e94ea
MCC
5921 pr_err("error %d\n", rc);
5922 goto rw_error;
5923 }
443f18d0 5924 {
57afe2f0 5925 u16 fec_oc_snc_mode = 0;
244c0e06 5926 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
9482354f 5927 if (rc != 0) {
068e94ea
MCC
5928 pr_err("error %d\n", rc);
5929 goto rw_error;
5930 }
443f18d0 5931 /* output data even when not locked */
244c0e06 5932 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
9482354f 5933 if (rc != 0) {
068e94ea
MCC
5934 pr_err("error %d\n", rc);
5935 goto rw_error;
5936 }
443f18d0 5937 }
38b2df95 5938
443f18d0 5939 /* set clip */
244c0e06 5940 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
9482354f 5941 if (rc != 0) {
068e94ea
MCC
5942 pr_err("error %d\n", rc);
5943 goto rw_error;
5944 }
244c0e06 5945 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
9482354f 5946 if (rc != 0) {
068e94ea
MCC
5947 pr_err("error %d\n", rc);
5948 goto rw_error;
5949 }
244c0e06 5950 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
9482354f 5951 if (rc != 0) {
068e94ea
MCC
5952 pr_err("error %d\n", rc);
5953 goto rw_error;
5954 }
244c0e06 5955 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
9482354f 5956 if (rc != 0) {
068e94ea
MCC
5957 pr_err("error %d\n", rc);
5958 goto rw_error;
5959 }
443f18d0
MCC
5960 /* no transparent, no A&C framing; parity is set in mpegoutput */
5961 {
57afe2f0 5962 u16 fec_oc_reg_mode = 0;
244c0e06 5963 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
9482354f 5964 if (rc != 0) {
068e94ea
MCC
5965 pr_err("error %d\n", rc);
5966 goto rw_error;
5967 }
244c0e06 5968 rc = drxj_dap_write_reg16(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);
9482354f 5969 if (rc != 0) {
068e94ea
MCC
5970 pr_err("error %d\n", rc);
5971 goto rw_error;
5972 }
443f18d0 5973 }
38b2df95 5974
244c0e06 5975 rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
9482354f 5976 if (rc != 0) {
068e94ea
MCC
5977 pr_err("error %d\n", rc);
5978 goto rw_error;
5979 } /* timeout counter for restarting */
244c0e06 5980 rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
9482354f 5981 if (rc != 0) {
068e94ea
MCC
5982 pr_err("error %d\n", rc);
5983 goto rw_error;
5984 }
244c0e06 5985 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, 0, 0);
9482354f 5986 if (rc != 0) {
068e94ea
MCC
5987 pr_err("error %d\n", rc);
5988 goto rw_error;
5989 } /* bypass disabled */
443f18d0 5990 /* initialize RS packet error measurement parameters */
244c0e06 5991 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
9482354f 5992 if (rc != 0) {
068e94ea
MCC
5993 pr_err("error %d\n", rc);
5994 goto rw_error;
5995 }
244c0e06 5996 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
9482354f 5997 if (rc != 0) {
068e94ea
MCC
5998 pr_err("error %d\n", rc);
5999 goto rw_error;
6000 }
443f18d0
MCC
6001
6002 /* init measurement period of MER/SER */
244c0e06 6003 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
9482354f 6004 if (rc != 0) {
068e94ea
MCC
6005 pr_err("error %d\n", rc);
6006 goto rw_error;
6007 }
244c0e06 6008 rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
9482354f 6009 if (rc != 0) {
068e94ea
MCC
6010 pr_err("error %d\n", rc);
6011 goto rw_error;
6012 }
244c0e06 6013 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
9482354f 6014 if (rc != 0) {
068e94ea
MCC
6015 pr_err("error %d\n", rc);
6016 goto rw_error;
6017 }
244c0e06 6018 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
9482354f 6019 if (rc != 0) {
068e94ea
MCC
6020 pr_err("error %d\n", rc);
6021 goto rw_error;
6022 }
443f18d0 6023
244c0e06 6024 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
9482354f 6025 if (rc != 0) {
068e94ea
MCC
6026 pr_err("error %d\n", rc);
6027 goto rw_error;
6028 }
443f18d0 6029 /* B-Input to ADC, PGA+filter in standby */
259f380e 6030 if (!ext_attr->has_lna) {
244c0e06 6031 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
9482354f 6032 if (rc != 0) {
068e94ea
MCC
6033 pr_err("error %d\n", rc);
6034 goto rw_error;
6035 }
259f380e 6036 }
443f18d0
MCC
6037
6038 /* turn on IQMAF. It has to be in front of setAgc**() */
068e94ea 6039 rc = set_iqm_af(demod, true);
9482354f 6040 if (rc != 0) {
068e94ea
MCC
6041 pr_err("error %d\n", rc);
6042 goto rw_error;
6043 }
6044 rc = adc_synchronization(demod);
9482354f 6045 if (rc != 0) {
068e94ea
MCC
6046 pr_err("error %d\n", rc);
6047 goto rw_error;
6048 }
443f18d0 6049
068e94ea 6050 rc = init_agc(demod);
9482354f 6051 if (rc != 0) {
068e94ea
MCC
6052 pr_err("error %d\n", rc);
6053 goto rw_error;
6054 }
6055 rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
9482354f 6056 if (rc != 0) {
068e94ea
MCC
6057 pr_err("error %d\n", rc);
6058 goto rw_error;
6059 }
6060 rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
9482354f 6061 if (rc != 0) {
068e94ea
MCC
6062 pr_err("error %d\n", rc);
6063 goto rw_error;
6064 }
443f18d0 6065 {
b3ce3a83 6066 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
443f18d0 6067 of only the gain */
b3ce3a83 6068 struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
443f18d0 6069
57afe2f0 6070 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
068e94ea 6071 rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
9482354f 6072 if (rc != 0) {
068e94ea
MCC
6073 pr_err("error %d\n", rc);
6074 goto rw_error;
6075 }
6076 }
6077 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
9482354f 6078 if (rc != 0) {
068e94ea
MCC
6079 pr_err("error %d\n", rc);
6080 goto rw_error;
443f18d0 6081 }
443f18d0
MCC
6082
6083 /* Mpeg output has to be in front of FEC active */
068e94ea 6084 rc = set_mpegtei_handling(demod);
9482354f 6085 if (rc != 0) {
068e94ea
MCC
6086 pr_err("error %d\n", rc);
6087 goto rw_error;
6088 }
6089 rc = bit_reverse_mpeg_output(demod);
9482354f 6090 if (rc != 0) {
068e94ea
MCC
6091 pr_err("error %d\n", rc);
6092 goto rw_error;
6093 }
6094 rc = set_mpeg_start_width(demod);
9482354f 6095 if (rc != 0) {
068e94ea
MCC
6096 pr_err("error %d\n", rc);
6097 goto rw_error;
6098 }
443f18d0 6099 {
57afe2f0 6100 /* TODO: move to set_standard after hardware reset value problem is solved */
443f18d0 6101 /* Configure initial MPEG output */
1bfc9e15 6102 struct drx_cfg_mpeg_output cfg_mpeg_output;
41b5cc0c
MCC
6103
6104 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
57afe2f0 6105 cfg_mpeg_output.enable_mpeg_output = true;
41b5cc0c 6106
068e94ea 6107 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 6108 if (rc != 0) {
068e94ea
MCC
6109 pr_err("error %d\n", rc);
6110 goto rw_error;
6111 }
443f18d0
MCC
6112 }
6113
6114 /* TBD: what parameters should be set */
57afe2f0
MCC
6115 cmd_param = 0x00; /* Default mode AGC on, etc */
6116 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
443f18d0 6117 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
57afe2f0
MCC
6118 cmd_scu.parameter_len = 1;
6119 cmd_scu.result_len = 1;
6120 cmd_scu.parameter = &cmd_param;
6121 cmd_scu.result = &cmd_result;
068e94ea 6122 rc = scu_command(dev_addr, &cmd_scu);
9482354f 6123 if (rc != 0) {
068e94ea
MCC
6124 pr_err("error %d\n", rc);
6125 goto rw_error;
6126 }
443f18d0 6127
244c0e06 6128 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
9482354f 6129 if (rc != 0) {
068e94ea
MCC
6130 pr_err("error %d\n", rc);
6131 goto rw_error;
6132 }
244c0e06 6133 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
9482354f 6134 if (rc != 0) {
068e94ea
MCC
6135 pr_err("error %d\n", rc);
6136 goto rw_error;
6137 }
244c0e06 6138 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
9482354f 6139 if (rc != 0) {
068e94ea
MCC
6140 pr_err("error %d\n", rc);
6141 goto rw_error;
6142 }
244c0e06 6143 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
9482354f 6144 if (rc != 0) {
068e94ea
MCC
6145 pr_err("error %d\n", rc);
6146 goto rw_error;
6147 }
244c0e06 6148 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
9482354f 6149 if (rc != 0) {
068e94ea
MCC
6150 pr_err("error %d\n", rc);
6151 goto rw_error;
6152 }
244c0e06 6153 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
9482354f 6154 if (rc != 0) {
068e94ea
MCC
6155 pr_err("error %d\n", rc);
6156 goto rw_error;
6157 }
244c0e06 6158 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
9482354f 6159 if (rc != 0) {
068e94ea
MCC
6160 pr_err("error %d\n", rc);
6161 goto rw_error;
6162 }
244c0e06 6163 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
9482354f 6164 if (rc != 0) {
068e94ea
MCC
6165 pr_err("error %d\n", rc);
6166 goto rw_error;
6167 }
6168
6169 /* start demodulator */
6170 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6171 | SCU_RAM_COMMAND_CMD_DEMOD_START;
57afe2f0
MCC
6172 cmd_scu.parameter_len = 0;
6173 cmd_scu.result_len = 1;
6174 cmd_scu.parameter = NULL;
6175 cmd_scu.result = &cmd_result;
068e94ea 6176 rc = scu_command(dev_addr, &cmd_scu);
9482354f 6177 if (rc != 0) {
068e94ea
MCC
6178 pr_err("error %d\n", rc);
6179 goto rw_error;
6180 }
443f18d0 6181
244c0e06 6182 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
9482354f 6183 if (rc != 0) {
068e94ea
MCC
6184 pr_err("error %d\n", rc);
6185 goto rw_error;
6186 }
244c0e06 6187 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
9482354f 6188 if (rc != 0) {
068e94ea
MCC
6189 pr_err("error %d\n", rc);
6190 goto rw_error;
6191 }
244c0e06 6192 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
9482354f 6193 if (rc != 0) {
068e94ea
MCC
6194 pr_err("error %d\n", rc);
6195 goto rw_error;
6196 }
443f18d0 6197
9482354f 6198 return 0;
38b2df95 6199rw_error:
30741871 6200 return rc;
38b2df95
DH
6201}
6202
34eb9751 6203/*
57afe2f0 6204* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
38b2df95
DH
6205* \brief Get the values of packet error in 8VSB mode
6206* \return Error code
6207*/
69832578 6208static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
d591590e 6209 u32 *pck_errs, u32 *pck_count)
443f18d0 6210{
068e94ea 6211 int rc;
43a431e4
MCC
6212 u16 data = 0;
6213 u16 period = 0;
6214 u16 prescale = 0;
e33f2193
MCC
6215 u16 packet_errors_mant = 0;
6216 u16 packet_errors_exp = 0;
443f18d0 6217
244c0e06 6218 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
9482354f 6219 if (rc != 0) {
068e94ea
MCC
6220 pr_err("error %d\n", rc);
6221 goto rw_error;
6222 }
e33f2193
MCC
6223 packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
6224 packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
443f18d0
MCC
6225 >> FEC_RS_NR_FAILURES_EXP__B;
6226 period = FEC_RS_MEASUREMENT_PERIOD;
6227 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6228 /* packet error rate = (error packet number) per second */
6229 /* 77.3 us is time for per packet */
068e94ea
MCC
6230 if (period * prescale == 0) {
6231 pr_err("error: period and/or prescale is zero!\n");
9482354f 6232 return -EIO;
068e94ea 6233 }
69832578
MCC
6234 *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
6235 *pck_count = period * prescale * 77;
443f18d0 6236
9482354f 6237 return 0;
38b2df95 6238rw_error:
30741871 6239 return rc;
38b2df95
DH
6240}
6241
34eb9751 6242/*
57afe2f0 6243* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
38b2df95
DH
6244* \brief Get the values of ber in VSB mode
6245* \return Error code
6246*/
69832578
MCC
6247static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
6248 u32 *ber, u32 *cnt)
443f18d0 6249{
068e94ea 6250 int rc;
43a431e4
MCC
6251 u16 data = 0;
6252 u16 period = 0;
6253 u16 prescale = 0;
57afe2f0
MCC
6254 u16 bit_errors_mant = 0;
6255 u16 bit_errors_exp = 0;
443f18d0 6256
244c0e06 6257 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
9482354f 6258 if (rc != 0) {
068e94ea
MCC
6259 pr_err("error %d\n", rc);
6260 goto rw_error;
6261 }
443f18d0
MCC
6262 period = FEC_RS_MEASUREMENT_PERIOD;
6263 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6264
57afe2f0
MCC
6265 bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
6266 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
443f18d0
MCC
6267 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
6268
69832578
MCC
6269 *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
6270
57afe2f0 6271 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
69832578 6272 *ber = (*cnt) * 26570;
443f18d0 6273 else {
068e94ea
MCC
6274 if (period * prescale == 0) {
6275 pr_err("error: period and/or prescale is zero!\n");
9482354f 6276 return -EIO;
068e94ea 6277 }
69832578
MCC
6278 *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
6279 (bit_errors_exp - 3) : bit_errors_exp);
443f18d0 6280 }
38b2df95 6281
9482354f 6282 return 0;
38b2df95 6283rw_error:
30741871 6284 return rc;
38b2df95
DH
6285}
6286
34eb9751 6287/*
57afe2f0 6288* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
38b2df95
DH
6289* \brief Get the values of ber in VSB mode
6290* \return Error code
6291*/
69832578
MCC
6292static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
6293 u32 *ber, u32 *cnt)
38b2df95 6294{
43a431e4 6295 u16 data = 0;
068e94ea 6296 int rc;
38b2df95 6297
244c0e06 6298 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
9482354f 6299 if (rc != 0) {
068e94ea 6300 pr_err("error %d\n", rc);
69832578 6301 return -EIO;
068e94ea 6302 }
69832578
MCC
6303 *ber = data;
6304 *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
38b2df95 6305
9482354f 6306 return 0;
38b2df95
DH
6307}
6308
34eb9751 6309/*
b6c4065e
MCC
6310* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6311* \brief Get the values of MER
38b2df95
DH
6312* \return Error code
6313*/
b6c4065e 6314static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
38b2df95 6315{
068e94ea 6316 int rc;
b6c4065e 6317 u16 data_hi = 0;
38b2df95 6318
b6c4065e 6319 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
9482354f 6320 if (rc != 0) {
068e94ea
MCC
6321 pr_err("error %d\n", rc);
6322 goto rw_error;
6323 }
b6c4065e
MCC
6324 *mer =
6325 (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
38b2df95 6326
9482354f 6327 return 0;
38b2df95 6328rw_error:
30741871 6329 return rc;
38b2df95 6330}
38b2df95 6331
443f18d0 6332
38b2df95
DH
6333/*============================================================================*/
6334/*== END 8VSB DATAPATH FUNCTIONS ==*/
6335/*============================================================================*/
6336
6337/*============================================================================*/
6338/*============================================================================*/
6339/*== QAM DATAPATH FUNCTIONS ==*/
6340/*============================================================================*/
6341/*============================================================================*/
6342
34eb9751 6343/*
57afe2f0 6344* \fn int power_down_qam ()
38b2df95
DH
6345* \brief Powr down QAM related blocks.
6346* \param demod instance of demodulator.
6347* \param channel pointer to channel data.
61263c75 6348* \return int.
38b2df95 6349*/
1bfc9e15 6350static int power_down_qam(struct drx_demod_instance *demod, bool primary)
38b2df95 6351{
b3ce3a83 6352 struct drxjscu_cmd cmd_scu = { /* command */ 0,
57afe2f0
MCC
6353 /* parameter_len */ 0,
6354 /* result_len */ 0,
443f18d0
MCC
6355 /* *parameter */ NULL,
6356 /* *result */ NULL
6357 };
068e94ea 6358 int rc;
4d7bb0eb 6359 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
1bfc9e15 6360 struct drx_cfg_mpeg_output cfg_mpeg_output;
41b5cc0c 6361 struct drx_common_attr *common_attr = demod->my_common_attr;
068e94ea 6362 u16 cmd_result = 0;
443f18d0 6363
443f18d0
MCC
6364 /*
6365 STOP demodulator
6366 resets IQM, QAM and FEC HW blocks
6367 */
6368 /* stop all comm_exec */
244c0e06 6369 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9482354f 6370 if (rc != 0) {
068e94ea
MCC
6371 pr_err("error %d\n", rc);
6372 goto rw_error;
6373 }
244c0e06 6374 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
9482354f 6375 if (rc != 0) {
068e94ea
MCC
6376 pr_err("error %d\n", rc);
6377 goto rw_error;
6378 }
443f18d0 6379
57afe2f0 6380 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 6381 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
57afe2f0
MCC
6382 cmd_scu.parameter_len = 0;
6383 cmd_scu.result_len = 1;
6384 cmd_scu.parameter = NULL;
6385 cmd_scu.result = &cmd_result;
068e94ea 6386 rc = scu_command(dev_addr, &cmd_scu);
9482354f 6387 if (rc != 0) {
068e94ea
MCC
6388 pr_err("error %d\n", rc);
6389 goto rw_error;
6390 }
443f18d0 6391
259f380e 6392 if (primary) {
244c0e06 6393 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9482354f 6394 if (rc != 0) {
068e94ea
MCC
6395 pr_err("error %d\n", rc);
6396 goto rw_error;
6397 }
6398 rc = set_iqm_af(demod, false);
9482354f 6399 if (rc != 0) {
068e94ea
MCC
6400 pr_err("error %d\n", rc);
6401 goto rw_error;
6402 }
443f18d0 6403 } else {
244c0e06 6404 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 6405 if (rc != 0) {
068e94ea
MCC
6406 pr_err("error %d\n", rc);
6407 goto rw_error;
6408 }
244c0e06 6409 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 6410 if (rc != 0) {
068e94ea
MCC
6411 pr_err("error %d\n", rc);
6412 goto rw_error;
6413 }
244c0e06 6414 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 6415 if (rc != 0) {
068e94ea
MCC
6416 pr_err("error %d\n", rc);
6417 goto rw_error;
6418 }
244c0e06 6419 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 6420 if (rc != 0) {
068e94ea
MCC
6421 pr_err("error %d\n", rc);
6422 goto rw_error;
6423 }
244c0e06 6424 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 6425 if (rc != 0) {
068e94ea
MCC
6426 pr_err("error %d\n", rc);
6427 goto rw_error;
6428 }
443f18d0
MCC
6429 }
6430
41b5cc0c 6431 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
57afe2f0 6432 cfg_mpeg_output.enable_mpeg_output = false;
41b5cc0c 6433
068e94ea 6434 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 6435 if (rc != 0) {
068e94ea
MCC
6436 pr_err("error %d\n", rc);
6437 goto rw_error;
6438 }
38b2df95 6439
9482354f 6440 return 0;
38b2df95 6441rw_error:
30741871 6442 return rc;
38b2df95
DH
6443}
6444
6445/*============================================================================*/
6446
34eb9751 6447/*
57afe2f0 6448* \fn int set_qam_measurement ()
38b2df95
DH
6449* \brief Setup of the QAM Measuremnt intervals for signal quality
6450* \param demod instance of demod.
6451* \param constellation current constellation.
61263c75 6452* \return int.
38b2df95
DH
6453*
6454* NOTE:
6455* Take into account that for certain settings the errorcounters can overflow.
6456* The implementation does not check this.
6457*
57afe2f0
MCC
6458* TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
6459* constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
38b2df95
DH
6460* field ?
6461*
6462*/
6463#ifndef DRXJ_VSB_ONLY
61263c75 6464static int
1bfc9e15 6465set_qam_measurement(struct drx_demod_instance *demod,
22892268 6466 enum drx_modulation constellation, u32 symbol_rate)
57afe2f0
MCC
6467{
6468 struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */
69bb7ab6 6469 struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specific data */
068e94ea 6470 int rc;
57afe2f0
MCC
6471 u32 fec_bits_desired = 0; /* BER accounting period */
6472 u16 fec_rs_plen = 0; /* defines RS BER measurement period */
6473 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
6474 u32 fec_rs_period = 0; /* Value for corresponding I2C register */
6475 u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
6476 u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
6477 u32 qam_vd_period = 0; /* Value for corresponding I2C register */
6478 u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
6479 u16 fec_vd_plen = 0; /* no of trellis symbols: VD SER measur period */
6480 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
6481
6482 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 6483 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0
MCC
6484
6485 fec_bits_desired = ext_attr->fec_bits_desired;
6486 fec_rs_prescale = ext_attr->fec_rs_prescale;
443f18d0
MCC
6487
6488 switch (constellation) {
6489 case DRX_CONSTELLATION_QAM16:
57afe2f0 6490 fec_bits_desired = 4 * symbol_rate;
443f18d0
MCC
6491 break;
6492 case DRX_CONSTELLATION_QAM32:
57afe2f0 6493 fec_bits_desired = 5 * symbol_rate;
443f18d0
MCC
6494 break;
6495 case DRX_CONSTELLATION_QAM64:
57afe2f0 6496 fec_bits_desired = 6 * symbol_rate;
443f18d0
MCC
6497 break;
6498 case DRX_CONSTELLATION_QAM128:
57afe2f0 6499 fec_bits_desired = 7 * symbol_rate;
443f18d0
MCC
6500 break;
6501 case DRX_CONSTELLATION_QAM256:
57afe2f0 6502 fec_bits_desired = 8 * symbol_rate;
443f18d0
MCC
6503 break;
6504 default:
9482354f 6505 return -EINVAL;
443f18d0
MCC
6506 }
6507
6508 /* Parameters for Reed-Solomon Decoder */
6509 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
6510 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
6511 /* result is within 32 bit arithmetic -> */
6512 /* no need for mult or frac functions */
6513
57afe2f0
MCC
6514 /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
6515 switch (ext_attr->standard) {
443f18d0
MCC
6516 case DRX_STANDARD_ITU_A:
6517 case DRX_STANDARD_ITU_C:
57afe2f0 6518 fec_rs_plen = 204 * 8;
443f18d0
MCC
6519 break;
6520 case DRX_STANDARD_ITU_B:
57afe2f0 6521 fec_rs_plen = 128 * 7;
443f18d0
MCC
6522 break;
6523 default:
9482354f 6524 return -EINVAL;
443f18d0
MCC
6525 }
6526
57afe2f0
MCC
6527 ext_attr->fec_rs_plen = fec_rs_plen; /* for getSigQual */
6528 fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage */
068e94ea
MCC
6529 if (fec_rs_bit_cnt == 0) {
6530 pr_err("error: fec_rs_bit_cnt is zero!\n");
9482354f 6531 return -EIO;
068e94ea 6532 }
57afe2f0
MCC
6533 fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1; /* ceil */
6534 if (ext_attr->standard != DRX_STANDARD_ITU_B)
6535 fec_oc_snc_fail_period = fec_rs_period;
443f18d0
MCC
6536
6537 /* limit to max 16 bit value (I2C register width) if needed */
57afe2f0
MCC
6538 if (fec_rs_period > 0xFFFF)
6539 fec_rs_period = 0xFFFF;
443f18d0
MCC
6540
6541 /* write corresponding registers */
57afe2f0 6542 switch (ext_attr->standard) {
443f18d0
MCC
6543 case DRX_STANDARD_ITU_A:
6544 case DRX_STANDARD_ITU_C:
6545 break;
6546 case DRX_STANDARD_ITU_B:
6547 switch (constellation) {
6548 case DRX_CONSTELLATION_QAM64:
57afe2f0
MCC
6549 fec_rs_period = 31581;
6550 fec_oc_snc_fail_period = 17932;
443f18d0
MCC
6551 break;
6552 case DRX_CONSTELLATION_QAM256:
57afe2f0
MCC
6553 fec_rs_period = 45446;
6554 fec_oc_snc_fail_period = 25805;
443f18d0
MCC
6555 break;
6556 default:
9482354f 6557 return -EINVAL;
443f18d0
MCC
6558 }
6559 break;
6560 default:
9482354f 6561 return -EINVAL;
443f18d0
MCC
6562 }
6563
244c0e06 6564 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
9482354f 6565 if (rc != 0) {
068e94ea
MCC
6566 pr_err("error %d\n", rc);
6567 goto rw_error;
6568 }
244c0e06 6569 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
9482354f 6570 if (rc != 0) {
068e94ea
MCC
6571 pr_err("error %d\n", rc);
6572 goto rw_error;
6573 }
244c0e06 6574 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
9482354f 6575 if (rc != 0) {
068e94ea
MCC
6576 pr_err("error %d\n", rc);
6577 goto rw_error;
6578 }
57afe2f0
MCC
6579 ext_attr->fec_rs_period = (u16) fec_rs_period;
6580 ext_attr->fec_rs_prescale = fec_rs_prescale;
244c0e06 6581 rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
9482354f 6582 if (rc != 0) {
068e94ea
MCC
6583 pr_err("error %d\n", rc);
6584 goto rw_error;
6585 }
244c0e06 6586 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
9482354f 6587 if (rc != 0) {
068e94ea
MCC
6588 pr_err("error %d\n", rc);
6589 goto rw_error;
6590 }
244c0e06 6591 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
9482354f 6592 if (rc != 0) {
068e94ea
MCC
6593 pr_err("error %d\n", rc);
6594 goto rw_error;
6595 }
443f18d0 6596
57afe2f0 6597 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
443f18d0
MCC
6598 /* Parameters for Viterbi Decoder */
6599 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
6600 /* (qamvd_prescale*plen*(qam_constellation+1))) */
6601 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
6602 /* result is within 32 bit arithmetic -> */
6603 /* no need for mult or frac functions */
6604
57afe2f0
MCC
6605 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
6606 fec_vd_plen = ext_attr->fec_vd_plen;
6607 qam_vd_prescale = ext_attr->qam_vd_prescale;
6608 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
443f18d0
MCC
6609
6610 switch (constellation) {
6611 case DRX_CONSTELLATION_QAM64:
57afe2f0
MCC
6612 /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
6613 qam_vd_period =
6614 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
443f18d0
MCC
6615 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
6616 break;
6617 case DRX_CONSTELLATION_QAM256:
57afe2f0
MCC
6618 /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
6619 qam_vd_period =
6620 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
443f18d0
MCC
6621 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
6622 break;
6623 default:
9482354f 6624 return -EINVAL;
443f18d0 6625 }
068e94ea
MCC
6626 if (qam_vd_period == 0) {
6627 pr_err("error: qam_vd_period is zero!\n");
9482354f 6628 return -EIO;
068e94ea 6629 }
57afe2f0 6630 qam_vd_period = fec_bits_desired / qam_vd_period;
443f18d0 6631 /* limit to max 16 bit value (I2C register width) if needed */
57afe2f0
MCC
6632 if (qam_vd_period > 0xFFFF)
6633 qam_vd_period = 0xFFFF;
443f18d0 6634
57afe2f0
MCC
6635 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
6636 qam_vd_bit_cnt *= qam_vd_period;
443f18d0 6637
244c0e06 6638 rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
9482354f 6639 if (rc != 0) {
068e94ea
MCC
6640 pr_err("error %d\n", rc);
6641 goto rw_error;
6642 }
244c0e06 6643 rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
9482354f 6644 if (rc != 0) {
068e94ea
MCC
6645 pr_err("error %d\n", rc);
6646 goto rw_error;
6647 }
57afe2f0
MCC
6648 ext_attr->qam_vd_period = (u16) qam_vd_period;
6649 ext_attr->qam_vd_prescale = qam_vd_prescale;
443f18d0
MCC
6650 }
6651
9482354f 6652 return 0;
38b2df95 6653rw_error:
30741871 6654 return rc;
38b2df95
DH
6655}
6656
6657/*============================================================================*/
6658
34eb9751 6659/*
57afe2f0 6660* \fn int set_qam16 ()
38b2df95
DH
6661* \brief QAM16 specific setup
6662* \param demod instance of demod.
61263c75 6663* \return int.
38b2df95 6664*/
1bfc9e15 6665static int set_qam16(struct drx_demod_instance *demod)
443f18d0 6666{
57afe2f0 6667 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 6668 int rc;
679cfbb1 6669 static const u8 qam_dq_qual_fun[] = {
443f18d0
MCC
6670 DRXJ_16TO8(2), /* fun0 */
6671 DRXJ_16TO8(2), /* fun1 */
6672 DRXJ_16TO8(2), /* fun2 */
6673 DRXJ_16TO8(2), /* fun3 */
6674 DRXJ_16TO8(3), /* fun4 */
6675 DRXJ_16TO8(3), /* fun5 */
6676 };
679cfbb1 6677 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
6678 DRXJ_16TO8(13517), /* RAD0 */
6679 DRXJ_16TO8(13517), /* RAD1 */
6680 DRXJ_16TO8(13517), /* RAD2 */
6681 DRXJ_16TO8(13517), /* RAD3 */
6682 DRXJ_16TO8(13517), /* RAD4 */
6683 DRXJ_16TO8(13517), /* RAD5 */
6684 };
6685
244c0e06 6686 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 6687 if (rc != 0) {
068e94ea
MCC
6688 pr_err("error %d\n", rc);
6689 goto rw_error;
6690 }
244c0e06 6691 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
9482354f 6692 if (rc != 0) {
068e94ea
MCC
6693 pr_err("error %d\n", rc);
6694 goto rw_error;
6695 }
6696
244c0e06 6697 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
9482354f 6698 if (rc != 0) {
068e94ea
MCC
6699 pr_err("error %d\n", rc);
6700 goto rw_error;
6701 }
244c0e06 6702 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
9482354f 6703 if (rc != 0) {
068e94ea
MCC
6704 pr_err("error %d\n", rc);
6705 goto rw_error;
6706 }
244c0e06 6707 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
9482354f 6708 if (rc != 0) {
068e94ea
MCC
6709 pr_err("error %d\n", rc);
6710 goto rw_error;
6711 }
244c0e06 6712 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
9482354f 6713 if (rc != 0) {
068e94ea
MCC
6714 pr_err("error %d\n", rc);
6715 goto rw_error;
6716 }
244c0e06 6717 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
9482354f 6718 if (rc != 0) {
068e94ea
MCC
6719 pr_err("error %d\n", rc);
6720 goto rw_error;
6721 }
244c0e06 6722 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
9482354f 6723 if (rc != 0) {
068e94ea
MCC
6724 pr_err("error %d\n", rc);
6725 goto rw_error;
6726 }
6727
244c0e06 6728 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 6729 if (rc != 0) {
068e94ea
MCC
6730 pr_err("error %d\n", rc);
6731 goto rw_error;
6732 }
244c0e06 6733 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
9482354f 6734 if (rc != 0) {
068e94ea
MCC
6735 pr_err("error %d\n", rc);
6736 goto rw_error;
6737 }
244c0e06 6738 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 6739 if (rc != 0) {
068e94ea
MCC
6740 pr_err("error %d\n", rc);
6741 goto rw_error;
6742 }
6743
244c0e06 6744 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
9482354f 6745 if (rc != 0) {
068e94ea
MCC
6746 pr_err("error %d\n", rc);
6747 goto rw_error;
6748 }
244c0e06 6749 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
9482354f 6750 if (rc != 0) {
068e94ea
MCC
6751 pr_err("error %d\n", rc);
6752 goto rw_error;
6753 }
244c0e06 6754 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
9482354f 6755 if (rc != 0) {
068e94ea
MCC
6756 pr_err("error %d\n", rc);
6757 goto rw_error;
6758 }
244c0e06 6759 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
9482354f 6760 if (rc != 0) {
068e94ea
MCC
6761 pr_err("error %d\n", rc);
6762 goto rw_error;
6763 }
244c0e06 6764 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
9482354f 6765 if (rc != 0) {
068e94ea
MCC
6766 pr_err("error %d\n", rc);
6767 goto rw_error;
6768 }
244c0e06 6769 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
9482354f 6770 if (rc != 0) {
068e94ea
MCC
6771 pr_err("error %d\n", rc);
6772 goto rw_error;
6773 }
244c0e06 6774 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
9482354f 6775 if (rc != 0) {
068e94ea
MCC
6776 pr_err("error %d\n", rc);
6777 goto rw_error;
6778 }
6779
244c0e06 6780 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 6781 if (rc != 0) {
068e94ea
MCC
6782 pr_err("error %d\n", rc);
6783 goto rw_error;
6784 }
244c0e06 6785 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 6786 if (rc != 0) {
068e94ea
MCC
6787 pr_err("error %d\n", rc);
6788 goto rw_error;
6789 }
244c0e06 6790 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 6791 if (rc != 0) {
068e94ea
MCC
6792 pr_err("error %d\n", rc);
6793 goto rw_error;
6794 }
244c0e06 6795 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
9482354f 6796 if (rc != 0) {
068e94ea
MCC
6797 pr_err("error %d\n", rc);
6798 goto rw_error;
6799 }
244c0e06 6800 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 6801 if (rc != 0) {
068e94ea
MCC
6802 pr_err("error %d\n", rc);
6803 goto rw_error;
6804 }
244c0e06 6805 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 6806 if (rc != 0) {
068e94ea
MCC
6807 pr_err("error %d\n", rc);
6808 goto rw_error;
6809 }
244c0e06 6810 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
9482354f 6811 if (rc != 0) {
068e94ea
MCC
6812 pr_err("error %d\n", rc);
6813 goto rw_error;
6814 }
244c0e06 6815 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
9482354f 6816 if (rc != 0) {
068e94ea
MCC
6817 pr_err("error %d\n", rc);
6818 goto rw_error;
6819 }
244c0e06 6820 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 6821 if (rc != 0) {
068e94ea
MCC
6822 pr_err("error %d\n", rc);
6823 goto rw_error;
6824 }
244c0e06 6825 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 6826 if (rc != 0) {
068e94ea
MCC
6827 pr_err("error %d\n", rc);
6828 goto rw_error;
6829 }
244c0e06 6830 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 6831 if (rc != 0) {
068e94ea
MCC
6832 pr_err("error %d\n", rc);
6833 goto rw_error;
6834 }
244c0e06 6835 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 6836 if (rc != 0) {
068e94ea
MCC
6837 pr_err("error %d\n", rc);
6838 goto rw_error;
6839 }
244c0e06 6840 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 6841 if (rc != 0) {
068e94ea
MCC
6842 pr_err("error %d\n", rc);
6843 goto rw_error;
6844 }
244c0e06 6845 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 6846 if (rc != 0) {
068e94ea
MCC
6847 pr_err("error %d\n", rc);
6848 goto rw_error;
6849 }
244c0e06 6850 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 6851 if (rc != 0) {
068e94ea
MCC
6852 pr_err("error %d\n", rc);
6853 goto rw_error;
6854 }
244c0e06 6855 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
9482354f 6856 if (rc != 0) {
068e94ea
MCC
6857 pr_err("error %d\n", rc);
6858 goto rw_error;
6859 }
244c0e06 6860 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
9482354f 6861 if (rc != 0) {
068e94ea
MCC
6862 pr_err("error %d\n", rc);
6863 goto rw_error;
6864 }
244c0e06 6865 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 6866 if (rc != 0) {
068e94ea
MCC
6867 pr_err("error %d\n", rc);
6868 goto rw_error;
6869 }
244c0e06 6870 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 6871 if (rc != 0) {
068e94ea
MCC
6872 pr_err("error %d\n", rc);
6873 goto rw_error;
6874 }
244c0e06 6875 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
9482354f 6876 if (rc != 0) {
068e94ea
MCC
6877 pr_err("error %d\n", rc);
6878 goto rw_error;
6879 }
6880
244c0e06 6881 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
9482354f 6882 if (rc != 0) {
068e94ea
MCC
6883 pr_err("error %d\n", rc);
6884 goto rw_error;
6885 }
443f18d0 6886
9482354f 6887 return 0;
38b2df95 6888rw_error:
30741871 6889 return rc;
38b2df95
DH
6890}
6891
6892/*============================================================================*/
6893
34eb9751 6894/*
57afe2f0 6895* \fn int set_qam32 ()
38b2df95
DH
6896* \brief QAM32 specific setup
6897* \param demod instance of demod.
61263c75 6898* \return int.
38b2df95 6899*/
1bfc9e15 6900static int set_qam32(struct drx_demod_instance *demod)
443f18d0 6901{
57afe2f0 6902 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 6903 int rc;
679cfbb1 6904 static const u8 qam_dq_qual_fun[] = {
443f18d0
MCC
6905 DRXJ_16TO8(3), /* fun0 */
6906 DRXJ_16TO8(3), /* fun1 */
6907 DRXJ_16TO8(3), /* fun2 */
6908 DRXJ_16TO8(3), /* fun3 */
6909 DRXJ_16TO8(4), /* fun4 */
6910 DRXJ_16TO8(4), /* fun5 */
6911 };
679cfbb1 6912 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
6913 DRXJ_16TO8(6707), /* RAD0 */
6914 DRXJ_16TO8(6707), /* RAD1 */
6915 DRXJ_16TO8(6707), /* RAD2 */
6916 DRXJ_16TO8(6707), /* RAD3 */
6917 DRXJ_16TO8(6707), /* RAD4 */
6918 DRXJ_16TO8(6707), /* RAD5 */
6919 };
6920
244c0e06 6921 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 6922 if (rc != 0) {
068e94ea
MCC
6923 pr_err("error %d\n", rc);
6924 goto rw_error;
6925 }
244c0e06 6926 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
9482354f 6927 if (rc != 0) {
068e94ea
MCC
6928 pr_err("error %d\n", rc);
6929 goto rw_error;
6930 }
6931
244c0e06 6932 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
9482354f 6933 if (rc != 0) {
068e94ea
MCC
6934 pr_err("error %d\n", rc);
6935 goto rw_error;
6936 }
244c0e06 6937 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
9482354f 6938 if (rc != 0) {
068e94ea
MCC
6939 pr_err("error %d\n", rc);
6940 goto rw_error;
6941 }
244c0e06 6942 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9482354f 6943 if (rc != 0) {
068e94ea
MCC
6944 pr_err("error %d\n", rc);
6945 goto rw_error;
6946 }
244c0e06 6947 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
9482354f 6948 if (rc != 0) {
068e94ea
MCC
6949 pr_err("error %d\n", rc);
6950 goto rw_error;
6951 }
244c0e06 6952 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9482354f 6953 if (rc != 0) {
068e94ea
MCC
6954 pr_err("error %d\n", rc);
6955 goto rw_error;
6956 }
244c0e06 6957 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
9482354f 6958 if (rc != 0) {
068e94ea
MCC
6959 pr_err("error %d\n", rc);
6960 goto rw_error;
6961 }
6962
244c0e06 6963 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 6964 if (rc != 0) {
068e94ea
MCC
6965 pr_err("error %d\n", rc);
6966 goto rw_error;
6967 }
244c0e06 6968 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
9482354f 6969 if (rc != 0) {
068e94ea
MCC
6970 pr_err("error %d\n", rc);
6971 goto rw_error;
6972 }
244c0e06 6973 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 6974 if (rc != 0) {
068e94ea
MCC
6975 pr_err("error %d\n", rc);
6976 goto rw_error;
6977 }
6978
244c0e06 6979 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
9482354f 6980 if (rc != 0) {
068e94ea
MCC
6981 pr_err("error %d\n", rc);
6982 goto rw_error;
6983 }
244c0e06 6984 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
9482354f 6985 if (rc != 0) {
068e94ea
MCC
6986 pr_err("error %d\n", rc);
6987 goto rw_error;
6988 }
244c0e06 6989 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
9482354f 6990 if (rc != 0) {
068e94ea
MCC
6991 pr_err("error %d\n", rc);
6992 goto rw_error;
6993 }
244c0e06 6994 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
9482354f 6995 if (rc != 0) {
068e94ea
MCC
6996 pr_err("error %d\n", rc);
6997 goto rw_error;
6998 }
244c0e06 6999 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
9482354f 7000 if (rc != 0) {
068e94ea
MCC
7001 pr_err("error %d\n", rc);
7002 goto rw_error;
7003 }
244c0e06 7004 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
9482354f 7005 if (rc != 0) {
068e94ea
MCC
7006 pr_err("error %d\n", rc);
7007 goto rw_error;
7008 }
244c0e06 7009 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
9482354f 7010 if (rc != 0) {
068e94ea
MCC
7011 pr_err("error %d\n", rc);
7012 goto rw_error;
7013 }
7014
244c0e06 7015 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 7016 if (rc != 0) {
068e94ea
MCC
7017 pr_err("error %d\n", rc);
7018 goto rw_error;
7019 }
244c0e06 7020 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 7021 if (rc != 0) {
068e94ea
MCC
7022 pr_err("error %d\n", rc);
7023 goto rw_error;
7024 }
244c0e06 7025 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 7026 if (rc != 0) {
068e94ea
MCC
7027 pr_err("error %d\n", rc);
7028 goto rw_error;
7029 }
244c0e06 7030 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
9482354f 7031 if (rc != 0) {
068e94ea
MCC
7032 pr_err("error %d\n", rc);
7033 goto rw_error;
7034 }
244c0e06 7035 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 7036 if (rc != 0) {
068e94ea
MCC
7037 pr_err("error %d\n", rc);
7038 goto rw_error;
7039 }
244c0e06 7040 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 7041 if (rc != 0) {
068e94ea
MCC
7042 pr_err("error %d\n", rc);
7043 goto rw_error;
7044 }
244c0e06 7045 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
9482354f 7046 if (rc != 0) {
068e94ea
MCC
7047 pr_err("error %d\n", rc);
7048 goto rw_error;
7049 }
244c0e06 7050 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
9482354f 7051 if (rc != 0) {
068e94ea
MCC
7052 pr_err("error %d\n", rc);
7053 goto rw_error;
7054 }
244c0e06 7055 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 7056 if (rc != 0) {
068e94ea
MCC
7057 pr_err("error %d\n", rc);
7058 goto rw_error;
7059 }
244c0e06 7060 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 7061 if (rc != 0) {
068e94ea
MCC
7062 pr_err("error %d\n", rc);
7063 goto rw_error;
7064 }
244c0e06 7065 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 7066 if (rc != 0) {
068e94ea
MCC
7067 pr_err("error %d\n", rc);
7068 goto rw_error;
7069 }
244c0e06 7070 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 7071 if (rc != 0) {
068e94ea
MCC
7072 pr_err("error %d\n", rc);
7073 goto rw_error;
7074 }
244c0e06 7075 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 7076 if (rc != 0) {
068e94ea
MCC
7077 pr_err("error %d\n", rc);
7078 goto rw_error;
7079 }
244c0e06 7080 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 7081 if (rc != 0) {
068e94ea
MCC
7082 pr_err("error %d\n", rc);
7083 goto rw_error;
7084 }
244c0e06 7085 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 7086 if (rc != 0) {
068e94ea
MCC
7087 pr_err("error %d\n", rc);
7088 goto rw_error;
7089 }
244c0e06 7090 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
9482354f 7091 if (rc != 0) {
068e94ea
MCC
7092 pr_err("error %d\n", rc);
7093 goto rw_error;
7094 }
244c0e06 7095 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
9482354f 7096 if (rc != 0) {
068e94ea
MCC
7097 pr_err("error %d\n", rc);
7098 goto rw_error;
7099 }
244c0e06 7100 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 7101 if (rc != 0) {
068e94ea
MCC
7102 pr_err("error %d\n", rc);
7103 goto rw_error;
7104 }
244c0e06 7105 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 7106 if (rc != 0) {
068e94ea
MCC
7107 pr_err("error %d\n", rc);
7108 goto rw_error;
7109 }
244c0e06 7110 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
9482354f 7111 if (rc != 0) {
068e94ea
MCC
7112 pr_err("error %d\n", rc);
7113 goto rw_error;
7114 }
7115
244c0e06 7116 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
9482354f 7117 if (rc != 0) {
068e94ea
MCC
7118 pr_err("error %d\n", rc);
7119 goto rw_error;
7120 }
443f18d0 7121
9482354f 7122 return 0;
38b2df95 7123rw_error:
30741871 7124 return rc;
38b2df95
DH
7125}
7126
7127/*============================================================================*/
7128
34eb9751 7129/*
57afe2f0 7130* \fn int set_qam64 ()
38b2df95
DH
7131* \brief QAM64 specific setup
7132* \param demod instance of demod.
61263c75 7133* \return int.
38b2df95 7134*/
1bfc9e15 7135static int set_qam64(struct drx_demod_instance *demod)
443f18d0 7136{
57afe2f0 7137 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 7138 int rc;
679cfbb1
CIK
7139 static const u8 qam_dq_qual_fun[] = {
7140 /* this is hw reset value. no necessary to re-write */
443f18d0
MCC
7141 DRXJ_16TO8(4), /* fun0 */
7142 DRXJ_16TO8(4), /* fun1 */
7143 DRXJ_16TO8(4), /* fun2 */
7144 DRXJ_16TO8(4), /* fun3 */
7145 DRXJ_16TO8(6), /* fun4 */
7146 DRXJ_16TO8(6), /* fun5 */
7147 };
679cfbb1 7148 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
7149 DRXJ_16TO8(13336), /* RAD0 */
7150 DRXJ_16TO8(12618), /* RAD1 */
7151 DRXJ_16TO8(11988), /* RAD2 */
7152 DRXJ_16TO8(13809), /* RAD3 */
7153 DRXJ_16TO8(13809), /* RAD4 */
7154 DRXJ_16TO8(15609), /* RAD5 */
7155 };
7156
244c0e06 7157 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 7158 if (rc != 0) {
068e94ea
MCC
7159 pr_err("error %d\n", rc);
7160 goto rw_error;
7161 }
244c0e06 7162 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
9482354f 7163 if (rc != 0) {
068e94ea
MCC
7164 pr_err("error %d\n", rc);
7165 goto rw_error;
7166 }
7167
244c0e06 7168 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
9482354f 7169 if (rc != 0) {
068e94ea
MCC
7170 pr_err("error %d\n", rc);
7171 goto rw_error;
7172 }
244c0e06 7173 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9482354f 7174 if (rc != 0) {
068e94ea
MCC
7175 pr_err("error %d\n", rc);
7176 goto rw_error;
7177 }
244c0e06 7178 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9482354f 7179 if (rc != 0) {
068e94ea
MCC
7180 pr_err("error %d\n", rc);
7181 goto rw_error;
7182 }
244c0e06 7183 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
9482354f 7184 if (rc != 0) {
068e94ea
MCC
7185 pr_err("error %d\n", rc);
7186 goto rw_error;
7187 }
244c0e06 7188 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9482354f 7189 if (rc != 0) {
068e94ea
MCC
7190 pr_err("error %d\n", rc);
7191 goto rw_error;
7192 }
244c0e06 7193 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
9482354f 7194 if (rc != 0) {
068e94ea
MCC
7195 pr_err("error %d\n", rc);
7196 goto rw_error;
7197 }
7198
244c0e06 7199 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 7200 if (rc != 0) {
068e94ea
MCC
7201 pr_err("error %d\n", rc);
7202 goto rw_error;
7203 }
244c0e06 7204 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
9482354f 7205 if (rc != 0) {
068e94ea
MCC
7206 pr_err("error %d\n", rc);
7207 goto rw_error;
7208 }
244c0e06 7209 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 7210 if (rc != 0) {
068e94ea
MCC
7211 pr_err("error %d\n", rc);
7212 goto rw_error;
7213 }
7214
244c0e06 7215 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
9482354f 7216 if (rc != 0) {
068e94ea
MCC
7217 pr_err("error %d\n", rc);
7218 goto rw_error;
7219 }
244c0e06 7220 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
9482354f 7221 if (rc != 0) {
068e94ea
MCC
7222 pr_err("error %d\n", rc);
7223 goto rw_error;
7224 }
244c0e06 7225 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
9482354f 7226 if (rc != 0) {
068e94ea
MCC
7227 pr_err("error %d\n", rc);
7228 goto rw_error;
7229 }
244c0e06 7230 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
9482354f 7231 if (rc != 0) {
068e94ea
MCC
7232 pr_err("error %d\n", rc);
7233 goto rw_error;
7234 }
244c0e06 7235 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
9482354f 7236 if (rc != 0) {
068e94ea
MCC
7237 pr_err("error %d\n", rc);
7238 goto rw_error;
7239 }
244c0e06 7240 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
9482354f 7241 if (rc != 0) {
068e94ea
MCC
7242 pr_err("error %d\n", rc);
7243 goto rw_error;
7244 }
244c0e06 7245 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
9482354f 7246 if (rc != 0) {
068e94ea
MCC
7247 pr_err("error %d\n", rc);
7248 goto rw_error;
7249 }
7250
244c0e06 7251 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 7252 if (rc != 0) {
068e94ea
MCC
7253 pr_err("error %d\n", rc);
7254 goto rw_error;
7255 }
244c0e06 7256 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 7257 if (rc != 0) {
068e94ea
MCC
7258 pr_err("error %d\n", rc);
7259 goto rw_error;
7260 }
244c0e06 7261 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 7262 if (rc != 0) {
068e94ea
MCC
7263 pr_err("error %d\n", rc);
7264 goto rw_error;
7265 }
244c0e06 7266 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
9482354f 7267 if (rc != 0) {
068e94ea
MCC
7268 pr_err("error %d\n", rc);
7269 goto rw_error;
7270 }
244c0e06 7271 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 7272 if (rc != 0) {
068e94ea
MCC
7273 pr_err("error %d\n", rc);
7274 goto rw_error;
7275 }
244c0e06 7276 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 7277 if (rc != 0) {
068e94ea
MCC
7278 pr_err("error %d\n", rc);
7279 goto rw_error;
7280 }
244c0e06 7281 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
9482354f 7282 if (rc != 0) {
068e94ea
MCC
7283 pr_err("error %d\n", rc);
7284 goto rw_error;
7285 }
244c0e06 7286 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9482354f 7287 if (rc != 0) {
068e94ea
MCC
7288 pr_err("error %d\n", rc);
7289 goto rw_error;
7290 }
244c0e06 7291 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 7292 if (rc != 0) {
068e94ea
MCC
7293 pr_err("error %d\n", rc);
7294 goto rw_error;
7295 }
244c0e06 7296 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 7297 if (rc != 0) {
068e94ea
MCC
7298 pr_err("error %d\n", rc);
7299 goto rw_error;
7300 }
244c0e06 7301 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 7302 if (rc != 0) {
068e94ea
MCC
7303 pr_err("error %d\n", rc);
7304 goto rw_error;
7305 }
244c0e06 7306 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 7307 if (rc != 0) {
068e94ea
MCC
7308 pr_err("error %d\n", rc);
7309 goto rw_error;
7310 }
244c0e06 7311 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 7312 if (rc != 0) {
068e94ea
MCC
7313 pr_err("error %d\n", rc);
7314 goto rw_error;
7315 }
244c0e06 7316 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 7317 if (rc != 0) {
068e94ea
MCC
7318 pr_err("error %d\n", rc);
7319 goto rw_error;
7320 }
244c0e06 7321 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 7322 if (rc != 0) {
068e94ea
MCC
7323 pr_err("error %d\n", rc);
7324 goto rw_error;
7325 }
244c0e06 7326 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
9482354f 7327 if (rc != 0) {
068e94ea
MCC
7328 pr_err("error %d\n", rc);
7329 goto rw_error;
7330 }
244c0e06 7331 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
9482354f 7332 if (rc != 0) {
068e94ea
MCC
7333 pr_err("error %d\n", rc);
7334 goto rw_error;
7335 }
244c0e06 7336 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 7337 if (rc != 0) {
068e94ea
MCC
7338 pr_err("error %d\n", rc);
7339 goto rw_error;
7340 }
244c0e06 7341 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 7342 if (rc != 0) {
068e94ea
MCC
7343 pr_err("error %d\n", rc);
7344 goto rw_error;
7345 }
244c0e06 7346 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
9482354f 7347 if (rc != 0) {
068e94ea
MCC
7348 pr_err("error %d\n", rc);
7349 goto rw_error;
7350 }
7351
244c0e06 7352 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
9482354f 7353 if (rc != 0) {
068e94ea
MCC
7354 pr_err("error %d\n", rc);
7355 goto rw_error;
7356 }
443f18d0 7357
9482354f 7358 return 0;
38b2df95 7359rw_error:
30741871 7360 return rc;
38b2df95
DH
7361}
7362
7363/*============================================================================*/
7364
34eb9751 7365/*
57afe2f0 7366* \fn int set_qam128 ()
38b2df95
DH
7367* \brief QAM128 specific setup
7368* \param demod: instance of demod.
61263c75 7369* \return int.
38b2df95 7370*/
1bfc9e15 7371static int set_qam128(struct drx_demod_instance *demod)
443f18d0 7372{
57afe2f0 7373 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 7374 int rc;
679cfbb1 7375 static const u8 qam_dq_qual_fun[] = {
443f18d0
MCC
7376 DRXJ_16TO8(6), /* fun0 */
7377 DRXJ_16TO8(6), /* fun1 */
7378 DRXJ_16TO8(6), /* fun2 */
7379 DRXJ_16TO8(6), /* fun3 */
7380 DRXJ_16TO8(9), /* fun4 */
7381 DRXJ_16TO8(9), /* fun5 */
7382 };
679cfbb1 7383 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
7384 DRXJ_16TO8(6164), /* RAD0 */
7385 DRXJ_16TO8(6598), /* RAD1 */
7386 DRXJ_16TO8(6394), /* RAD2 */
7387 DRXJ_16TO8(6409), /* RAD3 */
7388 DRXJ_16TO8(6656), /* RAD4 */
7389 DRXJ_16TO8(7238), /* RAD5 */
7390 };
7391
244c0e06 7392 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 7393 if (rc != 0) {
068e94ea
MCC
7394 pr_err("error %d\n", rc);
7395 goto rw_error;
7396 }
244c0e06 7397 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
9482354f 7398 if (rc != 0) {
068e94ea
MCC
7399 pr_err("error %d\n", rc);
7400 goto rw_error;
7401 }
7402
244c0e06 7403 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
9482354f 7404 if (rc != 0) {
068e94ea
MCC
7405 pr_err("error %d\n", rc);
7406 goto rw_error;
7407 }
244c0e06 7408 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9482354f 7409 if (rc != 0) {
068e94ea
MCC
7410 pr_err("error %d\n", rc);
7411 goto rw_error;
7412 }
244c0e06 7413 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9482354f 7414 if (rc != 0) {
068e94ea
MCC
7415 pr_err("error %d\n", rc);
7416 goto rw_error;
7417 }
244c0e06 7418 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
9482354f 7419 if (rc != 0) {
068e94ea
MCC
7420 pr_err("error %d\n", rc);
7421 goto rw_error;
7422 }
244c0e06 7423 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9482354f 7424 if (rc != 0) {
068e94ea
MCC
7425 pr_err("error %d\n", rc);
7426 goto rw_error;
7427 }
244c0e06 7428 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
9482354f 7429 if (rc != 0) {
068e94ea
MCC
7430 pr_err("error %d\n", rc);
7431 goto rw_error;
7432 }
7433
244c0e06 7434 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 7435 if (rc != 0) {
068e94ea
MCC
7436 pr_err("error %d\n", rc);
7437 goto rw_error;
7438 }
244c0e06 7439 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
9482354f 7440 if (rc != 0) {
068e94ea
MCC
7441 pr_err("error %d\n", rc);
7442 goto rw_error;
7443 }
244c0e06 7444 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 7445 if (rc != 0) {
068e94ea
MCC
7446 pr_err("error %d\n", rc);
7447 goto rw_error;
7448 }
7449
244c0e06 7450 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
9482354f 7451 if (rc != 0) {
068e94ea
MCC
7452 pr_err("error %d\n", rc);
7453 goto rw_error;
7454 }
244c0e06 7455 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
9482354f 7456 if (rc != 0) {
068e94ea
MCC
7457 pr_err("error %d\n", rc);
7458 goto rw_error;
7459 }
244c0e06 7460 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
9482354f 7461 if (rc != 0) {
068e94ea
MCC
7462 pr_err("error %d\n", rc);
7463 goto rw_error;
7464 }
244c0e06 7465 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
9482354f 7466 if (rc != 0) {
068e94ea
MCC
7467 pr_err("error %d\n", rc);
7468 goto rw_error;
7469 }
244c0e06 7470 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
9482354f 7471 if (rc != 0) {
068e94ea
MCC
7472 pr_err("error %d\n", rc);
7473 goto rw_error;
7474 }
244c0e06 7475 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
9482354f 7476 if (rc != 0) {
068e94ea
MCC
7477 pr_err("error %d\n", rc);
7478 goto rw_error;
7479 }
244c0e06 7480 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
9482354f 7481 if (rc != 0) {
068e94ea
MCC
7482 pr_err("error %d\n", rc);
7483 goto rw_error;
7484 }
7485
244c0e06 7486 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 7487 if (rc != 0) {
068e94ea
MCC
7488 pr_err("error %d\n", rc);
7489 goto rw_error;
7490 }
244c0e06 7491 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 7492 if (rc != 0) {
068e94ea
MCC
7493 pr_err("error %d\n", rc);
7494 goto rw_error;
7495 }
244c0e06 7496 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 7497 if (rc != 0) {
068e94ea
MCC
7498 pr_err("error %d\n", rc);
7499 goto rw_error;
7500 }
244c0e06 7501 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
9482354f 7502 if (rc != 0) {
068e94ea
MCC
7503 pr_err("error %d\n", rc);
7504 goto rw_error;
7505 }
244c0e06 7506 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 7507 if (rc != 0) {
068e94ea
MCC
7508 pr_err("error %d\n", rc);
7509 goto rw_error;
7510 }
244c0e06 7511 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 7512 if (rc != 0) {
068e94ea
MCC
7513 pr_err("error %d\n", rc);
7514 goto rw_error;
7515 }
244c0e06 7516 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
9482354f 7517 if (rc != 0) {
068e94ea
MCC
7518 pr_err("error %d\n", rc);
7519 goto rw_error;
7520 }
244c0e06 7521 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9482354f 7522 if (rc != 0) {
068e94ea
MCC
7523 pr_err("error %d\n", rc);
7524 goto rw_error;
7525 }
244c0e06 7526 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 7527 if (rc != 0) {
068e94ea
MCC
7528 pr_err("error %d\n", rc);
7529 goto rw_error;
7530 }
244c0e06 7531 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 7532 if (rc != 0) {
068e94ea
MCC
7533 pr_err("error %d\n", rc);
7534 goto rw_error;
7535 }
244c0e06 7536 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 7537 if (rc != 0) {
068e94ea
MCC
7538 pr_err("error %d\n", rc);
7539 goto rw_error;
7540 }
244c0e06 7541 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 7542 if (rc != 0) {
068e94ea
MCC
7543 pr_err("error %d\n", rc);
7544 goto rw_error;
7545 }
244c0e06 7546 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 7547 if (rc != 0) {
068e94ea
MCC
7548 pr_err("error %d\n", rc);
7549 goto rw_error;
7550 }
244c0e06 7551 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 7552 if (rc != 0) {
068e94ea
MCC
7553 pr_err("error %d\n", rc);
7554 goto rw_error;
7555 }
244c0e06 7556 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 7557 if (rc != 0) {
068e94ea
MCC
7558 pr_err("error %d\n", rc);
7559 goto rw_error;
7560 }
244c0e06 7561 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
9482354f 7562 if (rc != 0) {
068e94ea
MCC
7563 pr_err("error %d\n", rc);
7564 goto rw_error;
7565 }
244c0e06 7566 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
9482354f 7567 if (rc != 0) {
068e94ea
MCC
7568 pr_err("error %d\n", rc);
7569 goto rw_error;
7570 }
244c0e06 7571 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 7572 if (rc != 0) {
068e94ea
MCC
7573 pr_err("error %d\n", rc);
7574 goto rw_error;
7575 }
244c0e06 7576 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 7577 if (rc != 0) {
068e94ea
MCC
7578 pr_err("error %d\n", rc);
7579 goto rw_error;
7580 }
244c0e06 7581 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9482354f 7582 if (rc != 0) {
068e94ea
MCC
7583 pr_err("error %d\n", rc);
7584 goto rw_error;
7585 }
7586
244c0e06 7587 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
9482354f 7588 if (rc != 0) {
068e94ea
MCC
7589 pr_err("error %d\n", rc);
7590 goto rw_error;
7591 }
443f18d0 7592
9482354f 7593 return 0;
38b2df95 7594rw_error:
30741871 7595 return rc;
38b2df95
DH
7596}
7597
7598/*============================================================================*/
7599
34eb9751 7600/*
57afe2f0 7601* \fn int set_qam256 ()
38b2df95
DH
7602* \brief QAM256 specific setup
7603* \param demod: instance of demod.
61263c75 7604* \return int.
38b2df95 7605*/
1bfc9e15 7606static int set_qam256(struct drx_demod_instance *demod)
443f18d0 7607{
57afe2f0 7608 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 7609 int rc;
679cfbb1 7610 static const u8 qam_dq_qual_fun[] = {
443f18d0
MCC
7611 DRXJ_16TO8(8), /* fun0 */
7612 DRXJ_16TO8(8), /* fun1 */
7613 DRXJ_16TO8(8), /* fun2 */
7614 DRXJ_16TO8(8), /* fun3 */
7615 DRXJ_16TO8(12), /* fun4 */
7616 DRXJ_16TO8(12), /* fun5 */
7617 };
679cfbb1 7618 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
7619 DRXJ_16TO8(12345), /* RAD0 */
7620 DRXJ_16TO8(12345), /* RAD1 */
7621 DRXJ_16TO8(13626), /* RAD2 */
7622 DRXJ_16TO8(12931), /* RAD3 */
7623 DRXJ_16TO8(14719), /* RAD4 */
7624 DRXJ_16TO8(15356), /* RAD5 */
7625 };
7626
244c0e06 7627 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 7628 if (rc != 0) {
068e94ea
MCC
7629 pr_err("error %d\n", rc);
7630 goto rw_error;
7631 }
244c0e06 7632 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
9482354f 7633 if (rc != 0) {
068e94ea
MCC
7634 pr_err("error %d\n", rc);
7635 goto rw_error;
7636 }
7637
244c0e06 7638 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
9482354f 7639 if (rc != 0) {
068e94ea
MCC
7640 pr_err("error %d\n", rc);
7641 goto rw_error;
7642 }
244c0e06 7643 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9482354f 7644 if (rc != 0) {
068e94ea
MCC
7645 pr_err("error %d\n", rc);
7646 goto rw_error;
7647 }
244c0e06 7648 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9482354f 7649 if (rc != 0) {
068e94ea
MCC
7650 pr_err("error %d\n", rc);
7651 goto rw_error;
7652 }
244c0e06 7653 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
9482354f 7654 if (rc != 0) {
068e94ea
MCC
7655 pr_err("error %d\n", rc);
7656 goto rw_error;
7657 }
244c0e06 7658 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9482354f 7659 if (rc != 0) {
068e94ea
MCC
7660 pr_err("error %d\n", rc);
7661 goto rw_error;
7662 }
244c0e06 7663 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
9482354f 7664 if (rc != 0) {
068e94ea
MCC
7665 pr_err("error %d\n", rc);
7666 goto rw_error;
7667 }
7668
244c0e06 7669 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 7670 if (rc != 0) {
068e94ea
MCC
7671 pr_err("error %d\n", rc);
7672 goto rw_error;
7673 }
244c0e06 7674 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
9482354f 7675 if (rc != 0) {
068e94ea
MCC
7676 pr_err("error %d\n", rc);
7677 goto rw_error;
7678 }
244c0e06 7679 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 7680 if (rc != 0) {
068e94ea
MCC
7681 pr_err("error %d\n", rc);
7682 goto rw_error;
7683 }
7684
244c0e06 7685 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
9482354f 7686 if (rc != 0) {
068e94ea
MCC
7687 pr_err("error %d\n", rc);
7688 goto rw_error;
7689 }
244c0e06 7690 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
9482354f 7691 if (rc != 0) {
068e94ea
MCC
7692 pr_err("error %d\n", rc);
7693 goto rw_error;
7694 }
244c0e06 7695 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
9482354f 7696 if (rc != 0) {
068e94ea
MCC
7697 pr_err("error %d\n", rc);
7698 goto rw_error;
7699 }
244c0e06 7700 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
9482354f 7701 if (rc != 0) {
068e94ea
MCC
7702 pr_err("error %d\n", rc);
7703 goto rw_error;
7704 }
244c0e06 7705 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
9482354f 7706 if (rc != 0) {
068e94ea
MCC
7707 pr_err("error %d\n", rc);
7708 goto rw_error;
7709 }
244c0e06 7710 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
9482354f 7711 if (rc != 0) {
068e94ea
MCC
7712 pr_err("error %d\n", rc);
7713 goto rw_error;
7714 }
244c0e06 7715 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
9482354f 7716 if (rc != 0) {
068e94ea
MCC
7717 pr_err("error %d\n", rc);
7718 goto rw_error;
7719 }
7720
244c0e06 7721 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 7722 if (rc != 0) {
068e94ea
MCC
7723 pr_err("error %d\n", rc);
7724 goto rw_error;
7725 }
244c0e06 7726 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 7727 if (rc != 0) {
068e94ea
MCC
7728 pr_err("error %d\n", rc);
7729 goto rw_error;
7730 }
244c0e06 7731 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 7732 if (rc != 0) {
068e94ea
MCC
7733 pr_err("error %d\n", rc);
7734 goto rw_error;
7735 }
244c0e06 7736 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
9482354f 7737 if (rc != 0) {
068e94ea
MCC
7738 pr_err("error %d\n", rc);
7739 goto rw_error;
7740 }
244c0e06 7741 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 7742 if (rc != 0) {
068e94ea
MCC
7743 pr_err("error %d\n", rc);
7744 goto rw_error;
7745 }
244c0e06 7746 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 7747 if (rc != 0) {
068e94ea
MCC
7748 pr_err("error %d\n", rc);
7749 goto rw_error;
7750 }
244c0e06 7751 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
9482354f 7752 if (rc != 0) {
068e94ea
MCC
7753 pr_err("error %d\n", rc);
7754 goto rw_error;
7755 }
244c0e06 7756 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9482354f 7757 if (rc != 0) {
068e94ea
MCC
7758 pr_err("error %d\n", rc);
7759 goto rw_error;
7760 }
244c0e06 7761 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 7762 if (rc != 0) {
068e94ea
MCC
7763 pr_err("error %d\n", rc);
7764 goto rw_error;
7765 }
244c0e06 7766 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 7767 if (rc != 0) {
068e94ea
MCC
7768 pr_err("error %d\n", rc);
7769 goto rw_error;
7770 }
244c0e06 7771 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 7772 if (rc != 0) {
068e94ea
MCC
7773 pr_err("error %d\n", rc);
7774 goto rw_error;
7775 }
244c0e06 7776 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 7777 if (rc != 0) {
068e94ea
MCC
7778 pr_err("error %d\n", rc);
7779 goto rw_error;
7780 }
244c0e06 7781 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 7782 if (rc != 0) {
068e94ea
MCC
7783 pr_err("error %d\n", rc);
7784 goto rw_error;
7785 }
244c0e06 7786 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 7787 if (rc != 0) {
068e94ea
MCC
7788 pr_err("error %d\n", rc);
7789 goto rw_error;
7790 }
244c0e06 7791 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 7792 if (rc != 0) {
068e94ea
MCC
7793 pr_err("error %d\n", rc);
7794 goto rw_error;
7795 }
244c0e06 7796 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
9482354f 7797 if (rc != 0) {
068e94ea
MCC
7798 pr_err("error %d\n", rc);
7799 goto rw_error;
7800 }
244c0e06 7801 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
9482354f 7802 if (rc != 0) {
068e94ea
MCC
7803 pr_err("error %d\n", rc);
7804 goto rw_error;
7805 }
244c0e06 7806 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 7807 if (rc != 0) {
068e94ea
MCC
7808 pr_err("error %d\n", rc);
7809 goto rw_error;
7810 }
244c0e06 7811 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 7812 if (rc != 0) {
068e94ea
MCC
7813 pr_err("error %d\n", rc);
7814 goto rw_error;
7815 }
244c0e06 7816 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9482354f 7817 if (rc != 0) {
068e94ea
MCC
7818 pr_err("error %d\n", rc);
7819 goto rw_error;
7820 }
7821
244c0e06 7822 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
9482354f 7823 if (rc != 0) {
068e94ea
MCC
7824 pr_err("error %d\n", rc);
7825 goto rw_error;
7826 }
443f18d0 7827
9482354f 7828 return 0;
38b2df95 7829rw_error:
30741871 7830 return rc;
38b2df95
DH
7831}
7832
7833/*============================================================================*/
7834#define QAM_SET_OP_ALL 0x1
7835#define QAM_SET_OP_CONSTELLATION 0x2
7836#define QAM_SET_OP_SPECTRUM 0X4
7837
34eb9751 7838/*
57afe2f0 7839* \fn int set_qam ()
38b2df95
DH
7840* \brief Set QAM demod.
7841* \param demod: instance of demod.
7842* \param channel: pointer to channel data.
61263c75 7843* \return int.
38b2df95 7844*/
61263c75 7845static int
1bfc9e15
MCC
7846set_qam(struct drx_demod_instance *demod,
7847 struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
57afe2f0
MCC
7848{
7849 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 7850 struct drxj_data *ext_attr = NULL;
1bfc9e15 7851 struct drx_common_attr *common_attr = NULL;
068e94ea 7852 int rc;
57afe2f0
MCC
7853 u32 adc_frequency = 0;
7854 u32 iqm_rc_rate = 0;
068e94ea 7855 u16 cmd_result = 0;
57afe2f0
MCC
7856 u16 lc_symbol_freq = 0;
7857 u16 iqm_rc_stretch = 0;
7858 u16 set_env_parameters = 0;
7859 u16 set_param_parameters[2] = { 0 };
b3ce3a83 7860 struct drxjscu_cmd cmd_scu = { /* command */ 0,
57afe2f0
MCC
7861 /* parameter_len */ 0,
7862 /* result_len */ 0,
443f18d0
MCC
7863 /* parameter */ NULL,
7864 /* result */ NULL
7865 };
679cfbb1 7866 static const u8 qam_a_taps[] = {
443f18d0
MCC
7867 DRXJ_16TO8(-1), /* re0 */
7868 DRXJ_16TO8(1), /* re1 */
7869 DRXJ_16TO8(1), /* re2 */
7870 DRXJ_16TO8(-1), /* re3 */
7871 DRXJ_16TO8(-1), /* re4 */
7872 DRXJ_16TO8(2), /* re5 */
7873 DRXJ_16TO8(1), /* re6 */
7874 DRXJ_16TO8(-2), /* re7 */
7875 DRXJ_16TO8(0), /* re8 */
7876 DRXJ_16TO8(3), /* re9 */
7877 DRXJ_16TO8(-1), /* re10 */
7878 DRXJ_16TO8(-3), /* re11 */
7879 DRXJ_16TO8(4), /* re12 */
7880 DRXJ_16TO8(1), /* re13 */
7881 DRXJ_16TO8(-8), /* re14 */
7882 DRXJ_16TO8(4), /* re15 */
7883 DRXJ_16TO8(13), /* re16 */
7884 DRXJ_16TO8(-13), /* re17 */
7885 DRXJ_16TO8(-19), /* re18 */
7886 DRXJ_16TO8(28), /* re19 */
7887 DRXJ_16TO8(25), /* re20 */
7888 DRXJ_16TO8(-53), /* re21 */
7889 DRXJ_16TO8(-31), /* re22 */
7890 DRXJ_16TO8(96), /* re23 */
7891 DRXJ_16TO8(37), /* re24 */
7892 DRXJ_16TO8(-190), /* re25 */
7893 DRXJ_16TO8(-40), /* re26 */
7894 DRXJ_16TO8(619) /* re27 */
7895 };
679cfbb1 7896 static const u8 qam_b64_taps[] = {
443f18d0
MCC
7897 DRXJ_16TO8(0), /* re0 */
7898 DRXJ_16TO8(-2), /* re1 */
7899 DRXJ_16TO8(1), /* re2 */
7900 DRXJ_16TO8(2), /* re3 */
7901 DRXJ_16TO8(-2), /* re4 */
7902 DRXJ_16TO8(0), /* re5 */
7903 DRXJ_16TO8(4), /* re6 */
7904 DRXJ_16TO8(-2), /* re7 */
7905 DRXJ_16TO8(-4), /* re8 */
7906 DRXJ_16TO8(4), /* re9 */
7907 DRXJ_16TO8(3), /* re10 */
7908 DRXJ_16TO8(-6), /* re11 */
7909 DRXJ_16TO8(0), /* re12 */
7910 DRXJ_16TO8(6), /* re13 */
7911 DRXJ_16TO8(-5), /* re14 */
7912 DRXJ_16TO8(-3), /* re15 */
7913 DRXJ_16TO8(11), /* re16 */
7914 DRXJ_16TO8(-4), /* re17 */
7915 DRXJ_16TO8(-19), /* re18 */
7916 DRXJ_16TO8(19), /* re19 */
7917 DRXJ_16TO8(28), /* re20 */
7918 DRXJ_16TO8(-45), /* re21 */
7919 DRXJ_16TO8(-36), /* re22 */
7920 DRXJ_16TO8(90), /* re23 */
7921 DRXJ_16TO8(42), /* re24 */
7922 DRXJ_16TO8(-185), /* re25 */
7923 DRXJ_16TO8(-46), /* re26 */
7924 DRXJ_16TO8(614) /* re27 */
7925 };
679cfbb1 7926 static const u8 qam_b256_taps[] = {
443f18d0
MCC
7927 DRXJ_16TO8(-2), /* re0 */
7928 DRXJ_16TO8(4), /* re1 */
7929 DRXJ_16TO8(1), /* re2 */
7930 DRXJ_16TO8(-4), /* re3 */
7931 DRXJ_16TO8(0), /* re4 */
7932 DRXJ_16TO8(4), /* re5 */
7933 DRXJ_16TO8(-2), /* re6 */
7934 DRXJ_16TO8(-4), /* re7 */
7935 DRXJ_16TO8(5), /* re8 */
7936 DRXJ_16TO8(2), /* re9 */
7937 DRXJ_16TO8(-8), /* re10 */
7938 DRXJ_16TO8(2), /* re11 */
7939 DRXJ_16TO8(11), /* re12 */
7940 DRXJ_16TO8(-8), /* re13 */
7941 DRXJ_16TO8(-15), /* re14 */
7942 DRXJ_16TO8(16), /* re15 */
7943 DRXJ_16TO8(19), /* re16 */
7944 DRXJ_16TO8(-27), /* re17 */
7945 DRXJ_16TO8(-22), /* re18 */
7946 DRXJ_16TO8(44), /* re19 */
7947 DRXJ_16TO8(26), /* re20 */
7948 DRXJ_16TO8(-69), /* re21 */
7949 DRXJ_16TO8(-28), /* re22 */
7950 DRXJ_16TO8(110), /* re23 */
7951 DRXJ_16TO8(31), /* re24 */
7952 DRXJ_16TO8(-201), /* re25 */
7953 DRXJ_16TO8(-32), /* re26 */
7954 DRXJ_16TO8(628) /* re27 */
7955 };
679cfbb1 7956 static const u8 qam_c_taps[] = {
443f18d0
MCC
7957 DRXJ_16TO8(-3), /* re0 */
7958 DRXJ_16TO8(3), /* re1 */
7959 DRXJ_16TO8(2), /* re2 */
7960 DRXJ_16TO8(-4), /* re3 */
7961 DRXJ_16TO8(0), /* re4 */
7962 DRXJ_16TO8(4), /* re5 */
7963 DRXJ_16TO8(-1), /* re6 */
7964 DRXJ_16TO8(-4), /* re7 */
7965 DRXJ_16TO8(3), /* re8 */
7966 DRXJ_16TO8(3), /* re9 */
7967 DRXJ_16TO8(-5), /* re10 */
7968 DRXJ_16TO8(0), /* re11 */
7969 DRXJ_16TO8(9), /* re12 */
7970 DRXJ_16TO8(-4), /* re13 */
7971 DRXJ_16TO8(-12), /* re14 */
7972 DRXJ_16TO8(10), /* re15 */
7973 DRXJ_16TO8(16), /* re16 */
7974 DRXJ_16TO8(-21), /* re17 */
7975 DRXJ_16TO8(-20), /* re18 */
7976 DRXJ_16TO8(37), /* re19 */
7977 DRXJ_16TO8(25), /* re20 */
7978 DRXJ_16TO8(-62), /* re21 */
7979 DRXJ_16TO8(-28), /* re22 */
7980 DRXJ_16TO8(105), /* re23 */
7981 DRXJ_16TO8(31), /* re24 */
7982 DRXJ_16TO8(-197), /* re25 */
7983 DRXJ_16TO8(-33), /* re26 */
7984 DRXJ_16TO8(626) /* re27 */
7985 };
7986
57afe2f0 7987 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 7988 ext_attr = (struct drxj_data *) demod->my_ext_attr;
1bfc9e15 7989 common_attr = (struct drx_common_attr *) demod->my_common_attr;
443f18d0
MCC
7990
7991 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
57afe2f0 7992 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
443f18d0
MCC
7993 switch (channel->constellation) {
7994 case DRX_CONSTELLATION_QAM256:
57afe2f0
MCC
7995 iqm_rc_rate = 0x00AE3562;
7996 lc_symbol_freq =
443f18d0
MCC
7997 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
7998 channel->symbolrate = 5360537;
57afe2f0 7999 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
443f18d0
MCC
8000 break;
8001 case DRX_CONSTELLATION_QAM64:
57afe2f0
MCC
8002 iqm_rc_rate = 0x00C05A0E;
8003 lc_symbol_freq = 409;
443f18d0 8004 channel->symbolrate = 5056941;
57afe2f0 8005 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
443f18d0
MCC
8006 break;
8007 default:
9482354f 8008 return -EINVAL;
443f18d0
MCC
8009 }
8010 } else {
57afe2f0 8011 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
068e94ea
MCC
8012 if (channel->symbolrate == 0) {
8013 pr_err("error: channel symbolrate is zero!\n");
9482354f 8014 return -EIO;
068e94ea 8015 }
57afe2f0
MCC
8016 iqm_rc_rate =
8017 (adc_frequency / channel->symbolrate) * (1 << 21) +
8018 (frac28
8019 ((adc_frequency % channel->symbolrate),
443f18d0 8020 channel->symbolrate) >> 7) - (1 << 23);
57afe2f0
MCC
8021 lc_symbol_freq =
8022 (u16) (frac28
443f18d0 8023 (channel->symbolrate +
57afe2f0
MCC
8024 (adc_frequency >> 13),
8025 adc_frequency) >> 16);
8026 if (lc_symbol_freq > 511)
8027 lc_symbol_freq = 511;
8028
8029 iqm_rc_stretch = 21;
8030 }
8031
8032 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8033 set_env_parameters = QAM_TOP_ANNEX_A; /* annex */
8034 set_param_parameters[0] = channel->constellation; /* constellation */
8035 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
8036 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8037 set_env_parameters = QAM_TOP_ANNEX_B; /* annex */
8038 set_param_parameters[0] = channel->constellation; /* constellation */
8039 set_param_parameters[1] = channel->interleavemode; /* interleave mode */
8040 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8041 set_env_parameters = QAM_TOP_ANNEX_C; /* annex */
8042 set_param_parameters[0] = channel->constellation; /* constellation */
8043 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
443f18d0 8044 } else {
9482354f 8045 return -EINVAL;
443f18d0
MCC
8046 }
8047 }
38b2df95 8048
443f18d0
MCC
8049 if (op & QAM_SET_OP_ALL) {
8050 /*
8051 STEP 1: reset demodulator
8052 resets IQM, QAM and FEC HW blocks
8053 resets SCU variables
8054 */
8055 /* stop all comm_exec */
244c0e06 8056 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9482354f 8057 if (rc != 0) {
068e94ea
MCC
8058 pr_err("error %d\n", rc);
8059 goto rw_error;
8060 }
244c0e06 8061 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
9482354f 8062 if (rc != 0) {
068e94ea
MCC
8063 pr_err("error %d\n", rc);
8064 goto rw_error;
8065 }
244c0e06 8066 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 8067 if (rc != 0) {
068e94ea
MCC
8068 pr_err("error %d\n", rc);
8069 goto rw_error;
8070 }
244c0e06 8071 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 8072 if (rc != 0) {
068e94ea
MCC
8073 pr_err("error %d\n", rc);
8074 goto rw_error;
8075 }
244c0e06 8076 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 8077 if (rc != 0) {
068e94ea
MCC
8078 pr_err("error %d\n", rc);
8079 goto rw_error;
8080 }
244c0e06 8081 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 8082 if (rc != 0) {
068e94ea
MCC
8083 pr_err("error %d\n", rc);
8084 goto rw_error;
8085 }
244c0e06 8086 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 8087 if (rc != 0) {
068e94ea
MCC
8088 pr_err("error %d\n", rc);
8089 goto rw_error;
8090 }
57afe2f0
MCC
8091
8092 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 8093 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
57afe2f0
MCC
8094 cmd_scu.parameter_len = 0;
8095 cmd_scu.result_len = 1;
8096 cmd_scu.parameter = NULL;
8097 cmd_scu.result = &cmd_result;
068e94ea 8098 rc = scu_command(dev_addr, &cmd_scu);
9482354f 8099 if (rc != 0) {
068e94ea
MCC
8100 pr_err("error %d\n", rc);
8101 goto rw_error;
8102 }
443f18d0 8103 }
38b2df95 8104
443f18d0
MCC
8105 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8106 /*
8107 STEP 2: configure demodulator
8108 -set env
8109 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
8110 */
57afe2f0 8111 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 8112 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
57afe2f0
MCC
8113 cmd_scu.parameter_len = 1;
8114 cmd_scu.result_len = 1;
8115 cmd_scu.parameter = &set_env_parameters;
8116 cmd_scu.result = &cmd_result;
068e94ea 8117 rc = scu_command(dev_addr, &cmd_scu);
9482354f 8118 if (rc != 0) {
068e94ea
MCC
8119 pr_err("error %d\n", rc);
8120 goto rw_error;
8121 }
443f18d0 8122
57afe2f0 8123 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 8124 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
57afe2f0
MCC
8125 cmd_scu.parameter_len = 2;
8126 cmd_scu.result_len = 1;
8127 cmd_scu.parameter = set_param_parameters;
8128 cmd_scu.result = &cmd_result;
068e94ea 8129 rc = scu_command(dev_addr, &cmd_scu);
9482354f 8130 if (rc != 0) {
068e94ea
MCC
8131 pr_err("error %d\n", rc);
8132 goto rw_error;
8133 }
443f18d0 8134 /* set symbol rate */
244c0e06 8135 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
9482354f 8136 if (rc != 0) {
068e94ea
MCC
8137 pr_err("error %d\n", rc);
8138 goto rw_error;
8139 }
57afe2f0 8140 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
068e94ea 8141 rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
9482354f 8142 if (rc != 0) {
068e94ea
MCC
8143 pr_err("error %d\n", rc);
8144 goto rw_error;
8145 }
443f18d0
MCC
8146 }
8147 /* STEP 3: enable the system in a mode where the ADC provides valid signal
8148 setup constellation independent registers */
8149 /* from qam_cmd.py script (qam_driver_b) */
8150 /* TODO: remove re-writes of HW reset values */
8151 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
068e94ea 8152 rc = set_frequency(demod, channel, tuner_freq_offset);
9482354f 8153 if (rc != 0) {
068e94ea
MCC
8154 pr_err("error %d\n", rc);
8155 goto rw_error;
8156 }
443f18d0 8157 }
38b2df95 8158
443f18d0 8159 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
38b2df95 8160
244c0e06 8161 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
9482354f 8162 if (rc != 0) {
068e94ea
MCC
8163 pr_err("error %d\n", rc);
8164 goto rw_error;
8165 }
244c0e06 8166 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
9482354f 8167 if (rc != 0) {
068e94ea
MCC
8168 pr_err("error %d\n", rc);
8169 goto rw_error;
8170 }
443f18d0 8171 }
38b2df95 8172
443f18d0 8173 if (op & QAM_SET_OP_ALL) {
259f380e 8174 if (!ext_attr->has_lna) {
244c0e06 8175 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
9482354f 8176 if (rc != 0) {
068e94ea
MCC
8177 pr_err("error %d\n", rc);
8178 goto rw_error;
8179 }
8180 }
244c0e06 8181 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
9482354f 8182 if (rc != 0) {
068e94ea
MCC
8183 pr_err("error %d\n", rc);
8184 goto rw_error;
8185 }
244c0e06 8186 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
9482354f 8187 if (rc != 0) {
068e94ea
MCC
8188 pr_err("error %d\n", rc);
8189 goto rw_error;
8190 }
244c0e06 8191 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
9482354f 8192 if (rc != 0) {
068e94ea
MCC
8193 pr_err("error %d\n", rc);
8194 goto rw_error;
57afe2f0 8195 }
57afe2f0 8196
244c0e06 8197 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
9482354f 8198 if (rc != 0) {
068e94ea
MCC
8199 pr_err("error %d\n", rc);
8200 goto rw_error;
8201 } /* scu temporary shut down agc */
57afe2f0 8202
244c0e06 8203 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
9482354f 8204 if (rc != 0) {
068e94ea
MCC
8205 pr_err("error %d\n", rc);
8206 goto rw_error;
8207 }
244c0e06 8208 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
9482354f 8209 if (rc != 0) {
068e94ea
MCC
8210 pr_err("error %d\n", rc);
8211 goto rw_error;
8212 }
244c0e06 8213 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
9482354f 8214 if (rc != 0) {
068e94ea
MCC
8215 pr_err("error %d\n", rc);
8216 goto rw_error;
8217 }
244c0e06 8218 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
9482354f 8219 if (rc != 0) {
068e94ea
MCC
8220 pr_err("error %d\n", rc);
8221 goto rw_error;
8222 }
244c0e06 8223 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, 4, 0);
9482354f 8224 if (rc != 0) {
068e94ea
MCC
8225 pr_err("error %d\n", rc);
8226 goto rw_error;
8227 }
244c0e06 8228 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
9482354f 8229 if (rc != 0) {
068e94ea
MCC
8230 pr_err("error %d\n", rc);
8231 goto rw_error;
8232 }
244c0e06 8233 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
9482354f 8234 if (rc != 0) {
068e94ea
MCC
8235 pr_err("error %d\n", rc);
8236 goto rw_error;
8237 }
57afe2f0 8238
244c0e06 8239 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
9482354f 8240 if (rc != 0) {
068e94ea
MCC
8241 pr_err("error %d\n", rc);
8242 goto rw_error;
8243 }
244c0e06 8244 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
9482354f 8245 if (rc != 0) {
068e94ea
MCC
8246 pr_err("error %d\n", rc);
8247 goto rw_error;
8248 } /*! reset default val ! */
8249
244c0e06 8250 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
9482354f 8251 if (rc != 0) {
068e94ea
MCC
8252 pr_err("error %d\n", rc);
8253 goto rw_error;
8254 } /*! reset default val ! */
57afe2f0 8255 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
244c0e06 8256 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
9482354f 8257 if (rc != 0) {
068e94ea
MCC
8258 pr_err("error %d\n", rc);
8259 goto rw_error;
8260 } /*! reset default val ! */
244c0e06 8261 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
9482354f 8262 if (rc != 0) {
068e94ea
MCC
8263 pr_err("error %d\n", rc);
8264 goto rw_error;
8265 } /*! reset default val ! */
244c0e06 8266 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9482354f 8267 if (rc != 0) {
068e94ea
MCC
8268 pr_err("error %d\n", rc);
8269 goto rw_error;
8270 } /*! reset default val ! */
443f18d0
MCC
8271 } else {
8272 switch (channel->constellation) {
8273 case DRX_CONSTELLATION_QAM16:
8274 case DRX_CONSTELLATION_QAM64:
8275 case DRX_CONSTELLATION_QAM256:
244c0e06 8276 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9482354f 8277 if (rc != 0) {
068e94ea
MCC
8278 pr_err("error %d\n", rc);
8279 goto rw_error;
8280 }
244c0e06 8281 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
9482354f 8282 if (rc != 0) {
068e94ea
MCC
8283 pr_err("error %d\n", rc);
8284 goto rw_error;
8285 }
244c0e06 8286 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9482354f 8287 if (rc != 0) {
068e94ea
MCC
8288 pr_err("error %d\n", rc);
8289 goto rw_error;
8290 } /*! reset default val ! */
443f18d0
MCC
8291 break;
8292 case DRX_CONSTELLATION_QAM32:
8293 case DRX_CONSTELLATION_QAM128:
244c0e06 8294 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9482354f 8295 if (rc != 0) {
068e94ea
MCC
8296 pr_err("error %d\n", rc);
8297 goto rw_error;
8298 }
244c0e06 8299 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
9482354f 8300 if (rc != 0) {
068e94ea
MCC
8301 pr_err("error %d\n", rc);
8302 goto rw_error;
8303 }
244c0e06 8304 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
9482354f 8305 if (rc != 0) {
068e94ea
MCC
8306 pr_err("error %d\n", rc);
8307 goto rw_error;
8308 }
443f18d0
MCC
8309 break;
8310 default:
9482354f 8311 return -EIO;
443f18d0
MCC
8312 } /* switch */
8313 }
8314
244c0e06 8315 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
9482354f 8316 if (rc != 0) {
068e94ea
MCC
8317 pr_err("error %d\n", rc);
8318 goto rw_error;
8319 } /*! reset default val ! */
244c0e06 8320 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
9482354f 8321 if (rc != 0) {
068e94ea
MCC
8322 pr_err("error %d\n", rc);
8323 goto rw_error;
8324 }
244c0e06 8325 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
9482354f 8326 if (rc != 0) {
068e94ea
MCC
8327 pr_err("error %d\n", rc);
8328 goto rw_error;
8329 }
244c0e06 8330 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
9482354f 8331 if (rc != 0) {
068e94ea
MCC
8332 pr_err("error %d\n", rc);
8333 goto rw_error;
8334 }
244c0e06 8335 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, 7, 0);
9482354f 8336 if (rc != 0) {
068e94ea
MCC
8337 pr_err("error %d\n", rc);
8338 goto rw_error;
8339 }
244c0e06 8340 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
9482354f 8341 if (rc != 0) {
068e94ea
MCC
8342 pr_err("error %d\n", rc);
8343 goto rw_error;
8344 }
244c0e06 8345 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
9482354f 8346 if (rc != 0) {
068e94ea
MCC
8347 pr_err("error %d\n", rc);
8348 goto rw_error;
8349 }
244c0e06 8350 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
9482354f 8351 if (rc != 0) {
068e94ea
MCC
8352 pr_err("error %d\n", rc);
8353 goto rw_error;
8354 }
244c0e06 8355 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
9482354f 8356 if (rc != 0) {
068e94ea
MCC
8357 pr_err("error %d\n", rc);
8358 goto rw_error;
8359 }
244c0e06 8360 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
9482354f 8361 if (rc != 0) {
068e94ea
MCC
8362 pr_err("error %d\n", rc);
8363 goto rw_error;
8364 }
244c0e06 8365 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
9482354f 8366 if (rc != 0) {
068e94ea
MCC
8367 pr_err("error %d\n", rc);
8368 goto rw_error;
8369 }
244c0e06 8370 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
9482354f 8371 if (rc != 0) {
068e94ea
MCC
8372 pr_err("error %d\n", rc);
8373 goto rw_error;
8374 }
244c0e06 8375 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
9482354f 8376 if (rc != 0) {
068e94ea
MCC
8377 pr_err("error %d\n", rc);
8378 goto rw_error;
8379 }
244c0e06 8380 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
9482354f 8381 if (rc != 0) {
068e94ea
MCC
8382 pr_err("error %d\n", rc);
8383 goto rw_error;
8384 }
244c0e06 8385 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
9482354f 8386 if (rc != 0) {
068e94ea
MCC
8387 pr_err("error %d\n", rc);
8388 goto rw_error;
8389 }
244c0e06 8390 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
9482354f 8391 if (rc != 0) {
068e94ea
MCC
8392 pr_err("error %d\n", rc);
8393 goto rw_error;
8394 }
244c0e06 8395 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
9482354f 8396 if (rc != 0) {
068e94ea
MCC
8397 pr_err("error %d\n", rc);
8398 goto rw_error;
8399 }
244c0e06 8400 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
9482354f 8401 if (rc != 0) {
068e94ea
MCC
8402 pr_err("error %d\n", rc);
8403 goto rw_error;
8404 }
244c0e06 8405 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
9482354f 8406 if (rc != 0) {
068e94ea
MCC
8407 pr_err("error %d\n", rc);
8408 goto rw_error;
8409 }
244c0e06 8410 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
9482354f 8411 if (rc != 0) {
068e94ea
MCC
8412 pr_err("error %d\n", rc);
8413 goto rw_error;
8414 }
8415
244c0e06 8416 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
9482354f 8417 if (rc != 0) {
068e94ea
MCC
8418 pr_err("error %d\n", rc);
8419 goto rw_error;
8420 }
244c0e06 8421 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
9482354f 8422 if (rc != 0) {
068e94ea
MCC
8423 pr_err("error %d\n", rc);
8424 goto rw_error;
8425 }
244c0e06 8426 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
9482354f 8427 if (rc != 0) {
068e94ea
MCC
8428 pr_err("error %d\n", rc);
8429 goto rw_error;
8430 }
244c0e06 8431 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
9482354f 8432 if (rc != 0) {
068e94ea
MCC
8433 pr_err("error %d\n", rc);
8434 goto rw_error;
8435 }
244c0e06 8436 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
9482354f 8437 if (rc != 0) {
068e94ea
MCC
8438 pr_err("error %d\n", rc);
8439 goto rw_error;
8440 }
443f18d0
MCC
8441
8442 /* No more resets of the IQM, current standard correctly set =>
8443 now AGCs can be configured. */
8444 /* turn on IQMAF. It has to be in front of setAgc**() */
068e94ea 8445 rc = set_iqm_af(demod, true);
9482354f 8446 if (rc != 0) {
068e94ea
MCC
8447 pr_err("error %d\n", rc);
8448 goto rw_error;
8449 }
8450 rc = adc_synchronization(demod);
9482354f 8451 if (rc != 0) {
068e94ea
MCC
8452 pr_err("error %d\n", rc);
8453 goto rw_error;
8454 }
443f18d0 8455
068e94ea 8456 rc = init_agc(demod);
9482354f 8457 if (rc != 0) {
068e94ea
MCC
8458 pr_err("error %d\n", rc);
8459 goto rw_error;
8460 }
8461 rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
9482354f 8462 if (rc != 0) {
068e94ea
MCC
8463 pr_err("error %d\n", rc);
8464 goto rw_error;
8465 }
8466 rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
9482354f 8467 if (rc != 0) {
068e94ea
MCC
8468 pr_err("error %d\n", rc);
8469 goto rw_error;
8470 }
443f18d0 8471 {
b3ce3a83 8472 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
443f18d0 8473 of only the gain */
b3ce3a83 8474 struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
443f18d0 8475
57afe2f0 8476 qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
068e94ea 8477 rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
9482354f 8478 if (rc != 0) {
068e94ea
MCC
8479 pr_err("error %d\n", rc);
8480 goto rw_error;
8481 }
8482 }
8483 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
9482354f 8484 if (rc != 0) {
068e94ea
MCC
8485 pr_err("error %d\n", rc);
8486 goto rw_error;
443f18d0 8487 }
443f18d0 8488 }
38b2df95 8489
443f18d0 8490 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
57afe2f0 8491 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
244c0e06 8492 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9482354f 8493 if (rc != 0) {
068e94ea
MCC
8494 pr_err("error %d\n", rc);
8495 goto rw_error;
8496 }
244c0e06 8497 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9482354f 8498 if (rc != 0) {
068e94ea
MCC
8499 pr_err("error %d\n", rc);
8500 goto rw_error;
8501 }
57afe2f0 8502 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
443f18d0
MCC
8503 switch (channel->constellation) {
8504 case DRX_CONSTELLATION_QAM64:
244c0e06 8505 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9482354f 8506 if (rc != 0) {
068e94ea
MCC
8507 pr_err("error %d\n", rc);
8508 goto rw_error;
8509 }
244c0e06 8510 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9482354f 8511 if (rc != 0) {
068e94ea
MCC
8512 pr_err("error %d\n", rc);
8513 goto rw_error;
8514 }
443f18d0
MCC
8515 break;
8516 case DRX_CONSTELLATION_QAM256:
244c0e06 8517 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9482354f 8518 if (rc != 0) {
068e94ea
MCC
8519 pr_err("error %d\n", rc);
8520 goto rw_error;
8521 }
244c0e06 8522 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9482354f 8523 if (rc != 0) {
068e94ea
MCC
8524 pr_err("error %d\n", rc);
8525 goto rw_error;
8526 }
443f18d0
MCC
8527 break;
8528 default:
9482354f 8529 return -EIO;
443f18d0 8530 }
57afe2f0 8531 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
244c0e06 8532 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9482354f 8533 if (rc != 0) {
068e94ea
MCC
8534 pr_err("error %d\n", rc);
8535 goto rw_error;
8536 }
244c0e06 8537 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9482354f 8538 if (rc != 0) {
068e94ea
MCC
8539 pr_err("error %d\n", rc);
8540 goto rw_error;
8541 }
443f18d0
MCC
8542 }
8543
8544 /* SETP 4: constellation specific setup */
8545 switch (channel->constellation) {
8546 case DRX_CONSTELLATION_QAM16:
068e94ea 8547 rc = set_qam16(demod);
9482354f 8548 if (rc != 0) {
068e94ea
MCC
8549 pr_err("error %d\n", rc);
8550 goto rw_error;
8551 }
443f18d0
MCC
8552 break;
8553 case DRX_CONSTELLATION_QAM32:
068e94ea 8554 rc = set_qam32(demod);
9482354f 8555 if (rc != 0) {
068e94ea
MCC
8556 pr_err("error %d\n", rc);
8557 goto rw_error;
8558 }
443f18d0
MCC
8559 break;
8560 case DRX_CONSTELLATION_QAM64:
068e94ea 8561 rc = set_qam64(demod);
9482354f 8562 if (rc != 0) {
068e94ea
MCC
8563 pr_err("error %d\n", rc);
8564 goto rw_error;
8565 }
443f18d0
MCC
8566 break;
8567 case DRX_CONSTELLATION_QAM128:
068e94ea 8568 rc = set_qam128(demod);
9482354f 8569 if (rc != 0) {
068e94ea
MCC
8570 pr_err("error %d\n", rc);
8571 goto rw_error;
8572 }
443f18d0
MCC
8573 break;
8574 case DRX_CONSTELLATION_QAM256:
068e94ea 8575 rc = set_qam256(demod);
9482354f 8576 if (rc != 0) {
068e94ea
MCC
8577 pr_err("error %d\n", rc);
8578 goto rw_error;
8579 }
443f18d0
MCC
8580 break;
8581 default:
9482354f 8582 return -EIO;
443f18d0
MCC
8583 } /* switch */
8584 }
38b2df95 8585
443f18d0 8586 if ((op & QAM_SET_OP_ALL)) {
244c0e06 8587 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
9482354f 8588 if (rc != 0) {
068e94ea
MCC
8589 pr_err("error %d\n", rc);
8590 goto rw_error;
8591 }
443f18d0
MCC
8592
8593 /* Mpeg output has to be in front of FEC active */
068e94ea 8594 rc = set_mpegtei_handling(demod);
9482354f 8595 if (rc != 0) {
068e94ea
MCC
8596 pr_err("error %d\n", rc);
8597 goto rw_error;
8598 }
8599 rc = bit_reverse_mpeg_output(demod);
9482354f 8600 if (rc != 0) {
068e94ea
MCC
8601 pr_err("error %d\n", rc);
8602 goto rw_error;
8603 }
8604 rc = set_mpeg_start_width(demod);
9482354f 8605 if (rc != 0) {
068e94ea
MCC
8606 pr_err("error %d\n", rc);
8607 goto rw_error;
8608 }
443f18d0 8609 {
57afe2f0 8610 /* TODO: move to set_standard after hardware reset value problem is solved */
443f18d0 8611 /* Configure initial MPEG output */
1bfc9e15 8612 struct drx_cfg_mpeg_output cfg_mpeg_output;
443f18d0 8613
41b5cc0c 8614 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
57afe2f0 8615 cfg_mpeg_output.enable_mpeg_output = true;
41b5cc0c 8616
068e94ea 8617 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 8618 if (rc != 0) {
068e94ea
MCC
8619 pr_err("error %d\n", rc);
8620 goto rw_error;
8621 }
443f18d0
MCC
8622 }
8623 }
38b2df95 8624
443f18d0 8625 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
38b2df95 8626
443f18d0 8627 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
57afe2f0 8628 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 8629 SCU_RAM_COMMAND_CMD_DEMOD_START;
57afe2f0
MCC
8630 cmd_scu.parameter_len = 0;
8631 cmd_scu.result_len = 1;
8632 cmd_scu.parameter = NULL;
8633 cmd_scu.result = &cmd_result;
068e94ea 8634 rc = scu_command(dev_addr, &cmd_scu);
9482354f 8635 if (rc != 0) {
068e94ea
MCC
8636 pr_err("error %d\n", rc);
8637 goto rw_error;
8638 }
443f18d0
MCC
8639 }
8640
244c0e06 8641 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
9482354f 8642 if (rc != 0) {
068e94ea
MCC
8643 pr_err("error %d\n", rc);
8644 goto rw_error;
8645 }
244c0e06 8646 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
9482354f 8647 if (rc != 0) {
068e94ea
MCC
8648 pr_err("error %d\n", rc);
8649 goto rw_error;
8650 }
244c0e06 8651 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
9482354f 8652 if (rc != 0) {
068e94ea
MCC
8653 pr_err("error %d\n", rc);
8654 goto rw_error;
8655 }
443f18d0 8656
9482354f 8657 return 0;
443f18d0 8658rw_error:
30741871 8659 return rc;
443f18d0
MCC
8660}
8661
8662/*============================================================================*/
03fdfbfd
MCC
8663static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
8664
1bfc9e15 8665static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
443f18d0 8666{
03fdfbfd
MCC
8667 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8668 struct drxj_data *ext_attr = demod->my_ext_attr;
068e94ea 8669 int rc;
57afe2f0
MCC
8670 u32 iqm_fs_rate_ofs = 0;
8671 u32 iqm_fs_rate_lo = 0;
8672 u16 qam_ctl_ena = 0;
43a431e4 8673 u16 data = 0;
57afe2f0
MCC
8674 u16 equ_mode = 0;
8675 u16 fsm_state = 0;
443f18d0
MCC
8676 int i = 0;
8677 int ofsofs = 0;
443f18d0
MCC
8678
8679 /* Silence the controlling of lc, equ, and the acquisition state machine */
244c0e06 8680 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
9482354f 8681 if (rc != 0) {
068e94ea
MCC
8682 pr_err("error %d\n", rc);
8683 goto rw_error;
8684 }
244c0e06 8685 rc = drxj_dap_write_reg16(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);
9482354f 8686 if (rc != 0) {
068e94ea
MCC
8687 pr_err("error %d\n", rc);
8688 goto rw_error;
8689 }
443f18d0
MCC
8690
8691 /* freeze the frequency control loop */
244c0e06 8692 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, 0, 0);
9482354f 8693 if (rc != 0) {
068e94ea
MCC
8694 pr_err("error %d\n", rc);
8695 goto rw_error;
8696 }
244c0e06 8697 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, 0, 0);
9482354f 8698 if (rc != 0) {
068e94ea
MCC
8699 pr_err("error %d\n", rc);
8700 goto rw_error;
8701 }
443f18d0 8702
068e94ea 8703 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
9482354f 8704 if (rc != 0) {
068e94ea
MCC
8705 pr_err("error %d\n", rc);
8706 goto rw_error;
8707 }
8708 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
9482354f 8709 if (rc != 0) {
068e94ea
MCC
8710 pr_err("error %d\n", rc);
8711 goto rw_error;
8712 }
57afe2f0
MCC
8713 ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
8714 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
8715 iqm_fs_rate_ofs -= 2 * ofsofs;
443f18d0
MCC
8716
8717 /* freeze dq/fq updating */
244c0e06 8718 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
9482354f 8719 if (rc != 0) {
068e94ea
MCC
8720 pr_err("error %d\n", rc);
8721 goto rw_error;
8722 }
443f18d0 8723 data = (data & 0xfff9);
244c0e06 8724 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
9482354f 8725 if (rc != 0) {
068e94ea
MCC
8726 pr_err("error %d\n", rc);
8727 goto rw_error;
8728 }
244c0e06 8729 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
9482354f 8730 if (rc != 0) {
068e94ea
MCC
8731 pr_err("error %d\n", rc);
8732 goto rw_error;
8733 }
443f18d0
MCC
8734
8735 /* lc_cp / _ci / _ca */
244c0e06 8736 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, 0, 0);
9482354f 8737 if (rc != 0) {
068e94ea
MCC
8738 pr_err("error %d\n", rc);
8739 goto rw_error;
8740 }
244c0e06 8741 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, 0, 0);
9482354f 8742 if (rc != 0) {
068e94ea
MCC
8743 pr_err("error %d\n", rc);
8744 goto rw_error;
8745 }
244c0e06 8746 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
9482354f 8747 if (rc != 0) {
068e94ea
MCC
8748 pr_err("error %d\n", rc);
8749 goto rw_error;
8750 }
443f18d0
MCC
8751
8752 /* flip the spec */
244c0e06 8753 rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
9482354f 8754 if (rc != 0) {
068e94ea
MCC
8755 pr_err("error %d\n", rc);
8756 goto rw_error;
8757 }
57afe2f0
MCC
8758 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
8759 ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
443f18d0
MCC
8760
8761 /* freeze dq/fq updating */
244c0e06 8762 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
9482354f 8763 if (rc != 0) {
068e94ea
MCC
8764 pr_err("error %d\n", rc);
8765 goto rw_error;
8766 }
57afe2f0 8767 equ_mode = data;
443f18d0 8768 data = (data & 0xfff9);
244c0e06 8769 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
9482354f 8770 if (rc != 0) {
068e94ea
MCC
8771 pr_err("error %d\n", rc);
8772 goto rw_error;
8773 }
244c0e06 8774 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
9482354f 8775 if (rc != 0) {
068e94ea
MCC
8776 pr_err("error %d\n", rc);
8777 goto rw_error;
8778 }
443f18d0
MCC
8779
8780 for (i = 0; i < 28; i++) {
244c0e06 8781 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
9482354f 8782 if (rc != 0) {
068e94ea
MCC
8783 pr_err("error %d\n", rc);
8784 goto rw_error;
8785 }
244c0e06 8786 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
9482354f 8787 if (rc != 0) {
068e94ea
MCC
8788 pr_err("error %d\n", rc);
8789 goto rw_error;
8790 }
443f18d0
MCC
8791 }
8792
8793 for (i = 0; i < 24; i++) {
244c0e06 8794 rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
9482354f 8795 if (rc != 0) {
068e94ea
MCC
8796 pr_err("error %d\n", rc);
8797 goto rw_error;
8798 }
244c0e06 8799 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
9482354f 8800 if (rc != 0) {
068e94ea
MCC
8801 pr_err("error %d\n", rc);
8802 goto rw_error;
8803 }
443f18d0
MCC
8804 }
8805
57afe2f0 8806 data = equ_mode;
244c0e06 8807 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
9482354f 8808 if (rc != 0) {
068e94ea
MCC
8809 pr_err("error %d\n", rc);
8810 goto rw_error;
8811 }
244c0e06 8812 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
9482354f 8813 if (rc != 0) {
068e94ea
MCC
8814 pr_err("error %d\n", rc);
8815 goto rw_error;
8816 }
443f18d0 8817
244c0e06 8818 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
9482354f 8819 if (rc != 0) {
068e94ea
MCC
8820 pr_err("error %d\n", rc);
8821 goto rw_error;
8822 }
38b2df95 8823
443f18d0 8824 i = 0;
57afe2f0 8825 while ((fsm_state != 4) && (i++ < 100)) {
244c0e06 8826 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
9482354f 8827 if (rc != 0) {
068e94ea
MCC
8828 pr_err("error %d\n", rc);
8829 goto rw_error;
8830 }
8831 }
244c0e06 8832 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
9482354f 8833 if (rc != 0) {
068e94ea
MCC
8834 pr_err("error %d\n", rc);
8835 goto rw_error;
443f18d0 8836 }
443f18d0 8837
9482354f 8838 return 0;
38b2df95 8839rw_error:
30741871 8840 return rc;
38b2df95
DH
8841
8842}
8843
8844#define NO_LOCK 0x0
8845#define DEMOD_LOCKED 0x1
8846#define SYNC_FLIPPED 0x2
8847#define SPEC_MIRRORED 0x4
34eb9751 8848/*
57afe2f0 8849* \fn int qam64auto ()
38b2df95
DH
8850* \brief auto do sync pattern switching and mirroring.
8851* \param demod: instance of demod.
8852* \param channel: pointer to channel data.
57afe2f0
MCC
8853* \param tuner_freq_offset: tuner frequency offset.
8854* \param lock_status: pointer to lock status.
61263c75 8855* \return int.
38b2df95 8856*/
61263c75 8857static int
1bfc9e15
MCC
8858qam64auto(struct drx_demod_instance *demod,
8859 struct drx_channel *channel,
8860 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
443f18d0 8861{
03fdfbfd
MCC
8862 struct drxj_data *ext_attr = demod->my_ext_attr;
8863 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8864 struct drx39xxj_state *state = dev_addr->user_data;
8865 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
068e94ea 8866 int rc;
6f64c522 8867 u32 lck_state = NO_LOCK;
57afe2f0
MCC
8868 u32 start_time = 0;
8869 u32 d_locked_time = 0;
57afe2f0 8870 u32 timeout_ofs = 0;
068e94ea 8871 u16 data = 0;
443f18d0 8872
69bb7ab6 8873 /* external attributes for storing acquired channel constellation */
57afe2f0 8874 *lock_status = DRX_NOT_LOCKED;
d7b0631e 8875 start_time = jiffies_to_msecs(jiffies);
6f64c522 8876 lck_state = NO_LOCK;
443f18d0 8877 do {
068e94ea 8878 rc = ctrl_lock_status(demod, lock_status);
9482354f 8879 if (rc != 0) {
068e94ea
MCC
8880 pr_err("error %d\n", rc);
8881 goto rw_error;
8882 }
443f18d0 8883
6f64c522 8884 switch (lck_state) {
443f18d0 8885 case NO_LOCK:
57afe2f0 8886 if (*lock_status == DRXJ_DEMOD_LOCK) {
03fdfbfd 8887 rc = ctrl_get_qam_sig_quality(demod);
9482354f 8888 if (rc != 0) {
068e94ea
MCC
8889 pr_err("error %d\n", rc);
8890 goto rw_error;
8891 }
03fdfbfd 8892 if (p->cnr.stat[0].svalue > 20800) {
6f64c522 8893 lck_state = DEMOD_LOCKED;
443f18d0 8894 /* some delay to see if fec_lock possible TODO find the right value */
57afe2f0 8895 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
d7b0631e 8896 d_locked_time = jiffies_to_msecs(jiffies);
443f18d0
MCC
8897 }
8898 }
8899 break;
8900 case DEMOD_LOCKED:
57afe2f0 8901 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
d7b0631e 8902 ((jiffies_to_msecs(jiffies) - d_locked_time) >
443f18d0 8903 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
244c0e06 8904 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
9482354f 8905 if (rc != 0) {
068e94ea
MCC
8906 pr_err("error %d\n", rc);
8907 goto rw_error;
8908 }
244c0e06 8909 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
9482354f 8910 if (rc != 0) {
068e94ea
MCC
8911 pr_err("error %d\n", rc);
8912 goto rw_error;
8913 }
6f64c522 8914 lck_state = SYNC_FLIPPED;
d7b0631e 8915 msleep(10);
443f18d0
MCC
8916 }
8917 break;
8918 case SYNC_FLIPPED:
57afe2f0 8919 if (*lock_status == DRXJ_DEMOD_LOCK) {
443f18d0
MCC
8920 if (channel->mirror == DRX_MIRROR_AUTO) {
8921 /* flip sync pattern back */
244c0e06 8922 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
9482354f 8923 if (rc != 0) {
068e94ea
MCC
8924 pr_err("error %d\n", rc);
8925 goto rw_error;
8926 }
244c0e06 8927 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
9482354f 8928 if (rc != 0) {
068e94ea
MCC
8929 pr_err("error %d\n", rc);
8930 goto rw_error;
8931 }
443f18d0 8932 /* flip spectrum */
57afe2f0 8933 ext_attr->mirror = DRX_MIRROR_YES;
068e94ea 8934 rc = qam_flip_spec(demod, channel);
9482354f 8935 if (rc != 0) {
068e94ea
MCC
8936 pr_err("error %d\n", rc);
8937 goto rw_error;
8938 }
6f64c522 8939 lck_state = SPEC_MIRRORED;
443f18d0 8940 /* reset timer TODO: still need 500ms? */
57afe2f0 8941 start_time = d_locked_time =
d7b0631e 8942 jiffies_to_msecs(jiffies);
57afe2f0 8943 timeout_ofs = 0;
443f18d0
MCC
8944 } else { /* no need to wait lock */
8945
57afe2f0 8946 start_time =
d7b0631e 8947 jiffies_to_msecs(jiffies) -
57afe2f0 8948 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
443f18d0
MCC
8949 }
8950 }
8951 break;
8952 case SPEC_MIRRORED:
57afe2f0 8953 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
d7b0631e 8954 ((jiffies_to_msecs(jiffies) - d_locked_time) >
443f18d0 8955 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
03fdfbfd 8956 rc = ctrl_get_qam_sig_quality(demod);
9482354f 8957 if (rc != 0) {
068e94ea
MCC
8958 pr_err("error %d\n", rc);
8959 goto rw_error;
8960 }
03fdfbfd 8961 if (p->cnr.stat[0].svalue > 20800) {
244c0e06 8962 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
9482354f 8963 if (rc != 0) {
068e94ea
MCC
8964 pr_err("error %d\n", rc);
8965 goto rw_error;
8966 }
244c0e06 8967 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
9482354f 8968 if (rc != 0) {
068e94ea
MCC
8969 pr_err("error %d\n", rc);
8970 goto rw_error;
8971 }
443f18d0 8972 /* no need to wait lock */
57afe2f0 8973 start_time =
d7b0631e 8974 jiffies_to_msecs(jiffies) -
57afe2f0 8975 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
443f18d0
MCC
8976 }
8977 }
8978 break;
8979 default:
8980 break;
8981 }
d7b0631e 8982 msleep(10);
443f18d0 8983 } while
57afe2f0
MCC
8984 ((*lock_status != DRX_LOCKED) &&
8985 (*lock_status != DRX_NEVER_LOCK) &&
d7b0631e 8986 ((jiffies_to_msecs(jiffies) - start_time) <
57afe2f0 8987 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
443f18d0
MCC
8988 );
8989 /* Returning control to apllication ... */
8990
9482354f 8991 return 0;
38b2df95 8992rw_error:
30741871 8993 return rc;
38b2df95
DH
8994}
8995
34eb9751 8996/*
57afe2f0 8997* \fn int qam256auto ()
38b2df95
DH
8998* \brief auto do sync pattern switching and mirroring.
8999* \param demod: instance of demod.
9000* \param channel: pointer to channel data.
57afe2f0
MCC
9001* \param tuner_freq_offset: tuner frequency offset.
9002* \param lock_status: pointer to lock status.
61263c75 9003* \return int.
38b2df95 9004*/
61263c75 9005static int
1bfc9e15
MCC
9006qam256auto(struct drx_demod_instance *demod,
9007 struct drx_channel *channel,
9008 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
443f18d0 9009{
03fdfbfd
MCC
9010 struct drxj_data *ext_attr = demod->my_ext_attr;
9011 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9012 struct drx39xxj_state *state = dev_addr->user_data;
9013 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
068e94ea 9014 int rc;
6f64c522 9015 u32 lck_state = NO_LOCK;
57afe2f0
MCC
9016 u32 start_time = 0;
9017 u32 d_locked_time = 0;
57afe2f0 9018 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
443f18d0 9019
69bb7ab6 9020 /* external attributes for storing acquired channel constellation */
57afe2f0 9021 *lock_status = DRX_NOT_LOCKED;
d7b0631e 9022 start_time = jiffies_to_msecs(jiffies);
6f64c522 9023 lck_state = NO_LOCK;
443f18d0 9024 do {
068e94ea 9025 rc = ctrl_lock_status(demod, lock_status);
9482354f 9026 if (rc != 0) {
068e94ea
MCC
9027 pr_err("error %d\n", rc);
9028 goto rw_error;
9029 }
6f64c522 9030 switch (lck_state) {
443f18d0 9031 case NO_LOCK:
57afe2f0 9032 if (*lock_status == DRXJ_DEMOD_LOCK) {
03fdfbfd 9033 rc = ctrl_get_qam_sig_quality(demod);
9482354f 9034 if (rc != 0) {
068e94ea
MCC
9035 pr_err("error %d\n", rc);
9036 goto rw_error;
9037 }
03fdfbfd 9038 if (p->cnr.stat[0].svalue > 26800) {
6f64c522 9039 lck_state = DEMOD_LOCKED;
57afe2f0 9040 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
d7b0631e 9041 d_locked_time = jiffies_to_msecs(jiffies);
443f18d0
MCC
9042 }
9043 }
9044 break;
9045 case DEMOD_LOCKED:
57afe2f0 9046 if (*lock_status == DRXJ_DEMOD_LOCK) {
443f18d0 9047 if ((channel->mirror == DRX_MIRROR_AUTO) &&
d7b0631e 9048 ((jiffies_to_msecs(jiffies) - d_locked_time) >
443f18d0 9049 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
57afe2f0 9050 ext_attr->mirror = DRX_MIRROR_YES;
068e94ea 9051 rc = qam_flip_spec(demod, channel);
9482354f 9052 if (rc != 0) {
068e94ea
MCC
9053 pr_err("error %d\n", rc);
9054 goto rw_error;
9055 }
6f64c522 9056 lck_state = SPEC_MIRRORED;
443f18d0 9057 /* reset timer TODO: still need 300ms? */
d7b0631e 9058 start_time = jiffies_to_msecs(jiffies);
57afe2f0 9059 timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
443f18d0
MCC
9060 }
9061 }
9062 break;
9063 case SPEC_MIRRORED:
9064 break;
9065 default:
9066 break;
9067 }
d7b0631e 9068 msleep(10);
443f18d0 9069 } while
57afe2f0
MCC
9070 ((*lock_status < DRX_LOCKED) &&
9071 (*lock_status != DRX_NEVER_LOCK) &&
d7b0631e 9072 ((jiffies_to_msecs(jiffies) - start_time) <
57afe2f0 9073 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
443f18d0 9074
9482354f 9075 return 0;
38b2df95 9076rw_error:
30741871 9077 return rc;
38b2df95
DH
9078}
9079
34eb9751 9080/*
e33f2193 9081* \fn int set_qam_channel ()
38b2df95
DH
9082* \brief Set QAM channel according to the requested constellation.
9083* \param demod: instance of demod.
9084* \param channel: pointer to channel data.
61263c75 9085* \return int.
38b2df95 9086*/
61263c75 9087static int
e33f2193 9088set_qam_channel(struct drx_demod_instance *demod,
1bfc9e15 9089 struct drx_channel *channel, s32 tuner_freq_offset)
443f18d0 9090{
b3ce3a83 9091 struct drxj_data *ext_attr = NULL;
068e94ea
MCC
9092 int rc;
9093 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
57afe2f0 9094 bool auto_flag = false;
443f18d0 9095
69bb7ab6 9096 /* external attributes for storing acquired channel constellation */
b3ce3a83 9097 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
9098
9099 /* set QAM channel constellation */
9100 switch (channel->constellation) {
9101 case DRX_CONSTELLATION_QAM16:
9102 case DRX_CONSTELLATION_QAM32:
443f18d0 9103 case DRX_CONSTELLATION_QAM128:
938f11fa
MCC
9104 return -EINVAL;
9105 case DRX_CONSTELLATION_QAM64:
443f18d0 9106 case DRX_CONSTELLATION_QAM256:
938f11fa
MCC
9107 if (ext_attr->standard != DRX_STANDARD_ITU_B)
9108 return -EINVAL;
9109
57afe2f0 9110 ext_attr->constellation = channel->constellation;
63713517 9111 if (channel->mirror == DRX_MIRROR_AUTO)
57afe2f0 9112 ext_attr->mirror = DRX_MIRROR_NO;
63713517 9113 else
57afe2f0 9114 ext_attr->mirror = channel->mirror;
938f11fa 9115
068e94ea 9116 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
9482354f 9117 if (rc != 0) {
068e94ea
MCC
9118 pr_err("error %d\n", rc);
9119 goto rw_error;
9120 }
443f18d0 9121
938f11fa
MCC
9122 if (channel->constellation == DRX_CONSTELLATION_QAM64)
9123 rc = qam64auto(demod, channel, tuner_freq_offset,
9124 &lock_status);
9125 else
9126 rc = qam256auto(demod, channel, tuner_freq_offset,
9127 &lock_status);
9128 if (rc != 0) {
9129 pr_err("error %d\n", rc);
9130 goto rw_error;
9131 }
9132 break;
9133 case DRX_CONSTELLATION_AUTO: /* for channel scan */
9134 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9135 u16 qam_ctl_ena = 0;
9136
9137 auto_flag = true;
9138
9139 /* try to lock default QAM constellation: QAM256 */
9140 channel->constellation = DRX_CONSTELLATION_QAM256;
9141 ext_attr->constellation = DRX_CONSTELLATION_QAM256;
9142 if (channel->mirror == DRX_MIRROR_AUTO)
9143 ext_attr->mirror = DRX_MIRROR_NO;
9144 else
9145 ext_attr->mirror = channel->mirror;
9146 rc = set_qam(demod, channel, tuner_freq_offset,
9147 QAM_SET_OP_ALL);
9482354f 9148 if (rc != 0) {
068e94ea
MCC
9149 pr_err("error %d\n", rc);
9150 goto rw_error;
9151 }
938f11fa
MCC
9152 rc = qam256auto(demod, channel, tuner_freq_offset,
9153 &lock_status);
9482354f 9154 if (rc != 0) {
068e94ea
MCC
9155 pr_err("error %d\n", rc);
9156 goto rw_error;
9157 }
938f11fa
MCC
9158
9159 if (lock_status >= DRX_LOCKED) {
9160 channel->constellation = DRX_CONSTELLATION_AUTO;
9161 break;
9162 }
9163
9164 /* QAM254 not locked. Try QAM64 constellation */
9165 channel->constellation = DRX_CONSTELLATION_QAM64;
9166 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
63713517 9167 if (channel->mirror == DRX_MIRROR_AUTO)
57afe2f0 9168 ext_attr->mirror = DRX_MIRROR_NO;
63713517 9169 else
57afe2f0 9170 ext_attr->mirror = channel->mirror;
938f11fa 9171
244c0e06 9172 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9173 SCU_RAM_QAM_CTL_ENA__A,
9174 &qam_ctl_ena, 0);
9482354f 9175 if (rc != 0) {
068e94ea
MCC
9176 pr_err("error %d\n", rc);
9177 goto rw_error;
9178 }
244c0e06 9179 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9180 SCU_RAM_QAM_CTL_ENA__A,
9181 qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9482354f 9182 if (rc != 0) {
068e94ea
MCC
9183 pr_err("error %d\n", rc);
9184 goto rw_error;
9185 }
244c0e06 9186 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9187 SCU_RAM_QAM_FSM_STATE_TGT__A,
9188 0x2, 0);
9189 if (rc != 0) {
9190 pr_err("error %d\n", rc);
9191 goto rw_error;
9192 } /* force to rate hunting */
443f18d0 9193
938f11fa
MCC
9194 rc = set_qam(demod, channel, tuner_freq_offset,
9195 QAM_SET_OP_CONSTELLATION);
9196 if (rc != 0) {
9197 pr_err("error %d\n", rc);
9198 goto rw_error;
9199 }
244c0e06 9200 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9201 SCU_RAM_QAM_CTL_ENA__A,
9202 qam_ctl_ena, 0);
9203 if (rc != 0) {
9204 pr_err("error %d\n", rc);
9205 goto rw_error;
9206 }
068e94ea 9207
938f11fa
MCC
9208 rc = qam64auto(demod, channel, tuner_freq_offset,
9209 &lock_status);
9210 if (rc != 0) {
9211 pr_err("error %d\n", rc);
9212 goto rw_error;
443f18d0 9213 }
938f11fa 9214
443f18d0 9215 channel->constellation = DRX_CONSTELLATION_AUTO;
57afe2f0 9216 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
938f11fa
MCC
9217 u16 qam_ctl_ena = 0;
9218
443f18d0 9219 channel->constellation = DRX_CONSTELLATION_QAM64;
57afe2f0
MCC
9220 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9221 auto_flag = true;
443f18d0 9222
63713517 9223 if (channel->mirror == DRX_MIRROR_AUTO)
57afe2f0 9224 ext_attr->mirror = DRX_MIRROR_NO;
63713517 9225 else
57afe2f0 9226 ext_attr->mirror = channel->mirror;
244c0e06 9227 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9228 SCU_RAM_QAM_CTL_ENA__A,
9229 &qam_ctl_ena, 0);
9230 if (rc != 0) {
9231 pr_err("error %d\n", rc);
9232 goto rw_error;
9233 }
244c0e06 9234 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9235 SCU_RAM_QAM_CTL_ENA__A,
9236 qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9237 if (rc != 0) {
9238 pr_err("error %d\n", rc);
9239 goto rw_error;
9240 }
244c0e06 9241 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9242 SCU_RAM_QAM_FSM_STATE_TGT__A,
9243 0x2, 0);
9244 if (rc != 0) {
9245 pr_err("error %d\n", rc);
9246 goto rw_error;
9247 } /* force to rate hunting */
068e94ea 9248
938f11fa
MCC
9249 rc = set_qam(demod, channel, tuner_freq_offset,
9250 QAM_SET_OP_CONSTELLATION);
9251 if (rc != 0) {
9252 pr_err("error %d\n", rc);
9253 goto rw_error;
068e94ea 9254 }
244c0e06 9255 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9256 SCU_RAM_QAM_CTL_ENA__A,
9257 qam_ctl_ena, 0);
9258 if (rc != 0) {
9259 pr_err("error %d\n", rc);
9260 goto rw_error;
9261 }
9262 rc = qam64auto(demod, channel, tuner_freq_offset,
9263 &lock_status);
9482354f 9264 if (rc != 0) {
068e94ea
MCC
9265 pr_err("error %d\n", rc);
9266 goto rw_error;
9267 }
443f18d0
MCC
9268 channel->constellation = DRX_CONSTELLATION_AUTO;
9269 } else {
9482354f 9270 return -EINVAL;
443f18d0
MCC
9271 }
9272 break;
9273 default:
9482354f 9274 return -EINVAL;
443f18d0 9275 }
38b2df95 9276
9482354f 9277 return 0;
38b2df95 9278rw_error:
443f18d0 9279 /* restore starting value */
57afe2f0 9280 if (auto_flag)
443f18d0 9281 channel->constellation = DRX_CONSTELLATION_AUTO;
30741871 9282 return rc;
38b2df95
DH
9283}
9284
9285/*============================================================================*/
9286
34eb9751 9287/*
e33f2193 9288* \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
38b2df95
DH
9289* \brief Get RS error count in QAM mode (used for post RS BER calculation)
9290* \return Error code
9291*
9292* precondition: measurement period & measurement prescale must be set
9293*
9294*/
61263c75 9295static int
69832578
MCC
9296get_qamrs_err_count(struct i2c_device_addr *dev_addr,
9297 struct drxjrs_errors *rs_errors)
38b2df95 9298{
068e94ea 9299 int rc;
57afe2f0
MCC
9300 u16 nr_bit_errors = 0,
9301 nr_symbol_errors = 0,
9302 nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
443f18d0
MCC
9303
9304 /* check arguments */
63713517 9305 if (dev_addr == NULL)
9482354f 9306 return -EINVAL;
443f18d0
MCC
9307
9308 /* all reported errors are received in the */
9309 /* most recently finished measurment period */
9310 /* no of pre RS bit errors */
244c0e06 9311 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
9482354f 9312 if (rc != 0) {
068e94ea
MCC
9313 pr_err("error %d\n", rc);
9314 goto rw_error;
9315 }
443f18d0 9316 /* no of symbol errors */
244c0e06 9317 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
9482354f 9318 if (rc != 0) {
068e94ea
MCC
9319 pr_err("error %d\n", rc);
9320 goto rw_error;
9321 }
443f18d0 9322 /* no of packet errors */
244c0e06 9323 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
9482354f 9324 if (rc != 0) {
068e94ea
MCC
9325 pr_err("error %d\n", rc);
9326 goto rw_error;
9327 }
443f18d0 9328 /* no of failures to decode */
244c0e06 9329 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
9482354f 9330 if (rc != 0) {
068e94ea
MCC
9331 pr_err("error %d\n", rc);
9332 goto rw_error;
9333 }
443f18d0 9334 /* no of post RS bit erros */
244c0e06 9335 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
9482354f 9336 if (rc != 0) {
068e94ea
MCC
9337 pr_err("error %d\n", rc);
9338 goto rw_error;
9339 }
443f18d0
MCC
9340 /* TODO: NOTE */
9341 /* These register values are fetched in non-atomic fashion */
9342 /* It is possible that the read values contain unrelated information */
9343
57afe2f0
MCC
9344 rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
9345 rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
9346 rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
9347 rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
9348 rs_errors->nr_snc_par_fail_count =
9349 nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
443f18d0 9350
9482354f 9351 return 0;
38b2df95 9352rw_error:
30741871 9353 return rc;
38b2df95
DH
9354}
9355
9356/*============================================================================*/
9357
34eb9751 9358/*
80e5ed14
MCC
9359 * \fn int get_sig_strength()
9360 * \brief Retrieve signal strength for VSB and QAM.
9361 * \param demod Pointer to demod instance
9362 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
9363 * \return int.
9364 * \retval 0 sig_strength contains valid data.
9365 * \retval -EINVAL sig_strength is NULL.
9366 * \retval -EIO Erroneous data, sig_strength contains invalid data.
9367 */
9368#define DRXJ_AGC_TOP 0x2800
9369#define DRXJ_AGC_SNS 0x1600
9370#define DRXJ_RFAGC_MAX 0x3fff
9371#define DRXJ_RFAGC_MIN 0x800
9372
9373static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
9374{
9375 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9376 int rc;
9377 u16 rf_gain = 0;
9378 u16 if_gain = 0;
9379 u16 if_agc_sns = 0;
9380 u16 if_agc_top = 0;
9381 u16 rf_agc_max = 0;
9382 u16 rf_agc_min = 0;
9383
9384 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
9385 if (rc != 0) {
9386 pr_err("error %d\n", rc);
9387 goto rw_error;
9388 }
9389 if_gain &= IQM_AF_AGC_IF__M;
9390 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
9391 if (rc != 0) {
9392 pr_err("error %d\n", rc);
9393 goto rw_error;
9394 }
9395 rf_gain &= IQM_AF_AGC_RF__M;
9396
9397 if_agc_sns = DRXJ_AGC_SNS;
9398 if_agc_top = DRXJ_AGC_TOP;
9399 rf_agc_max = DRXJ_RFAGC_MAX;
9400 rf_agc_min = DRXJ_RFAGC_MIN;
9401
9402 if (if_gain > if_agc_top) {
9403 if (rf_gain > rf_agc_max)
9404 *sig_strength = 100;
9405 else if (rf_gain > rf_agc_min) {
9406 if (rf_agc_max == rf_agc_min) {
9407 pr_err("error: rf_agc_max == rf_agc_min\n");
9408 return -EIO;
9409 }
9410 *sig_strength =
9411 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
9412 rf_agc_min);
9413 } else
9414 *sig_strength = 75;
9415 } else if (if_gain > if_agc_sns) {
9416 if (if_agc_top == if_agc_sns) {
9417 pr_err("error: if_agc_top == if_agc_sns\n");
9418 return -EIO;
9419 }
9420 *sig_strength =
9421 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
9422 } else {
9423 if (!if_agc_sns) {
9424 pr_err("error: if_agc_sns is zero!\n");
9425 return -EIO;
9426 }
9427 *sig_strength = (20 * if_gain / if_agc_sns);
9428 }
9429
80846a5c
MCC
9430 if (*sig_strength <= 7)
9431 *sig_strength = 0;
9432
80e5ed14 9433 return 0;
30741871
SK
9434rw_error:
9435 return rc;
80e5ed14
MCC
9436}
9437
34eb9751 9438/*
57afe2f0 9439* \fn int ctrl_get_qam_sig_quality()
69bb7ab6 9440* \brief Retrieve QAM signal quality from device.
38b2df95 9441* \param devmod Pointer to demodulator instance.
57afe2f0 9442* \param sig_quality Pointer to signal quality data.
61263c75 9443* \return int.
9482354f
MCC
9444* \retval 0 sig_quality contains valid data.
9445* \retval -EINVAL sig_quality is NULL.
9446* \retval -EIO Erroneous data, sig_quality contains invalid data.
38b2df95
DH
9447
9448* Pre-condition: Device must be started and in lock.
9449*/
61263c75 9450static int
03fdfbfd 9451ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
443f18d0 9452{
03fdfbfd
MCC
9453 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9454 struct drxj_data *ext_attr = demod->my_ext_attr;
9455 struct drx39xxj_state *state = dev_addr->user_data;
9456 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
b3ce3a83 9457 struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
03fdfbfd
MCC
9458 enum drx_modulation constellation = ext_attr->constellation;
9459 int rc;
57afe2f0
MCC
9460
9461 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
9462 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
9463 u32 pkt_errs = 0; /* no of packet errors in RS */
9464 u16 qam_sl_err_power = 0; /* accumulated error between raw and sliced symbols */
9465 u16 qsym_err_vd = 0; /* quadrature symbol errors in QAM_VD */
9466 u16 fec_oc_period = 0; /* SNC sync failure measurement period */
9467 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
9468 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
443f18d0 9469 /* calculation constants */
57afe2f0
MCC
9470 u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
9471 u32 qam_sl_sig_power = 0; /* used for MER, depends of QAM constellation */
443f18d0 9472 /* intermediate results */
43a431e4
MCC
9473 u32 e = 0; /* exponent value used for QAM BER/SER */
9474 u32 m = 0; /* mantisa value used for QAM BER/SER */
57afe2f0 9475 u32 ber_cnt = 0; /* BER count */
443f18d0 9476 /* signal quality info */
57afe2f0
MCC
9477 u32 qam_sl_mer = 0; /* QAM MER */
9478 u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
9479 u32 qam_post_rs_ber = 0; /* Post RedSolomon BER */
9480 u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
9481 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
9482 u16 qam_vd_period = 0; /* Viterbi Measurement period */
9483 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
443f18d0 9484
69832578
MCC
9485 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9486
443f18d0
MCC
9487 /* read the physical registers */
9488 /* Get the RS error data */
e33f2193 9489 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
9482354f 9490 if (rc != 0) {
068e94ea
MCC
9491 pr_err("error %d\n", rc);
9492 goto rw_error;
9493 }
443f18d0 9494 /* get the register value needed for MER */
244c0e06 9495 rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
9482354f 9496 if (rc != 0) {
068e94ea
MCC
9497 pr_err("error %d\n", rc);
9498 goto rw_error;
9499 }
443f18d0 9500 /* get the register value needed for post RS BER */
244c0e06 9501 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
9482354f 9502 if (rc != 0) {
068e94ea
MCC
9503 pr_err("error %d\n", rc);
9504 goto rw_error;
9505 }
443f18d0
MCC
9506
9507 /* get constants needed for signal quality calculation */
57afe2f0
MCC
9508 fec_rs_period = ext_attr->fec_rs_period;
9509 fec_rs_prescale = ext_attr->fec_rs_prescale;
9510 rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
9511 qam_vd_period = ext_attr->qam_vd_period;
9512 qam_vd_prescale = ext_attr->qam_vd_prescale;
9513 vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
443f18d0
MCC
9514
9515 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
9516 switch (constellation) {
9517 case DRX_CONSTELLATION_QAM16:
57afe2f0 9518 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
443f18d0
MCC
9519 break;
9520 case DRX_CONSTELLATION_QAM32:
57afe2f0 9521 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
443f18d0
MCC
9522 break;
9523 case DRX_CONSTELLATION_QAM64:
57afe2f0 9524 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
443f18d0
MCC
9525 break;
9526 case DRX_CONSTELLATION_QAM128:
57afe2f0 9527 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
443f18d0
MCC
9528 break;
9529 case DRX_CONSTELLATION_QAM256:
57afe2f0 9530 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
443f18d0
MCC
9531 break;
9532 default:
9482354f 9533 return -EIO;
443f18d0 9534 }
38b2df95 9535
443f18d0
MCC
9536 /* ------------------------------ */
9537 /* MER Calculation */
9538 /* ------------------------------ */
9539 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
9540
9541 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
57afe2f0
MCC
9542 if (qam_sl_err_power == 0)
9543 qam_sl_mer = 0;
443f18d0 9544 else
63713517 9545 qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
443f18d0
MCC
9546
9547 /* ----------------------------------------- */
9548 /* Pre Viterbi Symbol Error Rate Calculation */
9549 /* ----------------------------------------- */
5a13e40b 9550 /* pre viterbi SER is good if it is below 0.025 */
443f18d0
MCC
9551
9552 /* get the register value */
9553 /* no of quadrature symbol errors */
244c0e06 9554 rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
9482354f 9555 if (rc != 0) {
068e94ea
MCC
9556 pr_err("error %d\n", rc);
9557 goto rw_error;
9558 }
443f18d0
MCC
9559 /* Extract the Exponent and the Mantisa */
9560 /* of number of quadrature symbol errors */
57afe2f0 9561 e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
443f18d0 9562 QAM_VD_NR_QSYM_ERRORS_EXP__B;
57afe2f0 9563 m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
443f18d0
MCC
9564 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
9565
63713517 9566 if ((m << e) >> 3 > 549752)
69832578 9567 qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
63713517 9568 else
69832578 9569 qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
38b2df95 9570
443f18d0
MCC
9571 /* --------------------------------------- */
9572 /* pre and post RedSolomon BER Calculation */
9573 /* --------------------------------------- */
9574 /* pre RS BER is good if it is below 3.5e-4 */
9575
9576 /* get the register values */
57afe2f0
MCC
9577 pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
9578 pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
443f18d0
MCC
9579
9580 /* Extract the Exponent and the Mantisa of the */
9581 /* pre Reed-Solomon bit error count */
57afe2f0 9582 e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
443f18d0 9583 FEC_RS_NR_BIT_ERRORS_EXP__B;
57afe2f0 9584 m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
443f18d0
MCC
9585 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
9586
57afe2f0 9587 ber_cnt = m << e;
443f18d0 9588
57afe2f0 9589 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
63713517 9590 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
69832578 9591 qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
63713517 9592 else
ee0f4a14 9593 qam_pre_rs_ber = ber_cnt;
38b2df95 9594
443f18d0
MCC
9595 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
9596 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
9597 /*
9598 => c = (1000000*100*11.17)/1504 =
9599 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
9600 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
9601 *100 and /100 is for more precision.
9602 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
38b2df95 9603
443f18d0
MCC
9604 Precision errors still possible.
9605 */
b6554ea5 9606 if (!fec_oc_period) {
57afe2f0 9607 qam_post_rs_ber = 0xFFFFFFFF;
b6554ea5
MCC
9608 } else {
9609 e = post_bit_err_rs * 742686;
9610 m = fec_oc_period * 100;
57afe2f0 9611 qam_post_rs_ber = e / m;
b6554ea5 9612 }
443f18d0
MCC
9613
9614 /* fill signal quality data structure */
03fdfbfd
MCC
9615 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9616 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9617 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9618 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9619 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
9620 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
9621
9622 p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
69832578 9623 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
03fdfbfd 9624 p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
69832578
MCC
9625 p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9626 } else {
03fdfbfd 9627 p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
69832578
MCC
9628 p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9629 }
03fdfbfd 9630
0d49e776
MCC
9631 p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;
9632 p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
03fdfbfd 9633
03fdfbfd
MCC
9634 p->block_error.stat[0].uvalue += pkt_errs;
9635
38b2df95 9636#ifdef DRXJ_SIGNAL_ACCUM_ERR
068e94ea 9637 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
9482354f 9638 if (rc != 0) {
068e94ea
MCC
9639 pr_err("error %d\n", rc);
9640 goto rw_error;
9641 }
38b2df95
DH
9642#endif
9643
9482354f 9644 return 0;
443f18d0 9645rw_error:
03fdfbfd
MCC
9646 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9647 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9648 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9649 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9650 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9651 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9652
30741871 9653 return rc;
38b2df95
DH
9654}
9655
38b2df95
DH
9656#endif /* #ifndef DRXJ_VSB_ONLY */
9657
9658/*============================================================================*/
9659/*== END QAM DATAPATH FUNCTIONS ==*/
9660/*============================================================================*/
9661
9662/*============================================================================*/
9663/*============================================================================*/
9664/*== ATV DATAPATH FUNCTIONS ==*/
9665/*============================================================================*/
9666/*============================================================================*/
9667
9668/*
9669 Implementation notes.
9670
9671 NTSC/FM AGCs
9672
9673 Four AGCs are used for NTSC:
9674 (1) RF (used to attenuate the input signal in case of to much power)
9675 (2) IF (used to attenuate the input signal in case of to much power)
9676 (3) Video AGC (used to amplify the output signal in case input to low)
9677 (4) SIF AGC (used to amplify the output signal in case input to low)
9678
9679 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
9680 that the coupling between Video AGC and the RF and IF AGCs also works in
9681 favor of the SIF AGC.
9682
9683 Three AGCs are used for FM:
9684 (1) RF (used to attenuate the input signal in case of to much power)
9685 (2) IF (used to attenuate the input signal in case of to much power)
9686 (3) SIF AGC (used to amplify the output signal in case input to low)
9687
9688 The SIF AGC is now coupled to the RF/IF AGCs.
9689 The SIF AGC is needed for both SIF ouput and the internal SIF signal to
9690 the AUD block.
9691
9692 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
9693 the ATV block. The AGC control algorithms are all implemented in
9694 microcode.
9695
9696 ATV SETTINGS
9697
9698 (Shadow settings will not be used for now, they will be implemented
9699 later on because of the schedule)
9700
9701 Several HW/SCU "settings" can be used for ATV. The standard selection
9702 will reset most of these settings. To avoid that the end user apllication
9703 has to perform these settings each time the ATV or FM standards is
9704 selected the driver will shadow these settings. This enables the end user
57afe2f0 9705 to perform the settings only once after a drx_open(). The driver must
38b2df95
DH
9706 write the shadow settings to HW/SCU incase:
9707 ( setstandard FM/ATV) ||
9708 ( settings have changed && FM/ATV standard is active)
9709 The shadow settings will be stored in the device specific data container.
9710 A set of flags will be defined to flag changes in shadow settings.
9711 A routine will be implemented to write all changed shadow settings to
9712 HW/SCU.
9713
9714 The "settings" will consist of: AGC settings, filter settings etc.
9715
9716 Disadvantage of use of shadow settings:
9717 Direct changes in HW/SCU registers will not be reflected in the
9718 shadow settings and these changes will be overwritten during a next
9719 update. This can happen during evaluation. This will not be a problem
9720 for normal customer usage.
9721*/
9722/* -------------------------------------------------------------------------- */
9723
34eb9751 9724/*
b6c4065e
MCC
9725* \fn int power_down_atv ()
9726* \brief Power down ATV.
38b2df95 9727* \param demod instance of demodulator
b6c4065e 9728* \param standard either NTSC or FM (sub strandard for ATV )
61263c75 9729* \return int.
38b2df95 9730*
b6c4065e
MCC
9731* Stops and thus resets ATV and IQM block
9732* SIF and CVBS ADC are powered down
9733* Calls audio power down
38b2df95 9734*/
61263c75 9735static int
b6c4065e 9736power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
38b2df95 9737{
b6c4065e
MCC
9738 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9739 struct drxjscu_cmd cmd_scu = { /* command */ 0,
9740 /* parameter_len */ 0,
9741 /* result_len */ 0,
9742 /* *parameter */ NULL,
9743 /* *result */ NULL
9744 };
068e94ea 9745 int rc;
b6c4065e 9746 u16 cmd_result = 0;
38b2df95 9747
b6c4065e 9748 /* ATV NTSC */
38b2df95 9749
b6c4065e
MCC
9750 /* Stop ATV SCU (will reset ATV and IQM hardware */
9751 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
9752 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9753 cmd_scu.parameter_len = 0;
9754 cmd_scu.result_len = 1;
9755 cmd_scu.parameter = NULL;
9756 cmd_scu.result = &cmd_result;
9757 rc = scu_command(dev_addr, &cmd_scu);
9758 if (rc != 0) {
9759 pr_err("error %d\n", rc);
9760 goto rw_error;
9761 }
9762 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
9763 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
9764 if (rc != 0) {
9765 pr_err("error %d\n", rc);
9766 goto rw_error;
443f18d0 9767 }
38b2df95 9768
b6c4065e
MCC
9769 rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
9770 if (rc != 0) {
9771 pr_err("error %d\n", rc);
9772 goto rw_error;
9773 }
9774 if (primary) {
9775 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9482354f 9776 if (rc != 0) {
068e94ea
MCC
9777 pr_err("error %d\n", rc);
9778 goto rw_error;
9779 }
b6c4065e 9780 rc = set_iqm_af(demod, false);
9482354f 9781 if (rc != 0) {
068e94ea
MCC
9782 pr_err("error %d\n", rc);
9783 goto rw_error;
9784 }
b6c4065e
MCC
9785 } else {
9786 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 9787 if (rc != 0) {
068e94ea
MCC
9788 pr_err("error %d\n", rc);
9789 goto rw_error;
9790 }
b6c4065e 9791 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 9792 if (rc != 0) {
068e94ea
MCC
9793 pr_err("error %d\n", rc);
9794 goto rw_error;
9795 }
b6c4065e 9796 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 9797 if (rc != 0) {
068e94ea
MCC
9798 pr_err("error %d\n", rc);
9799 goto rw_error;
9800 }
b6c4065e 9801 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 9802 if (rc != 0) {
068e94ea
MCC
9803 pr_err("error %d\n", rc);
9804 goto rw_error;
9805 }
b6c4065e 9806 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 9807 if (rc != 0) {
068e94ea
MCC
9808 pr_err("error %d\n", rc);
9809 goto rw_error;
9810 }
443f18d0 9811 }
b6c4065e
MCC
9812 rc = power_down_aud(demod);
9813 if (rc != 0) {
9814 pr_err("error %d\n", rc);
9815 goto rw_error;
9816 }
443f18d0 9817
9482354f 9818 return 0;
38b2df95 9819rw_error:
30741871 9820 return rc;
38b2df95
DH
9821}
9822
b6c4065e
MCC
9823/*============================================================================*/
9824
34eb9751 9825/*
b6c4065e 9826* \brief Power up AUD.
38b2df95 9827* \param demod instance of demodulator
61263c75 9828* \return int.
38b2df95
DH
9829*
9830*/
b6c4065e 9831static int power_down_aud(struct drx_demod_instance *demod)
38b2df95 9832{
b6c4065e 9833 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 9834 struct drxj_data *ext_attr = NULL;
068e94ea 9835 int rc;
38b2df95 9836
b6c4065e 9837 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
b3ce3a83 9838 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0 9839
b6c4065e 9840 rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
9482354f 9841 if (rc != 0) {
068e94ea
MCC
9842 pr_err("error %d\n", rc);
9843 goto rw_error;
9844 }
38b2df95 9845
b6c4065e
MCC
9846 ext_attr->aud_data.audio_is_active = false;
9847
9482354f 9848 return 0;
38b2df95 9849rw_error:
30741871 9850 return rc;
38b2df95
DH
9851}
9852
34eb9751 9853/*
b6c4065e
MCC
9854* \fn int set_orx_nsu_aox()
9855* \brief Configure OrxNsuAox for OOB
9856* \param demod instance of demodulator.
9857* \param active
61263c75 9858* \return int.
38b2df95 9859*/
b6c4065e 9860static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
38b2df95 9861{
b6c4065e 9862 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 9863 int rc;
b6c4065e 9864 u16 data = 0;
38b2df95 9865
b6c4065e
MCC
9866 /* Configure NSU_AOX */
9867 rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
9482354f 9868 if (rc != 0) {
068e94ea
MCC
9869 pr_err("error %d\n", rc);
9870 goto rw_error;
9871 }
b6c4065e
MCC
9872 if (!active)
9873 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));
9874 else
9875 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);
9876 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
9482354f 9877 if (rc != 0) {
068e94ea
MCC
9878 pr_err("error %d\n", rc);
9879 goto rw_error;
9880 }
38b2df95 9881
9482354f 9882 return 0;
38b2df95 9883rw_error:
30741871 9884 return rc;
38b2df95
DH
9885}
9886
34eb9751 9887/*
b6c4065e
MCC
9888* \fn int ctrl_set_oob()
9889* \brief Set OOB channel to be used.
38b2df95 9890* \param demod instance of demodulator
b6c4065e
MCC
9891* \param oob_param OOB parameters for channel setting.
9892* \frequency should be in KHz
61263c75 9893* \return int.
38b2df95 9894*
b6c4065e
MCC
9895* Accepts only. Returns error otherwise.
9896* Demapper value is written after scu_command START
9897* because START command causes COMM_EXEC transition
9898* from 0 to 1 which causes all registers to be
9899* overwritten with initial value
38b2df95
DH
9900*
9901*/
38b2df95 9902
b6c4065e
MCC
9903/* Nyquist filter impulse response */
9904#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 */
9905#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 */
9906#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) */
38b2df95 9907
b6c4065e
MCC
9908/* Coefficients for the nyquist fitler (total: 27 taps) */
9909#define NYQFILTERLEN 27
38b2df95 9910
b6c4065e 9911static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
38b2df95 9912{
068e94ea 9913 int rc;
b6c4065e
MCC
9914 s32 freq = 0; /* KHz */
9915 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 9916 struct drxj_data *ext_attr = NULL;
b6c4065e
MCC
9917 u16 i = 0;
9918 bool mirror_freq_spect_oob = false;
9919 u16 trk_filter_value = 0;
9920 struct drxjscu_cmd scu_cmd;
9921 u16 set_param_parameters[3];
9922 u16 cmd_result[2] = { 0, 0 };
9923 s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
9924 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
9925 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
9926 IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
9927 IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
9928 };
9929 u8 mode_val[4] = { 2, 2, 0, 1 };
9930 u8 pfi_coeffs[4][6] = {
9931 {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) */
9932 {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) */
9933 {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) */
9934 {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) */
9935 };
9936 u16 mode_index;
38b2df95 9937
b6c4065e 9938 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 9939 ext_attr = (struct drxj_data *) demod->my_ext_attr;
b6c4065e 9940 mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
38b2df95 9941
b6c4065e
MCC
9942 /* Check parameters */
9943 if (oob_param == NULL) {
9944 /* power off oob module */
9945 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
9946 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9947 scu_cmd.parameter_len = 0;
9948 scu_cmd.result_len = 1;
9949 scu_cmd.result = cmd_result;
9950 rc = scu_command(dev_addr, &scu_cmd);
9951 if (rc != 0) {
9952 pr_err("error %d\n", rc);
9953 goto rw_error;
9954 }
9955 rc = set_orx_nsu_aox(demod, false);
9956 if (rc != 0) {
9957 pr_err("error %d\n", rc);
9958 goto rw_error;
9959 }
9960 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
9482354f 9961 if (rc != 0) {
068e94ea
MCC
9962 pr_err("error %d\n", rc);
9963 goto rw_error;
9964 }
38b2df95 9965
b6c4065e
MCC
9966 ext_attr->oob_power_on = false;
9967 return 0;
9968 }
443f18d0 9969
b6c4065e
MCC
9970 freq = oob_param->frequency;
9971 if ((freq < 70000) || (freq > 130000))
9972 return -EIO;
9973 freq = (freq - 50000) / 50;
443f18d0 9974
b6c4065e
MCC
9975 {
9976 u16 index = 0;
9977 u16 remainder = 0;
9978 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
443f18d0 9979
b6c4065e
MCC
9980 index = (u16) ((freq - 400) / 200);
9981 remainder = (u16) ((freq - 400) % 200);
9982 trk_filter_value =
9983 trk_filtercfg[index] - (trk_filtercfg[index] -
9984 trk_filtercfg[index +
9985 1]) / 10 * remainder /
9986 20;
068e94ea 9987 }
443f18d0 9988
34eb9751 9989 /********/
b6c4065e 9990 /* Stop */
34eb9751 9991 /********/
b6c4065e 9992 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
9482354f 9993 if (rc != 0) {
068e94ea
MCC
9994 pr_err("error %d\n", rc);
9995 goto rw_error;
9996 }
b6c4065e
MCC
9997 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
9998 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9999 scu_cmd.parameter_len = 0;
10000 scu_cmd.result_len = 1;
10001 scu_cmd.result = cmd_result;
10002 rc = scu_command(dev_addr, &scu_cmd);
9482354f 10003 if (rc != 0) {
068e94ea
MCC
10004 pr_err("error %d\n", rc);
10005 goto rw_error;
10006 }
34eb9751 10007 /********/
b6c4065e 10008 /* Reset */
34eb9751 10009 /********/
b6c4065e
MCC
10010 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10011 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
10012 scu_cmd.parameter_len = 0;
10013 scu_cmd.result_len = 1;
10014 scu_cmd.result = cmd_result;
10015 rc = scu_command(dev_addr, &scu_cmd);
10016 if (rc != 0) {
068e94ea
MCC
10017 pr_err("error %d\n", rc);
10018 goto rw_error;
10019 }
34eb9751 10020 /**********/
b6c4065e 10021 /* SET_ENV */
34eb9751 10022 /**********/
b6c4065e
MCC
10023 /* set frequency, spectrum inversion and data rate */
10024 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10025 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
10026 scu_cmd.parameter_len = 3;
10027 /* 1-data rate;2-frequency */
10028 switch (oob_param->standard) {
10029 case DRX_OOB_MODE_A:
10030 if (
10031 /* signal is transmitted inverted */
10032 ((oob_param->spectrum_inverted == true) &&
10033 /* and tuner is not mirroring the signal */
10034 (!mirror_freq_spect_oob)) |
10035 /* or */
10036 /* signal is transmitted noninverted */
10037 ((oob_param->spectrum_inverted == false) &&
10038 /* and tuner is mirroring the signal */
10039 (mirror_freq_spect_oob))
10040 )
10041 set_param_parameters[0] =
10042 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
10043 else
10044 set_param_parameters[0] =
10045 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
10046 break;
10047 case DRX_OOB_MODE_B_GRADE_A:
10048 if (
10049 /* signal is transmitted inverted */
10050 ((oob_param->spectrum_inverted == true) &&
10051 /* and tuner is not mirroring the signal */
10052 (!mirror_freq_spect_oob)) |
10053 /* or */
10054 /* signal is transmitted noninverted */
10055 ((oob_param->spectrum_inverted == false) &&
10056 /* and tuner is mirroring the signal */
10057 (mirror_freq_spect_oob))
10058 )
10059 set_param_parameters[0] =
10060 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
10061 else
10062 set_param_parameters[0] =
10063 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
10064 break;
10065 case DRX_OOB_MODE_B_GRADE_B:
10066 default:
10067 if (
10068 /* signal is transmitted inverted */
10069 ((oob_param->spectrum_inverted == true) &&
10070 /* and tuner is not mirroring the signal */
10071 (!mirror_freq_spect_oob)) |
10072 /* or */
10073 /* signal is transmitted noninverted */
10074 ((oob_param->spectrum_inverted == false) &&
10075 /* and tuner is mirroring the signal */
10076 (mirror_freq_spect_oob))
10077 )
10078 set_param_parameters[0] =
10079 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
10080 else
10081 set_param_parameters[0] =
10082 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
10083 break;
10084 }
10085 set_param_parameters[1] = (u16) (freq & 0xFFFF);
10086 set_param_parameters[2] = trk_filter_value;
10087 scu_cmd.parameter = set_param_parameters;
10088 scu_cmd.result_len = 1;
10089 scu_cmd.result = cmd_result;
10090 mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
10091 rc = scu_command(dev_addr, &scu_cmd);
9482354f 10092 if (rc != 0) {
068e94ea
MCC
10093 pr_err("error %d\n", rc);
10094 goto rw_error;
10095 }
38b2df95 10096
b6c4065e
MCC
10097 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
10098 if (rc != 0) {
10099 pr_err("error %d\n", rc);
10100 goto rw_error;
10101 } /* Write magic word to enable pdr reg write */
10102 rc = drxj_dap_write_reg16(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);
10103 if (rc != 0) {
10104 pr_err("error %d\n", rc);
10105 goto rw_error;
10106 }
10107 rc = drxj_dap_write_reg16(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);
10108 if (rc != 0) {
10109 pr_err("error %d\n", rc);
10110 goto rw_error;
10111 }
10112 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
10113 if (rc != 0) {
10114 pr_err("error %d\n", rc);
10115 goto rw_error;
10116 } /* Write magic word to disable pdr reg write */
38b2df95 10117
b6c4065e 10118 rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
9482354f 10119 if (rc != 0) {
068e94ea
MCC
10120 pr_err("error %d\n", rc);
10121 goto rw_error;
10122 }
b6c4065e 10123 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
9482354f 10124 if (rc != 0) {
068e94ea
MCC
10125 pr_err("error %d\n", rc);
10126 goto rw_error;
10127 }
b6c4065e 10128 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
9482354f 10129 if (rc != 0) {
068e94ea
MCC
10130 pr_err("error %d\n", rc);
10131 goto rw_error;
10132 }
38b2df95 10133
b6c4065e
MCC
10134 /* ddc */
10135 rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
9482354f 10136 if (rc != 0) {
068e94ea
MCC
10137 pr_err("error %d\n", rc);
10138 goto rw_error;
10139 }
38b2df95 10140
b6c4065e
MCC
10141 /* nsu */
10142 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
10143 if (rc != 0) {
10144 pr_err("error %d\n", rc);
10145 goto rw_error;
10146 }
443f18d0 10147
b6c4065e
MCC
10148 /* initialization for target mode */
10149 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
9482354f 10150 if (rc != 0) {
068e94ea
MCC
10151 pr_err("error %d\n", rc);
10152 goto rw_error;
10153 }
b6c4065e 10154 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
9482354f 10155 if (rc != 0) {
068e94ea
MCC
10156 pr_err("error %d\n", rc);
10157 goto rw_error;
10158 }
443f18d0 10159
b6c4065e
MCC
10160 /* Reset bits for timing and freq. recovery */
10161 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
9482354f 10162 if (rc != 0) {
068e94ea
MCC
10163 pr_err("error %d\n", rc);
10164 goto rw_error;
10165 }
b6c4065e
MCC
10166 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
10167 if (rc != 0) {
10168 pr_err("error %d\n", rc);
10169 goto rw_error;
068e94ea 10170 }
b6c4065e
MCC
10171 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
10172 if (rc != 0) {
10173 pr_err("error %d\n", rc);
10174 goto rw_error;
10175 }
10176 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
9482354f 10177 if (rc != 0) {
068e94ea
MCC
10178 pr_err("error %d\n", rc);
10179 goto rw_error;
443f18d0 10180 }
443f18d0 10181
b6c4065e
MCC
10182 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
10183 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
10184 if (rc != 0) {
10185 pr_err("error %d\n", rc);
10186 goto rw_error;
10187 }
10188 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
10189 if (rc != 0) {
10190 pr_err("error %d\n", rc);
10191 goto rw_error;
10192 }
10193 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
10194 if (rc != 0) {
10195 pr_err("error %d\n", rc);
10196 goto rw_error;
10197 }
10198 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
10199 if (rc != 0) {
10200 pr_err("error %d\n", rc);
10201 goto rw_error;
10202 }
10203 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
10204 if (rc != 0) {
10205 pr_err("error %d\n", rc);
10206 goto rw_error;
10207 }
443f18d0 10208
b6c4065e
MCC
10209 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
10210 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
10211 if (rc != 0) {
10212 pr_err("error %d\n", rc);
10213 goto rw_error;
10214 }
10215 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
10216 if (rc != 0) {
10217 pr_err("error %d\n", rc);
10218 goto rw_error;
10219 }
10220 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
10221 if (rc != 0) {
10222 pr_err("error %d\n", rc);
10223 goto rw_error;
10224 }
10225 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
10226 if (rc != 0) {
10227 pr_err("error %d\n", rc);
10228 goto rw_error;
10229 }
10230 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
10231 if (rc != 0) {
10232 pr_err("error %d\n", rc);
10233 goto rw_error;
10234 }
38b2df95 10235
b6c4065e
MCC
10236 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
10237 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
10238 if (rc != 0) {
10239 pr_err("error %d\n", rc);
10240 goto rw_error;
10241 }
10242 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
10243 if (rc != 0) {
10244 pr_err("error %d\n", rc);
10245 goto rw_error;
10246 }
10247 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
10248 if (rc != 0) {
10249 pr_err("error %d\n", rc);
10250 goto rw_error;
10251 }
10252 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
10253 if (rc != 0) {
10254 pr_err("error %d\n", rc);
10255 goto rw_error;
10256 }
10257 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
10258 if (rc != 0) {
10259 pr_err("error %d\n", rc);
10260 goto rw_error;
10261 }
38b2df95 10262
b6c4065e
MCC
10263 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
10264 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
9482354f 10265 if (rc != 0) {
63713517
MCC
10266 pr_err("error %d\n", rc);
10267 goto rw_error;
068e94ea 10268 }
b6c4065e 10269 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
9482354f 10270 if (rc != 0) {
63713517
MCC
10271 pr_err("error %d\n", rc);
10272 goto rw_error;
068e94ea 10273 }
b6c4065e 10274 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
9482354f 10275 if (rc != 0) {
63713517
MCC
10276 pr_err("error %d\n", rc);
10277 goto rw_error;
068e94ea 10278 }
b6c4065e 10279 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
9482354f 10280 if (rc != 0) {
63713517
MCC
10281 pr_err("error %d\n", rc);
10282 goto rw_error;
068e94ea 10283 }
b6c4065e 10284 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
9482354f 10285 if (rc != 0) {
63713517
MCC
10286 pr_err("error %d\n", rc);
10287 goto rw_error;
068e94ea 10288 }
b6c4065e
MCC
10289
10290 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
10291 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
9482354f 10292 if (rc != 0) {
63713517
MCC
10293 pr_err("error %d\n", rc);
10294 goto rw_error;
068e94ea 10295 }
b6c4065e
MCC
10296 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
10297 if (rc != 0) {
10298 pr_err("error %d\n", rc);
10299 goto rw_error;
10300 }
10301 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
10302 if (rc != 0) {
10303 pr_err("error %d\n", rc);
10304 goto rw_error;
10305 }
10306 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
10307 if (rc != 0) {
10308 pr_err("error %d\n", rc);
10309 goto rw_error;
10310 }
10311 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
9482354f 10312 if (rc != 0) {
068e94ea
MCC
10313 pr_err("error %d\n", rc);
10314 goto rw_error;
10315 }
443f18d0 10316
b6c4065e
MCC
10317 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
10318 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
10319 if (rc != 0) {
10320 pr_err("error %d\n", rc);
10321 goto rw_error;
10322 }
10323 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
10324 if (rc != 0) {
10325 pr_err("error %d\n", rc);
10326 goto rw_error;
10327 }
10328 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
10329 if (rc != 0) {
10330 pr_err("error %d\n", rc);
10331 goto rw_error;
10332 }
10333 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
10334 if (rc != 0) {
10335 pr_err("error %d\n", rc);
10336 goto rw_error;
10337 }
10338 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
9482354f 10339 if (rc != 0) {
63713517
MCC
10340 pr_err("error %d\n", rc);
10341 goto rw_error;
068e94ea 10342 }
443f18d0 10343
b6c4065e
MCC
10344 /* PRE-Filter coefficients (PFI) */
10345 rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
10346 if (rc != 0) {
10347 pr_err("error %d\n", rc);
10348 goto rw_error;
10349 }
10350 rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
10351 if (rc != 0) {
10352 pr_err("error %d\n", rc);
10353 goto rw_error;
10354 }
443f18d0 10355
b6c4065e
MCC
10356 /* NYQUIST-Filter coefficients (NYQ) */
10357 for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
10358 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
9482354f 10359 if (rc != 0) {
63713517
MCC
10360 pr_err("error %d\n", rc);
10361 goto rw_error;
068e94ea 10362 }
b6c4065e 10363 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
9482354f 10364 if (rc != 0) {
63713517
MCC
10365 pr_err("error %d\n", rc);
10366 goto rw_error;
068e94ea 10367 }
b6c4065e
MCC
10368 }
10369 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
10370 if (rc != 0) {
10371 pr_err("error %d\n", rc);
10372 goto rw_error;
10373 }
10374 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
10375 if (rc != 0) {
10376 pr_err("error %d\n", rc);
10377 goto rw_error;
10378 }
34eb9751 10379 /********/
b6c4065e 10380 /* Start */
34eb9751 10381 /********/
b6c4065e
MCC
10382 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10383 | SCU_RAM_COMMAND_CMD_DEMOD_START;
10384 scu_cmd.parameter_len = 0;
10385 scu_cmd.result_len = 1;
10386 scu_cmd.result = cmd_result;
10387 rc = scu_command(dev_addr, &scu_cmd);
10388 if (rc != 0) {
10389 pr_err("error %d\n", rc);
10390 goto rw_error;
10391 }
068e94ea 10392
b6c4065e
MCC
10393 rc = set_orx_nsu_aox(demod, true);
10394 if (rc != 0) {
10395 pr_err("error %d\n", rc);
10396 goto rw_error;
10397 }
10398 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
10399 if (rc != 0) {
10400 pr_err("error %d\n", rc);
10401 goto rw_error;
10402 }
068e94ea 10403
b6c4065e 10404 ext_attr->oob_power_on = true;
aafdbaa6 10405
b6c4065e
MCC
10406 return 0;
10407rw_error:
30741871 10408 return rc;
aafdbaa6
MCC
10409}
10410
b6c4065e
MCC
10411/*============================================================================*/
10412/*== END OOB DATAPATH FUNCTIONS ==*/
10413/*============================================================================*/
10414
10415/*=============================================================================
10416 ===== MC command related functions ==========================================
10417 ===========================================================================*/
10418
10419/*=============================================================================
10420 ===== ctrl_set_channel() ==========================================================
10421 ===========================================================================*/
34eb9751 10422/*
b6c4065e
MCC
10423* \fn int ctrl_set_channel()
10424* \brief Select a new transmission channel.
10425* \param demod instance of demod.
10426* \param channel Pointer to channel data.
61263c75 10427* \return int.
38b2df95 10428*
b6c4065e
MCC
10429* In case the tuner module is not used and in case of NTSC/FM the pogrammer
10430* must tune the tuner to the centre frequency of the NTSC/FM channel.
38b2df95
DH
10431*
10432*/
61263c75 10433static int
b6c4065e 10434ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
38b2df95 10435{
068e94ea 10436 int rc;
b6c4065e 10437 s32 tuner_freq_offset = 0;
b6c4065e
MCC
10438 struct drxj_data *ext_attr = NULL;
10439 struct i2c_device_addr *dev_addr = NULL;
10440 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
b6c4065e
MCC
10441#ifndef DRXJ_VSB_ONLY
10442 u32 min_symbol_rate = 0;
10443 u32 max_symbol_rate = 0;
10444 int bandwidth_temp = 0;
10445 int bandwidth = 0;
10446#endif
10447 /*== check arguments ======================================================*/
10448 if ((demod == NULL) || (channel == NULL))
10449 return -EINVAL;
38b2df95 10450
57afe2f0 10451 dev_addr = demod->my_i2c_dev_addr;
b6c4065e
MCC
10452 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10453 standard = ext_attr->standard;
38b2df95 10454
b6c4065e
MCC
10455 /* check valid standards */
10456 switch (standard) {
10457 case DRX_STANDARD_8VSB:
10458#ifndef DRXJ_VSB_ONLY
10459 case DRX_STANDARD_ITU_A:
10460 case DRX_STANDARD_ITU_B:
10461 case DRX_STANDARD_ITU_C:
10462#endif /* DRXJ_VSB_ONLY */
443f18d0 10463 break;
b6c4065e 10464 case DRX_STANDARD_UNKNOWN:
443f18d0 10465 default:
9482354f 10466 return -EINVAL;
443f18d0 10467 }
38b2df95 10468
b6c4065e
MCC
10469 /* check bandwidth QAM annex B, NTSC and 8VSB */
10470 if ((standard == DRX_STANDARD_ITU_B) ||
10471 (standard == DRX_STANDARD_8VSB) ||
10472 (standard == DRX_STANDARD_NTSC)) {
10473 switch (channel->bandwidth) {
10474 case DRX_BANDWIDTH_6MHZ:
10475 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
10476 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10477 break;
10478 case DRX_BANDWIDTH_8MHZ: /* fall through */
10479 case DRX_BANDWIDTH_7MHZ: /* fall through */
10480 default:
10481 return -EINVAL;
10482 }
10483 }
10484
10485 /* For QAM annex A and annex C:
10486 -check symbolrate and constellation
10487 -derive bandwidth from symbolrate (input bandwidth is ignored)
10488 */
10489#ifndef DRXJ_VSB_ONLY
10490 if ((standard == DRX_STANDARD_ITU_A) ||
10491 (standard == DRX_STANDARD_ITU_C)) {
10492 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
10493 int bw_rolloff_factor = 0;
10494
10495 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
10496 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
10497 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
10498 /* config SMA_TX pin to SAW switch mode */
10499 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
9482354f 10500 if (rc != 0) {
068e94ea
MCC
10501 pr_err("error %d\n", rc);
10502 goto rw_error;
10503 }
443f18d0 10504
b6c4065e
MCC
10505 if (channel->symbolrate < min_symbol_rate ||
10506 channel->symbolrate > max_symbol_rate) {
10507 return -EINVAL;
10508 }
aafdbaa6 10509
b6c4065e
MCC
10510 switch (channel->constellation) {
10511 case DRX_CONSTELLATION_QAM16: /* fall through */
10512 case DRX_CONSTELLATION_QAM32: /* fall through */
10513 case DRX_CONSTELLATION_QAM64: /* fall through */
10514 case DRX_CONSTELLATION_QAM128: /* fall through */
10515 case DRX_CONSTELLATION_QAM256:
10516 bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
10517 bandwidth = bandwidth_temp / 100;
443f18d0 10518
b6c4065e
MCC
10519 if ((bandwidth_temp % 100) >= 50)
10520 bandwidth++;
10521
10522 if (bandwidth <= 6100000) {
10523 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10524 } else if ((bandwidth > 6100000)
10525 && (bandwidth <= 7100000)) {
10526 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
10527 } else if (bandwidth > 7100000) {
10528 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
068e94ea 10529 }
443f18d0 10530 break;
b6c4065e
MCC
10531 default:
10532 return -EINVAL;
10533 }
10534 }
10535
10536 /* For QAM annex B:
10537 -check constellation
10538 */
10539 if (standard == DRX_STANDARD_ITU_B) {
10540 switch (channel->constellation) {
10541 case DRX_CONSTELLATION_AUTO:
10542 case DRX_CONSTELLATION_QAM256:
10543 case DRX_CONSTELLATION_QAM64:
443f18d0 10544 break;
b6c4065e
MCC
10545 default:
10546 return -EINVAL;
10547 }
10548
10549 switch (channel->interleavemode) {
10550 case DRX_INTERLEAVEMODE_I128_J1:
10551 case DRX_INTERLEAVEMODE_I128_J1_V2:
10552 case DRX_INTERLEAVEMODE_I128_J2:
10553 case DRX_INTERLEAVEMODE_I64_J2:
10554 case DRX_INTERLEAVEMODE_I128_J3:
10555 case DRX_INTERLEAVEMODE_I32_J4:
10556 case DRX_INTERLEAVEMODE_I128_J4:
10557 case DRX_INTERLEAVEMODE_I16_J8:
10558 case DRX_INTERLEAVEMODE_I128_J5:
10559 case DRX_INTERLEAVEMODE_I8_J16:
10560 case DRX_INTERLEAVEMODE_I128_J6:
10561 case DRX_INTERLEAVEMODE_I128_J7:
10562 case DRX_INTERLEAVEMODE_I128_J8:
10563 case DRX_INTERLEAVEMODE_I12_J17:
10564 case DRX_INTERLEAVEMODE_I5_J4:
10565 case DRX_INTERLEAVEMODE_B52_M240:
10566 case DRX_INTERLEAVEMODE_B52_M720:
10567 case DRX_INTERLEAVEMODE_UNKNOWN:
10568 case DRX_INTERLEAVEMODE_AUTO:
443f18d0 10569 break;
443f18d0 10570 default:
b6c4065e 10571 return -EINVAL;
443f18d0 10572 }
d7a5478a 10573 }
443f18d0 10574
b6c4065e
MCC
10575 if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
10576 /* SAW SW, user UIO is used for switchable SAW */
10577 struct drxuio_data uio1 = { DRX_UIO1, false };
10578
10579 switch (channel->bandwidth) {
10580 case DRX_BANDWIDTH_8MHZ:
10581 uio1.value = true;
10582 break;
10583 case DRX_BANDWIDTH_7MHZ:
10584 uio1.value = false;
10585 break;
10586 case DRX_BANDWIDTH_6MHZ:
10587 uio1.value = false;
10588 break;
10589 case DRX_BANDWIDTH_UNKNOWN:
10590 default:
10591 return -EINVAL;
d7a5478a 10592 }
b6c4065e
MCC
10593
10594 rc = ctrl_uio_write(demod, &uio1);
d7a5478a
MCC
10595 if (rc != 0) {
10596 pr_err("error %d\n", rc);
10597 goto rw_error;
10598 }
b6c4065e
MCC
10599 }
10600#endif /* DRXJ_VSB_ONLY */
10601 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
10602 if (rc != 0) {
10603 pr_err("error %d\n", rc);
10604 goto rw_error;
443f18d0
MCC
10605 }
10606
b6c4065e 10607 tuner_freq_offset = 0;
443f18d0 10608
b6c4065e
MCC
10609 /*== Setup demod for specific standard ====================================*/
10610 switch (standard) {
10611 case DRX_STANDARD_8VSB:
10612 if (channel->mirror == DRX_MIRROR_AUTO)
10613 ext_attr->mirror = DRX_MIRROR_NO;
10614 else
10615 ext_attr->mirror = channel->mirror;
10616 rc = set_vsb(demod);
9482354f 10617 if (rc != 0) {
068e94ea
MCC
10618 pr_err("error %d\n", rc);
10619 goto rw_error;
10620 }
b6c4065e 10621 rc = set_frequency(demod, channel, tuner_freq_offset);
9482354f 10622 if (rc != 0) {
068e94ea
MCC
10623 pr_err("error %d\n", rc);
10624 goto rw_error;
10625 }
b6c4065e
MCC
10626 break;
10627#ifndef DRXJ_VSB_ONLY
10628 case DRX_STANDARD_ITU_A: /* fallthrough */
10629 case DRX_STANDARD_ITU_B: /* fallthrough */
10630 case DRX_STANDARD_ITU_C:
10631 rc = set_qam_channel(demod, channel, tuner_freq_offset);
9482354f 10632 if (rc != 0) {
068e94ea
MCC
10633 pr_err("error %d\n", rc);
10634 goto rw_error;
10635 }
b6c4065e
MCC
10636 break;
10637#endif
10638 case DRX_STANDARD_UNKNOWN:
10639 default:
10640 return -EIO;
443f18d0 10641 }
38b2df95 10642
b6c4065e
MCC
10643 /* flag the packet error counter reset */
10644 ext_attr->reset_pkt_err_acc = true;
38b2df95 10645
b6c4065e 10646 return 0;
443f18d0 10647rw_error:
30741871 10648 return rc;
38b2df95
DH
10649}
10650
b6c4065e
MCC
10651/*=============================================================================
10652 ===== SigQuality() ==========================================================
10653 ===========================================================================*/
10654
34eb9751 10655/*
b6c4065e 10656* \fn int ctrl_sig_quality()
69bb7ab6 10657* \brief Retrieve signal quality form device.
38b2df95 10658* \param devmod Pointer to demodulator instance.
b6c4065e 10659* \param sig_quality Pointer to signal quality data.
61263c75 10660* \return int.
b6c4065e
MCC
10661* \retval 0 sig_quality contains valid data.
10662* \retval -EINVAL sig_quality is NULL.
10663* \retval -EIO Erroneous data, sig_quality contains invalid data.
38b2df95
DH
10664
10665*/
61263c75 10666static int
03fdfbfd
MCC
10667ctrl_sig_quality(struct drx_demod_instance *demod,
10668 enum drx_lock_status lock_status)
38b2df95 10669{
03fdfbfd
MCC
10670 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
10671 struct drxj_data *ext_attr = demod->my_ext_attr;
10672 struct drx39xxj_state *state = dev_addr->user_data;
10673 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
10674 enum drx_standard standard = ext_attr->standard;
068e94ea 10675 int rc;
d591590e 10676 u32 ber, cnt, err, pkt;
4182438e 10677 u16 mer, strength = 0;
38b2df95 10678
03fdfbfd
MCC
10679 rc = get_sig_strength(demod, &strength);
10680 if (rc < 0) {
10681 pr_err("error getting signal strength %d\n", rc);
10682 p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10683 } else {
10684 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
10685 p->strength.stat[0].uvalue = 65535UL * strength/ 100;
b6c4065e 10686 }
03fdfbfd 10687
443f18d0 10688 switch (standard) {
b6c4065e
MCC
10689 case DRX_STANDARD_8VSB:
10690#ifdef DRXJ_SIGNAL_ACCUM_ERR
03fdfbfd 10691 rc = get_acc_pkt_err(demod, &pkt);
b6c4065e
MCC
10692 if (rc != 0) {
10693 pr_err("error %d\n", rc);
10694 goto rw_error;
10695 }
10696#endif
10697 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
03fdfbfd 10698 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
03fdfbfd 10699 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
69832578 10700 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
03fdfbfd 10701 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
69832578 10702 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
03fdfbfd
MCC
10703 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10704 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
b6c4065e 10705 } else {
69832578 10706 rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);
03fdfbfd
MCC
10707 if (rc != 0) {
10708 pr_err("error %d getting UCB\n", rc);
10709 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10710 } else {
10711 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
69832578
MCC
10712 p->block_error.stat[0].uvalue += err;
10713 p->block_count.stat[0].scale = FE_SCALE_COUNTER;
10714 p->block_count.stat[0].uvalue += pkt;
03fdfbfd
MCC
10715 }
10716
b6c4065e 10717 /* PostViterbi is compute in steps of 10^(-6) */
69832578 10718 rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);
b6c4065e 10719 if (rc != 0) {
03fdfbfd
MCC
10720 pr_err("error %d getting pre-ber\n", rc);
10721 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10722 } else {
10723 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10724 p->pre_bit_error.stat[0].uvalue += ber;
10725 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
69832578 10726 p->pre_bit_count.stat[0].uvalue += cnt;
b6c4065e 10727 }
03fdfbfd 10728
69832578 10729 rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);
b6c4065e 10730 if (rc != 0) {
03fdfbfd
MCC
10731 pr_err("error %d getting post-ber\n", rc);
10732 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10733 } else {
10734 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10735 p->post_bit_error.stat[0].uvalue += ber;
10736 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
69832578 10737 p->post_bit_count.stat[0].uvalue += cnt;
b6c4065e 10738 }
03fdfbfd 10739 rc = get_vsbmer(dev_addr, &mer);
b6c4065e 10740 if (rc != 0) {
03fdfbfd
MCC
10741 pr_err("error %d getting MER\n", rc);
10742 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10743 } else {
10744 p->cnr.stat[0].svalue = mer * 100;
10745 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
b6c4065e
MCC
10746 }
10747 }
b6c4065e 10748 break;
38b2df95 10749#ifndef DRXJ_VSB_ONLY
b6c4065e
MCC
10750 case DRX_STANDARD_ITU_A:
10751 case DRX_STANDARD_ITU_B:
443f18d0 10752 case DRX_STANDARD_ITU_C:
03fdfbfd 10753 rc = ctrl_get_qam_sig_quality(demod);
9482354f 10754 if (rc != 0) {
068e94ea
MCC
10755 pr_err("error %d\n", rc);
10756 goto rw_error;
10757 }
443f18d0 10758 break;
b6c4065e 10759#endif
443f18d0 10760 default:
b6c4065e 10761 return -EIO;
443f18d0
MCC
10762 }
10763
9482354f 10764 return 0;
443f18d0 10765rw_error:
30741871 10766 return rc;
38b2df95
DH
10767}
10768
10769/*============================================================================*/
38b2df95 10770
34eb9751 10771/*
b6c4065e 10772* \fn int ctrl_lock_status()
69bb7ab6 10773* \brief Retrieve lock status .
b6c4065e
MCC
10774* \param dev_addr Pointer to demodulator device address.
10775* \param lock_stat Pointer to lock status structure.
61263c75 10776* \return int.
38b2df95
DH
10777*
10778*/
61263c75 10779static int
b6c4065e 10780ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
38b2df95 10781{
b6c4065e
MCC
10782 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10783 struct drxj_data *ext_attr = NULL;
57afe2f0 10784 struct i2c_device_addr *dev_addr = NULL;
b6c4065e
MCC
10785 struct drxjscu_cmd cmd_scu = { /* command */ 0,
10786 /* parameter_len */ 0,
10787 /* result_len */ 0,
10788 /* *parameter */ NULL,
10789 /* *result */ NULL
10790 };
068e94ea 10791 int rc;
b6c4065e
MCC
10792 u16 cmd_result[2] = { 0, 0 };
10793 u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
38b2df95 10794
443f18d0 10795 /* check arguments */
b6c4065e 10796 if ((demod == NULL) || (lock_stat == NULL))
9482354f 10797 return -EINVAL;
63713517 10798
57afe2f0 10799 dev_addr = demod->my_i2c_dev_addr;
b6c4065e
MCC
10800 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10801 standard = ext_attr->standard;
38b2df95 10802
b6c4065e 10803 *lock_stat = DRX_NOT_LOCKED;
443f18d0 10804
b6c4065e
MCC
10805 /* define the SCU command code */
10806 switch (standard) {
10807 case DRX_STANDARD_8VSB:
10808 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
10809 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10810 demod_lock |= 0x6;
443f18d0 10811 break;
38b2df95 10812#ifndef DRXJ_VSB_ONLY
b6c4065e
MCC
10813 case DRX_STANDARD_ITU_A:
10814 case DRX_STANDARD_ITU_B:
443f18d0 10815 case DRX_STANDARD_ITU_C:
b6c4065e
MCC
10816 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10817 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10818 break;
38b2df95 10819#endif
b6c4065e 10820 case DRX_STANDARD_UNKNOWN: /* fallthrough */
443f18d0 10821 default:
b6c4065e 10822 return -EIO;
443f18d0 10823 }
38b2df95 10824
69bb7ab6 10825 /* define the SCU command parameters and execute the command */
b6c4065e
MCC
10826 cmd_scu.parameter_len = 0;
10827 cmd_scu.result_len = 2;
10828 cmd_scu.parameter = NULL;
10829 cmd_scu.result = cmd_result;
10830 rc = scu_command(dev_addr, &cmd_scu);
10831 if (rc != 0) {
10832 pr_err("error %d\n", rc);
10833 goto rw_error;
443f18d0
MCC
10834 }
10835
b6c4065e
MCC
10836 /* set the lock status */
10837 if (cmd_scu.result[1] < demod_lock) {
10838 /* 0x0000 NOT LOCKED */
10839 *lock_stat = DRX_NOT_LOCKED;
10840 } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
10841 *lock_stat = DRXJ_DEMOD_LOCK;
10842 } else if (cmd_scu.result[1] <
10843 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
10844 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
10845 *lock_stat = DRX_LOCKED;
10846 } else {
10847 /* 0xC000 NEVER LOCKED */
10848 /* (system will never be able to lock to the signal) */
10849 *lock_stat = DRX_NEVER_LOCK;
443f18d0 10850 }
38b2df95 10851
9482354f 10852 return 0;
b6c4065e 10853rw_error:
30741871 10854 return rc;
38b2df95
DH
10855}
10856
10857/*============================================================================*/
10858
34eb9751 10859/*
b6c4065e
MCC
10860* \fn int ctrl_set_standard()
10861* \brief Set modulation standard to be used.
10862* \param standard Modulation standard.
61263c75 10863* \return int.
38b2df95 10864*
b6c4065e
MCC
10865* Setup stuff for the desired demodulation standard.
10866* Disable and power down the previous selected demodulation standard
38b2df95
DH
10867*
10868*/
61263c75 10869static int
b6c4065e 10870ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
38b2df95 10871{
b6c4065e
MCC
10872 struct drxj_data *ext_attr = NULL;
10873 int rc;
10874 enum drx_standard prev_standard;
10875
443f18d0 10876 /* check arguments */
b6c4065e 10877 if ((standard == NULL) || (demod == NULL))
9482354f 10878 return -EINVAL;
38b2df95 10879
b6c4065e
MCC
10880 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10881 prev_standard = ext_attr->standard;
10882
10883 /*
10884 Stop and power down previous standard
10885 */
10886 switch (prev_standard) {
38b2df95 10887#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
10888 case DRX_STANDARD_ITU_A: /* fallthrough */
10889 case DRX_STANDARD_ITU_B: /* fallthrough */
10890 case DRX_STANDARD_ITU_C:
b6c4065e
MCC
10891 rc = power_down_qam(demod, false);
10892 if (rc != 0) {
10893 pr_err("error %d\n", rc);
10894 goto rw_error;
10895 }
10896 break;
38b2df95 10897#endif
b6c4065e
MCC
10898 case DRX_STANDARD_8VSB:
10899 rc = power_down_vsb(demod, false);
10900 if (rc != 0) {
10901 pr_err("error %d\n", rc);
10902 goto rw_error;
10903 }
10904 break;
443f18d0 10905 case DRX_STANDARD_UNKNOWN:
b6c4065e
MCC
10906 /* Do nothing */
10907 break;
10908 case DRX_STANDARD_AUTO: /* fallthrough */
10909 default:
10910 return -EINVAL;
10911 }
10912
10913 /*
10914 Initialize channel independent registers
10915 Power up new standard
10916 */
10917 ext_attr->standard = *standard;
10918
10919 switch (*standard) {
10920#ifndef DRXJ_VSB_ONLY
10921 case DRX_STANDARD_ITU_A: /* fallthrough */
10922 case DRX_STANDARD_ITU_B: /* fallthrough */
10923 case DRX_STANDARD_ITU_C:
10924 do {
10925 u16 dummy;
10926 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
10927 if (rc != 0) {
10928 pr_err("error %d\n", rc);
10929 goto rw_error;
10930 }
10931 } while (0);
10932 break;
10933#endif
10934 case DRX_STANDARD_8VSB:
10935 rc = set_vsb_leak_n_gain(demod);
10936 if (rc != 0) {
10937 pr_err("error %d\n", rc);
10938 goto rw_error;
10939 }
10940 break;
443f18d0 10941 default:
b6c4065e 10942 ext_attr->standard = DRX_STANDARD_UNKNOWN;
9482354f 10943 return -EINVAL;
b6c4065e 10944 break;
443f18d0 10945 }
38b2df95 10946
9482354f 10947 return 0;
b6c4065e
MCC
10948rw_error:
10949 /* Don't know what the standard is now ... try again */
10950 ext_attr->standard = DRX_STANDARD_UNKNOWN;
30741871 10951 return rc;
38b2df95
DH
10952}
10953
38b2df95
DH
10954/*============================================================================*/
10955
b6c4065e
MCC
10956static void drxj_reset_mode(struct drxj_data *ext_attr)
10957{
2c149601 10958 /* Initialize default AFE configuration for QAM */
b6c4065e
MCC
10959 if (ext_attr->has_lna) {
10960 /* IF AGC off, PGA active */
10961#ifndef DRXJ_VSB_ONLY
10962 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10963 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10964 ext_attr->qam_pga_cfg = 140 + (11 * 13);
10965#endif
10966 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10967 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10968 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
10969 } else {
10970 /* IF AGC on, PGA not active */
10971#ifndef DRXJ_VSB_ONLY
10972 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10973 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10974 ext_attr->qam_if_agc_cfg.min_output_level = 0;
10975 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
10976 ext_attr->qam_if_agc_cfg.speed = 3;
10977 ext_attr->qam_if_agc_cfg.top = 1297;
10978 ext_attr->qam_pga_cfg = 140;
10979#endif
10980 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10981 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10982 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
10983 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
10984 ext_attr->vsb_if_agc_cfg.speed = 3;
10985 ext_attr->vsb_if_agc_cfg.top = 1024;
10986 ext_attr->vsb_pga_cfg = 140;
10987 }
10988 /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
10989 /* mc has not used them */
10990#ifndef DRXJ_VSB_ONLY
10991 ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
10992 ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10993 ext_attr->qam_rf_agc_cfg.min_output_level = 0;
10994 ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
10995 ext_attr->qam_rf_agc_cfg.speed = 3;
10996 ext_attr->qam_rf_agc_cfg.top = 9500;
10997 ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
10998 ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
10999 ext_attr->qam_pre_saw_cfg.reference = 0x07;
11000 ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
11001#endif
2c149601 11002 /* Initialize default AFE configuration for VSB */
b6c4065e
MCC
11003 ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
11004 ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11005 ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
11006 ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
11007 ext_attr->vsb_rf_agc_cfg.speed = 3;
11008 ext_attr->vsb_rf_agc_cfg.top = 9500;
11009 ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
11010 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
11011 ext_attr->vsb_pre_saw_cfg.reference = 0x07;
11012 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
11013}
11014
34eb9751 11015/*
b6c4065e
MCC
11016* \fn int ctrl_power_mode()
11017* \brief Set the power mode of the device to the specified power mode
11018* \param demod Pointer to demodulator instance.
11019* \param mode Pointer to new power mode.
61263c75 11020* \return int.
b6c4065e
MCC
11021* \retval 0 Success
11022* \retval -EIO I2C error or other failure
11023* \retval -EINVAL Invalid mode argument.
38b2df95 11024*
38b2df95
DH
11025*
11026*/
61263c75 11027static int
b6c4065e 11028ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
38b2df95 11029{
b6c4065e
MCC
11030 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
11031 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
11032 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
068e94ea 11033 int rc;
b6c4065e 11034 u16 sio_cc_pwd_mode = 0;
38b2df95 11035
b6c4065e 11036 common_attr = (struct drx_common_attr *) demod->my_common_attr;
b3ce3a83 11037 ext_attr = (struct drxj_data *) demod->my_ext_attr;
b6c4065e 11038 dev_addr = demod->my_i2c_dev_addr;
443f18d0 11039
b6c4065e
MCC
11040 /* Check arguments */
11041 if (mode == NULL)
11042 return -EINVAL;
11043
11044 /* If already in requested power mode, do nothing */
11045 if (common_attr->current_power_mode == *mode)
9482354f 11046 return 0;
443f18d0 11047
b6c4065e
MCC
11048 switch (*mode) {
11049 case DRX_POWER_UP:
11050 case DRXJ_POWER_DOWN_MAIN_PATH:
11051 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
443f18d0 11052 break;
b6c4065e
MCC
11053 case DRXJ_POWER_DOWN_CORE:
11054 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
11055 break;
11056 case DRXJ_POWER_DOWN_PLL:
11057 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
11058 break;
11059 case DRX_POWER_DOWN:
11060 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
11061 break;
11062 default:
11063 /* Unknow sleep mode */
11064 return -EINVAL;
11065 break;
11066 }
11067
11068 /* Check if device needs to be powered up */
11069 if ((common_attr->current_power_mode != DRX_POWER_UP)) {
11070 rc = power_up_device(demod);
11071 if (rc != 0) {
11072 pr_err("error %d\n", rc);
11073 goto rw_error;
11074 }
11075 }
11076
11077 if ((*mode == DRX_POWER_UP)) {
2c149601 11078 /* Restore analog & pin configuration */
b6c4065e 11079
2c149601 11080 /* Initialize default AFE configuration for VSB */
b6c4065e
MCC
11081 drxj_reset_mode(ext_attr);
11082 } else {
11083 /* Power down to requested mode */
11084 /* Backup some register settings */
11085 /* Set pins with possible pull-ups connected to them in input mode */
11086 /* Analog power down */
11087 /* ADC power down */
11088 /* Power down device */
11089 /* stop all comm_exec */
11090 /*
11091 Stop and power down previous standard
11092 */
11093
11094 switch (ext_attr->standard) {
11095 case DRX_STANDARD_ITU_A:
11096 case DRX_STANDARD_ITU_B:
11097 case DRX_STANDARD_ITU_C:
11098 rc = power_down_qam(demod, true);
11099 if (rc != 0) {
11100 pr_err("error %d\n", rc);
11101 goto rw_error;
11102 }
11103 break;
11104 case DRX_STANDARD_8VSB:
11105 rc = power_down_vsb(demod, true);
11106 if (rc != 0) {
11107 pr_err("error %d\n", rc);
11108 goto rw_error;
11109 }
11110 break;
11111 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
11112 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
11113 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
11114 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
11115 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
11116 case DRX_STANDARD_NTSC: /* fallthrough */
11117 case DRX_STANDARD_FM:
11118 rc = power_down_atv(demod, ext_attr->standard, true);
11119 if (rc != 0) {
11120 pr_err("error %d\n", rc);
11121 goto rw_error;
11122 }
443f18d0 11123 break;
b6c4065e
MCC
11124 case DRX_STANDARD_UNKNOWN:
11125 /* Do nothing */
443f18d0 11126 break;
b6c4065e 11127 case DRX_STANDARD_AUTO: /* fallthrough */
443f18d0 11128 default:
9482354f 11129 return -EIO;
443f18d0 11130 }
b6c4065e 11131 ext_attr->standard = DRX_STANDARD_UNKNOWN;
443f18d0
MCC
11132 }
11133
b6c4065e
MCC
11134 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
11135 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
11136 if (rc != 0) {
11137 pr_err("error %d\n", rc);
11138 goto rw_error;
11139 }
11140 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
11141 if (rc != 0) {
11142 pr_err("error %d\n", rc);
11143 goto rw_error;
11144 }
11145
11146 if ((*mode != DRX_POWER_UP)) {
11147 /* Initialize HI, wakeup key especially before put IC to sleep */
11148 rc = init_hi(demod);
11149 if (rc != 0) {
11150 pr_err("error %d\n", rc);
11151 goto rw_error;
11152 }
11153
11154 ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
11155 rc = hi_cfg_command(demod);
11156 if (rc != 0) {
11157 pr_err("error %d\n", rc);
11158 goto rw_error;
11159 }
11160 }
068e94ea 11161 }
b6c4065e
MCC
11162
11163 common_attr->current_power_mode = *mode;
443f18d0 11164
9482354f 11165 return 0;
38b2df95 11166rw_error:
b6c4065e 11167 return rc;
38b2df95
DH
11168}
11169
11170/*============================================================================*/
b6c4065e
MCC
11171/*== CTRL Set/Get Config related functions ===================================*/
11172/*============================================================================*/
38b2df95 11173
34eb9751 11174/*
57afe2f0 11175* \fn int ctrl_set_cfg_pre_saw()
38b2df95
DH
11176* \brief Set Pre-saw reference.
11177* \param demod demod instance
43a431e4 11178* \param u16 *
61263c75 11179* \return int.
38b2df95
DH
11180*
11181* Check arguments
11182* Dispatch handling to standard specific function.
11183*
11184*/
61263c75 11185static int
b3ce3a83 11186ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
38b2df95 11187{
57afe2f0 11188 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 11189 struct drxj_data *ext_attr = NULL;
068e94ea 11190 int rc;
38b2df95 11191
57afe2f0 11192 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 11193 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 11194
443f18d0 11195 /* check arguments */
57afe2f0 11196 if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
443f18d0 11197 ) {
9482354f 11198 return -EINVAL;
443f18d0
MCC
11199 }
11200
11201 /* Only if standard is currently active */
57afe2f0
MCC
11202 if ((ext_attr->standard == pre_saw->standard) ||
11203 (DRXJ_ISQAMSTD(ext_attr->standard) &&
11204 DRXJ_ISQAMSTD(pre_saw->standard)) ||
11205 (DRXJ_ISATVSTD(ext_attr->standard) &&
11206 DRXJ_ISATVSTD(pre_saw->standard))) {
244c0e06 11207 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
9482354f 11208 if (rc != 0) {
068e94ea
MCC
11209 pr_err("error %d\n", rc);
11210 goto rw_error;
11211 }
443f18d0
MCC
11212 }
11213
11214 /* Store pre-saw settings */
57afe2f0 11215 switch (pre_saw->standard) {
443f18d0 11216 case DRX_STANDARD_8VSB:
57afe2f0 11217 ext_attr->vsb_pre_saw_cfg = *pre_saw;
443f18d0 11218 break;
38b2df95 11219#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
11220 case DRX_STANDARD_ITU_A: /* fallthrough */
11221 case DRX_STANDARD_ITU_B: /* fallthrough */
11222 case DRX_STANDARD_ITU_C:
57afe2f0 11223 ext_attr->qam_pre_saw_cfg = *pre_saw;
443f18d0 11224 break;
38b2df95 11225#endif
443f18d0 11226 default:
9482354f 11227 return -EINVAL;
443f18d0 11228 }
38b2df95 11229
9482354f 11230 return 0;
38b2df95 11231rw_error:
30741871 11232 return rc;
38b2df95
DH
11233}
11234
11235/*============================================================================*/
11236
34eb9751 11237/*
57afe2f0 11238* \fn int ctrl_set_cfg_afe_gain()
38b2df95
DH
11239* \brief Set AFE Gain.
11240* \param demod demod instance
43a431e4 11241* \param u16 *
61263c75 11242* \return int.
38b2df95
DH
11243*
11244* Check arguments
11245* Dispatch handling to standard specific function.
11246*
11247*/
61263c75 11248static int
b3ce3a83 11249ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
38b2df95 11250{
57afe2f0 11251 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 11252 struct drxj_data *ext_attr = NULL;
068e94ea 11253 int rc;
43a431e4 11254 u8 gain = 0;
38b2df95 11255
443f18d0 11256 /* check arguments */
63713517 11257 if (afe_gain == NULL)
9482354f 11258 return -EINVAL;
38b2df95 11259
57afe2f0 11260 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 11261 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 11262
57afe2f0 11263 switch (afe_gain->standard) {
443f18d0 11264 case DRX_STANDARD_8VSB: /* fallthrough */
38b2df95 11265#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
11266 case DRX_STANDARD_ITU_A: /* fallthrough */
11267 case DRX_STANDARD_ITU_B: /* fallthrough */
11268 case DRX_STANDARD_ITU_C:
38b2df95 11269#endif
443f18d0
MCC
11270 /* Do nothing */
11271 break;
11272 default:
9482354f 11273 return -EINVAL;
443f18d0 11274 }
38b2df95 11275
443f18d0 11276 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
38b2df95
DH
11277 So I (PJ) think interface requires choice between auto, user mode */
11278
57afe2f0 11279 if (afe_gain->gain >= 329)
443f18d0 11280 gain = 15;
57afe2f0 11281 else if (afe_gain->gain <= 147)
443f18d0
MCC
11282 gain = 0;
11283 else
57afe2f0 11284 gain = (afe_gain->gain - 140 + 6) / 13;
443f18d0
MCC
11285
11286 /* Only if standard is currently active */
63713517 11287 if (ext_attr->standard == afe_gain->standard) {
244c0e06 11288 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
9482354f 11289 if (rc != 0) {
068e94ea
MCC
11290 pr_err("error %d\n", rc);
11291 goto rw_error;
11292 }
11293 }
443f18d0
MCC
11294
11295 /* Store AFE Gain settings */
57afe2f0 11296 switch (afe_gain->standard) {
443f18d0 11297 case DRX_STANDARD_8VSB:
57afe2f0 11298 ext_attr->vsb_pga_cfg = gain * 13 + 140;
443f18d0 11299 break;
38b2df95 11300#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
11301 case DRX_STANDARD_ITU_A: /* fallthrough */
11302 case DRX_STANDARD_ITU_B: /* fallthrough */
11303 case DRX_STANDARD_ITU_C:
57afe2f0 11304 ext_attr->qam_pga_cfg = gain * 13 + 140;
443f18d0 11305 break;
38b2df95 11306#endif
443f18d0 11307 default:
9482354f 11308 return -EIO;
443f18d0 11309 }
38b2df95 11310
9482354f 11311 return 0;
38b2df95 11312rw_error:
30741871 11313 return rc;
38b2df95
DH
11314}
11315
11316/*============================================================================*/
11317
38b2df95
DH
11318
11319/*=============================================================================
11320===== EXPORTED FUNCTIONS ====================================================*/
aafdbaa6 11321
dc5a91d4
MCC
11322static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11323 struct drxu_code_info *mc_info,
11324 enum drxu_code_action action);
998819d2 11325static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
dc5a91d4 11326
34eb9751 11327/*
57afe2f0 11328* \fn drxj_open()
38b2df95
DH
11329* \brief Open the demod instance, configure device, configure drxdriver
11330* \return Status_t Return status.
11331*
57afe2f0
MCC
11332* drxj_open() can be called with a NULL ucode image => no ucode upload.
11333* This means that drxj_open() must NOT contain SCU commands or, in general,
38b2df95
DH
11334* rely on SCU or AUD ucode to be present.
11335*
11336*/
dc5a91d4 11337
01473146 11338static int drxj_open(struct drx_demod_instance *demod)
38b2df95 11339{
57afe2f0 11340 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 11341 struct drxj_data *ext_attr = NULL;
1bfc9e15 11342 struct drx_common_attr *common_attr = NULL;
57afe2f0 11343 u32 driver_version = 0;
1bfc9e15
MCC
11344 struct drxu_code_info ucode_info;
11345 struct drx_cfg_mpeg_output cfg_mpeg_output;
068e94ea 11346 int rc;
d7a5478a 11347 enum drx_power_mode power_mode = DRX_POWER_UP;
b78359a6
MCC
11348
11349 if ((demod == NULL) ||
11350 (demod->my_common_attr == NULL) ||
11351 (demod->my_ext_attr == NULL) ||
11352 (demod->my_i2c_dev_addr == NULL) ||
11353 (demod->my_common_attr->is_opened)) {
11354 return -EINVAL;
11355 }
11356
443f18d0 11357 /* Check arguments */
068e94ea 11358 if (demod->my_ext_attr == NULL)
9482354f 11359 return -EINVAL;
38b2df95 11360
57afe2f0 11361 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 11362 ext_attr = (struct drxj_data *) demod->my_ext_attr;
1bfc9e15 11363 common_attr = (struct drx_common_attr *) demod->my_common_attr;
38b2df95 11364
d7a5478a 11365 rc = ctrl_power_mode(demod, &power_mode);
9482354f 11366 if (rc != 0) {
068e94ea
MCC
11367 pr_err("error %d\n", rc);
11368 goto rw_error;
11369 }
d7a5478a
MCC
11370 if (power_mode != DRX_POWER_UP) {
11371 rc = -EINVAL;
11372 pr_err("failed to powerup device\n");
11373 goto rw_error;
11374 }
38b2df95 11375
443f18d0 11376 /* has to be in front of setIqmAf and setOrxNsuAox */
068e94ea 11377 rc = get_device_capabilities(demod);
9482354f 11378 if (rc != 0) {
068e94ea
MCC
11379 pr_err("error %d\n", rc);
11380 goto rw_error;
11381 }
38b2df95 11382
8afff9a2
MCC
11383 /*
11384 * Soft reset of sys- and osc-clockdomain
11385 *
11386 * HACK: On windows, it writes a 0x07 here, instead of just 0x03.
11387 * As we didn't load the firmware here yet, we should do the same.
11388 * Btw, this is coherent with DRX-K, where we send reset codes
11389 * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.
11390 */
11391 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_SOFT_RST__A, (0x04 | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), 0);
9482354f 11392 if (rc != 0) {
068e94ea
MCC
11393 pr_err("error %d\n", rc);
11394 goto rw_error;
11395 }
244c0e06 11396 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
9482354f 11397 if (rc != 0) {
068e94ea
MCC
11398 pr_err("error %d\n", rc);
11399 goto rw_error;
11400 }
d7b0631e 11401 msleep(1);
38b2df95 11402
443f18d0
MCC
11403 /* TODO first make sure that everything keeps working before enabling this */
11404 /* PowerDownAnalogBlocks() */
244c0e06 11405 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, 0);
9482354f 11406 if (rc != 0) {
068e94ea
MCC
11407 pr_err("error %d\n", rc);
11408 goto rw_error;
11409 }
38b2df95 11410
068e94ea 11411 rc = set_iqm_af(demod, false);
9482354f 11412 if (rc != 0) {
068e94ea
MCC
11413 pr_err("error %d\n", rc);
11414 goto rw_error;
11415 }
11416 rc = set_orx_nsu_aox(demod, false);
9482354f 11417 if (rc != 0) {
068e94ea
MCC
11418 pr_err("error %d\n", rc);
11419 goto rw_error;
11420 }
38b2df95 11421
068e94ea 11422 rc = init_hi(demod);
9482354f 11423 if (rc != 0) {
068e94ea
MCC
11424 pr_err("error %d\n", rc);
11425 goto rw_error;
11426 }
38b2df95 11427
443f18d0 11428 /* disable mpegoutput pins */
41b5cc0c 11429 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
57afe2f0 11430 cfg_mpeg_output.enable_mpeg_output = false;
41b5cc0c 11431
068e94ea 11432 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 11433 if (rc != 0) {
068e94ea
MCC
11434 pr_err("error %d\n", rc);
11435 goto rw_error;
11436 }
443f18d0 11437 /* Stop AUD Inform SetAudio it will need to do all setting */
068e94ea 11438 rc = power_down_aud(demod);
9482354f 11439 if (rc != 0) {
068e94ea
MCC
11440 pr_err("error %d\n", rc);
11441 goto rw_error;
11442 }
443f18d0 11443 /* Stop SCU */
244c0e06 11444 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
9482354f 11445 if (rc != 0) {
068e94ea
MCC
11446 pr_err("error %d\n", rc);
11447 goto rw_error;
11448 }
38b2df95 11449
443f18d0 11450 /* Upload microcode */
b48293db 11451 if (common_attr->microcode_file != NULL) {
443f18d0
MCC
11452 /* Dirty trick to use common ucode upload & verify,
11453 pretend device is already open */
57afe2f0 11454 common_attr->is_opened = true;
b48293db 11455 ucode_info.mc_file = common_attr->microcode_file;
38b2df95 11456
dc5a91d4
MCC
11457 if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
11458 pr_err("Should powerup before loading the firmware.");
11459 return -EINVAL;
11460 }
11461
11462 rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);
9482354f 11463 if (rc != 0) {
dc5a91d4 11464 pr_err("error %d while uploading the firmware\n", rc);
068e94ea
MCC
11465 goto rw_error;
11466 }
57afe2f0 11467 if (common_attr->verify_microcode == true) {
dc5a91d4 11468 rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_VERIFY);
9482354f 11469 if (rc != 0) {
dc5a91d4
MCC
11470 pr_err("error %d while verifying the firmware\n",
11471 rc);
068e94ea
MCC
11472 goto rw_error;
11473 }
443f18d0 11474 }
57afe2f0 11475 common_attr->is_opened = false;
443f18d0 11476 }
38b2df95 11477
443f18d0 11478 /* Run SCU for a little while to initialize microcode version numbers */
244c0e06 11479 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
9482354f 11480 if (rc != 0) {
068e94ea
MCC
11481 pr_err("error %d\n", rc);
11482 goto rw_error;
11483 }
38b2df95 11484
443f18d0 11485 /* Initialize scan timeout */
57afe2f0
MCC
11486 common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
11487 common_attr->scan_desired_lock = DRX_LOCKED;
443f18d0 11488
aafdbaa6 11489 drxj_reset_mode(ext_attr);
57afe2f0 11490 ext_attr->standard = DRX_STANDARD_UNKNOWN;
443f18d0 11491
068e94ea 11492 rc = smart_ant_init(demod);
9482354f 11493 if (rc != 0) {
068e94ea
MCC
11494 pr_err("error %d\n", rc);
11495 goto rw_error;
11496 }
443f18d0
MCC
11497
11498 /* Stamp driver version number in SCU data RAM in BCD code
69bb7ab6 11499 Done to enable field application engineers to retrieve drxdriver version
443f18d0
MCC
11500 via I2C from SCU RAM
11501 */
57afe2f0
MCC
11502 driver_version = (VERSION_MAJOR / 100) % 10;
11503 driver_version <<= 4;
11504 driver_version += (VERSION_MAJOR / 10) % 10;
11505 driver_version <<= 4;
11506 driver_version += (VERSION_MAJOR % 10);
11507 driver_version <<= 4;
11508 driver_version += (VERSION_MINOR % 10);
11509 driver_version <<= 4;
11510 driver_version += (VERSION_PATCH / 1000) % 10;
11511 driver_version <<= 4;
11512 driver_version += (VERSION_PATCH / 100) % 10;
11513 driver_version <<= 4;
11514 driver_version += (VERSION_PATCH / 10) % 10;
11515 driver_version <<= 4;
11516 driver_version += (VERSION_PATCH % 10);
244c0e06 11517 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
9482354f 11518 if (rc != 0) {
068e94ea
MCC
11519 pr_err("error %d\n", rc);
11520 goto rw_error;
11521 }
244c0e06 11522 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
9482354f 11523 if (rc != 0) {
068e94ea
MCC
11524 pr_err("error %d\n", rc);
11525 goto rw_error;
11526 }
443f18d0 11527
bf9b94ab
MCC
11528 rc = ctrl_set_oob(demod, NULL);
11529 if (rc != 0) {
11530 pr_err("error %d\n", rc);
11531 goto rw_error;
11532 }
11533
443f18d0 11534 /* refresh the audio data structure with default */
57afe2f0 11535 ext_attr->aud_data = drxj_default_aud_data_g;
443f18d0 11536
b78359a6 11537 demod->my_common_attr->is_opened = true;
998819d2 11538 drxj_set_lna_state(demod, false);
9482354f 11539 return 0;
38b2df95 11540rw_error:
57afe2f0 11541 common_attr->is_opened = false;
30741871 11542 return rc;
38b2df95
DH
11543}
11544
11545/*============================================================================*/
34eb9751 11546/*
57afe2f0 11547* \fn drxj_close()
38b2df95
DH
11548* \brief Close the demod instance, power down the device
11549* \return Status_t Return status.
11550*
11551*/
01473146 11552static int drxj_close(struct drx_demod_instance *demod)
38b2df95 11553{
4d7bb0eb 11554 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 11555 int rc;
1bfc9e15 11556 enum drx_power_mode power_mode = DRX_POWER_UP;
38b2df95 11557
1e5ec31a 11558 if ((demod->my_common_attr == NULL) ||
b78359a6
MCC
11559 (demod->my_ext_attr == NULL) ||
11560 (demod->my_i2c_dev_addr == NULL) ||
11561 (!demod->my_common_attr->is_opened)) {
11562 return -EINVAL;
11563 }
11564
443f18d0 11565 /* power up */
068e94ea 11566 rc = ctrl_power_mode(demod, &power_mode);
9482354f 11567 if (rc != 0) {
068e94ea
MCC
11568 pr_err("error %d\n", rc);
11569 goto rw_error;
11570 }
38b2df95 11571
244c0e06 11572 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
9482354f 11573 if (rc != 0) {
068e94ea
MCC
11574 pr_err("error %d\n", rc);
11575 goto rw_error;
11576 }
57afe2f0 11577 power_mode = DRX_POWER_DOWN;
068e94ea 11578 rc = ctrl_power_mode(demod, &power_mode);
9482354f 11579 if (rc != 0) {
068e94ea
MCC
11580 pr_err("error %d\n", rc);
11581 goto rw_error;
11582 }
443f18d0 11583
b78359a6
MCC
11584 DRX_ATTR_ISOPENED(demod) = false;
11585
9482354f 11586 return 0;
38b2df95 11587rw_error:
b78359a6
MCC
11588 DRX_ATTR_ISOPENED(demod) = false;
11589
30741871 11590 return rc;
38b2df95
DH
11591}
11592
b240eacd
MCC
11593/*
11594 * Microcode related functions
11595 */
11596
34eb9751 11597/*
b240eacd
MCC
11598 * drx_u_code_compute_crc - Compute CRC of block of microcode data.
11599 * @block_data: Pointer to microcode data.
11600 * @nr_words: Size of microcode block (number of 16 bits words).
11601 *
11602 * returns The computed CRC residue.
11603 */
11604static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
11605{
11606 u16 i = 0;
11607 u16 j = 0;
11608 u32 crc_word = 0;
11609 u32 carry = 0;
11610
11611 while (i < nr_words) {
4182438e 11612 crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
b240eacd
MCC
11613 for (j = 0; j < 16; j++) {
11614 crc_word <<= 1;
11615 if (carry != 0)
11616 crc_word ^= 0x80050000UL;
11617 carry = crc_word & 0x80000000UL;
11618 }
11619 i++;
11620 block_data += (sizeof(u16));
11621 }
11622 return (u16)(crc_word >> 16);
11623}
11624
34eb9751 11625/*
b240eacd
MCC
11626 * drx_check_firmware - checks if the loaded firmware is valid
11627 *
11628 * @demod: demod structure
11629 * @mc_data: pointer to the start of the firmware
11630 * @size: firmware size
11631 */
11632static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
11633 unsigned size)
11634{
11635 struct drxu_code_block_hdr block_hdr;
11636 int i;
11637 unsigned count = 2 * sizeof(u16);
11638 u32 mc_dev_type, mc_version, mc_base_version;
4182438e 11639 u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
b240eacd
MCC
11640
11641 /*
11642 * Scan microcode blocks first for version info
11643 * and firmware check
11644 */
11645
11646 /* Clear version block */
11647 DRX_ATTR_MCRECORD(demod).aux_type = 0;
11648 DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
11649 DRX_ATTR_MCRECORD(demod).mc_version = 0;
11650 DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
11651
11652 for (i = 0; i < mc_nr_of_blks; i++) {
11653 if (count + 3 * sizeof(u16) + sizeof(u32) > size)
11654 goto eof;
11655
11656 /* Process block header */
4182438e 11657 block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
b240eacd 11658 count += sizeof(u32);
4182438e 11659 block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
b240eacd 11660 count += sizeof(u16);
4182438e 11661 block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
b240eacd 11662 count += sizeof(u16);
4182438e 11663 block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
b240eacd
MCC
11664 count += sizeof(u16);
11665
11666 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11667 count, block_hdr.addr, block_hdr.size, block_hdr.flags,
11668 block_hdr.CRC);
11669
11670 if (block_hdr.flags & 0x8) {
11671 u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
11672 u16 auxtype;
11673
11674 if (block_hdr.addr + sizeof(u16) > size)
11675 goto eof;
11676
4182438e 11677 auxtype = be16_to_cpu(*(__be16 *)(auxblk));
b240eacd
MCC
11678
11679 /* Aux block. Check type */
11680 if (DRX_ISMCVERTYPE(auxtype)) {
11681 if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
11682 goto eof;
11683
11684 auxblk += sizeof(u16);
4182438e 11685 mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
b240eacd 11686 auxblk += sizeof(u32);
4182438e 11687 mc_version = be32_to_cpu(*(__be32 *)(auxblk));
b240eacd 11688 auxblk += sizeof(u32);
4182438e 11689 mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
b240eacd
MCC
11690
11691 DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
11692 DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
11693 DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
11694 DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
11695
11696 pr_info("Firmware dev %x, ver %x, base ver %x\n",
11697 mc_dev_type, mc_version, mc_base_version);
11698
11699 }
11700 } else if (count + block_hdr.size * sizeof(u16) > size)
11701 goto eof;
11702
11703 count += block_hdr.size * sizeof(u16);
11704 }
11705 return 0;
11706eof:
11707 pr_err("Firmware is truncated at pos %u/%u\n", count, size);
11708 return -EINVAL;
11709}
11710
34eb9751 11711/*
b240eacd
MCC
11712 * drx_ctrl_u_code - Handle microcode upload or verify.
11713 * @dev_addr: Address of device.
11714 * @mc_info: Pointer to information about microcode data.
11715 * @action: Either UCODE_UPLOAD or UCODE_VERIFY
11716 *
11717 * This function returns:
11718 * 0:
11719 * - In case of UCODE_UPLOAD: code is successfully uploaded.
11720 * - In case of UCODE_VERIFY: image on device is equal to
11721 * image provided to this control function.
11722 * -EIO:
11723 * - In case of UCODE_UPLOAD: I2C error.
11724 * - In case of UCODE_VERIFY: I2C error or image on device
11725 * is not equal to image provided to this control function.
11726 * -EINVAL:
11727 * - Invalid arguments.
11728 * - Provided image is corrupt
11729 */
11730static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11731 struct drxu_code_info *mc_info,
11732 enum drxu_code_action action)
11733{
11734 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11735 int rc;
11736 u16 i = 0;
11737 u16 mc_nr_of_blks = 0;
11738 u16 mc_magic_word = 0;
11739 const u8 *mc_data_init = NULL;
11740 u8 *mc_data = NULL;
11741 unsigned size;
1d001c3f 11742 char *mc_file;
b240eacd
MCC
11743
11744 /* Check arguments */
1d001c3f 11745 if (!mc_info || !mc_info->mc_file)
b240eacd
MCC
11746 return -EINVAL;
11747
1d001c3f
MCC
11748 mc_file = mc_info->mc_file;
11749
b240eacd
MCC
11750 if (!demod->firmware) {
11751 const struct firmware *fw = NULL;
11752
11753 rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
11754 if (rc < 0) {
11755 pr_err("Couldn't read firmware %s\n", mc_file);
691cbbe3 11756 return rc;
b240eacd
MCC
11757 }
11758 demod->firmware = fw;
11759
11760 if (demod->firmware->size < 2 * sizeof(u16)) {
11761 rc = -EINVAL;
11762 pr_err("Firmware is too short!\n");
11763 goto release;
11764 }
11765
11766 pr_info("Firmware %s, size %zu\n",
11767 mc_file, demod->firmware->size);
11768 }
11769
11770 mc_data_init = demod->firmware->data;
11771 size = demod->firmware->size;
11772
11773 mc_data = (void *)mc_data_init;
11774 /* Check data */
4182438e 11775 mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd 11776 mc_data += sizeof(u16);
4182438e 11777 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd
MCC
11778 mc_data += sizeof(u16);
11779
11780 if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
11781 rc = -EINVAL;
11782 pr_err("Firmware magic word doesn't match\n");
11783 goto release;
11784 }
11785
11786 if (action == UCODE_UPLOAD) {
11787 rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
11788 if (rc)
11789 goto release;
b240eacd 11790 pr_info("Uploading firmware %s\n", mc_file);
dc5a91d4 11791 } else {
b240eacd
MCC
11792 pr_info("Verifying if firmware upload was ok.\n");
11793 }
11794
11795 /* Process microcode blocks */
11796 for (i = 0; i < mc_nr_of_blks; i++) {
11797 struct drxu_code_block_hdr block_hdr;
11798 u16 mc_block_nr_bytes = 0;
11799
11800 /* Process block header */
4182438e 11801 block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
b240eacd 11802 mc_data += sizeof(u32);
4182438e 11803 block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd 11804 mc_data += sizeof(u16);
4182438e 11805 block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd 11806 mc_data += sizeof(u16);
4182438e 11807 block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd
MCC
11808 mc_data += sizeof(u16);
11809
11810 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11811 (unsigned)(mc_data - mc_data_init), block_hdr.addr,
11812 block_hdr.size, block_hdr.flags, block_hdr.CRC);
11813
11814 /* Check block header on:
11815 - data larger than 64Kb
11816 - if CRC enabled check CRC
11817 */
11818 if ((block_hdr.size > 0x7FFF) ||
11819 (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
11820 (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
11821 ) {
11822 /* Wrong data ! */
11823 rc = -EINVAL;
11824 pr_err("firmware CRC is wrong\n");
11825 goto release;
11826 }
11827
11828 if (!block_hdr.size)
11829 continue;
11830
11831 mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
11832
11833 /* Perform the desired action */
11834 switch (action) {
11835 case UCODE_UPLOAD: /* Upload microcode */
244c0e06 11836 if (drxdap_fasi_write_block(dev_addr,
b240eacd
MCC
11837 block_hdr.addr,
11838 mc_block_nr_bytes,
11839 mc_data, 0x0000)) {
11840 rc = -EIO;
11841 pr_err("error writing firmware at pos %u\n",
11842 (unsigned)(mc_data - mc_data_init));
11843 goto release;
11844 }
11845 break;
11846 case UCODE_VERIFY: { /* Verify uploaded microcode */
11847 int result = 0;
11848 u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
11849 u32 bytes_to_comp = 0;
11850 u32 bytes_left = mc_block_nr_bytes;
11851 u32 curr_addr = block_hdr.addr;
11852 u8 *curr_ptr = mc_data;
11853
11854 while (bytes_left != 0) {
11855 if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
11856 bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
11857 else
11858 bytes_to_comp = bytes_left;
11859
244c0e06 11860 if (drxdap_fasi_read_block(dev_addr,
b240eacd
MCC
11861 curr_addr,
11862 (u16)bytes_to_comp,
11863 (u8 *)mc_data_buffer,
11864 0x0000)) {
11865 pr_err("error reading firmware at pos %u\n",
11866 (unsigned)(mc_data - mc_data_init));
11867 return -EIO;
11868 }
11869
d7b0631e
MCC
11870 result = memcmp(curr_ptr, mc_data_buffer,
11871 bytes_to_comp);
b240eacd
MCC
11872
11873 if (result) {
11874 pr_err("error verifying firmware at pos %u\n",
11875 (unsigned)(mc_data - mc_data_init));
11876 return -EIO;
11877 }
11878
11879 curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
11880 curr_ptr =&(curr_ptr[bytes_to_comp]);
11881 bytes_left -=((u32) bytes_to_comp);
11882 }
11883 break;
11884 }
11885 default:
11886 return -EINVAL;
11887 break;
11888
11889 }
11890 mc_data += mc_block_nr_bytes;
11891 }
11892
11893 return 0;
11894
11895release:
11896 release_firmware(demod->firmware);
11897 demod->firmware = NULL;
11898
11899 return rc;
11900}
19013747 11901
69bb7ab6 11902/* caller is expected to check if lna is supported before enabling */
998819d2
SK
11903static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
11904{
11905 struct drxuio_cfg uio_cfg;
11906 struct drxuio_data uio_data;
11907 int result;
11908
11909 uio_cfg.uio = DRX_UIO1;
11910 uio_cfg.mode = DRX_UIO_MODE_READWRITE;
11911 /* Configure user-I/O #3: enable read/write */
11912 result = ctrl_set_uio_cfg(demod, &uio_cfg);
11913 if (result) {
11914 pr_err("Failed to setup LNA GPIO!\n");
11915 return result;
11916 }
11917
11918 uio_data.uio = DRX_UIO1;
11919 uio_data.value = state;
11920 result = ctrl_uio_write(demod, &uio_data);
11921 if (result != 0) {
11922 pr_err("Failed to %sable LNA!\n",
11923 state ? "en" : "dis");
11924 return result;
11925 }
11926 return 0;
11927}
11928
19013747
MCC
11929/*
11930 * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
11931 *
11932 * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
11933 */
11934
11935static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
11936{
11937 struct drx39xxj_state *state = fe->demodulator_priv;
11938 struct drx_demod_instance *demod = state->demod;
11939 int result;
11940 enum drx_power_mode power_mode;
11941
11942 if (enable)
11943 power_mode = DRX_POWER_UP;
11944 else
11945 power_mode = DRX_POWER_DOWN;
11946
b0baeb49 11947 result = ctrl_power_mode(demod, &power_mode);
19013747
MCC
11948 if (result != 0) {
11949 pr_err("Power state change failed\n");
11950 return 0;
11951 }
11952
19013747
MCC
11953 return 0;
11954}
11955
0df289a2 11956static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)
19013747
MCC
11957{
11958 struct drx39xxj_state *state = fe->demodulator_priv;
11959 struct drx_demod_instance *demod = state->demod;
11960 int result;
11961 enum drx_lock_status lock_status;
11962
11963 *status = 0;
11964
b0baeb49 11965 result = ctrl_lock_status(demod, &lock_status);
19013747
MCC
11966 if (result != 0) {
11967 pr_err("drx39xxj: could not get lock status!\n");
11968 *status = 0;
11969 }
11970
11971 switch (lock_status) {
11972 case DRX_NEVER_LOCK:
11973 *status = 0;
11974 pr_err("drx says NEVER_LOCK\n");
11975 break;
11976 case DRX_NOT_LOCKED:
11977 *status = 0;
11978 break;
11979 case DRX_LOCK_STATE_1:
11980 case DRX_LOCK_STATE_2:
11981 case DRX_LOCK_STATE_3:
11982 case DRX_LOCK_STATE_4:
11983 case DRX_LOCK_STATE_5:
11984 case DRX_LOCK_STATE_6:
11985 case DRX_LOCK_STATE_7:
11986 case DRX_LOCK_STATE_8:
11987 case DRX_LOCK_STATE_9:
11988 *status = FE_HAS_SIGNAL
11989 | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
11990 break;
11991 case DRX_LOCKED:
11992 *status = FE_HAS_SIGNAL
11993 | FE_HAS_CARRIER
11994 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
11995 break;
11996 default:
11997 pr_err("Lock state unknown %d\n", lock_status);
11998 }
03fdfbfd 11999 ctrl_sig_quality(demod, lock_status);
19013747
MCC
12000
12001 return 0;
12002}
12003
12004static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
12005{
03fdfbfd 12006 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
19013747 12007
03fdfbfd 12008 if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
19013747
MCC
12009 *ber = 0;
12010 return 0;
12011 }
12012
69832578
MCC
12013 if (!p->pre_bit_count.stat[0].uvalue) {
12014 if (!p->pre_bit_error.stat[0].uvalue)
12015 *ber = 0;
12016 else
12017 *ber = 1000000;
12018 } else {
12019 *ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,
12020 p->pre_bit_count.stat[0].uvalue);
12021 }
19013747
MCC
12022 return 0;
12023}
12024
12025static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
12026 u16 *strength)
12027{
03fdfbfd 12028 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
19013747 12029
03fdfbfd 12030 if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
19013747
MCC
12031 *strength = 0;
12032 return 0;
12033 }
12034
03fdfbfd 12035 *strength = p->strength.stat[0].uvalue;
19013747
MCC
12036 return 0;
12037}
12038
12039static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
12040{
03fdfbfd 12041 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
90d9c3e1 12042 u64 tmp64;
19013747 12043
03fdfbfd 12044 if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
19013747
MCC
12045 *snr = 0;
12046 return 0;
12047 }
12048
90d9c3e1
GG
12049 tmp64 = p->cnr.stat[0].svalue;
12050 do_div(tmp64, 10);
12051 *snr = tmp64;
19013747
MCC
12052 return 0;
12053}
12054
03fdfbfd 12055static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
19013747 12056{
03fdfbfd 12057 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
19013747 12058
03fdfbfd
MCC
12059 if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12060 *ucb = 0;
19013747
MCC
12061 return 0;
12062 }
12063
03fdfbfd 12064 *ucb = p->block_error.stat[0].uvalue;
19013747
MCC
12065 return 0;
12066}
12067
12068static int drx39xxj_set_frontend(struct dvb_frontend *fe)
12069{
12070#ifdef DJH_DEBUG
12071 int i;
12072#endif
12073 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12074 struct drx39xxj_state *state = fe->demodulator_priv;
12075 struct drx_demod_instance *demod = state->demod;
12076 enum drx_standard standard = DRX_STANDARD_8VSB;
12077 struct drx_channel channel;
12078 int result;
19013747
MCC
12079 static const struct drx_channel def_channel = {
12080 /* frequency */ 0,
12081 /* bandwidth */ DRX_BANDWIDTH_6MHZ,
12082 /* mirror */ DRX_MIRROR_NO,
12083 /* constellation */ DRX_CONSTELLATION_AUTO,
12084 /* hierarchy */ DRX_HIERARCHY_UNKNOWN,
12085 /* priority */ DRX_PRIORITY_UNKNOWN,
12086 /* coderate */ DRX_CODERATE_UNKNOWN,
12087 /* guard */ DRX_GUARD_UNKNOWN,
12088 /* fftmode */ DRX_FFTMODE_UNKNOWN,
12089 /* classification */ DRX_CLASSIFICATION_AUTO,
12090 /* symbolrate */ 5057000,
12091 /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,
12092 /* ldpc */ DRX_LDPC_UNKNOWN,
12093 /* carrier */ DRX_CARRIER_UNKNOWN,
12094 /* frame mode */ DRX_FRAMEMODE_UNKNOWN
12095 };
12096 u32 constellation = DRX_CONSTELLATION_AUTO;
12097
12098 /* Bring the demod out of sleep */
12099 drx39xxj_set_powerstate(fe, 1);
12100
19013747 12101 if (fe->ops.tuner_ops.set_params) {
7abc7a54
MCC
12102 u32 int_freq;
12103
19013747
MCC
12104 if (fe->ops.i2c_gate_ctrl)
12105 fe->ops.i2c_gate_ctrl(fe, 1);
7abc7a54
MCC
12106
12107 /* Set tuner to desired frequency and standard */
19013747 12108 fe->ops.tuner_ops.set_params(fe);
7abc7a54
MCC
12109
12110 /* Use the tuner's IF */
12111 if (fe->ops.tuner_ops.get_if_frequency) {
12112 fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);
12113 demod->my_common_attr->intermediate_freq = int_freq / 1000;
12114 }
12115
19013747
MCC
12116 if (fe->ops.i2c_gate_ctrl)
12117 fe->ops.i2c_gate_ctrl(fe, 0);
12118 }
12119
12120 switch (p->delivery_system) {
12121 case SYS_ATSC:
12122 standard = DRX_STANDARD_8VSB;
12123 break;
12124 case SYS_DVBC_ANNEX_B:
12125 standard = DRX_STANDARD_ITU_B;
12126
12127 switch (p->modulation) {
12128 case QAM_64:
12129 constellation = DRX_CONSTELLATION_QAM64;
12130 break;
12131 case QAM_256:
12132 constellation = DRX_CONSTELLATION_QAM256;
12133 break;
12134 default:
12135 constellation = DRX_CONSTELLATION_AUTO;
12136 break;
12137 }
12138 break;
12139 default:
12140 return -EINVAL;
12141 }
c4dc6f92
MCC
12142 /* Set the standard (will be powered up if necessary */
12143 result = ctrl_set_standard(demod, &standard);
12144 if (result != 0) {
12145 pr_err("Failed to set standard! result=%02x\n",
12146 result);
12147 return -EINVAL;
19013747
MCC
12148 }
12149
12150 /* set channel parameters */
12151 channel = def_channel;
12152 channel.frequency = p->frequency / 1000;
12153 channel.bandwidth = DRX_BANDWIDTH_6MHZ;
12154 channel.constellation = constellation;
12155
12156 /* program channel */
b0baeb49 12157 result = ctrl_set_channel(demod, &channel);
19013747
MCC
12158 if (result != 0) {
12159 pr_err("Failed to set channel!\n");
12160 return -EINVAL;
12161 }
12162 /* Just for giggles, let's shut off the LNA again.... */
b601fe56 12163 drxj_set_lna_state(demod, false);
03fdfbfd
MCC
12164
12165 /* After set_frontend, except for strength, stats aren't available */
12166 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
19013747
MCC
12167
12168 return 0;
12169}
12170
12171static int drx39xxj_sleep(struct dvb_frontend *fe)
12172{
12173 /* power-down the demodulator */
12174 return drx39xxj_set_powerstate(fe, 0);
12175}
12176
12177static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
12178{
12179 struct drx39xxj_state *state = fe->demodulator_priv;
12180 struct drx_demod_instance *demod = state->demod;
12181 bool i2c_gate_state;
12182 int result;
12183
12184#ifdef DJH_DEBUG
6c955b8b 12185 pr_debug("i2c gate call: enable=%d state=%d\n", enable,
19013747
MCC
12186 state->i2c_gate_open);
12187#endif
12188
12189 if (enable)
12190 i2c_gate_state = true;
12191 else
12192 i2c_gate_state = false;
12193
12194 if (state->i2c_gate_open == enable) {
12195 /* We're already in the desired state */
12196 return 0;
12197 }
12198
b0baeb49 12199 result = ctrl_i2c_bridge(demod, &i2c_gate_state);
19013747
MCC
12200 if (result != 0) {
12201 pr_err("drx39xxj: could not open i2c gate [%d]\n",
12202 result);
12203 dump_stack();
12204 } else {
12205 state->i2c_gate_open = enable;
12206 }
12207 return 0;
12208}
12209
12210static int drx39xxj_init(struct dvb_frontend *fe)
12211{
998819d2
SK
12212 struct drx39xxj_state *state = fe->demodulator_priv;
12213 struct drx_demod_instance *demod = state->demod;
12214 int rc = 0;
19013747 12215
998819d2
SK
12216 if (fe->exit == DVB_FE_DEVICE_RESUME) {
12217 /* so drxj_open() does what it needs to do */
12218 demod->my_common_attr->is_opened = false;
12219 rc = drxj_open(demod);
12220 if (rc != 0)
12221 pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
12222 } else
12223 drx39xxj_set_powerstate(fe, 1);
12224
12225 return rc;
19013747
MCC
12226}
12227
ea8f3c2c
MCC
12228static int drx39xxj_set_lna(struct dvb_frontend *fe)
12229{
ea8f3c2c
MCC
12230 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
12231 struct drx39xxj_state *state = fe->demodulator_priv;
12232 struct drx_demod_instance *demod = state->demod;
12233 struct drxj_data *ext_attr = demod->my_ext_attr;
ea8f3c2c
MCC
12234
12235 if (c->lna) {
12236 if (!ext_attr->has_lna) {
12237 pr_err("LNA is not supported on this device!\n");
12238 return -EINVAL;
12239
12240 }
12241 }
12242
b601fe56 12243 return drxj_set_lna_state(demod, c->lna);
ea8f3c2c
MCC
12244}
12245
19013747
MCC
12246static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
12247 struct dvb_frontend_tune_settings *tune)
12248{
12249 tune->min_delay_ms = 1000;
12250 return 0;
12251}
12252
12253static void drx39xxj_release(struct dvb_frontend *fe)
12254{
12255 struct drx39xxj_state *state = fe->demodulator_priv;
12256 struct drx_demod_instance *demod = state->demod;
12257
5b22b1a4
SK
12258 /* if device is removed don't access it */
12259 if (fe->exit != DVB_FE_DEVICE_REMOVED)
12260 drxj_close(demod);
1e5ec31a 12261
19013747
MCC
12262 kfree(demod->my_ext_attr);
12263 kfree(demod->my_common_attr);
12264 kfree(demod->my_i2c_dev_addr);
9bc2dd7e 12265 release_firmware(demod->firmware);
19013747
MCC
12266 kfree(demod);
12267 kfree(state);
12268}
12269
bd336e63 12270static const struct dvb_frontend_ops drx39xxj_ops;
19013747
MCC
12271
12272struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
12273{
12274 struct drx39xxj_state *state = NULL;
19013747
MCC
12275 struct i2c_device_addr *demod_addr = NULL;
12276 struct drx_common_attr *demod_comm_attr = NULL;
12277 struct drxj_data *demod_ext_attr = NULL;
12278 struct drx_demod_instance *demod = NULL;
d591590e 12279 struct dtv_frontend_properties *p;
19013747
MCC
12280 int result;
12281
12282 /* allocate memory for the internal state */
12283 state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL);
12284 if (state == NULL)
12285 goto error;
12286
12287 demod = kmalloc(sizeof(struct drx_demod_instance), GFP_KERNEL);
12288 if (demod == NULL)
12289 goto error;
12290
20f63150
BT
12291 demod_addr = kmemdup(&drxj_default_addr_g,
12292 sizeof(struct i2c_device_addr), GFP_KERNEL);
19013747
MCC
12293 if (demod_addr == NULL)
12294 goto error;
19013747 12295
20f63150
BT
12296 demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,
12297 sizeof(struct drx_common_attr), GFP_KERNEL);
19013747
MCC
12298 if (demod_comm_attr == NULL)
12299 goto error;
19013747 12300
20f63150
BT
12301 demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),
12302 GFP_KERNEL);
19013747
MCC
12303 if (demod_ext_attr == NULL)
12304 goto error;
19013747
MCC
12305
12306 /* setup the state */
12307 state->i2c = i2c;
12308 state->demod = demod;
12309
12310 /* setup the demod data */
12311 memcpy(demod, &drxj_default_demod_g, sizeof(struct drx_demod_instance));
12312
12313 demod->my_i2c_dev_addr = demod_addr;
12314 demod->my_common_attr = demod_comm_attr;
12315 demod->my_i2c_dev_addr->user_data = state;
12316 demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;
12317 demod->my_common_attr->verify_microcode = true;
12318 demod->my_common_attr->intermediate_freq = 5000;
d7a5478a 12319 demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;
19013747
MCC
12320 demod->my_ext_attr = demod_ext_attr;
12321 ((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;
19013747
MCC
12322 demod->i2c = i2c;
12323
12324 result = drxj_open(demod);
12325 if (result != 0) {
12326 pr_err("DRX open failed! Aborting\n");
12327 goto error;
12328 }
12329
19013747
MCC
12330 /* create dvb_frontend */
12331 memcpy(&state->frontend.ops, &drx39xxj_ops,
12332 sizeof(struct dvb_frontend_ops));
12333
12334 state->frontend.demodulator_priv = state;
d591590e
MCC
12335
12336 /* Initialize stats - needed for DVBv5 stats to work */
12337 p = &state->frontend.dtv_property_cache;
12338 p->strength.len = 1;
12339 p->pre_bit_count.len = 1;
12340 p->pre_bit_error.len = 1;
12341 p->post_bit_count.len = 1;
12342 p->post_bit_error.len = 1;
12343 p->block_count.len = 1;
12344 p->block_error.len = 1;
12345 p->cnr.len = 1;
12346
12347 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12348 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12349 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12350 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12351 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12352 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12353 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12354 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12355
19013747
MCC
12356 return &state->frontend;
12357
12358error:
12359 kfree(demod_ext_attr);
12360 kfree(demod_comm_attr);
12361 kfree(demod_addr);
12362 kfree(demod);
12363 kfree(state);
12364
12365 return NULL;
12366}
12367EXPORT_SYMBOL(drx39xxj_attach);
12368
bd336e63 12369static const struct dvb_frontend_ops drx39xxj_ops = {
19013747
MCC
12370 .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
12371 .info = {
12372 .name = "Micronas DRX39xxj family Frontend",
12373 .frequency_stepsize = 62500,
12374 .frequency_min = 51000000,
12375 .frequency_max = 858000000,
12376 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
12377 },
12378
12379 .init = drx39xxj_init,
12380 .i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,
12381 .sleep = drx39xxj_sleep,
12382 .set_frontend = drx39xxj_set_frontend,
12383 .get_tune_settings = drx39xxj_get_tune_settings,
12384 .read_status = drx39xxj_read_status,
12385 .read_ber = drx39xxj_read_ber,
12386 .read_signal_strength = drx39xxj_read_signal_strength,
12387 .read_snr = drx39xxj_read_snr,
12388 .read_ucblocks = drx39xxj_read_ucblocks,
12389 .release = drx39xxj_release,
ea8f3c2c 12390 .set_lna = drx39xxj_set_lna,
19013747
MCC
12391};
12392
12393MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
12394MODULE_AUTHOR("Devin Heitmueller");
12395MODULE_LICENSE("GPL");
12396MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);