Merge tag 'csky-for-linus-4.20-fixup-dtb' of https://github.com/c-sky/csky-linux
[linux-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 63
fada1935 64#include <media/dvb_frontend.h>
19013747
MCC
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++) {
452c6446
MCC
2154 rc = drxj_dap_read_reg16(dev_addr,
2155 (DRXJ_HI_ATOMIC_BUF_START + i),
2156 &word, 0);
2157 if (rc) {
2158 pr_err("error %d\n", rc);
2159 goto rw_error;
2160 }
43a431e4
MCC
2161 data[2 * i] = (u8) (word & 0xFF);
2162 data[(2 * i) + 1] = (u8) (word >> 8);
443f18d0
MCC
2163 }
2164 }
38b2df95 2165
9482354f 2166 return 0;
38b2df95 2167
443f18d0 2168rw_error:
30741871 2169 return rc;
38b2df95
DH
2170
2171}
2172
2173/*============================================================================*/
2174
34eb9751 2175/*
57afe2f0 2176* \fn int drxj_dap_atomic_read_reg32()
38b2df95
DH
2177* \brief Atomic read of 32 bits words
2178*/
2179static
57afe2f0 2180int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
2181 u32 addr,
2182 u32 *data, u32 flags)
38b2df95 2183{
4182438e 2184 u8 buf[sizeof(*data)] = { 0 };
9482354f 2185 int rc = -EIO;
43a431e4 2186 u32 word = 0;
38b2df95 2187
63713517 2188 if (!data)
9482354f 2189 return -EINVAL;
38b2df95 2190
57afe2f0 2191 rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
63713517 2192 sizeof(*data), buf, true);
38b2df95 2193
b1d0a596
MCC
2194 if (rc < 0)
2195 return 0;
2196
43a431e4 2197 word = (u32) buf[3];
443f18d0 2198 word <<= 8;
43a431e4 2199 word |= (u32) buf[2];
443f18d0 2200 word <<= 8;
43a431e4 2201 word |= (u32) buf[1];
443f18d0 2202 word <<= 8;
43a431e4 2203 word |= (u32) buf[0];
38b2df95 2204
443f18d0 2205 *data = word;
38b2df95 2206
443f18d0 2207 return rc;
38b2df95
DH
2208}
2209
38b2df95
DH
2210/*============================================================================*/
2211
38b2df95
DH
2212/*============================================================================*/
2213/*== END DRXJ DAP FUNCTIONS ==*/
2214/*============================================================================*/
2215
2216/*============================================================================*/
2217/*============================================================================*/
2218/*== HOST INTERFACE FUNCTIONS ==*/
2219/*============================================================================*/
2220/*============================================================================*/
2221
34eb9751 2222/*
57afe2f0 2223* \fn int hi_cfg_command()
38b2df95
DH
2224* \brief Configure HI with settings stored in the demod structure.
2225* \param demod Demodulator.
61263c75 2226* \return int.
38b2df95
DH
2227*
2228* This routine was created because to much orthogonal settings have
2229* been put into one HI API function (configure). Especially the I2C bridge
2230* enable/disable should not need re-configuration of the HI.
2231*
2232*/
1bfc9e15 2233static int hi_cfg_command(const struct drx_demod_instance *demod)
38b2df95 2234{
b3ce3a83 2235 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
60d3603b 2236 struct drxj_hi_cmd hi_cmd;
43a431e4 2237 u16 result = 0;
068e94ea 2238 int rc;
38b2df95 2239
b3ce3a83 2240 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 2241
57afe2f0
MCC
2242 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2243 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2244 hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2245 hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2246 hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2247 hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2248 hi_cmd.param6 = ext_attr->hi_cfg_transmit;
38b2df95 2249
068e94ea 2250 rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
9482354f 2251 if (rc != 0) {
068e94ea
MCC
2252 pr_err("error %d\n", rc);
2253 goto rw_error;
2254 }
38b2df95 2255
443f18d0 2256 /* Reset power down flag (set one call only) */
57afe2f0 2257 ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
38b2df95 2258
9482354f 2259 return 0;
38b2df95 2260
443f18d0 2261rw_error:
30741871 2262 return rc;
38b2df95
DH
2263}
2264
34eb9751 2265/*
57afe2f0 2266* \fn int hi_command()
38b2df95 2267* \brief Configure HI with settings stored in the demod structure.
57afe2f0 2268* \param dev_addr I2C address.
38b2df95
DH
2269* \param cmd HI command.
2270* \param result HI command result.
61263c75 2271* \return int.
38b2df95
DH
2272*
2273* Sends command to HI
2274*
2275*/
61263c75 2276static int
60d3603b 2277hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
38b2df95 2278{
57afe2f0
MCC
2279 u16 wait_cmd = 0;
2280 u16 nr_retries = 0;
73f7065b 2281 bool powerdown_cmd = false;
068e94ea 2282 int rc;
38b2df95 2283
443f18d0
MCC
2284 /* Write parameters */
2285 switch (cmd->cmd) {
38b2df95 2286
443f18d0
MCC
2287 case SIO_HI_RA_RAM_CMD_CONFIG:
2288 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
244c0e06 2289 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
9482354f 2290 if (rc != 0) {
068e94ea
MCC
2291 pr_err("error %d\n", rc);
2292 goto rw_error;
2293 }
244c0e06 2294 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
9482354f 2295 if (rc != 0) {
068e94ea
MCC
2296 pr_err("error %d\n", rc);
2297 goto rw_error;
2298 }
244c0e06 2299 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
9482354f 2300 if (rc != 0) {
068e94ea
MCC
2301 pr_err("error %d\n", rc);
2302 goto rw_error;
2303 }
244c0e06 2304 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
9482354f 2305 if (rc != 0) {
068e94ea
MCC
2306 pr_err("error %d\n", rc);
2307 goto rw_error;
2308 }
443f18d0
MCC
2309 /* fallthrough */
2310 case SIO_HI_RA_RAM_CMD_BRDCTRL:
244c0e06 2311 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
9482354f 2312 if (rc != 0) {
068e94ea
MCC
2313 pr_err("error %d\n", rc);
2314 goto rw_error;
2315 }
244c0e06 2316 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
9482354f 2317 if (rc != 0) {
068e94ea
MCC
2318 pr_err("error %d\n", rc);
2319 goto rw_error;
2320 }
443f18d0
MCC
2321 /* fallthrough */
2322 case SIO_HI_RA_RAM_CMD_NULL:
2323 /* No parameters */
2324 break;
38b2df95 2325
443f18d0 2326 default:
9482354f 2327 return -EINVAL;
443f18d0
MCC
2328 break;
2329 }
2330
2331 /* Write command */
244c0e06 2332 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
9482354f 2333 if (rc != 0) {
068e94ea
MCC
2334 pr_err("error %d\n", rc);
2335 goto rw_error;
2336 }
443f18d0 2337
63713517 2338 if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
d7b0631e 2339 msleep(1);
38b2df95 2340
443f18d0 2341 /* Detect power down to ommit reading result */
73f7065b 2342 powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
443f18d0
MCC
2343 (((cmd->
2344 param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2345 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
259f380e 2346 if (!powerdown_cmd) {
443f18d0
MCC
2347 /* Wait until command rdy */
2348 do {
57afe2f0
MCC
2349 nr_retries++;
2350 if (nr_retries > DRXJ_MAX_RETRIES) {
63713517 2351 pr_err("timeout\n");
443f18d0 2352 goto rw_error;
259f380e 2353 }
443f18d0 2354
244c0e06 2355 rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
9482354f 2356 if (rc != 0) {
068e94ea
MCC
2357 pr_err("error %d\n", rc);
2358 goto rw_error;
2359 }
57afe2f0 2360 } while (wait_cmd != 0);
443f18d0
MCC
2361
2362 /* Read result */
244c0e06 2363 rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
9482354f 2364 if (rc != 0) {
068e94ea
MCC
2365 pr_err("error %d\n", rc);
2366 goto rw_error;
2367 }
443f18d0
MCC
2368
2369 }
73f7065b 2370 /* if ( powerdown_cmd == true ) */
9482354f 2371 return 0;
38b2df95 2372rw_error:
30741871 2373 return rc;
38b2df95
DH
2374}
2375
34eb9751 2376/*
1bfc9e15 2377* \fn int init_hi( const struct drx_demod_instance *demod )
38b2df95
DH
2378* \brief Initialise and configurate HI.
2379* \param demod pointer to demod data.
61263c75 2380* \return int Return status.
9482354f
MCC
2381* \retval 0 Success.
2382* \retval -EIO Failure.
38b2df95
DH
2383*
2384* Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2385* Need to store configuration in driver because of the way I2C
2386* bridging is controlled.
2387*
2388*/
1bfc9e15 2389static int init_hi(const struct drx_demod_instance *demod)
38b2df95 2390{
b3ce3a83 2391 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
1bfc9e15 2392 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
22892268 2393 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
068e94ea 2394 int rc;
443f18d0 2395
b3ce3a83 2396 ext_attr = (struct drxj_data *) demod->my_ext_attr;
1bfc9e15 2397 common_attr = (struct drx_common_attr *) demod->my_common_attr;
57afe2f0 2398 dev_addr = demod->my_i2c_dev_addr;
443f18d0
MCC
2399
2400 /* PATCH for bug 5003, HI ucode v3.1.0 */
244c0e06 2401 rc = drxj_dap_write_reg16(dev_addr, 0x4301D7, 0x801, 0);
9482354f 2402 if (rc != 0) {
068e94ea
MCC
2403 pr_err("error %d\n", rc);
2404 goto rw_error;
2405 }
38b2df95 2406
443f18d0
MCC
2407 /* Timing div, 250ns/Psys */
2408 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
57afe2f0
MCC
2409 ext_attr->hi_cfg_timing_div =
2410 (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
443f18d0 2411 /* Clipping */
63713517 2412 if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
57afe2f0 2413 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
443f18d0
MCC
2414 /* Bridge delay, uses oscilator clock */
2415 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2416 /* SDA brdige delay */
57afe2f0
MCC
2417 ext_attr->hi_cfg_bridge_delay =
2418 (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
443f18d0
MCC
2419 1000;
2420 /* Clipping */
63713517 2421 if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
57afe2f0 2422 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
443f18d0 2423 /* SCL bridge delay, same as SDA for now */
57afe2f0 2424 ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
443f18d0
MCC
2425 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2426 /* Wakeup key, setting the read flag (as suggest in the documentation) does
2427 not always result into a working solution (barebones worked VI2C failed).
2428 Not setting the bit works in all cases . */
57afe2f0 2429 ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
443f18d0 2430 /* port/bridge/power down ctrl */
57afe2f0 2431 ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
443f18d0 2432 /* transit mode time out delay and watch dog divider */
57afe2f0 2433 ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
443f18d0 2434
068e94ea 2435 rc = hi_cfg_command(demod);
9482354f 2436 if (rc != 0) {
068e94ea
MCC
2437 pr_err("error %d\n", rc);
2438 goto rw_error;
2439 }
443f18d0 2440
9482354f 2441 return 0;
443f18d0
MCC
2442
2443rw_error:
30741871 2444 return rc;
443f18d0 2445}
38b2df95
DH
2446
2447/*============================================================================*/
2448/*== END HOST INTERFACE FUNCTIONS ==*/
2449/*============================================================================*/
2450
2451/*============================================================================*/
2452/*============================================================================*/
2453/*== AUXILIARY FUNCTIONS ==*/
2454/*============================================================================*/
2455/*============================================================================*/
2456
34eb9751 2457/*
57afe2f0 2458* \fn int get_device_capabilities()
38b2df95
DH
2459* \brief Get and store device capabilities.
2460* \param demod Pointer to demodulator instance.
61263c75 2461* \return int.
9482354f
MCC
2462* \return 0 Success
2463* \retval -EIO Failure
38b2df95
DH
2464*
2465* Depending on pulldowns on MDx pins the following internals are set:
57afe2f0
MCC
2466* * common_attr->osc_clock_freq
2467* * ext_attr->has_lna
2468* * ext_attr->has_ntsc
2469* * ext_attr->has_btsc
2470* * ext_attr->has_oob
38b2df95
DH
2471*
2472*/
1bfc9e15 2473static int get_device_capabilities(struct drx_demod_instance *demod)
38b2df95 2474{
1bfc9e15 2475 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
b3ce3a83 2476 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
22892268 2477 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
57afe2f0
MCC
2478 u16 sio_pdr_ohw_cfg = 0;
2479 u32 sio_top_jtagid_lo = 0;
43a431e4 2480 u16 bid = 0;
068e94ea 2481 int rc;
443f18d0 2482
1bfc9e15 2483 common_attr = (struct drx_common_attr *) demod->my_common_attr;
b3ce3a83 2484 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0 2485 dev_addr = demod->my_i2c_dev_addr;
443f18d0 2486
244c0e06 2487 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 2488 if (rc != 0) {
068e94ea
MCC
2489 pr_err("error %d\n", rc);
2490 goto rw_error;
2491 }
244c0e06 2492 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
9482354f 2493 if (rc != 0) {
068e94ea
MCC
2494 pr_err("error %d\n", rc);
2495 goto rw_error;
2496 }
244c0e06 2497 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
9482354f 2498 if (rc != 0) {
068e94ea
MCC
2499 pr_err("error %d\n", rc);
2500 goto rw_error;
2501 }
443f18d0 2502
57afe2f0 2503 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
443f18d0
MCC
2504 case 0:
2505 /* ignore (bypass ?) */
2506 break;
2507 case 1:
2508 /* 27 MHz */
57afe2f0 2509 common_attr->osc_clock_freq = 27000;
443f18d0
MCC
2510 break;
2511 case 2:
2512 /* 20.25 MHz */
57afe2f0 2513 common_attr->osc_clock_freq = 20250;
443f18d0
MCC
2514 break;
2515 case 3:
2516 /* 4 MHz */
57afe2f0 2517 common_attr->osc_clock_freq = 4000;
443f18d0
MCC
2518 break;
2519 default:
9482354f 2520 return -EIO;
443f18d0
MCC
2521 }
2522
2523 /*
2524 Determine device capabilities
2525 Based on pinning v47
2526 */
244c0e06 2527 rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
9482354f 2528 if (rc != 0) {
068e94ea
MCC
2529 pr_err("error %d\n", rc);
2530 goto rw_error;
2531 }
57afe2f0 2532 ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
443f18d0 2533
57afe2f0 2534 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
443f18d0 2535 case 0x31:
244c0e06 2536 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 2537 if (rc != 0) {
068e94ea
MCC
2538 pr_err("error %d\n", rc);
2539 goto rw_error;
2540 }
244c0e06 2541 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
9482354f 2542 if (rc != 0) {
068e94ea
MCC
2543 pr_err("error %d\n", rc);
2544 goto rw_error;
2545 }
443f18d0 2546 bid = (bid >> 10) & 0xf;
244c0e06 2547 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
9482354f 2548 if (rc != 0) {
068e94ea
MCC
2549 pr_err("error %d\n", rc);
2550 goto rw_error;
2551 }
443f18d0 2552
57afe2f0
MCC
2553 ext_attr->has_lna = true;
2554 ext_attr->has_ntsc = false;
2555 ext_attr->has_btsc = false;
2556 ext_attr->has_oob = false;
2557 ext_attr->has_smatx = true;
2558 ext_attr->has_smarx = false;
2559 ext_attr->has_gpio = false;
2560 ext_attr->has_irqn = false;
443f18d0
MCC
2561 break;
2562 case 0x33:
57afe2f0
MCC
2563 ext_attr->has_lna = false;
2564 ext_attr->has_ntsc = false;
2565 ext_attr->has_btsc = false;
2566 ext_attr->has_oob = false;
2567 ext_attr->has_smatx = true;
2568 ext_attr->has_smarx = false;
2569 ext_attr->has_gpio = false;
2570 ext_attr->has_irqn = false;
443f18d0
MCC
2571 break;
2572 case 0x45:
57afe2f0
MCC
2573 ext_attr->has_lna = true;
2574 ext_attr->has_ntsc = true;
2575 ext_attr->has_btsc = false;
2576 ext_attr->has_oob = false;
2577 ext_attr->has_smatx = true;
2578 ext_attr->has_smarx = true;
2579 ext_attr->has_gpio = true;
2580 ext_attr->has_irqn = false;
443f18d0
MCC
2581 break;
2582 case 0x46:
57afe2f0
MCC
2583 ext_attr->has_lna = false;
2584 ext_attr->has_ntsc = true;
2585 ext_attr->has_btsc = false;
2586 ext_attr->has_oob = false;
2587 ext_attr->has_smatx = true;
2588 ext_attr->has_smarx = true;
2589 ext_attr->has_gpio = true;
2590 ext_attr->has_irqn = false;
443f18d0
MCC
2591 break;
2592 case 0x41:
57afe2f0
MCC
2593 ext_attr->has_lna = true;
2594 ext_attr->has_ntsc = true;
2595 ext_attr->has_btsc = true;
2596 ext_attr->has_oob = false;
2597 ext_attr->has_smatx = true;
2598 ext_attr->has_smarx = true;
2599 ext_attr->has_gpio = true;
2600 ext_attr->has_irqn = false;
443f18d0
MCC
2601 break;
2602 case 0x43:
57afe2f0
MCC
2603 ext_attr->has_lna = false;
2604 ext_attr->has_ntsc = true;
2605 ext_attr->has_btsc = true;
2606 ext_attr->has_oob = false;
2607 ext_attr->has_smatx = true;
2608 ext_attr->has_smarx = true;
2609 ext_attr->has_gpio = true;
2610 ext_attr->has_irqn = false;
443f18d0
MCC
2611 break;
2612 case 0x32:
57afe2f0
MCC
2613 ext_attr->has_lna = true;
2614 ext_attr->has_ntsc = false;
2615 ext_attr->has_btsc = false;
2616 ext_attr->has_oob = true;
2617 ext_attr->has_smatx = true;
2618 ext_attr->has_smarx = true;
2619 ext_attr->has_gpio = true;
2620 ext_attr->has_irqn = true;
443f18d0
MCC
2621 break;
2622 case 0x34:
57afe2f0
MCC
2623 ext_attr->has_lna = false;
2624 ext_attr->has_ntsc = true;
2625 ext_attr->has_btsc = true;
2626 ext_attr->has_oob = true;
2627 ext_attr->has_smatx = true;
2628 ext_attr->has_smarx = true;
2629 ext_attr->has_gpio = true;
2630 ext_attr->has_irqn = true;
443f18d0
MCC
2631 break;
2632 case 0x42:
57afe2f0
MCC
2633 ext_attr->has_lna = true;
2634 ext_attr->has_ntsc = true;
2635 ext_attr->has_btsc = true;
2636 ext_attr->has_oob = true;
2637 ext_attr->has_smatx = true;
2638 ext_attr->has_smarx = true;
2639 ext_attr->has_gpio = true;
2640 ext_attr->has_irqn = true;
443f18d0
MCC
2641 break;
2642 case 0x44:
57afe2f0
MCC
2643 ext_attr->has_lna = false;
2644 ext_attr->has_ntsc = true;
2645 ext_attr->has_btsc = true;
2646 ext_attr->has_oob = true;
2647 ext_attr->has_smatx = true;
2648 ext_attr->has_smarx = true;
2649 ext_attr->has_gpio = true;
2650 ext_attr->has_irqn = true;
443f18d0
MCC
2651 break;
2652 default:
2653 /* Unknown device variant */
9482354f 2654 return -EIO;
443f18d0
MCC
2655 break;
2656 }
2657
9482354f 2658 return 0;
38b2df95 2659rw_error:
30741871 2660 return rc;
38b2df95
DH
2661}
2662
34eb9751 2663/*
57afe2f0 2664* \fn int power_up_device()
38b2df95
DH
2665* \brief Power up device.
2666* \param demod Pointer to demodulator instance.
61263c75 2667* \return int.
9482354f
MCC
2668* \return 0 Success
2669* \retval -EIO Failure, I2C or max retries reached
38b2df95
DH
2670*
2671*/
2672
2673#ifndef DRXJ_MAX_RETRIES_POWERUP
2674#define DRXJ_MAX_RETRIES_POWERUP 10
2675#endif
2676
1bfc9e15 2677static int power_up_device(struct drx_demod_instance *demod)
443f18d0 2678{
22892268 2679 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
43a431e4 2680 u8 data = 0;
57afe2f0
MCC
2681 u16 retry_count = 0;
2682 struct i2c_device_addr wake_up_addr;
443f18d0 2683
57afe2f0
MCC
2684 dev_addr = demod->my_i2c_dev_addr;
2685 wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2686 wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2687 wake_up_addr.user_data = dev_addr->user_data;
068e94ea
MCC
2688 /*
2689 * I2C access may fail in this case: no ack
2690 * dummy write must be used to wake uop device, dummy read must be used to
2691 * reset HI state machine (avoiding actual writes)
2692 */
443f18d0
MCC
2693 do {
2694 data = 0;
57afe2f0 2695 drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
22892268
MCC
2696 (struct i2c_device_addr *)(NULL), 0,
2697 (u8 *)(NULL));
d7b0631e 2698 msleep(10);
57afe2f0
MCC
2699 retry_count++;
2700 } while ((drxbsp_i2c_write_read
22892268 2701 ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
443f18d0 2702 &data)
9482354f 2703 != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
443f18d0
MCC
2704
2705 /* Need some recovery time .... */
d7b0631e 2706 msleep(10);
443f18d0 2707
63713517 2708 if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
9482354f 2709 return -EIO;
38b2df95 2710
9482354f 2711 return 0;
38b2df95
DH
2712}
2713
2714/*----------------------------------------------------------------------------*/
2715/* MPEG Output Configuration Functions - begin */
2716/*----------------------------------------------------------------------------*/
34eb9751 2717/*
57afe2f0 2718* \fn int ctrl_set_cfg_mpeg_output()
38b2df95
DH
2719* \brief Set MPEG output configuration of the device.
2720* \param devmod Pointer to demodulator instance.
57afe2f0 2721* \param cfg_data Pointer to mpeg output configuaration.
61263c75 2722* \return int.
38b2df95
DH
2723*
2724* Configure MPEG output parameters.
2725*
2726*/
61263c75 2727static int
1bfc9e15 2728ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
57afe2f0 2729{
22892268 2730 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
b3ce3a83 2731 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
1bfc9e15 2732 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
068e94ea 2733 int rc;
57afe2f0
MCC
2734 u16 fec_oc_reg_mode = 0;
2735 u16 fec_oc_reg_ipr_mode = 0;
2736 u16 fec_oc_reg_ipr_invert = 0;
2737 u32 max_bit_rate = 0;
2738 u32 rcn_rate = 0;
2739 u32 nr_bits = 0;
2740 u16 sio_pdr_md_cfg = 0;
443f18d0 2741 /* data mask for the output data byte */
57afe2f0 2742 u16 invert_data_mask =
443f18d0
MCC
2743 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2744 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2745 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2746 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
068e94ea 2747
443f18d0 2748 /* check arguments */
63713517 2749 if ((demod == NULL) || (cfg_data == NULL))
9482354f 2750 return -EINVAL;
38b2df95 2751
57afe2f0 2752 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 2753 ext_attr = (struct drxj_data *) demod->my_ext_attr;
1bfc9e15 2754 common_attr = (struct drx_common_attr *) demod->my_common_attr;
443f18d0 2755
57afe2f0 2756 if (cfg_data->enable_mpeg_output == true) {
443f18d0
MCC
2757 /* quick and dirty patch to set MPEG incase current std is not
2758 producing MPEG */
57afe2f0 2759 switch (ext_attr->standard) {
443f18d0
MCC
2760 case DRX_STANDARD_8VSB:
2761 case DRX_STANDARD_ITU_A:
2762 case DRX_STANDARD_ITU_B:
2763 case DRX_STANDARD_ITU_C:
2764 break;
2765 default:
9482354f 2766 return 0;
443f18d0
MCC
2767 }
2768
244c0e06 2769 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
9482354f 2770 if (rc != 0) {
068e94ea
MCC
2771 pr_err("error %d\n", rc);
2772 goto rw_error;
2773 }
57afe2f0 2774 switch (ext_attr->standard) {
443f18d0 2775 case DRX_STANDARD_8VSB:
244c0e06 2776 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
9482354f 2777 if (rc != 0) {
068e94ea
MCC
2778 pr_err("error %d\n", rc);
2779 goto rw_error;
2780 } /* 2048 bytes fifo ram */
244c0e06 2781 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
9482354f 2782 if (rc != 0) {
068e94ea
MCC
2783 pr_err("error %d\n", rc);
2784 goto rw_error;
2785 }
244c0e06 2786 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
9482354f 2787 if (rc != 0) {
068e94ea
MCC
2788 pr_err("error %d\n", rc);
2789 goto rw_error;
2790 }
244c0e06 2791 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
9482354f 2792 if (rc != 0) {
068e94ea
MCC
2793 pr_err("error %d\n", rc);
2794 goto rw_error;
2795 }
244c0e06 2796 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
9482354f 2797 if (rc != 0) {
068e94ea
MCC
2798 pr_err("error %d\n", rc);
2799 goto rw_error;
2800 }
244c0e06 2801 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
9482354f 2802 if (rc != 0) {
068e94ea
MCC
2803 pr_err("error %d\n", rc);
2804 goto rw_error;
2805 }
443f18d0 2806 /* Low Water Mark for synchronization */
244c0e06 2807 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
9482354f 2808 if (rc != 0) {
068e94ea
MCC
2809 pr_err("error %d\n", rc);
2810 goto rw_error;
2811 }
443f18d0 2812 /* High Water Mark for synchronization */
244c0e06 2813 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
9482354f 2814 if (rc != 0) {
068e94ea
MCC
2815 pr_err("error %d\n", rc);
2816 goto rw_error;
2817 }
443f18d0
MCC
2818 break;
2819 case DRX_STANDARD_ITU_A:
2820 case DRX_STANDARD_ITU_C:
57afe2f0 2821 switch (ext_attr->constellation) {
443f18d0 2822 case DRX_CONSTELLATION_QAM256:
57afe2f0 2823 nr_bits = 8;
443f18d0
MCC
2824 break;
2825 case DRX_CONSTELLATION_QAM128:
57afe2f0 2826 nr_bits = 7;
443f18d0
MCC
2827 break;
2828 case DRX_CONSTELLATION_QAM64:
57afe2f0 2829 nr_bits = 6;
443f18d0
MCC
2830 break;
2831 case DRX_CONSTELLATION_QAM32:
57afe2f0 2832 nr_bits = 5;
443f18d0
MCC
2833 break;
2834 case DRX_CONSTELLATION_QAM16:
57afe2f0 2835 nr_bits = 4;
443f18d0
MCC
2836 break;
2837 default:
9482354f 2838 return -EIO;
57afe2f0
MCC
2839 } /* ext_attr->constellation */
2840 /* max_bit_rate = symbol_rate * nr_bits * coef */
443f18d0 2841 /* coef = 188/204 */
57afe2f0
MCC
2842 max_bit_rate =
2843 (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
40e43111 2844 /* fall-through - as b/c Annex A/C need following settings */
443f18d0 2845 case DRX_STANDARD_ITU_B:
244c0e06 2846 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
9482354f 2847 if (rc != 0) {
068e94ea
MCC
2848 pr_err("error %d\n", rc);
2849 goto rw_error;
2850 }
244c0e06 2851 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
9482354f 2852 if (rc != 0) {
068e94ea
MCC
2853 pr_err("error %d\n", rc);
2854 goto rw_error;
2855 }
244c0e06 2856 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
9482354f 2857 if (rc != 0) {
068e94ea
MCC
2858 pr_err("error %d\n", rc);
2859 goto rw_error;
2860 }
244c0e06 2861 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
9482354f 2862 if (rc != 0) {
068e94ea
MCC
2863 pr_err("error %d\n", rc);
2864 goto rw_error;
2865 }
244c0e06 2866 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
9482354f 2867 if (rc != 0) {
068e94ea
MCC
2868 pr_err("error %d\n", rc);
2869 goto rw_error;
2870 }
57afe2f0 2871 if (cfg_data->static_clk == true) {
244c0e06 2872 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
9482354f 2873 if (rc != 0) {
068e94ea
MCC
2874 pr_err("error %d\n", rc);
2875 goto rw_error;
2876 }
443f18d0 2877 } else {
244c0e06 2878 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
9482354f 2879 if (rc != 0) {
068e94ea
MCC
2880 pr_err("error %d\n", rc);
2881 goto rw_error;
2882 }
2883 }
244c0e06 2884 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
9482354f 2885 if (rc != 0) {
068e94ea
MCC
2886 pr_err("error %d\n", rc);
2887 goto rw_error;
2888 }
244c0e06 2889 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
9482354f 2890 if (rc != 0) {
068e94ea
MCC
2891 pr_err("error %d\n", rc);
2892 goto rw_error;
443f18d0 2893 }
443f18d0
MCC
2894 break;
2895 default:
2896 break;
2897 } /* swtich (standard) */
2898
2899 /* Check insertion of the Reed-Solomon parity bytes */
244c0e06 2900 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
9482354f 2901 if (rc != 0) {
068e94ea
MCC
2902 pr_err("error %d\n", rc);
2903 goto rw_error;
2904 }
244c0e06 2905 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
9482354f 2906 if (rc != 0) {
068e94ea
MCC
2907 pr_err("error %d\n", rc);
2908 goto rw_error;
2909 }
57afe2f0 2910 if (cfg_data->insert_rs_byte == true) {
443f18d0 2911 /* enable parity symbol forward */
57afe2f0 2912 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
443f18d0 2913 /* MVAL disable during parity bytes */
57afe2f0
MCC
2914 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2915 switch (ext_attr->standard) {
443f18d0 2916 case DRX_STANDARD_8VSB:
57afe2f0 2917 rcn_rate = 0x004854D3;
443f18d0
MCC
2918 break;
2919 case DRX_STANDARD_ITU_B:
57afe2f0
MCC
2920 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2921 switch (ext_attr->constellation) {
443f18d0 2922 case DRX_CONSTELLATION_QAM256:
57afe2f0 2923 rcn_rate = 0x008945E7;
443f18d0
MCC
2924 break;
2925 case DRX_CONSTELLATION_QAM64:
57afe2f0 2926 rcn_rate = 0x005F64D4;
443f18d0
MCC
2927 break;
2928 default:
9482354f 2929 return -EIO;
443f18d0
MCC
2930 }
2931 break;
2932 case DRX_STANDARD_ITU_A:
2933 case DRX_STANDARD_ITU_C:
57afe2f0
MCC
2934 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2935 rcn_rate =
2936 (frac28
2937 (max_bit_rate,
2938 (u32) (common_attr->sys_clock_freq / 8))) /
443f18d0
MCC
2939 188;
2940 break;
2941 default:
9482354f 2942 return -EIO;
57afe2f0
MCC
2943 } /* ext_attr->standard */
2944 } else { /* insert_rs_byte == false */
443f18d0
MCC
2945
2946 /* disable parity symbol forward */
57afe2f0 2947 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
443f18d0 2948 /* MVAL enable during parity bytes */
57afe2f0
MCC
2949 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2950 switch (ext_attr->standard) {
443f18d0 2951 case DRX_STANDARD_8VSB:
57afe2f0 2952 rcn_rate = 0x0041605C;
443f18d0
MCC
2953 break;
2954 case DRX_STANDARD_ITU_B:
57afe2f0
MCC
2955 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2956 switch (ext_attr->constellation) {
443f18d0 2957 case DRX_CONSTELLATION_QAM256:
57afe2f0 2958 rcn_rate = 0x0082D6A0;
443f18d0
MCC
2959 break;
2960 case DRX_CONSTELLATION_QAM64:
57afe2f0 2961 rcn_rate = 0x005AEC1A;
443f18d0
MCC
2962 break;
2963 default:
9482354f 2964 return -EIO;
443f18d0
MCC
2965 }
2966 break;
2967 case DRX_STANDARD_ITU_A:
2968 case DRX_STANDARD_ITU_C:
57afe2f0
MCC
2969 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2970 rcn_rate =
2971 (frac28
2972 (max_bit_rate,
2973 (u32) (common_attr->sys_clock_freq / 8))) /
443f18d0
MCC
2974 204;
2975 break;
2976 default:
9482354f 2977 return -EIO;
57afe2f0 2978 } /* ext_attr->standard */
443f18d0
MCC
2979 }
2980
69bb7ab6 2981 if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> clear ipr_mode[0] */
57afe2f0 2982 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
443f18d0 2983 } else { /* MPEG data output is serial -> set ipr_mode[0] */
57afe2f0 2984 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
443f18d0
MCC
2985 }
2986
2987 /* Control slective inversion of output bits */
63713517 2988 if (cfg_data->invert_data == true)
57afe2f0 2989 fec_oc_reg_ipr_invert |= invert_data_mask;
63713517 2990 else
57afe2f0 2991 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
443f18d0 2992
63713517 2993 if (cfg_data->invert_err == true)
57afe2f0 2994 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
63713517 2995 else
57afe2f0 2996 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
443f18d0 2997
63713517 2998 if (cfg_data->invert_str == true)
57afe2f0 2999 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
63713517 3000 else
57afe2f0 3001 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
443f18d0 3002
63713517 3003 if (cfg_data->invert_val == true)
57afe2f0 3004 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
63713517 3005 else
57afe2f0 3006 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
443f18d0 3007
63713517 3008 if (cfg_data->invert_clk == true)
57afe2f0 3009 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
63713517 3010 else
57afe2f0 3011 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
443f18d0 3012
41b5cc0c 3013
57afe2f0
MCC
3014 if (cfg_data->static_clk == true) { /* Static mode */
3015 u32 dto_rate = 0;
3016 u32 bit_rate = 0;
3017 u16 fec_oc_dto_burst_len = 0;
3018 u16 fec_oc_dto_period = 0;
443f18d0 3019
57afe2f0 3020 fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
443f18d0 3021
57afe2f0 3022 switch (ext_attr->standard) {
443f18d0 3023 case DRX_STANDARD_8VSB:
57afe2f0 3024 fec_oc_dto_period = 4;
63713517 3025 if (cfg_data->insert_rs_byte == true)
57afe2f0 3026 fec_oc_dto_burst_len = 208;
443f18d0
MCC
3027 break;
3028 case DRX_STANDARD_ITU_A:
3029 {
57afe2f0
MCC
3030 u32 symbol_rate_th = 6400000;
3031 if (cfg_data->insert_rs_byte == true) {
3032 fec_oc_dto_burst_len = 204;
3033 symbol_rate_th = 5900000;
443f18d0 3034 }
57afe2f0
MCC
3035 if (ext_attr->curr_symbol_rate >=
3036 symbol_rate_th) {
3037 fec_oc_dto_period = 0;
443f18d0 3038 } else {
57afe2f0 3039 fec_oc_dto_period = 1;
443f18d0
MCC
3040 }
3041 }
3042 break;
3043 case DRX_STANDARD_ITU_B:
57afe2f0 3044 fec_oc_dto_period = 1;
63713517 3045 if (cfg_data->insert_rs_byte == true)
57afe2f0 3046 fec_oc_dto_burst_len = 128;
443f18d0
MCC
3047 break;
3048 case DRX_STANDARD_ITU_C:
57afe2f0 3049 fec_oc_dto_period = 1;
63713517 3050 if (cfg_data->insert_rs_byte == true)
57afe2f0 3051 fec_oc_dto_burst_len = 204;
443f18d0
MCC
3052 break;
3053 default:
9482354f 3054 return -EIO;
443f18d0 3055 }
57afe2f0
MCC
3056 bit_rate =
3057 common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
443f18d0 3058 2);
57afe2f0
MCC
3059 dto_rate =
3060 frac28(bit_rate, common_attr->sys_clock_freq * 1000);
3061 dto_rate >>= 3;
244c0e06 3062 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 3063 if (rc != 0) {
068e94ea
MCC
3064 pr_err("error %d\n", rc);
3065 goto rw_error;
3066 }
244c0e06 3067 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 3068 if (rc != 0) {
068e94ea
MCC
3069 pr_err("error %d\n", rc);
3070 goto rw_error;
3071 }
244c0e06 3072 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 3073 if (rc != 0) {
068e94ea
MCC
3074 pr_err("error %d\n", rc);
3075 goto rw_error;
3076 }
244c0e06 3077 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 3078 if (rc != 0) {
068e94ea
MCC
3079 pr_err("error %d\n", rc);
3080 goto rw_error;
3081 }
244c0e06 3082 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
9482354f 3083 if (rc != 0) {
068e94ea
MCC
3084 pr_err("error %d\n", rc);
3085 goto rw_error;
3086 }
63713517
MCC
3087 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3088 fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
244c0e06 3089 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
9482354f 3090 if (rc != 0) {
068e94ea
MCC
3091 pr_err("error %d\n", rc);
3092 goto rw_error;
3093 }
443f18d0
MCC
3094 } else { /* Dynamic mode */
3095
244c0e06 3096 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
9482354f 3097 if (rc != 0) {
068e94ea
MCC
3098 pr_err("error %d\n", rc);
3099 goto rw_error;
3100 }
244c0e06 3101 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
9482354f 3102 if (rc != 0) {
068e94ea
MCC
3103 pr_err("error %d\n", rc);
3104 goto rw_error;
3105 }
443f18d0
MCC
3106 }
3107
244c0e06 3108 rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
9482354f 3109 if (rc != 0) {
068e94ea
MCC
3110 pr_err("error %d\n", rc);
3111 goto rw_error;
3112 }
443f18d0
MCC
3113
3114 /* Write appropriate registers with requested configuration */
244c0e06 3115 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
9482354f 3116 if (rc != 0) {
068e94ea
MCC
3117 pr_err("error %d\n", rc);
3118 goto rw_error;
3119 }
244c0e06 3120 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
9482354f 3121 if (rc != 0) {
068e94ea
MCC
3122 pr_err("error %d\n", rc);
3123 goto rw_error;
3124 }
244c0e06 3125 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
9482354f 3126 if (rc != 0) {
068e94ea
MCC
3127 pr_err("error %d\n", rc);
3128 goto rw_error;
3129 }
443f18d0
MCC
3130
3131 /* enabling for both parallel and serial now */
3132 /* Write magic word to enable pdr reg write */
244c0e06 3133 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
9482354f 3134 if (rc != 0) {
068e94ea
MCC
3135 pr_err("error %d\n", rc);
3136 goto rw_error;
3137 }
443f18d0 3138 /* Set MPEG TS pads to outputmode */
244c0e06 3139 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
9482354f 3140 if (rc != 0) {
068e94ea
MCC
3141 pr_err("error %d\n", rc);
3142 goto rw_error;
3143 }
244c0e06 3144 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
9482354f 3145 if (rc != 0) {
068e94ea
MCC
3146 pr_err("error %d\n", rc);
3147 goto rw_error;
3148 }
244c0e06 3149 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 3150 if (rc != 0) {
068e94ea
MCC
3151 pr_err("error %d\n", rc);
3152 goto rw_error;
3153 }
244c0e06 3154 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
9482354f 3155 if (rc != 0) {
068e94ea
MCC
3156 pr_err("error %d\n", rc);
3157 goto rw_error;
3158 }
57afe2f0 3159 sio_pdr_md_cfg =
443f18d0
MCC
3160 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3161 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
244c0e06 3162 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3163 if (rc != 0) {
068e94ea
MCC
3164 pr_err("error %d\n", rc);
3165 goto rw_error;
3166 }
69bb7ab6 3167 if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> set MD1 to MD7 to output mode */
57afe2f0 3168 sio_pdr_md_cfg =
443f18d0
MCC
3169 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3170 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3171 SIO_PDR_MD0_CFG_MODE__B;
244c0e06 3172 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3173 if (rc != 0) {
068e94ea
MCC
3174 pr_err("error %d\n", rc);
3175 goto rw_error;
3176 }
244c0e06 3177 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3178 if (rc != 0) {
068e94ea
MCC
3179 pr_err("error %d\n", rc);
3180 goto rw_error;
3181 }
244c0e06 3182 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3183 if (rc != 0) {
068e94ea
MCC
3184 pr_err("error %d\n", rc);
3185 goto rw_error;
3186 }
244c0e06 3187 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3188 if (rc != 0) {
068e94ea
MCC
3189 pr_err("error %d\n", rc);
3190 goto rw_error;
3191 }
244c0e06 3192 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3193 if (rc != 0) {
068e94ea
MCC
3194 pr_err("error %d\n", rc);
3195 goto rw_error;
3196 }
244c0e06 3197 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3198 if (rc != 0) {
068e94ea
MCC
3199 pr_err("error %d\n", rc);
3200 goto rw_error;
3201 }
244c0e06 3202 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3203 if (rc != 0) {
068e94ea
MCC
3204 pr_err("error %d\n", rc);
3205 goto rw_error;
3206 }
244c0e06 3207 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
9482354f 3208 if (rc != 0) {
068e94ea
MCC
3209 pr_err("error %d\n", rc);
3210 goto rw_error;
3211 }
443f18d0 3212 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
244c0e06 3213 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
9482354f 3214 if (rc != 0) {
068e94ea
MCC
3215 pr_err("error %d\n", rc);
3216 goto rw_error;
3217 }
244c0e06 3218 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
9482354f 3219 if (rc != 0) {
068e94ea
MCC
3220 pr_err("error %d\n", rc);
3221 goto rw_error;
3222 }
244c0e06 3223 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
9482354f 3224 if (rc != 0) {
068e94ea
MCC
3225 pr_err("error %d\n", rc);
3226 goto rw_error;
3227 }
244c0e06 3228 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
9482354f 3229 if (rc != 0) {
068e94ea
MCC
3230 pr_err("error %d\n", rc);
3231 goto rw_error;
3232 }
244c0e06 3233 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
9482354f 3234 if (rc != 0) {
068e94ea
MCC
3235 pr_err("error %d\n", rc);
3236 goto rw_error;
3237 }
244c0e06 3238 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
9482354f 3239 if (rc != 0) {
068e94ea
MCC
3240 pr_err("error %d\n", rc);
3241 goto rw_error;
3242 }
244c0e06 3243 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
9482354f 3244 if (rc != 0) {
068e94ea
MCC
3245 pr_err("error %d\n", rc);
3246 goto rw_error;
3247 }
443f18d0
MCC
3248 }
3249 /* Enable Monitor Bus output over MPEG pads and ctl input */
244c0e06 3250 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
9482354f 3251 if (rc != 0) {
068e94ea
MCC
3252 pr_err("error %d\n", rc);
3253 goto rw_error;
3254 }
443f18d0 3255 /* Write nomagic word to enable pdr reg write */
244c0e06 3256 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3257 if (rc != 0) {
068e94ea
MCC
3258 pr_err("error %d\n", rc);
3259 goto rw_error;
3260 }
443f18d0
MCC
3261 } else {
3262 /* Write magic word to enable pdr reg write */
244c0e06 3263 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
9482354f 3264 if (rc != 0) {
068e94ea
MCC
3265 pr_err("error %d\n", rc);
3266 goto rw_error;
3267 }
443f18d0 3268 /* Set MPEG TS pads to inputmode */
244c0e06 3269 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
9482354f 3270 if (rc != 0) {
068e94ea
MCC
3271 pr_err("error %d\n", rc);
3272 goto rw_error;
3273 }
244c0e06 3274 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
9482354f 3275 if (rc != 0) {
068e94ea
MCC
3276 pr_err("error %d\n", rc);
3277 goto rw_error;
3278 }
244c0e06 3279 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
9482354f 3280 if (rc != 0) {
068e94ea
MCC
3281 pr_err("error %d\n", rc);
3282 goto rw_error;
3283 }
244c0e06 3284 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
9482354f 3285 if (rc != 0) {
068e94ea
MCC
3286 pr_err("error %d\n", rc);
3287 goto rw_error;
3288 }
244c0e06 3289 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
9482354f 3290 if (rc != 0) {
068e94ea
MCC
3291 pr_err("error %d\n", rc);
3292 goto rw_error;
3293 }
244c0e06 3294 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
9482354f 3295 if (rc != 0) {
068e94ea
MCC
3296 pr_err("error %d\n", rc);
3297 goto rw_error;
3298 }
244c0e06 3299 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
9482354f 3300 if (rc != 0) {
068e94ea
MCC
3301 pr_err("error %d\n", rc);
3302 goto rw_error;
3303 }
244c0e06 3304 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
9482354f 3305 if (rc != 0) {
068e94ea
MCC
3306 pr_err("error %d\n", rc);
3307 goto rw_error;
3308 }
244c0e06 3309 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
9482354f 3310 if (rc != 0) {
068e94ea
MCC
3311 pr_err("error %d\n", rc);
3312 goto rw_error;
3313 }
244c0e06 3314 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
9482354f 3315 if (rc != 0) {
068e94ea
MCC
3316 pr_err("error %d\n", rc);
3317 goto rw_error;
3318 }
244c0e06 3319 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
9482354f 3320 if (rc != 0) {
068e94ea
MCC
3321 pr_err("error %d\n", rc);
3322 goto rw_error;
3323 }
244c0e06 3324 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
9482354f 3325 if (rc != 0) {
068e94ea
MCC
3326 pr_err("error %d\n", rc);
3327 goto rw_error;
3328 }
443f18d0 3329 /* Enable Monitor Bus output over MPEG pads and ctl input */
244c0e06 3330 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
9482354f 3331 if (rc != 0) {
068e94ea
MCC
3332 pr_err("error %d\n", rc);
3333 goto rw_error;
3334 }
443f18d0 3335 /* Write nomagic word to enable pdr reg write */
244c0e06 3336 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3337 if (rc != 0) {
068e94ea
MCC
3338 pr_err("error %d\n", rc);
3339 goto rw_error;
3340 }
443f18d0
MCC
3341 }
3342
3343 /* save values for restore after re-acquire */
57afe2f0 3344 common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
443f18d0 3345
9482354f 3346 return 0;
38b2df95 3347rw_error:
30741871 3348 return rc;
38b2df95
DH
3349}
3350
3351/*----------------------------------------------------------------------------*/
3352
38b2df95
DH
3353
3354/*----------------------------------------------------------------------------*/
3355/* MPEG Output Configuration Functions - end */
3356/*----------------------------------------------------------------------------*/
3357
3358/*----------------------------------------------------------------------------*/
2c149601 3359/* miscellaneous configurations - begin */
38b2df95
DH
3360/*----------------------------------------------------------------------------*/
3361
34eb9751 3362/*
57afe2f0 3363* \fn int set_mpegtei_handling()
38b2df95
DH
3364* \brief Activate MPEG TEI handling settings.
3365* \param devmod Pointer to demodulator instance.
61263c75 3366* \return int.
38b2df95
DH
3367*
3368* This routine should be called during a set channel of QAM/VSB
3369*
3370*/
1bfc9e15 3371static int set_mpegtei_handling(struct drx_demod_instance *demod)
38b2df95 3372{
b3ce3a83 3373 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
22892268 3374 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
068e94ea 3375 int rc;
57afe2f0
MCC
3376 u16 fec_oc_dpr_mode = 0;
3377 u16 fec_oc_snc_mode = 0;
3378 u16 fec_oc_ems_mode = 0;
443f18d0 3379
57afe2f0 3380 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 3381 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0 3382
244c0e06 3383 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
9482354f 3384 if (rc != 0) {
068e94ea
MCC
3385 pr_err("error %d\n", rc);
3386 goto rw_error;
3387 }
244c0e06 3388 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
9482354f 3389 if (rc != 0) {
068e94ea
MCC
3390 pr_err("error %d\n", rc);
3391 goto rw_error;
3392 }
244c0e06 3393 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
9482354f 3394 if (rc != 0) {
068e94ea
MCC
3395 pr_err("error %d\n", rc);
3396 goto rw_error;
3397 }
443f18d0
MCC
3398
3399 /* reset to default, allow TEI bit to be changed */
57afe2f0
MCC
3400 fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3401 fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
443f18d0 3402 FEC_OC_SNC_MODE_CORR_DISABLE__M));
57afe2f0 3403 fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
443f18d0 3404
259f380e 3405 if (ext_attr->disable_te_ihandling) {
443f18d0 3406 /* do not change TEI bit */
57afe2f0
MCC
3407 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3408 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
443f18d0 3409 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
57afe2f0 3410 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
443f18d0
MCC
3411 }
3412
244c0e06 3413 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
9482354f 3414 if (rc != 0) {
068e94ea
MCC
3415 pr_err("error %d\n", rc);
3416 goto rw_error;
3417 }
244c0e06 3418 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
9482354f 3419 if (rc != 0) {
068e94ea
MCC
3420 pr_err("error %d\n", rc);
3421 goto rw_error;
3422 }
244c0e06 3423 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
9482354f 3424 if (rc != 0) {
068e94ea
MCC
3425 pr_err("error %d\n", rc);
3426 goto rw_error;
3427 }
443f18d0 3428
9482354f 3429 return 0;
38b2df95 3430rw_error:
30741871 3431 return rc;
38b2df95
DH
3432}
3433
3434/*----------------------------------------------------------------------------*/
34eb9751 3435/*
57afe2f0 3436* \fn int bit_reverse_mpeg_output()
38b2df95
DH
3437* \brief Set MPEG output bit-endian settings.
3438* \param devmod Pointer to demodulator instance.
61263c75 3439* \return int.
38b2df95
DH
3440*
3441* This routine should be called during a set channel of QAM/VSB
3442*
3443*/
1bfc9e15 3444static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
38b2df95 3445{
b3ce3a83 3446 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
22892268 3447 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
068e94ea 3448 int rc;
57afe2f0 3449 u16 fec_oc_ipr_mode = 0;
38b2df95 3450
57afe2f0 3451 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 3452 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 3453
244c0e06 3454 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
9482354f 3455 if (rc != 0) {
068e94ea
MCC
3456 pr_err("error %d\n", rc);
3457 goto rw_error;
3458 }
38b2df95 3459
443f18d0 3460 /* reset to default (normal bit order) */
57afe2f0 3461 fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
38b2df95 3462
63713517 3463 if (ext_attr->bit_reverse_mpeg_outout)
57afe2f0 3464 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
38b2df95 3465
244c0e06 3466 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
9482354f 3467 if (rc != 0) {
068e94ea
MCC
3468 pr_err("error %d\n", rc);
3469 goto rw_error;
3470 }
38b2df95 3471
9482354f 3472 return 0;
38b2df95 3473rw_error:
30741871 3474 return rc;
38b2df95
DH
3475}
3476
38b2df95 3477/*----------------------------------------------------------------------------*/
34eb9751 3478/*
57afe2f0 3479* \fn int set_mpeg_start_width()
38b2df95
DH
3480* \brief Set MPEG start width.
3481* \param devmod Pointer to demodulator instance.
61263c75 3482* \return int.
38b2df95
DH
3483*
3484* This routine should be called during a set channel of QAM/VSB
3485*
3486*/
1bfc9e15 3487static int set_mpeg_start_width(struct drx_demod_instance *demod)
38b2df95 3488{
b3ce3a83 3489 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
22892268 3490 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
1bfc9e15 3491 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
068e94ea
MCC
3492 int rc;
3493 u16 fec_oc_comm_mb = 0;
38b2df95 3494
57afe2f0 3495 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 3496 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0 3497 common_attr = demod->my_common_attr;
38b2df95 3498
57afe2f0
MCC
3499 if ((common_attr->mpeg_cfg.static_clk == true)
3500 && (common_attr->mpeg_cfg.enable_parallel == false)) {
244c0e06 3501 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
9482354f 3502 if (rc != 0) {
068e94ea
MCC
3503 pr_err("error %d\n", rc);
3504 goto rw_error;
3505 }
57afe2f0 3506 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
63713517 3507 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
57afe2f0 3508 fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
244c0e06 3509 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
9482354f 3510 if (rc != 0) {
068e94ea
MCC
3511 pr_err("error %d\n", rc);
3512 goto rw_error;
3513 }
443f18d0
MCC
3514 }
3515
9482354f 3516 return 0;
38b2df95 3517rw_error:
30741871 3518 return rc;
38b2df95
DH
3519}
3520
38b2df95 3521/*----------------------------------------------------------------------------*/
2c149601 3522/* miscellaneous configurations - end */
38b2df95
DH
3523/*----------------------------------------------------------------------------*/
3524
3525/*----------------------------------------------------------------------------*/
3526/* UIO Configuration Functions - begin */
3527/*----------------------------------------------------------------------------*/
34eb9751 3528/*
57afe2f0 3529* \fn int ctrl_set_uio_cfg()
38b2df95
DH
3530* \brief Configure modus oprandi UIO.
3531* \param demod Pointer to demodulator instance.
57afe2f0 3532* \param uio_cfg Pointer to a configuration setting for a certain UIO.
61263c75 3533* \return int.
38b2df95 3534*/
1bfc9e15 3535static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
38b2df95 3536{
b3ce3a83 3537 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
068e94ea 3538 int rc;
38b2df95 3539
63713517 3540 if ((uio_cfg == NULL) || (demod == NULL))
9482354f 3541 return -EINVAL;
63713517 3542
b3ce3a83 3543 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 3544
443f18d0 3545 /* Write magic word to enable pdr reg write */
244c0e06 3546 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 3547 if (rc != 0) {
068e94ea
MCC
3548 pr_err("error %d\n", rc);
3549 goto rw_error;
3550 }
57afe2f0 3551 switch (uio_cfg->uio) {
38b2df95 3552 /*====================================================================*/
443f18d0
MCC
3553 case DRX_UIO1:
3554 /* DRX_UIO1: SMA_TX UIO-1 */
259f380e 3555 if (!ext_attr->has_smatx)
9482354f 3556 return -EIO;
57afe2f0 3557 switch (uio_cfg->mode) {
78cf8c84
GS
3558 case DRX_UIO_MODE_FIRMWARE_SMA: /* fall through */
3559 case DRX_UIO_MODE_FIRMWARE_SAW: /* fall through */
443f18d0 3560 case DRX_UIO_MODE_READWRITE:
57afe2f0 3561 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
443f18d0
MCC
3562 break;
3563 case DRX_UIO_MODE_DISABLE:
57afe2f0 3564 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
443f18d0 3565 /* pad configuration register is set 0 - input mode */
244c0e06 3566 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
9482354f 3567 if (rc != 0) {
068e94ea
MCC
3568 pr_err("error %d\n", rc);
3569 goto rw_error;
3570 }
443f18d0
MCC
3571 break;
3572 default:
9482354f 3573 return -EINVAL;
57afe2f0 3574 } /* switch ( uio_cfg->mode ) */
443f18d0 3575 break;
38b2df95 3576 /*====================================================================*/
443f18d0
MCC
3577 case DRX_UIO2:
3578 /* DRX_UIO2: SMA_RX UIO-2 */
259f380e 3579 if (!ext_attr->has_smarx)
9482354f 3580 return -EIO;
57afe2f0 3581 switch (uio_cfg->mode) {
78cf8c84 3582 case DRX_UIO_MODE_FIRMWARE0: /* fall through */
443f18d0 3583 case DRX_UIO_MODE_READWRITE:
57afe2f0 3584 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
443f18d0
MCC
3585 break;
3586 case DRX_UIO_MODE_DISABLE:
57afe2f0 3587 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
443f18d0 3588 /* pad configuration register is set 0 - input mode */
244c0e06 3589 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
9482354f 3590 if (rc != 0) {
068e94ea
MCC
3591 pr_err("error %d\n", rc);
3592 goto rw_error;
3593 }
443f18d0
MCC
3594 break;
3595 default:
9482354f 3596 return -EINVAL;
443f18d0 3597 break;
57afe2f0 3598 } /* switch ( uio_cfg->mode ) */
443f18d0 3599 break;
38b2df95 3600 /*====================================================================*/
443f18d0
MCC
3601 case DRX_UIO3:
3602 /* DRX_UIO3: GPIO UIO-3 */
259f380e 3603 if (!ext_attr->has_gpio)
9482354f 3604 return -EIO;
57afe2f0 3605 switch (uio_cfg->mode) {
78cf8c84 3606 case DRX_UIO_MODE_FIRMWARE0: /* fall through */
443f18d0 3607 case DRX_UIO_MODE_READWRITE:
57afe2f0 3608 ext_attr->uio_gpio_mode = uio_cfg->mode;
443f18d0
MCC
3609 break;
3610 case DRX_UIO_MODE_DISABLE:
57afe2f0 3611 ext_attr->uio_gpio_mode = uio_cfg->mode;
443f18d0 3612 /* pad configuration register is set 0 - input mode */
244c0e06 3613 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
9482354f 3614 if (rc != 0) {
068e94ea
MCC
3615 pr_err("error %d\n", rc);
3616 goto rw_error;
3617 }
443f18d0
MCC
3618 break;
3619 default:
9482354f 3620 return -EINVAL;
443f18d0 3621 break;
57afe2f0 3622 } /* switch ( uio_cfg->mode ) */
443f18d0 3623 break;
38b2df95 3624 /*====================================================================*/
443f18d0
MCC
3625 case DRX_UIO4:
3626 /* DRX_UIO4: IRQN UIO-4 */
259f380e 3627 if (!ext_attr->has_irqn)
9482354f 3628 return -EIO;
57afe2f0 3629 switch (uio_cfg->mode) {
443f18d0 3630 case DRX_UIO_MODE_READWRITE:
57afe2f0 3631 ext_attr->uio_irqn_mode = uio_cfg->mode;
443f18d0
MCC
3632 break;
3633 case DRX_UIO_MODE_DISABLE:
3634 /* pad configuration register is set 0 - input mode */
244c0e06 3635 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
9482354f 3636 if (rc != 0) {
068e94ea
MCC
3637 pr_err("error %d\n", rc);
3638 goto rw_error;
3639 }
57afe2f0 3640 ext_attr->uio_irqn_mode = uio_cfg->mode;
443f18d0 3641 break;
78cf8c84 3642 case DRX_UIO_MODE_FIRMWARE0: /* fall through */
443f18d0 3643 default:
9482354f 3644 return -EINVAL;
443f18d0 3645 break;
57afe2f0 3646 } /* switch ( uio_cfg->mode ) */
443f18d0 3647 break;
38b2df95 3648 /*====================================================================*/
443f18d0 3649 default:
9482354f 3650 return -EINVAL;
57afe2f0 3651 } /* switch ( uio_cfg->uio ) */
38b2df95 3652
443f18d0 3653 /* Write magic word to disable pdr reg write */
244c0e06 3654 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3655 if (rc != 0) {
068e94ea
MCC
3656 pr_err("error %d\n", rc);
3657 goto rw_error;
3658 }
38b2df95 3659
9482354f 3660 return 0;
443f18d0 3661rw_error:
30741871 3662 return rc;
38b2df95
DH
3663}
3664
34eb9751 3665/*
b6c4065e
MCC
3666* \fn int ctrl_uio_write()
3667* \brief Write to a UIO.
38b2df95 3668* \param demod Pointer to demodulator instance.
b6c4065e 3669* \param uio_data Pointer to data container for a certain UIO.
61263c75 3670* \return int.
38b2df95 3671*/
b6c4065e
MCC
3672static int
3673ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
38b2df95 3674{
b6c4065e
MCC
3675 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3676 int rc;
3677 u16 pin_cfg_value = 0;
3678 u16 value = 0;
38b2df95 3679
b6c4065e 3680 if ((uio_data == NULL) || (demod == NULL))
9482354f 3681 return -EINVAL;
38b2df95 3682
b6c4065e 3683 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 3684
443f18d0 3685 /* Write magic word to enable pdr reg write */
244c0e06 3686 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 3687 if (rc != 0) {
068e94ea
MCC
3688 pr_err("error %d\n", rc);
3689 goto rw_error;
3690 }
57afe2f0 3691 switch (uio_data->uio) {
38b2df95 3692 /*====================================================================*/
443f18d0
MCC
3693 case DRX_UIO1:
3694 /* DRX_UIO1: SMA_TX UIO-1 */
259f380e 3695 if (!ext_attr->has_smatx)
9482354f 3696 return -EIO;
57afe2f0
MCC
3697 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3698 && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
9482354f 3699 return -EIO;
443f18d0 3700 }
57afe2f0 3701 pin_cfg_value = 0;
443f18d0 3702 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
57afe2f0 3703 pin_cfg_value |= 0x0113;
443f18d0
MCC
3704 /* io_pad_cfg_mode output mode is drive always */
3705 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3706
3707 /* write to io pad configuration register - output mode */
244c0e06 3708 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
9482354f 3709 if (rc != 0) {
068e94ea
MCC
3710 pr_err("error %d\n", rc);
3711 goto rw_error;
3712 }
443f18d0
MCC
3713
3714 /* use corresponding bit in io data output registar */
244c0e06 3715 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
9482354f 3716 if (rc != 0) {
068e94ea
MCC
3717 pr_err("error %d\n", rc);
3718 goto rw_error;
3719 }
63713517 3720 if (!uio_data->value)
443f18d0 3721 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
63713517 3722 else
443f18d0 3723 value |= 0x8000; /* write one to 15th bit - 1st UIO */
63713517 3724
443f18d0 3725 /* write back to io data output register */
244c0e06 3726 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
9482354f 3727 if (rc != 0) {
068e94ea
MCC
3728 pr_err("error %d\n", rc);
3729 goto rw_error;
3730 }
443f18d0 3731 break;
38b2df95 3732 /*======================================================================*/
443f18d0
MCC
3733 case DRX_UIO2:
3734 /* DRX_UIO2: SMA_RX UIO-2 */
259f380e 3735 if (!ext_attr->has_smarx)
9482354f 3736 return -EIO;
63713517 3737 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
9482354f 3738 return -EIO;
63713517 3739
57afe2f0 3740 pin_cfg_value = 0;
443f18d0 3741 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
57afe2f0 3742 pin_cfg_value |= 0x0113;
443f18d0
MCC
3743 /* io_pad_cfg_mode output mode is drive always */
3744 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3745
3746 /* write to io pad configuration register - output mode */
244c0e06 3747 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
9482354f 3748 if (rc != 0) {
068e94ea
MCC
3749 pr_err("error %d\n", rc);
3750 goto rw_error;
3751 }
443f18d0
MCC
3752
3753 /* use corresponding bit in io data output registar */
244c0e06 3754 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
9482354f 3755 if (rc != 0) {
068e94ea
MCC
3756 pr_err("error %d\n", rc);
3757 goto rw_error;
3758 }
63713517 3759 if (!uio_data->value)
443f18d0 3760 value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
63713517 3761 else
443f18d0 3762 value |= 0x4000; /* write one to 14th bit - 2nd UIO */
63713517 3763
443f18d0 3764 /* write back to io data output register */
244c0e06 3765 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
9482354f 3766 if (rc != 0) {
068e94ea
MCC
3767 pr_err("error %d\n", rc);
3768 goto rw_error;
3769 }
443f18d0 3770 break;
38b2df95 3771 /*====================================================================*/
443f18d0
MCC
3772 case DRX_UIO3:
3773 /* DRX_UIO3: ASEL UIO-3 */
259f380e 3774 if (!ext_attr->has_gpio)
9482354f 3775 return -EIO;
63713517 3776 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
9482354f 3777 return -EIO;
63713517 3778
57afe2f0 3779 pin_cfg_value = 0;
443f18d0 3780 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
57afe2f0 3781 pin_cfg_value |= 0x0113;
443f18d0
MCC
3782 /* io_pad_cfg_mode output mode is drive always */
3783 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3784
3785 /* write to io pad configuration register - output mode */
244c0e06 3786 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
9482354f 3787 if (rc != 0) {
068e94ea
MCC
3788 pr_err("error %d\n", rc);
3789 goto rw_error;
3790 }
443f18d0
MCC
3791
3792 /* use corresponding bit in io data output registar */
244c0e06 3793 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
9482354f 3794 if (rc != 0) {
068e94ea
MCC
3795 pr_err("error %d\n", rc);
3796 goto rw_error;
3797 }
63713517 3798 if (!uio_data->value)
443f18d0 3799 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
63713517 3800 else
443f18d0 3801 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
63713517 3802
443f18d0 3803 /* write back to io data output register */
244c0e06 3804 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
9482354f 3805 if (rc != 0) {
068e94ea
MCC
3806 pr_err("error %d\n", rc);
3807 goto rw_error;
3808 }
443f18d0 3809 break;
38b2df95 3810 /*=====================================================================*/
443f18d0
MCC
3811 case DRX_UIO4:
3812 /* DRX_UIO4: IRQN UIO-4 */
259f380e 3813 if (!ext_attr->has_irqn)
9482354f 3814 return -EIO;
443f18d0 3815
63713517 3816 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
9482354f 3817 return -EIO;
63713517 3818
57afe2f0 3819 pin_cfg_value = 0;
443f18d0 3820 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
57afe2f0 3821 pin_cfg_value |= 0x0113;
443f18d0
MCC
3822 /* io_pad_cfg_mode output mode is drive always */
3823 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3824
3825 /* write to io pad configuration register - output mode */
244c0e06 3826 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
9482354f 3827 if (rc != 0) {
068e94ea
MCC
3828 pr_err("error %d\n", rc);
3829 goto rw_error;
3830 }
443f18d0
MCC
3831
3832 /* use corresponding bit in io data output registar */
244c0e06 3833 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
9482354f 3834 if (rc != 0) {
068e94ea
MCC
3835 pr_err("error %d\n", rc);
3836 goto rw_error;
3837 }
63713517 3838 if (uio_data->value == false)
443f18d0 3839 value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
63713517 3840 else
443f18d0 3841 value |= 0x1000; /* write one to 12th bit - 4th UIO */
63713517 3842
443f18d0 3843 /* write back to io data output register */
244c0e06 3844 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
9482354f 3845 if (rc != 0) {
068e94ea
MCC
3846 pr_err("error %d\n", rc);
3847 goto rw_error;
3848 }
443f18d0 3849 break;
38b2df95 3850 /*=====================================================================*/
443f18d0 3851 default:
9482354f 3852 return -EINVAL;
57afe2f0 3853 } /* switch ( uio_data->uio ) */
38b2df95 3854
443f18d0 3855 /* Write magic word to disable pdr reg write */
244c0e06 3856 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3857 if (rc != 0) {
068e94ea
MCC
3858 pr_err("error %d\n", rc);
3859 goto rw_error;
3860 }
38b2df95 3861
9482354f 3862 return 0;
443f18d0 3863rw_error:
30741871 3864 return rc;
38b2df95
DH
3865}
3866
38b2df95
DH
3867/*---------------------------------------------------------------------------*/
3868/* UIO Configuration Functions - end */
3869/*---------------------------------------------------------------------------*/
3870
3871/*----------------------------------------------------------------------------*/
3872/* I2C Bridge Functions - begin */
3873/*----------------------------------------------------------------------------*/
34eb9751 3874/*
57afe2f0 3875* \fn int ctrl_i2c_bridge()
38b2df95
DH
3876* \brief Open or close the I2C switch to tuner.
3877* \param demod Pointer to demodulator instance.
57afe2f0 3878* \param bridge_closed Pointer to bool indication if bridge is closed not.
61263c75 3879* \return int.
38b2df95
DH
3880
3881*/
61263c75 3882static int
1bfc9e15 3883ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
38b2df95 3884{
60d3603b 3885 struct drxj_hi_cmd hi_cmd;
43a431e4 3886 u16 result = 0;
38b2df95 3887
443f18d0 3888 /* check arguments */
63713517 3889 if (bridge_closed == NULL)
9482354f 3890 return -EINVAL;
38b2df95 3891
57afe2f0
MCC
3892 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
3893 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
63713517 3894 if (*bridge_closed)
57afe2f0 3895 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
63713517 3896 else
57afe2f0 3897 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
38b2df95 3898
57afe2f0 3899 return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
38b2df95 3900}
443f18d0 3901
38b2df95
DH
3902/*----------------------------------------------------------------------------*/
3903/* I2C Bridge Functions - end */
3904/*----------------------------------------------------------------------------*/
3905
3906/*----------------------------------------------------------------------------*/
3907/* Smart antenna Functions - begin */
3908/*----------------------------------------------------------------------------*/
34eb9751 3909/*
57afe2f0 3910* \fn int smart_ant_init()
38b2df95 3911* \brief Initialize Smart Antenna.
1bfc9e15 3912* \param pointer to struct drx_demod_instance.
61263c75 3913* \return int.
38b2df95
DH
3914*
3915*/
1bfc9e15 3916static int smart_ant_init(struct drx_demod_instance *demod)
38b2df95 3917{
b3ce3a83 3918 struct drxj_data *ext_attr = NULL;
57afe2f0 3919 struct i2c_device_addr *dev_addr = NULL;
1bfc9e15 3920 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
068e94ea
MCC
3921 int rc;
3922 u16 data = 0;
443f18d0 3923
57afe2f0 3924 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 3925 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
3926
3927 /* Write magic word to enable pdr reg write */
244c0e06 3928 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
9482354f 3929 if (rc != 0) {
068e94ea
MCC
3930 pr_err("error %d\n", rc);
3931 goto rw_error;
3932 }
443f18d0 3933 /* init smart antenna */
244c0e06 3934 rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
9482354f 3935 if (rc != 0) {
068e94ea
MCC
3936 pr_err("error %d\n", rc);
3937 goto rw_error;
3938 }
63713517 3939 if (ext_attr->smart_ant_inverted) {
244c0e06 3940 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 3941 if (rc != 0) {
63713517
MCC
3942 pr_err("error %d\n", rc);
3943 goto rw_error;
068e94ea 3944 }
63713517 3945 } else {
244c0e06 3946 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 3947 if (rc != 0) {
63713517
MCC
3948 pr_err("error %d\n", rc);
3949 goto rw_error;
068e94ea 3950 }
63713517 3951 }
443f18d0
MCC
3952
3953 /* config SMA_TX pin to smart antenna mode */
068e94ea 3954 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
9482354f 3955 if (rc != 0) {
068e94ea
MCC
3956 pr_err("error %d\n", rc);
3957 goto rw_error;
3958 }
244c0e06 3959 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
9482354f 3960 if (rc != 0) {
068e94ea
MCC
3961 pr_err("error %d\n", rc);
3962 goto rw_error;
3963 }
244c0e06 3964 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
9482354f 3965 if (rc != 0) {
068e94ea
MCC
3966 pr_err("error %d\n", rc);
3967 goto rw_error;
3968 }
443f18d0
MCC
3969
3970 /* Write magic word to disable pdr reg write */
244c0e06 3971 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
9482354f 3972 if (rc != 0) {
068e94ea
MCC
3973 pr_err("error %d\n", rc);
3974 goto rw_error;
3975 }
443f18d0 3976
9482354f 3977 return 0;
38b2df95 3978rw_error:
30741871 3979 return rc;
38b2df95
DH
3980}
3981
b3ce3a83 3982static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
38b2df95 3983{
068e94ea 3984 int rc;
068e94ea 3985 u16 cur_cmd = 0;
ceea5e2d 3986 unsigned long timeout;
38b2df95 3987
443f18d0
MCC
3988 /* Check param */
3989 if (cmd == NULL)
9482354f 3990 return -EINVAL;
38b2df95 3991
443f18d0 3992 /* Wait until SCU command interface is ready to receive command */
244c0e06 3993 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
9482354f 3994 if (rc != 0) {
068e94ea
MCC
3995 pr_err("error %d\n", rc);
3996 goto rw_error;
3997 }
63713517 3998 if (cur_cmd != DRX_SCU_READY)
9482354f 3999 return -EIO;
38b2df95 4000
57afe2f0 4001 switch (cmd->parameter_len) {
443f18d0 4002 case 5:
244c0e06 4003 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
9482354f 4004 if (rc != 0) {
068e94ea
MCC
4005 pr_err("error %d\n", rc);
4006 goto rw_error;
4007 } /* fallthrough */
443f18d0 4008 case 4:
244c0e06 4009 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
9482354f 4010 if (rc != 0) {
068e94ea
MCC
4011 pr_err("error %d\n", rc);
4012 goto rw_error;
4013 } /* fallthrough */
443f18d0 4014 case 3:
244c0e06 4015 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
9482354f 4016 if (rc != 0) {
068e94ea
MCC
4017 pr_err("error %d\n", rc);
4018 goto rw_error;
4019 } /* fallthrough */
443f18d0 4020 case 2:
244c0e06 4021 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
9482354f 4022 if (rc != 0) {
068e94ea
MCC
4023 pr_err("error %d\n", rc);
4024 goto rw_error;
4025 } /* fallthrough */
443f18d0 4026 case 1:
244c0e06 4027 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
9482354f 4028 if (rc != 0) {
068e94ea
MCC
4029 pr_err("error %d\n", rc);
4030 goto rw_error;
4031 } /* fallthrough */
443f18d0
MCC
4032 case 0:
4033 /* do nothing */
4034 break;
4035 default:
4036 /* this number of parameters is not supported */
9482354f 4037 return -EIO;
443f18d0 4038 }
244c0e06 4039 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
9482354f 4040 if (rc != 0) {
068e94ea
MCC
4041 pr_err("error %d\n", rc);
4042 goto rw_error;
4043 }
38b2df95 4044
443f18d0 4045 /* Wait until SCU has processed command */
ceea5e2d
MCC
4046 timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);
4047 while (time_is_after_jiffies(timeout)) {
244c0e06 4048 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
9482354f 4049 if (rc != 0) {
068e94ea
MCC
4050 pr_err("error %d\n", rc);
4051 goto rw_error;
4052 }
ceea5e2d
MCC
4053 if (cur_cmd == DRX_SCU_READY)
4054 break;
4055 usleep_range(1000, 2000);
4056 }
443f18d0 4057
63713517 4058 if (cur_cmd != DRX_SCU_READY)
9482354f 4059 return -EIO;
443f18d0
MCC
4060
4061 /* read results */
57afe2f0 4062 if ((cmd->result_len > 0) && (cmd->result != NULL)) {
43a431e4 4063 s16 err;
443f18d0 4064
57afe2f0 4065 switch (cmd->result_len) {
443f18d0 4066 case 4:
244c0e06 4067 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
9482354f 4068 if (rc != 0) {
068e94ea
MCC
4069 pr_err("error %d\n", rc);
4070 goto rw_error;
4071 } /* fallthrough */
443f18d0 4072 case 3:
244c0e06 4073 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
9482354f 4074 if (rc != 0) {
068e94ea
MCC
4075 pr_err("error %d\n", rc);
4076 goto rw_error;
4077 } /* fallthrough */
443f18d0 4078 case 2:
244c0e06 4079 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
9482354f 4080 if (rc != 0) {
068e94ea
MCC
4081 pr_err("error %d\n", rc);
4082 goto rw_error;
4083 } /* fallthrough */
443f18d0 4084 case 1:
244c0e06 4085 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
9482354f 4086 if (rc != 0) {
068e94ea
MCC
4087 pr_err("error %d\n", rc);
4088 goto rw_error;
4089 } /* fallthrough */
443f18d0
MCC
4090 case 0:
4091 /* do nothing */
4092 break;
4093 default:
4094 /* this number of parameters is not supported */
9482354f 4095 return -EIO;
443f18d0
MCC
4096 }
4097
4098 /* Check if an error was reported by SCU */
4099 err = cmd->result[0];
4100
4101 /* check a few fixed error codes */
43a431e4
MCC
4102 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4103 || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4104 || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4105 || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
443f18d0 4106 ) {
9482354f 4107 return -EINVAL;
443f18d0
MCC
4108 }
4109 /* here it is assumed that negative means error, and positive no error */
63713517 4110 else if (err < 0)
9482354f 4111 return -EIO;
63713517 4112 else
9482354f 4113 return 0;
443f18d0
MCC
4114 }
4115
9482354f 4116 return 0;
443f18d0
MCC
4117
4118rw_error:
30741871 4119 return rc;
38b2df95 4120}
443f18d0 4121
34eb9751 4122/*
61263c75 4123* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
38b2df95 4124* \brief Basic access routine for SCU atomic read or write access
57afe2f0 4125* \param dev_addr pointer to i2c dev address
38b2df95
DH
4126* \param addr destination/source address
4127* \param datasize size of data buffer in bytes
4128* \param data pointer to data buffer
61263c75 4129* \return int
9482354f
MCC
4130* \retval 0 Succes
4131* \retval -EIO Timeout, I2C error, illegal bank
38b2df95
DH
4132*
4133*/
4134#define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4135static
1bfc9e15 4136int 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 4137 u8 *data, bool read_flag)
443f18d0 4138{
b3ce3a83 4139 struct drxjscu_cmd scu_cmd;
068e94ea 4140 int rc;
54c8cdd4 4141 u16 set_param_parameters[18];
57afe2f0 4142 u16 cmd_result[15];
443f18d0
MCC
4143
4144 /* Parameter check */
63713517 4145 if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
9482354f 4146 return -EINVAL;
38b2df95 4147
57afe2f0
MCC
4148 set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4149 if (read_flag) { /* read */
4150 set_param_parameters[0] = ((~(0x0080)) & datasize);
4151 scu_cmd.parameter_len = 2;
4152 scu_cmd.result_len = datasize / 2 + 2;
443f18d0
MCC
4153 } else {
4154 int i = 0;
4155
57afe2f0 4156 set_param_parameters[0] = 0x0080 | datasize;
443f18d0 4157 for (i = 0; i < (datasize / 2); i++) {
57afe2f0 4158 set_param_parameters[i + 2] =
443f18d0
MCC
4159 (data[2 * i] | (data[(2 * i) + 1] << 8));
4160 }
57afe2f0
MCC
4161 scu_cmd.parameter_len = datasize / 2 + 2;
4162 scu_cmd.result_len = 1;
443f18d0
MCC
4163 }
4164
57afe2f0 4165 scu_cmd.command =
443f18d0
MCC
4166 SCU_RAM_COMMAND_STANDARD_TOP |
4167 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
57afe2f0
MCC
4168 scu_cmd.result = cmd_result;
4169 scu_cmd.parameter = set_param_parameters;
068e94ea 4170 rc = scu_command(dev_addr, &scu_cmd);
9482354f 4171 if (rc != 0) {
068e94ea
MCC
4172 pr_err("error %d\n", rc);
4173 goto rw_error;
4174 }
443f18d0 4175
259f380e 4176 if (read_flag) {
443f18d0
MCC
4177 int i = 0;
4178 /* read data from buffer */
4179 for (i = 0; i < (datasize / 2); i++) {
57afe2f0
MCC
4180 data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4181 data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
443f18d0
MCC
4182 }
4183 }
38b2df95 4184
9482354f 4185 return 0;
38b2df95 4186
443f18d0 4187rw_error:
30741871 4188 return rc;
38b2df95
DH
4189
4190}
4191
4192/*============================================================================*/
4193
34eb9751 4194/*
61263c75 4195* \fn int DRXJ_DAP_AtomicReadReg16()
38b2df95
DH
4196* \brief Atomic read of 16 bits words
4197*/
4198static
57afe2f0 4199int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
4200 u32 addr,
4201 u16 *data, u32 flags)
38b2df95 4202{
4182438e 4203 u8 buf[2] = { 0 };
9482354f 4204 int rc = -EIO;
43a431e4 4205 u16 word = 0;
38b2df95 4206
63713517 4207 if (!data)
9482354f 4208 return -EINVAL;
38b2df95 4209
57afe2f0 4210 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
b1d0a596
MCC
4211 if (rc < 0)
4212 return rc;
38b2df95 4213
43a431e4 4214 word = (u16) (buf[0] + (buf[1] << 8));
38b2df95 4215
443f18d0 4216 *data = word;
38b2df95 4217
443f18d0 4218 return rc;
38b2df95 4219}
443f18d0 4220
38b2df95 4221/*============================================================================*/
34eb9751 4222/*
57afe2f0 4223* \fn int drxj_dap_scu_atomic_write_reg16()
38b2df95
DH
4224* \brief Atomic read of 16 bits words
4225*/
4226static
57afe2f0 4227int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
1bfc9e15
MCC
4228 u32 addr,
4229 u16 data, u32 flags)
38b2df95 4230{
43a431e4 4231 u8 buf[2];
9482354f 4232 int rc = -EIO;
38b2df95 4233
43a431e4
MCC
4234 buf[0] = (u8) (data & 0xff);
4235 buf[1] = (u8) ((data >> 8) & 0xff);
38b2df95 4236
57afe2f0 4237 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
38b2df95 4238
443f18d0 4239 return rc;
38b2df95
DH
4240}
4241
38b2df95 4242/* -------------------------------------------------------------------------- */
34eb9751 4243/*
38b2df95
DH
4244* \brief Measure result of ADC synchronisation
4245* \param demod demod instance
4246* \param count (returned) count
61263c75 4247* \return int.
9482354f
MCC
4248* \retval 0 Success
4249* \retval -EIO Failure: I2C error
38b2df95
DH
4250*
4251*/
1bfc9e15 4252static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
38b2df95 4253{
57afe2f0 4254 struct i2c_device_addr *dev_addr = NULL;
068e94ea
MCC
4255 int rc;
4256 u16 data = 0;
38b2df95 4257
57afe2f0 4258 dev_addr = demod->my_i2c_dev_addr;
38b2df95 4259
443f18d0 4260 /* Start measurement */
244c0e06 4261 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
9482354f 4262 if (rc != 0) {
068e94ea
MCC
4263 pr_err("error %d\n", rc);
4264 goto rw_error;
4265 }
244c0e06 4266 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
9482354f 4267 if (rc != 0) {
068e94ea
MCC
4268 pr_err("error %d\n", rc);
4269 goto rw_error;
4270 }
38b2df95 4271
443f18d0 4272 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
d7b0631e 4273 msleep(1);
38b2df95 4274
443f18d0 4275 *count = 0;
244c0e06 4276 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, &data, 0);
9482354f 4277 if (rc != 0) {
068e94ea
MCC
4278 pr_err("error %d\n", rc);
4279 goto rw_error;
4280 }
63713517 4281 if (data == 127)
443f18d0 4282 *count = *count + 1;
244c0e06 4283 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, &data, 0);
9482354f 4284 if (rc != 0) {
068e94ea
MCC
4285 pr_err("error %d\n", rc);
4286 goto rw_error;
4287 }
63713517 4288 if (data == 127)
443f18d0 4289 *count = *count + 1;
244c0e06 4290 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, &data, 0);
9482354f 4291 if (rc != 0) {
068e94ea
MCC
4292 pr_err("error %d\n", rc);
4293 goto rw_error;
4294 }
63713517 4295 if (data == 127)
443f18d0 4296 *count = *count + 1;
38b2df95 4297
9482354f 4298 return 0;
38b2df95 4299rw_error:
30741871 4300 return rc;
38b2df95
DH
4301}
4302
34eb9751 4303/*
38b2df95
DH
4304* \brief Synchronize analog and digital clock domains
4305* \param demod demod instance
61263c75 4306* \return int.
9482354f
MCC
4307* \retval 0 Success
4308* \retval -EIO Failure: I2C error or failure to synchronize
38b2df95
DH
4309*
4310* An IQM reset will also reset the results of this synchronization.
4311* After an IQM reset this routine needs to be called again.
4312*
4313*/
4314
1bfc9e15 4315static int adc_synchronization(struct drx_demod_instance *demod)
38b2df95 4316{
57afe2f0 4317 struct i2c_device_addr *dev_addr = NULL;
068e94ea
MCC
4318 int rc;
4319 u16 count = 0;
38b2df95 4320
57afe2f0 4321 dev_addr = demod->my_i2c_dev_addr;
38b2df95 4322
068e94ea 4323 rc = adc_sync_measurement(demod, &count);
9482354f 4324 if (rc != 0) {
068e94ea
MCC
4325 pr_err("error %d\n", rc);
4326 goto rw_error;
4327 }
38b2df95 4328
443f18d0 4329 if (count == 1) {
69bb7ab6 4330 /* Try sampling on a different edge */
57afe2f0 4331 u16 clk_neg = 0;
38b2df95 4332
244c0e06 4333 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
9482354f 4334 if (rc != 0) {
068e94ea
MCC
4335 pr_err("error %d\n", rc);
4336 goto rw_error;
4337 }
38b2df95 4338
57afe2f0 4339 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
244c0e06 4340 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
9482354f 4341 if (rc != 0) {
068e94ea
MCC
4342 pr_err("error %d\n", rc);
4343 goto rw_error;
4344 }
38b2df95 4345
068e94ea 4346 rc = adc_sync_measurement(demod, &count);
9482354f 4347 if (rc != 0) {
068e94ea
MCC
4348 pr_err("error %d\n", rc);
4349 goto rw_error;
4350 }
443f18d0 4351 }
38b2df95 4352
63713517
MCC
4353 /* TODO: implement fallback scenarios */
4354 if (count < 2)
9482354f 4355 return -EIO;
38b2df95 4356
9482354f 4357 return 0;
38b2df95 4358rw_error:
30741871 4359 return rc;
38b2df95
DH
4360}
4361
38b2df95
DH
4362/*============================================================================*/
4363/*== END AUXILIARY FUNCTIONS ==*/
4364/*============================================================================*/
4365
4366/*============================================================================*/
4367/*============================================================================*/
4368/*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
4369/*============================================================================*/
4370/*============================================================================*/
34eb9751 4371/*
57afe2f0 4372* \fn int init_agc ()
38b2df95
DH
4373* \brief Initialize AGC for all standards.
4374* \param demod instance of demodulator.
4375* \param channel pointer to channel data.
61263c75 4376* \return int.
38b2df95 4377*/
1bfc9e15 4378static int init_agc(struct drx_demod_instance *demod)
57afe2f0
MCC
4379{
4380 struct i2c_device_addr *dev_addr = NULL;
1bfc9e15 4381 struct drx_common_attr *common_attr = NULL;
b3ce3a83
MCC
4382 struct drxj_data *ext_attr = NULL;
4383 struct drxj_cfg_agc *p_agc_rf_settings = NULL;
4384 struct drxj_cfg_agc *p_agc_if_settings = NULL;
068e94ea 4385 int rc;
57afe2f0
MCC
4386 u16 ingain_tgt_max = 0;
4387 u16 clp_dir_to = 0;
4388 u16 sns_sum_max = 0;
4389 u16 clp_sum_max = 0;
4390 u16 sns_dir_to = 0;
4391 u16 ki_innergain_min = 0;
4392 u16 agc_ki = 0;
4393 u16 ki_max = 0;
4394 u16 if_iaccu_hi_tgt_min = 0;
43a431e4 4395 u16 data = 0;
e33f2193 4396 u16 agc_ki_dgain = 0;
57afe2f0
MCC
4397 u16 ki_min = 0;
4398 u16 clp_ctrl_mode = 0;
4399 u16 agc_rf = 0;
4400 u16 agc_if = 0;
068e94ea 4401
57afe2f0 4402 dev_addr = demod->my_i2c_dev_addr;
1bfc9e15 4403 common_attr = (struct drx_common_attr *) demod->my_common_attr;
b3ce3a83 4404 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0
MCC
4405
4406 switch (ext_attr->standard) {
443f18d0 4407 case DRX_STANDARD_8VSB:
57afe2f0
MCC
4408 clp_sum_max = 1023;
4409 clp_dir_to = (u16) (-9);
4410 sns_sum_max = 1023;
4411 sns_dir_to = (u16) (-9);
4412 ki_innergain_min = (u16) (-32768);
4413 ki_max = 0x032C;
e33f2193 4414 agc_ki_dgain = 0xC;
57afe2f0
MCC
4415 if_iaccu_hi_tgt_min = 2047;
4416 ki_min = 0x0117;
4417 ingain_tgt_max = 16383;
4418 clp_ctrl_mode = 0;
244c0e06 4419 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
9482354f 4420 if (rc != 0) {
068e94ea
MCC
4421 pr_err("error %d\n", rc);
4422 goto rw_error;
4423 }
244c0e06 4424 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
9482354f 4425 if (rc != 0) {
068e94ea
MCC
4426 pr_err("error %d\n", rc);
4427 goto rw_error;
4428 }
244c0e06 4429 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
9482354f 4430 if (rc != 0) {
068e94ea
MCC
4431 pr_err("error %d\n", rc);
4432 goto rw_error;
4433 }
244c0e06 4434 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
9482354f 4435 if (rc != 0) {
068e94ea
MCC
4436 pr_err("error %d\n", rc);
4437 goto rw_error;
4438 }
244c0e06 4439 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
9482354f 4440 if (rc != 0) {
068e94ea
MCC
4441 pr_err("error %d\n", rc);
4442 goto rw_error;
4443 }
244c0e06 4444 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
9482354f 4445 if (rc != 0) {
068e94ea
MCC
4446 pr_err("error %d\n", rc);
4447 goto rw_error;
4448 }
244c0e06 4449 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
9482354f 4450 if (rc != 0) {
068e94ea
MCC
4451 pr_err("error %d\n", rc);
4452 goto rw_error;
4453 }
244c0e06 4454 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
9482354f 4455 if (rc != 0) {
068e94ea
MCC
4456 pr_err("error %d\n", rc);
4457 goto rw_error;
4458 }
244c0e06 4459 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
9482354f 4460 if (rc != 0) {
068e94ea
MCC
4461 pr_err("error %d\n", rc);
4462 goto rw_error;
4463 }
244c0e06 4464 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
9482354f 4465 if (rc != 0) {
068e94ea
MCC
4466 pr_err("error %d\n", rc);
4467 goto rw_error;
4468 }
244c0e06 4469 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
9482354f 4470 if (rc != 0) {
068e94ea
MCC
4471 pr_err("error %d\n", rc);
4472 goto rw_error;
4473 }
244c0e06 4474 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
9482354f 4475 if (rc != 0) {
068e94ea
MCC
4476 pr_err("error %d\n", rc);
4477 goto rw_error;
4478 }
244c0e06 4479 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
9482354f 4480 if (rc != 0) {
068e94ea
MCC
4481 pr_err("error %d\n", rc);
4482 goto rw_error;
4483 }
57afe2f0
MCC
4484 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
4485 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
443f18d0 4486 break;
38b2df95 4487#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
4488 case DRX_STANDARD_ITU_A:
4489 case DRX_STANDARD_ITU_C:
4490 case DRX_STANDARD_ITU_B:
57afe2f0
MCC
4491 ingain_tgt_max = 5119;
4492 clp_sum_max = 1023;
4493 clp_dir_to = (u16) (-5);
4494 sns_sum_max = 127;
4495 sns_dir_to = (u16) (-3);
4496 ki_innergain_min = 0;
4497 ki_max = 0x0657;
4498 if_iaccu_hi_tgt_min = 2047;
e33f2193 4499 agc_ki_dgain = 0x7;
57afe2f0
MCC
4500 ki_min = 0x0117;
4501 clp_ctrl_mode = 0;
244c0e06 4502 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
9482354f 4503 if (rc != 0) {
068e94ea
MCC
4504 pr_err("error %d\n", rc);
4505 goto rw_error;
4506 }
244c0e06 4507 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
9482354f 4508 if (rc != 0) {
068e94ea
MCC
4509 pr_err("error %d\n", rc);
4510 goto rw_error;
4511 }
244c0e06 4512 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
9482354f 4513 if (rc != 0) {
068e94ea
MCC
4514 pr_err("error %d\n", rc);
4515 goto rw_error;
4516 }
244c0e06 4517 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
9482354f 4518 if (rc != 0) {
068e94ea
MCC
4519 pr_err("error %d\n", rc);
4520 goto rw_error;
4521 }
244c0e06 4522 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
9482354f 4523 if (rc != 0) {
068e94ea
MCC
4524 pr_err("error %d\n", rc);
4525 goto rw_error;
4526 }
244c0e06 4527 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
9482354f 4528 if (rc != 0) {
068e94ea
MCC
4529 pr_err("error %d\n", rc);
4530 goto rw_error;
4531 }
244c0e06 4532 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
9482354f 4533 if (rc != 0) {
068e94ea
MCC
4534 pr_err("error %d\n", rc);
4535 goto rw_error;
4536 }
244c0e06 4537 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
9482354f 4538 if (rc != 0) {
068e94ea
MCC
4539 pr_err("error %d\n", rc);
4540 goto rw_error;
4541 }
244c0e06 4542 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
9482354f 4543 if (rc != 0) {
068e94ea
MCC
4544 pr_err("error %d\n", rc);
4545 goto rw_error;
4546 }
244c0e06 4547 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
9482354f 4548 if (rc != 0) {
068e94ea
MCC
4549 pr_err("error %d\n", rc);
4550 goto rw_error;
4551 }
57afe2f0
MCC
4552 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
4553 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
244c0e06 4554 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
9482354f 4555 if (rc != 0) {
068e94ea
MCC
4556 pr_err("error %d\n", rc);
4557 goto rw_error;
4558 }
57afe2f0 4559
244c0e06 4560 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
9482354f 4561 if (rc != 0) {
068e94ea
MCC
4562 pr_err("error %d\n", rc);
4563 goto rw_error;
4564 }
57afe2f0 4565 agc_ki &= 0xf000;
244c0e06 4566 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
9482354f 4567 if (rc != 0) {
068e94ea
MCC
4568 pr_err("error %d\n", rc);
4569 goto rw_error;
4570 }
443f18d0 4571 break;
38b2df95 4572#endif
443f18d0 4573 default:
9482354f 4574 return -EINVAL;
443f18d0 4575 }
38b2df95 4576
443f18d0 4577 /* for new AGC interface */
244c0e06 4578 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
9482354f 4579 if (rc != 0) {
068e94ea
MCC
4580 pr_err("error %d\n", rc);
4581 goto rw_error;
4582 }
244c0e06 4583 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
9482354f 4584 if (rc != 0) {
068e94ea
MCC
4585 pr_err("error %d\n", rc);
4586 goto rw_error;
4587 } /* Gain fed from inner to outer AGC */
244c0e06 4588 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
9482354f 4589 if (rc != 0) {
068e94ea
MCC
4590 pr_err("error %d\n", rc);
4591 goto rw_error;
4592 }
244c0e06 4593 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
9482354f 4594 if (rc != 0) {
068e94ea
MCC
4595 pr_err("error %d\n", rc);
4596 goto rw_error;
4597 }
244c0e06 4598 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
9482354f 4599 if (rc != 0) {
068e94ea
MCC
4600 pr_err("error %d\n", rc);
4601 goto rw_error;
4602 } /* set to p_agc_settings->top before */
244c0e06 4603 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
9482354f 4604 if (rc != 0) {
068e94ea
MCC
4605 pr_err("error %d\n", rc);
4606 goto rw_error;
4607 }
244c0e06 4608 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
9482354f 4609 if (rc != 0) {
068e94ea
MCC
4610 pr_err("error %d\n", rc);
4611 goto rw_error;
4612 }
244c0e06 4613 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
9482354f 4614 if (rc != 0) {
068e94ea
MCC
4615 pr_err("error %d\n", rc);
4616 goto rw_error;
4617 }
244c0e06 4618 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
9482354f 4619 if (rc != 0) {
068e94ea
MCC
4620 pr_err("error %d\n", rc);
4621 goto rw_error;
4622 }
244c0e06 4623 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
9482354f 4624 if (rc != 0) {
068e94ea
MCC
4625 pr_err("error %d\n", rc);
4626 goto rw_error;
4627 }
244c0e06 4628 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
9482354f 4629 if (rc != 0) {
068e94ea
MCC
4630 pr_err("error %d\n", rc);
4631 goto rw_error;
4632 }
244c0e06 4633 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
9482354f 4634 if (rc != 0) {
068e94ea
MCC
4635 pr_err("error %d\n", rc);
4636 goto rw_error;
4637 }
244c0e06 4638 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
9482354f 4639 if (rc != 0) {
068e94ea
MCC
4640 pr_err("error %d\n", rc);
4641 goto rw_error;
4642 }
244c0e06 4643 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
9482354f 4644 if (rc != 0) {
068e94ea
MCC
4645 pr_err("error %d\n", rc);
4646 goto rw_error;
4647 }
244c0e06 4648 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
9482354f 4649 if (rc != 0) {
068e94ea
MCC
4650 pr_err("error %d\n", rc);
4651 goto rw_error;
4652 }
244c0e06 4653 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
9482354f 4654 if (rc != 0) {
068e94ea
MCC
4655 pr_err("error %d\n", rc);
4656 goto rw_error;
4657 }
244c0e06 4658 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
9482354f 4659 if (rc != 0) {
068e94ea
MCC
4660 pr_err("error %d\n", rc);
4661 goto rw_error;
4662 }
244c0e06 4663 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
9482354f 4664 if (rc != 0) {
068e94ea
MCC
4665 pr_err("error %d\n", rc);
4666 goto rw_error;
4667 }
244c0e06 4668 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
9482354f 4669 if (rc != 0) {
068e94ea
MCC
4670 pr_err("error %d\n", rc);
4671 goto rw_error;
4672 }
244c0e06 4673 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
9482354f 4674 if (rc != 0) {
068e94ea
MCC
4675 pr_err("error %d\n", rc);
4676 goto rw_error;
4677 }
244c0e06 4678 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
9482354f 4679 if (rc != 0) {
068e94ea
MCC
4680 pr_err("error %d\n", rc);
4681 goto rw_error;
4682 }
244c0e06 4683 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
9482354f 4684 if (rc != 0) {
068e94ea
MCC
4685 pr_err("error %d\n", rc);
4686 goto rw_error;
4687 }
244c0e06 4688 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
9482354f 4689 if (rc != 0) {
068e94ea
MCC
4690 pr_err("error %d\n", rc);
4691 goto rw_error;
4692 }
244c0e06 4693 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
9482354f 4694 if (rc != 0) {
068e94ea
MCC
4695 pr_err("error %d\n", rc);
4696 goto rw_error;
4697 }
244c0e06 4698 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
9482354f 4699 if (rc != 0) {
068e94ea
MCC
4700 pr_err("error %d\n", rc);
4701 goto rw_error;
4702 }
244c0e06 4703 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
9482354f 4704 if (rc != 0) {
068e94ea
MCC
4705 pr_err("error %d\n", rc);
4706 goto rw_error;
4707 }
57afe2f0
MCC
4708
4709 agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
63713517 4710 if (common_attr->tuner_rf_agc_pol == true)
57afe2f0 4711 agc_rf = 0x87ff - agc_rf;
57afe2f0
MCC
4712
4713 agc_if = 0x800;
63713517 4714 if (common_attr->tuner_if_agc_pol == true)
57afe2f0 4715 agc_rf = 0x87ff - agc_rf;
57afe2f0 4716
244c0e06 4717 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
9482354f 4718 if (rc != 0) {
068e94ea
MCC
4719 pr_err("error %d\n", rc);
4720 goto rw_error;
4721 }
244c0e06 4722 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
9482354f 4723 if (rc != 0) {
068e94ea
MCC
4724 pr_err("error %d\n", rc);
4725 goto rw_error;
4726 }
38b2df95 4727
443f18d0 4728 /* Set/restore Ki DGAIN factor */
244c0e06 4729 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 4730 if (rc != 0) {
068e94ea
MCC
4731 pr_err("error %d\n", rc);
4732 goto rw_error;
4733 }
443f18d0 4734 data &= ~SCU_RAM_AGC_KI_DGAIN__M;
e33f2193 4735 data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
244c0e06 4736 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 4737 if (rc != 0) {
068e94ea
MCC
4738 pr_err("error %d\n", rc);
4739 goto rw_error;
4740 }
38b2df95 4741
9482354f 4742 return 0;
38b2df95 4743rw_error:
30741871 4744 return rc;
38b2df95
DH
4745}
4746
34eb9751 4747/*
57afe2f0 4748* \fn int set_frequency ()
38b2df95
DH
4749* \brief Set frequency shift.
4750* \param demod instance of demodulator.
4751* \param channel pointer to channel data.
57afe2f0 4752* \param tuner_freq_offset residual frequency from tuner.
61263c75 4753* \return int.
38b2df95 4754*/
61263c75 4755static int
1bfc9e15
MCC
4756set_frequency(struct drx_demod_instance *demod,
4757 struct drx_channel *channel, s32 tuner_freq_offset)
57afe2f0 4758{
4d7bb0eb 4759 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 4760 struct drxj_data *ext_attr = demod->my_ext_attr;
068e94ea 4761 int rc;
57afe2f0
MCC
4762 s32 sampling_frequency = 0;
4763 s32 frequency_shift = 0;
4764 s32 if_freq_actual = 0;
4d7bb0eb 4765 s32 rf_freq_residual = -1 * tuner_freq_offset;
57afe2f0
MCC
4766 s32 adc_freq = 0;
4767 s32 intermediate_freq = 0;
4768 u32 iqm_fs_rate_ofs = 0;
57afe2f0
MCC
4769 bool adc_flip = true;
4770 bool select_pos_image = false;
4d7bb0eb
MCC
4771 bool rf_mirror;
4772 bool tuner_mirror;
57afe2f0
MCC
4773 bool image_to_select = true;
4774 s32 fm_frequency_shift = 0;
4775
57afe2f0
MCC
4776 rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
4777 tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
443f18d0
MCC
4778 /*
4779 Program frequency shifter
4780 No need to account for mirroring on RF
4781 */
57afe2f0 4782 switch (ext_attr->standard) {
06eeefe8
MCC
4783 case DRX_STANDARD_ITU_A:
4784 case DRX_STANDARD_ITU_C:
4785 case DRX_STANDARD_PAL_SECAM_LP:
443f18d0 4786 case DRX_STANDARD_8VSB:
57afe2f0 4787 select_pos_image = true;
443f18d0
MCC
4788 break;
4789 case DRX_STANDARD_FM:
4790 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
4791 Sound carrier is already 3Mhz above centre frequency due
4792 to tuner setting so now add an extra shift of 1MHz... */
57afe2f0 4793 fm_frequency_shift = 1000;
06eeefe8
MCC
4794 /*fall through */
4795 case DRX_STANDARD_ITU_B:
4796 case DRX_STANDARD_NTSC:
4797 case DRX_STANDARD_PAL_SECAM_BG:
4798 case DRX_STANDARD_PAL_SECAM_DK:
4799 case DRX_STANDARD_PAL_SECAM_I:
443f18d0 4800 case DRX_STANDARD_PAL_SECAM_L:
57afe2f0 4801 select_pos_image = false;
443f18d0
MCC
4802 break;
4803 default:
9482354f 4804 return -EINVAL;
443f18d0 4805 }
57afe2f0
MCC
4806 intermediate_freq = demod->my_common_attr->intermediate_freq;
4807 sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
63713517
MCC
4808 if (tuner_mirror)
4809 if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
4810 else
4811 if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
57afe2f0 4812 if (if_freq_actual > sampling_frequency / 2) {
443f18d0 4813 /* adc mirrors */
57afe2f0
MCC
4814 adc_freq = sampling_frequency - if_freq_actual;
4815 adc_flip = true;
443f18d0
MCC
4816 } else {
4817 /* adc doesn't mirror */
57afe2f0
MCC
4818 adc_freq = if_freq_actual;
4819 adc_flip = false;
443f18d0
MCC
4820 }
4821
57afe2f0
MCC
4822 frequency_shift = adc_freq;
4823 image_to_select =
4824 (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
4825 iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
443f18d0 4826
57afe2f0
MCC
4827 if (image_to_select)
4828 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
443f18d0
MCC
4829
4830 /* Program frequency shifter with tuner offset compensation */
57afe2f0 4831 /* frequency_shift += tuner_freq_offset; TODO */
244c0e06 4832 rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
9482354f 4833 if (rc != 0) {
068e94ea
MCC
4834 pr_err("error %d\n", rc);
4835 goto rw_error;
4836 }
57afe2f0
MCC
4837 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
4838 ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
443f18d0 4839
9482354f 4840 return 0;
38b2df95 4841rw_error:
30741871 4842 return rc;
38b2df95
DH
4843}
4844
34eb9751 4845/*
57afe2f0 4846* \fn int get_acc_pkt_err()
38b2df95
DH
4847* \brief Retrieve signal strength for VSB and QAM.
4848* \param demod Pointer to demod instance
57afe2f0 4849* \param packet_err Pointer to packet error
61263c75 4850* \return int.
9482354f
MCC
4851* \retval 0 sig_strength contains valid data.
4852* \retval -EINVAL sig_strength is NULL.
4853* \retval -EIO Erroneous data, sig_strength contains invalid data.
38b2df95
DH
4854*/
4855#ifdef DRXJ_SIGNAL_ACCUM_ERR
1bfc9e15 4856static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
443f18d0 4857{
068e94ea 4858 int rc;
57afe2f0
MCC
4859 static u16 pkt_err;
4860 static u16 last_pkt_err;
43a431e4 4861 u16 data = 0;
b3ce3a83 4862 struct drxj_data *ext_attr = NULL;
57afe2f0 4863 struct i2c_device_addr *dev_addr = NULL;
443f18d0 4864
b3ce3a83 4865 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0 4866 dev_addr = demod->my_i2c_dev_addr;
443f18d0 4867
244c0e06 4868 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
9482354f 4869 if (rc != 0) {
068e94ea
MCC
4870 pr_err("error %d\n", rc);
4871 goto rw_error;
4872 }
259f380e 4873 if (ext_attr->reset_pkt_err_acc) {
57afe2f0
MCC
4874 last_pkt_err = data;
4875 pkt_err = 0;
4876 ext_attr->reset_pkt_err_acc = false;
443f18d0 4877 }
38b2df95 4878
57afe2f0
MCC
4879 if (data < last_pkt_err) {
4880 pkt_err += 0xffff - last_pkt_err;
4881 pkt_err += data;
443f18d0 4882 } else {
57afe2f0 4883 pkt_err += (data - last_pkt_err);
443f18d0 4884 }
57afe2f0
MCC
4885 *packet_err = pkt_err;
4886 last_pkt_err = data;
38b2df95 4887
9482354f 4888 return 0;
38b2df95 4889rw_error:
30741871 4890 return rc;
38b2df95
DH
4891}
4892#endif
4893
38b2df95
DH
4894
4895/*============================================================================*/
4896
34eb9751 4897/*
57afe2f0 4898* \fn int set_agc_rf ()
38b2df95
DH
4899* \brief Configure RF AGC
4900* \param demod instance of demodulator.
57afe2f0 4901* \param agc_settings AGC configuration structure
61263c75 4902* \return int.
38b2df95 4903*/
61263c75 4904static int
b3ce3a83 4905set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
38b2df95 4906{
57afe2f0 4907 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83
MCC
4908 struct drxj_data *ext_attr = NULL;
4909 struct drxj_cfg_agc *p_agc_settings = NULL;
1bfc9e15 4910 struct drx_common_attr *common_attr = NULL;
068e94ea 4911 int rc;
57afe2f0
MCC
4912 drx_write_reg16func_t scu_wr16 = NULL;
4913 drx_read_reg16func_t scu_rr16 = NULL;
443f18d0 4914
1bfc9e15 4915 common_attr = (struct drx_common_attr *) demod->my_common_attr;
57afe2f0 4916 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 4917 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
4918
4919 if (atomic) {
57afe2f0
MCC
4920 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
4921 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
443f18d0 4922 } else {
244c0e06
MCC
4923 scu_rr16 = drxj_dap_read_reg16;
4924 scu_wr16 = drxj_dap_write_reg16;
443f18d0
MCC
4925 }
4926
4927 /* Configure AGC only if standard is currently active */
57afe2f0
MCC
4928 if ((ext_attr->standard == agc_settings->standard) ||
4929 (DRXJ_ISQAMSTD(ext_attr->standard) &&
4930 DRXJ_ISQAMSTD(agc_settings->standard)) ||
4931 (DRXJ_ISATVSTD(ext_attr->standard) &&
4932 DRXJ_ISATVSTD(agc_settings->standard))) {
43a431e4 4933 u16 data = 0;
443f18d0 4934
57afe2f0 4935 switch (agc_settings->ctrl_mode) {
443f18d0
MCC
4936 case DRX_AGC_CTRL_AUTO:
4937
4938 /* Enable RF AGC DAC */
244c0e06 4939 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 4940 if (rc != 0) {
068e94ea
MCC
4941 pr_err("error %d\n", rc);
4942 goto rw_error;
4943 }
443f18d0 4944 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
244c0e06 4945 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 4946 if (rc != 0) {
068e94ea
MCC
4947 pr_err("error %d\n", rc);
4948 goto rw_error;
4949 }
443f18d0
MCC
4950
4951 /* Enable SCU RF AGC loop */
068e94ea 4952 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 4953 if (rc != 0) {
068e94ea
MCC
4954 pr_err("error %d\n", rc);
4955 goto rw_error;
4956 }
443f18d0 4957 data &= ~SCU_RAM_AGC_KI_RF__M;
63713517 4958 if (ext_attr->standard == DRX_STANDARD_8VSB)
443f18d0 4959 data |= (2 << SCU_RAM_AGC_KI_RF__B);
63713517 4960 else if (DRXJ_ISQAMSTD(ext_attr->standard))
443f18d0 4961 data |= (5 << SCU_RAM_AGC_KI_RF__B);
63713517 4962 else
443f18d0 4963 data |= (4 << SCU_RAM_AGC_KI_RF__B);
443f18d0 4964
63713517 4965 if (common_attr->tuner_rf_agc_pol)
443f18d0 4966 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
63713517 4967 else
443f18d0 4968 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
068e94ea 4969 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 4970 if (rc != 0) {
068e94ea
MCC
4971 pr_err("error %d\n", rc);
4972 goto rw_error;
4973 }
443f18d0
MCC
4974
4975 /* Set speed ( using complementary reduction value ) */
068e94ea 4976 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
9482354f 4977 if (rc != 0) {
068e94ea
MCC
4978 pr_err("error %d\n", rc);
4979 goto rw_error;
4980 }
443f18d0 4981 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
63713517 4982 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 4983 if (rc != 0) {
068e94ea
MCC
4984 pr_err("error %d\n", rc);
4985 goto rw_error;
4986 }
443f18d0 4987
57afe2f0
MCC
4988 if (agc_settings->standard == DRX_STANDARD_8VSB)
4989 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
4990 else if (DRXJ_ISQAMSTD(agc_settings->standard))
4991 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
4992 else if (DRXJ_ISATVSTD(agc_settings->standard))
4993 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
443f18d0 4994 else
9482354f 4995 return -EINVAL;
443f18d0
MCC
4996
4997 /* Set TOP, only if IF-AGC is in AUTO mode */
57afe2f0 4998 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
068e94ea 4999 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
9482354f 5000 if (rc != 0) {
068e94ea
MCC
5001 pr_err("error %d\n", rc);
5002 goto rw_error;
5003 }
5004 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
9482354f 5005 if (rc != 0) {
068e94ea
MCC
5006 pr_err("error %d\n", rc);
5007 goto rw_error;
5008 }
443f18d0
MCC
5009 }
5010
5011 /* Cut-Off current */
068e94ea 5012 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
9482354f 5013 if (rc != 0) {
068e94ea
MCC
5014 pr_err("error %d\n", rc);
5015 goto rw_error;
5016 }
443f18d0
MCC
5017 break;
5018 case DRX_AGC_CTRL_USER:
5019
5020 /* Enable RF AGC DAC */
244c0e06 5021 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5022 if (rc != 0) {
068e94ea
MCC
5023 pr_err("error %d\n", rc);
5024 goto rw_error;
5025 }
443f18d0 5026 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
244c0e06 5027 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5028 if (rc != 0) {
068e94ea
MCC
5029 pr_err("error %d\n", rc);
5030 goto rw_error;
5031 }
443f18d0
MCC
5032
5033 /* Disable SCU RF AGC loop */
068e94ea 5034 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5035 if (rc != 0) {
068e94ea
MCC
5036 pr_err("error %d\n", rc);
5037 goto rw_error;
5038 }
443f18d0 5039 data &= ~SCU_RAM_AGC_KI_RF__M;
63713517 5040 if (common_attr->tuner_rf_agc_pol)
443f18d0 5041 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
63713517 5042 else
443f18d0 5043 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
068e94ea 5044 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5045 if (rc != 0) {
068e94ea
MCC
5046 pr_err("error %d\n", rc);
5047 goto rw_error;
5048 }
443f18d0
MCC
5049
5050 /* Write value to output pin */
068e94ea 5051 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
9482354f 5052 if (rc != 0) {
068e94ea
MCC
5053 pr_err("error %d\n", rc);
5054 goto rw_error;
5055 }
443f18d0
MCC
5056 break;
5057 case DRX_AGC_CTRL_OFF:
5058
5059 /* Disable RF AGC DAC */
244c0e06 5060 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5061 if (rc != 0) {
068e94ea
MCC
5062 pr_err("error %d\n", rc);
5063 goto rw_error;
5064 }
443f18d0 5065 data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
244c0e06 5066 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5067 if (rc != 0) {
068e94ea
MCC
5068 pr_err("error %d\n", rc);
5069 goto rw_error;
5070 }
443f18d0
MCC
5071
5072 /* Disable SCU RF AGC loop */
068e94ea 5073 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5074 if (rc != 0) {
068e94ea
MCC
5075 pr_err("error %d\n", rc);
5076 goto rw_error;
5077 }
443f18d0 5078 data &= ~SCU_RAM_AGC_KI_RF__M;
068e94ea 5079 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5080 if (rc != 0) {
068e94ea
MCC
5081 pr_err("error %d\n", rc);
5082 goto rw_error;
5083 }
443f18d0
MCC
5084 break;
5085 default:
9482354f 5086 return -EINVAL;
57afe2f0 5087 } /* switch ( agcsettings->ctrl_mode ) */
443f18d0
MCC
5088 }
5089
5090 /* Store rf agc settings */
57afe2f0 5091 switch (agc_settings->standard) {
443f18d0 5092 case DRX_STANDARD_8VSB:
57afe2f0 5093 ext_attr->vsb_rf_agc_cfg = *agc_settings;
443f18d0 5094 break;
38b2df95 5095#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
5096 case DRX_STANDARD_ITU_A:
5097 case DRX_STANDARD_ITU_B:
5098 case DRX_STANDARD_ITU_C:
57afe2f0 5099 ext_attr->qam_rf_agc_cfg = *agc_settings;
443f18d0 5100 break;
38b2df95 5101#endif
443f18d0 5102 default:
9482354f 5103 return -EIO;
443f18d0 5104 }
38b2df95 5105
9482354f 5106 return 0;
38b2df95 5107rw_error:
30741871 5108 return rc;
38b2df95
DH
5109}
5110
34eb9751 5111/*
57afe2f0 5112* \fn int set_agc_if ()
38b2df95
DH
5113* \brief Configure If AGC
5114* \param demod instance of demodulator.
57afe2f0 5115* \param agc_settings AGC configuration structure
61263c75 5116* \return int.
38b2df95 5117*/
61263c75 5118static int
b3ce3a83 5119set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
38b2df95 5120{
57afe2f0 5121 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83
MCC
5122 struct drxj_data *ext_attr = NULL;
5123 struct drxj_cfg_agc *p_agc_settings = NULL;
1bfc9e15 5124 struct drx_common_attr *common_attr = NULL;
57afe2f0
MCC
5125 drx_write_reg16func_t scu_wr16 = NULL;
5126 drx_read_reg16func_t scu_rr16 = NULL;
068e94ea 5127 int rc;
443f18d0 5128
1bfc9e15 5129 common_attr = (struct drx_common_attr *) demod->my_common_attr;
57afe2f0 5130 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 5131 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
5132
5133 if (atomic) {
57afe2f0
MCC
5134 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
5135 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
443f18d0 5136 } else {
244c0e06
MCC
5137 scu_rr16 = drxj_dap_read_reg16;
5138 scu_wr16 = drxj_dap_write_reg16;
443f18d0
MCC
5139 }
5140
5141 /* Configure AGC only if standard is currently active */
57afe2f0
MCC
5142 if ((ext_attr->standard == agc_settings->standard) ||
5143 (DRXJ_ISQAMSTD(ext_attr->standard) &&
5144 DRXJ_ISQAMSTD(agc_settings->standard)) ||
5145 (DRXJ_ISATVSTD(ext_attr->standard) &&
5146 DRXJ_ISATVSTD(agc_settings->standard))) {
43a431e4 5147 u16 data = 0;
443f18d0 5148
57afe2f0 5149 switch (agc_settings->ctrl_mode) {
443f18d0
MCC
5150 case DRX_AGC_CTRL_AUTO:
5151 /* Enable IF AGC DAC */
244c0e06 5152 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5153 if (rc != 0) {
068e94ea
MCC
5154 pr_err("error %d\n", rc);
5155 goto rw_error;
5156 }
443f18d0 5157 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
244c0e06 5158 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5159 if (rc != 0) {
068e94ea
MCC
5160 pr_err("error %d\n", rc);
5161 goto rw_error;
5162 }
443f18d0
MCC
5163
5164 /* Enable SCU IF AGC loop */
068e94ea 5165 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5166 if (rc != 0) {
068e94ea
MCC
5167 pr_err("error %d\n", rc);
5168 goto rw_error;
5169 }
443f18d0
MCC
5170 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5171 data &= ~SCU_RAM_AGC_KI_IF__M;
63713517 5172 if (ext_attr->standard == DRX_STANDARD_8VSB)
443f18d0 5173 data |= (3 << SCU_RAM_AGC_KI_IF__B);
63713517 5174 else if (DRXJ_ISQAMSTD(ext_attr->standard))
443f18d0 5175 data |= (6 << SCU_RAM_AGC_KI_IF__B);
63713517 5176 else
443f18d0 5177 data |= (5 << SCU_RAM_AGC_KI_IF__B);
443f18d0 5178
63713517 5179 if (common_attr->tuner_if_agc_pol)
443f18d0 5180 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
63713517 5181 else
443f18d0 5182 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
068e94ea 5183 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5184 if (rc != 0) {
068e94ea
MCC
5185 pr_err("error %d\n", rc);
5186 goto rw_error;
5187 }
443f18d0
MCC
5188
5189 /* Set speed (using complementary reduction value) */
068e94ea 5190 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
9482354f 5191 if (rc != 0) {
068e94ea
MCC
5192 pr_err("error %d\n", rc);
5193 goto rw_error;
5194 }
443f18d0 5195 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
068e94ea 5196 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 5197 if (rc != 0) {
068e94ea
MCC
5198 pr_err("error %d\n", rc);
5199 goto rw_error;
5200 }
443f18d0 5201
57afe2f0
MCC
5202 if (agc_settings->standard == DRX_STANDARD_8VSB)
5203 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
5204 else if (DRXJ_ISQAMSTD(agc_settings->standard))
5205 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
5206 else if (DRXJ_ISATVSTD(agc_settings->standard))
5207 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
443f18d0 5208 else
9482354f 5209 return -EINVAL;
443f18d0
MCC
5210
5211 /* Restore TOP */
57afe2f0 5212 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
068e94ea 5213 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
9482354f 5214 if (rc != 0) {
068e94ea
MCC
5215 pr_err("error %d\n", rc);
5216 goto rw_error;
5217 }
5218 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
9482354f 5219 if (rc != 0) {
068e94ea
MCC
5220 pr_err("error %d\n", rc);
5221 goto rw_error;
5222 }
443f18d0 5223 } else {
068e94ea 5224 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
9482354f 5225 if (rc != 0) {
068e94ea
MCC
5226 pr_err("error %d\n", rc);
5227 goto rw_error;
5228 }
5229 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
9482354f 5230 if (rc != 0) {
068e94ea
MCC
5231 pr_err("error %d\n", rc);
5232 goto rw_error;
5233 }
443f18d0
MCC
5234 }
5235 break;
5236
5237 case DRX_AGC_CTRL_USER:
5238
5239 /* Enable IF AGC DAC */
244c0e06 5240 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5241 if (rc != 0) {
068e94ea
MCC
5242 pr_err("error %d\n", rc);
5243 goto rw_error;
5244 }
443f18d0 5245 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
244c0e06 5246 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5247 if (rc != 0) {
068e94ea
MCC
5248 pr_err("error %d\n", rc);
5249 goto rw_error;
5250 }
443f18d0
MCC
5251
5252 /* Disable SCU IF AGC loop */
068e94ea 5253 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5254 if (rc != 0) {
068e94ea
MCC
5255 pr_err("error %d\n", rc);
5256 goto rw_error;
5257 }
443f18d0
MCC
5258 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5259 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
63713517 5260 if (common_attr->tuner_if_agc_pol)
443f18d0 5261 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
63713517 5262 else
443f18d0 5263 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
068e94ea 5264 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5265 if (rc != 0) {
068e94ea
MCC
5266 pr_err("error %d\n", rc);
5267 goto rw_error;
5268 }
443f18d0
MCC
5269
5270 /* Write value to output pin */
068e94ea 5271 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
9482354f 5272 if (rc != 0) {
068e94ea
MCC
5273 pr_err("error %d\n", rc);
5274 goto rw_error;
5275 }
443f18d0
MCC
5276 break;
5277
5278 case DRX_AGC_CTRL_OFF:
5279
5280 /* Disable If AGC DAC */
244c0e06 5281 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5282 if (rc != 0) {
068e94ea
MCC
5283 pr_err("error %d\n", rc);
5284 goto rw_error;
5285 }
443f18d0 5286 data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
244c0e06 5287 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5288 if (rc != 0) {
068e94ea
MCC
5289 pr_err("error %d\n", rc);
5290 goto rw_error;
5291 }
443f18d0
MCC
5292
5293 /* Disable SCU IF AGC loop */
068e94ea 5294 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
9482354f 5295 if (rc != 0) {
068e94ea
MCC
5296 pr_err("error %d\n", rc);
5297 goto rw_error;
5298 }
443f18d0
MCC
5299 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5300 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
068e94ea 5301 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
9482354f 5302 if (rc != 0) {
068e94ea
MCC
5303 pr_err("error %d\n", rc);
5304 goto rw_error;
5305 }
443f18d0
MCC
5306 break;
5307 default:
9482354f 5308 return -EINVAL;
57afe2f0 5309 } /* switch ( agcsettings->ctrl_mode ) */
443f18d0
MCC
5310
5311 /* always set the top to support configurations without if-loop */
068e94ea 5312 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
9482354f 5313 if (rc != 0) {
068e94ea
MCC
5314 pr_err("error %d\n", rc);
5315 goto rw_error;
5316 }
443f18d0
MCC
5317 }
5318
5319 /* Store if agc settings */
57afe2f0 5320 switch (agc_settings->standard) {
443f18d0 5321 case DRX_STANDARD_8VSB:
57afe2f0 5322 ext_attr->vsb_if_agc_cfg = *agc_settings;
443f18d0 5323 break;
38b2df95 5324#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
5325 case DRX_STANDARD_ITU_A:
5326 case DRX_STANDARD_ITU_B:
5327 case DRX_STANDARD_ITU_C:
57afe2f0 5328 ext_attr->qam_if_agc_cfg = *agc_settings;
443f18d0 5329 break;
38b2df95 5330#endif
443f18d0 5331 default:
9482354f 5332 return -EIO;
443f18d0 5333 }
38b2df95 5334
9482354f 5335 return 0;
38b2df95 5336rw_error:
30741871 5337 return rc;
38b2df95
DH
5338}
5339
34eb9751 5340/*
57afe2f0 5341* \fn int set_iqm_af ()
38b2df95
DH
5342* \brief Configure IQM AF registers
5343* \param demod instance of demodulator.
5344* \param active
61263c75 5345* \return int.
38b2df95 5346*/
1bfc9e15 5347static int set_iqm_af(struct drx_demod_instance *demod, bool active)
38b2df95 5348{
43a431e4 5349 u16 data = 0;
57afe2f0 5350 struct i2c_device_addr *dev_addr = NULL;
068e94ea 5351 int rc;
38b2df95 5352
57afe2f0 5353 dev_addr = demod->my_i2c_dev_addr;
38b2df95 5354
443f18d0 5355 /* Configure IQM */
244c0e06 5356 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
9482354f 5357 if (rc != 0) {
068e94ea
MCC
5358 pr_err("error %d\n", rc);
5359 goto rw_error;
5360 }
63713517
MCC
5361 if (!active)
5362 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));
5363 else
5364 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 5365 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
9482354f 5366 if (rc != 0) {
068e94ea
MCC
5367 pr_err("error %d\n", rc);
5368 goto rw_error;
5369 }
443f18d0 5370
9482354f 5371 return 0;
38b2df95 5372rw_error:
30741871 5373 return rc;
38b2df95
DH
5374}
5375
5376/*============================================================================*/
5377/*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5378/*============================================================================*/
5379
5380/*============================================================================*/
5381/*============================================================================*/
5382/*== 8VSB DATAPATH FUNCTIONS ==*/
5383/*============================================================================*/
5384/*============================================================================*/
5385
34eb9751 5386/*
57afe2f0 5387* \fn int power_down_vsb ()
38b2df95
DH
5388* \brief Powr down QAM related blocks.
5389* \param demod instance of demodulator.
5390* \param channel pointer to channel data.
61263c75 5391* \return int.
38b2df95 5392*/
1bfc9e15 5393static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
443f18d0 5394{
4d7bb0eb 5395 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 5396 struct drxjscu_cmd cmd_scu = { /* command */ 0,
57afe2f0
MCC
5397 /* parameter_len */ 0,
5398 /* result_len */ 0,
443f18d0
MCC
5399 /* *parameter */ NULL,
5400 /* *result */ NULL
5401 };
1bfc9e15 5402 struct drx_cfg_mpeg_output cfg_mpeg_output;
068e94ea
MCC
5403 int rc;
5404 u16 cmd_result = 0;
443f18d0 5405
443f18d0
MCC
5406 /*
5407 STOP demodulator
5408 reset of FEC and VSB HW
5409 */
57afe2f0 5410 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
443f18d0 5411 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
57afe2f0
MCC
5412 cmd_scu.parameter_len = 0;
5413 cmd_scu.result_len = 1;
5414 cmd_scu.parameter = NULL;
5415 cmd_scu.result = &cmd_result;
068e94ea 5416 rc = scu_command(dev_addr, &cmd_scu);
9482354f 5417 if (rc != 0) {
068e94ea
MCC
5418 pr_err("error %d\n", rc);
5419 goto rw_error;
5420 }
443f18d0
MCC
5421
5422 /* stop all comm_exec */
244c0e06 5423 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9482354f 5424 if (rc != 0) {
068e94ea
MCC
5425 pr_err("error %d\n", rc);
5426 goto rw_error;
5427 }
244c0e06 5428 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
9482354f 5429 if (rc != 0) {
068e94ea
MCC
5430 pr_err("error %d\n", rc);
5431 goto rw_error;
5432 }
259f380e 5433 if (primary) {
244c0e06 5434 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9482354f 5435 if (rc != 0) {
068e94ea
MCC
5436 pr_err("error %d\n", rc);
5437 goto rw_error;
5438 }
5439 rc = set_iqm_af(demod, false);
9482354f 5440 if (rc != 0) {
068e94ea
MCC
5441 pr_err("error %d\n", rc);
5442 goto rw_error;
5443 }
443f18d0 5444 } else {
244c0e06 5445 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 5446 if (rc != 0) {
068e94ea
MCC
5447 pr_err("error %d\n", rc);
5448 goto rw_error;
5449 }
244c0e06 5450 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 5451 if (rc != 0) {
068e94ea
MCC
5452 pr_err("error %d\n", rc);
5453 goto rw_error;
5454 }
244c0e06 5455 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 5456 if (rc != 0) {
068e94ea
MCC
5457 pr_err("error %d\n", rc);
5458 goto rw_error;
5459 }
244c0e06 5460 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 5461 if (rc != 0) {
068e94ea
MCC
5462 pr_err("error %d\n", rc);
5463 goto rw_error;
5464 }
244c0e06 5465 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 5466 if (rc != 0) {
068e94ea
MCC
5467 pr_err("error %d\n", rc);
5468 goto rw_error;
5469 }
443f18d0 5470 }
38b2df95 5471
57afe2f0 5472 cfg_mpeg_output.enable_mpeg_output = false;
068e94ea 5473 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 5474 if (rc != 0) {
068e94ea
MCC
5475 pr_err("error %d\n", rc);
5476 goto rw_error;
5477 }
38b2df95 5478
9482354f 5479 return 0;
38b2df95 5480rw_error:
30741871 5481 return rc;
38b2df95 5482}
443f18d0 5483
34eb9751 5484/*
57afe2f0 5485* \fn int set_vsb_leak_n_gain ()
38b2df95
DH
5486* \brief Set ATSC demod.
5487* \param demod instance of demodulator.
61263c75 5488* \return int.
38b2df95 5489*/
1bfc9e15 5490static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
443f18d0 5491{
57afe2f0 5492 struct i2c_device_addr *dev_addr = NULL;
068e94ea 5493 int rc;
443f18d0 5494
679cfbb1 5495 static const u8 vsb_ffe_leak_gain_ram0[] = {
443f18d0
MCC
5496 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
5497 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
5498 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
5499 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
5500 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
5501 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
5502 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
5503 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
5504 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
5505 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
5506 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
5507 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
5508 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
5509 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
5510 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
5511 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
5512 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
5513 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
5514 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
5515 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
5516 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
5517 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
5518 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
5519 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
5520 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
5521 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
5522 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
5523 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
5524 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
5525 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
5526 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
5527 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
5528 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
5529 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
5530 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
5531 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
5532 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
5533 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
5534 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
5535 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
5536 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
5537 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
5538 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
5539 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
5540 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
5541 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
5542 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
5543 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
5544 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
5545 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
5546 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
5547 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
5548 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
5549 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
5550 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
5551 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
5552 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
5553 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
5554 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
5555 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
5556 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
5557 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
5558 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
5559 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
5560 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
5561 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
5562 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
5563 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
5564 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
5565 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
5566 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
5567 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
5568 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
5569 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
5570 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
5571 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
5572 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
5573 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
5574 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
5575 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
5576 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
5577 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
5578 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
5579 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
5580 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
5581 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
5582 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
5583 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
5584 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
5585 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
5586 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
5587 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
5588 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
5589 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
5590 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
5591 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
5592 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
5593 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
5594 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
5595 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
5596 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
5597 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
5598 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
5599 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
5600 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
5601 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
5602 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
5603 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
5604 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
5605 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
5606 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
5607 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
5608 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
5609 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
5610 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
5611 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
5612 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
5613 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
5614 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
5615 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
5616 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
5617 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
5618 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
5619 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
5620 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
5621 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
5622 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
5623 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
5624 };
5625
679cfbb1 5626 static const u8 vsb_ffe_leak_gain_ram1[] = {
443f18d0
MCC
5627 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
5628 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
5629 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
5630 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
5631 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
5632 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
5633 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
5634 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
5635 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
5636 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
5637 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
5638 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
5639 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
5640 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
5641 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
5642 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
5643 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
5644 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
5645 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
5646 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
5647 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
5648 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
5649 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
5650 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
5651 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
5652 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
5653 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
5654 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
5655 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
5656 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
5657 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
5658 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
5659 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
5660 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
5661 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
5662 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
5663 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
5664 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
5665 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
5666 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
5667 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
5668 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
5669 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
5670 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
5671 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
5672 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
5673 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
5674 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
5675 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
5676 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
5677 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
5678 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
5679 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
5680 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
5681 };
5682
57afe2f0 5683 dev_addr = demod->my_i2c_dev_addr;
244c0e06 5684 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 5685 if (rc != 0) {
068e94ea
MCC
5686 pr_err("error %d\n", rc);
5687 goto rw_error;
5688 }
244c0e06 5689 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 5690 if (rc != 0) {
068e94ea
MCC
5691 pr_err("error %d\n", rc);
5692 goto rw_error;
5693 }
443f18d0 5694
9482354f 5695 return 0;
38b2df95 5696rw_error:
30741871 5697 return rc;
38b2df95
DH
5698}
5699
34eb9751 5700/*
57afe2f0 5701* \fn int set_vsb()
38b2df95
DH
5702* \brief Set 8VSB demod.
5703* \param demod instance of demodulator.
61263c75 5704* \return int.
38b2df95
DH
5705*
5706*/
1bfc9e15 5707static int set_vsb(struct drx_demod_instance *demod)
443f18d0 5708{
57afe2f0 5709 struct i2c_device_addr *dev_addr = NULL;
068e94ea 5710 int rc;
1bfc9e15 5711 struct drx_common_attr *common_attr = NULL;
b3ce3a83
MCC
5712 struct drxjscu_cmd cmd_scu;
5713 struct drxj_data *ext_attr = NULL;
068e94ea
MCC
5714 u16 cmd_result = 0;
5715 u16 cmd_param = 0;
679cfbb1 5716 static const u8 vsb_taps_re[] = {
443f18d0
MCC
5717 DRXJ_16TO8(-2), /* re0 */
5718 DRXJ_16TO8(4), /* re1 */
5719 DRXJ_16TO8(1), /* re2 */
5720 DRXJ_16TO8(-4), /* re3 */
5721 DRXJ_16TO8(1), /* re4 */
5722 DRXJ_16TO8(4), /* re5 */
5723 DRXJ_16TO8(-3), /* re6 */
5724 DRXJ_16TO8(-3), /* re7 */
5725 DRXJ_16TO8(6), /* re8 */
5726 DRXJ_16TO8(1), /* re9 */
5727 DRXJ_16TO8(-9), /* re10 */
5728 DRXJ_16TO8(3), /* re11 */
5729 DRXJ_16TO8(12), /* re12 */
5730 DRXJ_16TO8(-9), /* re13 */
5731 DRXJ_16TO8(-15), /* re14 */
5732 DRXJ_16TO8(17), /* re15 */
5733 DRXJ_16TO8(19), /* re16 */
5734 DRXJ_16TO8(-29), /* re17 */
5735 DRXJ_16TO8(-22), /* re18 */
5736 DRXJ_16TO8(45), /* re19 */
5737 DRXJ_16TO8(25), /* re20 */
5738 DRXJ_16TO8(-70), /* re21 */
5739 DRXJ_16TO8(-28), /* re22 */
5740 DRXJ_16TO8(111), /* re23 */
5741 DRXJ_16TO8(30), /* re24 */
5742 DRXJ_16TO8(-201), /* re25 */
5743 DRXJ_16TO8(-31), /* re26 */
5744 DRXJ_16TO8(629) /* re27 */
5745 };
5746
57afe2f0 5747 dev_addr = demod->my_i2c_dev_addr;
1bfc9e15 5748 common_attr = (struct drx_common_attr *) demod->my_common_attr;
b3ce3a83 5749 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
5750
5751 /* stop all comm_exec */
244c0e06 5752 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9482354f 5753 if (rc != 0) {
068e94ea
MCC
5754 pr_err("error %d\n", rc);
5755 goto rw_error;
5756 }
244c0e06 5757 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
9482354f 5758 if (rc != 0) {
068e94ea
MCC
5759 pr_err("error %d\n", rc);
5760 goto rw_error;
5761 }
244c0e06 5762 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 5763 if (rc != 0) {
068e94ea
MCC
5764 pr_err("error %d\n", rc);
5765 goto rw_error;
5766 }
244c0e06 5767 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 5768 if (rc != 0) {
068e94ea
MCC
5769 pr_err("error %d\n", rc);
5770 goto rw_error;
5771 }
244c0e06 5772 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 5773 if (rc != 0) {
068e94ea
MCC
5774 pr_err("error %d\n", rc);
5775 goto rw_error;
5776 }
244c0e06 5777 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 5778 if (rc != 0) {
068e94ea
MCC
5779 pr_err("error %d\n", rc);
5780 goto rw_error;
5781 }
244c0e06 5782 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 5783 if (rc != 0) {
068e94ea
MCC
5784 pr_err("error %d\n", rc);
5785 goto rw_error;
5786 }
443f18d0
MCC
5787
5788 /* reset demodulator */
57afe2f0 5789 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
443f18d0 5790 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
57afe2f0
MCC
5791 cmd_scu.parameter_len = 0;
5792 cmd_scu.result_len = 1;
5793 cmd_scu.parameter = NULL;
5794 cmd_scu.result = &cmd_result;
068e94ea 5795 rc = scu_command(dev_addr, &cmd_scu);
9482354f 5796 if (rc != 0) {
068e94ea
MCC
5797 pr_err("error %d\n", rc);
5798 goto rw_error;
5799 }
57afe2f0 5800
244c0e06 5801 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
9482354f 5802 if (rc != 0) {
068e94ea
MCC
5803 pr_err("error %d\n", rc);
5804 goto rw_error;
5805 }
244c0e06 5806 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
9482354f 5807 if (rc != 0) {
068e94ea
MCC
5808 pr_err("error %d\n", rc);
5809 goto rw_error;
5810 }
244c0e06 5811 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
9482354f 5812 if (rc != 0) {
068e94ea
MCC
5813 pr_err("error %d\n", rc);
5814 goto rw_error;
5815 }
57afe2f0 5816 ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
244c0e06 5817 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
9482354f 5818 if (rc != 0) {
068e94ea
MCC
5819 pr_err("error %d\n", rc);
5820 goto rw_error;
5821 }
244c0e06 5822 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
9482354f 5823 if (rc != 0) {
068e94ea
MCC
5824 pr_err("error %d\n", rc);
5825 goto rw_error;
5826 }
244c0e06 5827 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
9482354f 5828 if (rc != 0) {
068e94ea
MCC
5829 pr_err("error %d\n", rc);
5830 goto rw_error;
5831 }
5832
244c0e06 5833 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
9482354f 5834 if (rc != 0) {
068e94ea
MCC
5835 pr_err("error %d\n", rc);
5836 goto rw_error;
5837 }
244c0e06 5838 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, 28, 0);
9482354f 5839 if (rc != 0) {
068e94ea
MCC
5840 pr_err("error %d\n", rc);
5841 goto rw_error;
5842 }
244c0e06 5843 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
9482354f 5844 if (rc != 0) {
068e94ea
MCC
5845 pr_err("error %d\n", rc);
5846 goto rw_error;
5847 }
244c0e06 5848 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
9482354f 5849 if (rc != 0) {
068e94ea
MCC
5850 pr_err("error %d\n", rc);
5851 goto rw_error;
5852 }
244c0e06 5853 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
9482354f 5854 if (rc != 0) {
068e94ea
MCC
5855 pr_err("error %d\n", rc);
5856 goto rw_error;
5857 }
244c0e06 5858 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
9482354f 5859 if (rc != 0) {
068e94ea
MCC
5860 pr_err("error %d\n", rc);
5861 goto rw_error;
5862 }
244c0e06 5863 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, 1393, 0);
9482354f 5864 if (rc != 0) {
068e94ea
MCC
5865 pr_err("error %d\n", rc);
5866 goto rw_error;
5867 }
244c0e06 5868 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
9482354f 5869 if (rc != 0) {
068e94ea
MCC
5870 pr_err("error %d\n", rc);
5871 goto rw_error;
5872 }
244c0e06 5873 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
9482354f 5874 if (rc != 0) {
068e94ea
MCC
5875 pr_err("error %d\n", rc);
5876 goto rw_error;
5877 }
5878
244c0e06 5879 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
9482354f 5880 if (rc != 0) {
068e94ea
MCC
5881 pr_err("error %d\n", rc);
5882 goto rw_error;
5883 }
244c0e06 5884 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
9482354f 5885 if (rc != 0) {
068e94ea
MCC
5886 pr_err("error %d\n", rc);
5887 goto rw_error;
5888 }
5889
244c0e06 5890 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
9482354f 5891 if (rc != 0) {
068e94ea
MCC
5892 pr_err("error %d\n", rc);
5893 goto rw_error;
5894 } /* set higher threshold */
244c0e06 5895 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
9482354f 5896 if (rc != 0) {
068e94ea
MCC
5897 pr_err("error %d\n", rc);
5898 goto rw_error;
5899 } /* burst detection on */
244c0e06 5900 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
9482354f 5901 if (rc != 0) {
068e94ea
MCC
5902 pr_err("error %d\n", rc);
5903 goto rw_error;
5904 } /* drop thresholds by 1 dB */
244c0e06 5905 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
9482354f 5906 if (rc != 0) {
068e94ea
MCC
5907 pr_err("error %d\n", rc);
5908 goto rw_error;
5909 } /* drop thresholds by 2 dB */
244c0e06 5910 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
9482354f 5911 if (rc != 0) {
068e94ea
MCC
5912 pr_err("error %d\n", rc);
5913 goto rw_error;
5914 } /* cma on */
244c0e06 5915 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
9482354f 5916 if (rc != 0) {
068e94ea
MCC
5917 pr_err("error %d\n", rc);
5918 goto rw_error;
5919 } /* GPIO */
443f18d0
MCC
5920
5921 /* Initialize the FEC Subsystem */
244c0e06 5922 rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
9482354f 5923 if (rc != 0) {
068e94ea
MCC
5924 pr_err("error %d\n", rc);
5925 goto rw_error;
5926 }
443f18d0 5927 {
57afe2f0 5928 u16 fec_oc_snc_mode = 0;
244c0e06 5929 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
9482354f 5930 if (rc != 0) {
068e94ea
MCC
5931 pr_err("error %d\n", rc);
5932 goto rw_error;
5933 }
443f18d0 5934 /* output data even when not locked */
244c0e06 5935 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 5936 if (rc != 0) {
068e94ea
MCC
5937 pr_err("error %d\n", rc);
5938 goto rw_error;
5939 }
443f18d0 5940 }
38b2df95 5941
443f18d0 5942 /* set clip */
244c0e06 5943 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
9482354f 5944 if (rc != 0) {
068e94ea
MCC
5945 pr_err("error %d\n", rc);
5946 goto rw_error;
5947 }
244c0e06 5948 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
9482354f 5949 if (rc != 0) {
068e94ea
MCC
5950 pr_err("error %d\n", rc);
5951 goto rw_error;
5952 }
244c0e06 5953 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
9482354f 5954 if (rc != 0) {
068e94ea
MCC
5955 pr_err("error %d\n", rc);
5956 goto rw_error;
5957 }
244c0e06 5958 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
9482354f 5959 if (rc != 0) {
068e94ea
MCC
5960 pr_err("error %d\n", rc);
5961 goto rw_error;
5962 }
443f18d0
MCC
5963 /* no transparent, no A&C framing; parity is set in mpegoutput */
5964 {
57afe2f0 5965 u16 fec_oc_reg_mode = 0;
244c0e06 5966 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
9482354f 5967 if (rc != 0) {
068e94ea
MCC
5968 pr_err("error %d\n", rc);
5969 goto rw_error;
5970 }
244c0e06 5971 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 5972 if (rc != 0) {
068e94ea
MCC
5973 pr_err("error %d\n", rc);
5974 goto rw_error;
5975 }
443f18d0 5976 }
38b2df95 5977
244c0e06 5978 rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
9482354f 5979 if (rc != 0) {
068e94ea
MCC
5980 pr_err("error %d\n", rc);
5981 goto rw_error;
5982 } /* timeout counter for restarting */
244c0e06 5983 rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
9482354f 5984 if (rc != 0) {
068e94ea
MCC
5985 pr_err("error %d\n", rc);
5986 goto rw_error;
5987 }
244c0e06 5988 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, 0, 0);
9482354f 5989 if (rc != 0) {
068e94ea
MCC
5990 pr_err("error %d\n", rc);
5991 goto rw_error;
5992 } /* bypass disabled */
443f18d0 5993 /* initialize RS packet error measurement parameters */
244c0e06 5994 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
9482354f 5995 if (rc != 0) {
068e94ea
MCC
5996 pr_err("error %d\n", rc);
5997 goto rw_error;
5998 }
244c0e06 5999 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
9482354f 6000 if (rc != 0) {
068e94ea
MCC
6001 pr_err("error %d\n", rc);
6002 goto rw_error;
6003 }
443f18d0
MCC
6004
6005 /* init measurement period of MER/SER */
244c0e06 6006 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
9482354f 6007 if (rc != 0) {
068e94ea
MCC
6008 pr_err("error %d\n", rc);
6009 goto rw_error;
6010 }
244c0e06 6011 rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
9482354f 6012 if (rc != 0) {
068e94ea
MCC
6013 pr_err("error %d\n", rc);
6014 goto rw_error;
6015 }
244c0e06 6016 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
9482354f 6017 if (rc != 0) {
068e94ea
MCC
6018 pr_err("error %d\n", rc);
6019 goto rw_error;
6020 }
244c0e06 6021 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
9482354f 6022 if (rc != 0) {
068e94ea
MCC
6023 pr_err("error %d\n", rc);
6024 goto rw_error;
6025 }
443f18d0 6026
244c0e06 6027 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
9482354f 6028 if (rc != 0) {
068e94ea
MCC
6029 pr_err("error %d\n", rc);
6030 goto rw_error;
6031 }
443f18d0 6032 /* B-Input to ADC, PGA+filter in standby */
259f380e 6033 if (!ext_attr->has_lna) {
244c0e06 6034 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
9482354f 6035 if (rc != 0) {
068e94ea
MCC
6036 pr_err("error %d\n", rc);
6037 goto rw_error;
6038 }
259f380e 6039 }
443f18d0
MCC
6040
6041 /* turn on IQMAF. It has to be in front of setAgc**() */
068e94ea 6042 rc = set_iqm_af(demod, true);
9482354f 6043 if (rc != 0) {
068e94ea
MCC
6044 pr_err("error %d\n", rc);
6045 goto rw_error;
6046 }
6047 rc = adc_synchronization(demod);
9482354f 6048 if (rc != 0) {
068e94ea
MCC
6049 pr_err("error %d\n", rc);
6050 goto rw_error;
6051 }
443f18d0 6052
068e94ea 6053 rc = init_agc(demod);
9482354f 6054 if (rc != 0) {
068e94ea
MCC
6055 pr_err("error %d\n", rc);
6056 goto rw_error;
6057 }
6058 rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
9482354f 6059 if (rc != 0) {
068e94ea
MCC
6060 pr_err("error %d\n", rc);
6061 goto rw_error;
6062 }
6063 rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
9482354f 6064 if (rc != 0) {
068e94ea
MCC
6065 pr_err("error %d\n", rc);
6066 goto rw_error;
6067 }
443f18d0 6068 {
b3ce3a83 6069 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
443f18d0 6070 of only the gain */
b3ce3a83 6071 struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
443f18d0 6072
57afe2f0 6073 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
068e94ea 6074 rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
9482354f 6075 if (rc != 0) {
068e94ea
MCC
6076 pr_err("error %d\n", rc);
6077 goto rw_error;
6078 }
6079 }
6080 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
9482354f 6081 if (rc != 0) {
068e94ea
MCC
6082 pr_err("error %d\n", rc);
6083 goto rw_error;
443f18d0 6084 }
443f18d0
MCC
6085
6086 /* Mpeg output has to be in front of FEC active */
068e94ea 6087 rc = set_mpegtei_handling(demod);
9482354f 6088 if (rc != 0) {
068e94ea
MCC
6089 pr_err("error %d\n", rc);
6090 goto rw_error;
6091 }
6092 rc = bit_reverse_mpeg_output(demod);
9482354f 6093 if (rc != 0) {
068e94ea
MCC
6094 pr_err("error %d\n", rc);
6095 goto rw_error;
6096 }
6097 rc = set_mpeg_start_width(demod);
9482354f 6098 if (rc != 0) {
068e94ea
MCC
6099 pr_err("error %d\n", rc);
6100 goto rw_error;
6101 }
443f18d0 6102 {
57afe2f0 6103 /* TODO: move to set_standard after hardware reset value problem is solved */
443f18d0 6104 /* Configure initial MPEG output */
1bfc9e15 6105 struct drx_cfg_mpeg_output cfg_mpeg_output;
41b5cc0c
MCC
6106
6107 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
57afe2f0 6108 cfg_mpeg_output.enable_mpeg_output = true;
41b5cc0c 6109
068e94ea 6110 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 6111 if (rc != 0) {
068e94ea
MCC
6112 pr_err("error %d\n", rc);
6113 goto rw_error;
6114 }
443f18d0
MCC
6115 }
6116
6117 /* TBD: what parameters should be set */
57afe2f0
MCC
6118 cmd_param = 0x00; /* Default mode AGC on, etc */
6119 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
443f18d0 6120 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
57afe2f0
MCC
6121 cmd_scu.parameter_len = 1;
6122 cmd_scu.result_len = 1;
6123 cmd_scu.parameter = &cmd_param;
6124 cmd_scu.result = &cmd_result;
068e94ea 6125 rc = scu_command(dev_addr, &cmd_scu);
9482354f 6126 if (rc != 0) {
068e94ea
MCC
6127 pr_err("error %d\n", rc);
6128 goto rw_error;
6129 }
443f18d0 6130
244c0e06 6131 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
9482354f 6132 if (rc != 0) {
068e94ea
MCC
6133 pr_err("error %d\n", rc);
6134 goto rw_error;
6135 }
244c0e06 6136 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
9482354f 6137 if (rc != 0) {
068e94ea
MCC
6138 pr_err("error %d\n", rc);
6139 goto rw_error;
6140 }
244c0e06 6141 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
9482354f 6142 if (rc != 0) {
068e94ea
MCC
6143 pr_err("error %d\n", rc);
6144 goto rw_error;
6145 }
244c0e06 6146 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
9482354f 6147 if (rc != 0) {
068e94ea
MCC
6148 pr_err("error %d\n", rc);
6149 goto rw_error;
6150 }
244c0e06 6151 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
9482354f 6152 if (rc != 0) {
068e94ea
MCC
6153 pr_err("error %d\n", rc);
6154 goto rw_error;
6155 }
244c0e06 6156 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
9482354f 6157 if (rc != 0) {
068e94ea
MCC
6158 pr_err("error %d\n", rc);
6159 goto rw_error;
6160 }
244c0e06 6161 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
9482354f 6162 if (rc != 0) {
068e94ea
MCC
6163 pr_err("error %d\n", rc);
6164 goto rw_error;
6165 }
244c0e06 6166 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
9482354f 6167 if (rc != 0) {
068e94ea
MCC
6168 pr_err("error %d\n", rc);
6169 goto rw_error;
6170 }
6171
6172 /* start demodulator */
6173 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6174 | SCU_RAM_COMMAND_CMD_DEMOD_START;
57afe2f0
MCC
6175 cmd_scu.parameter_len = 0;
6176 cmd_scu.result_len = 1;
6177 cmd_scu.parameter = NULL;
6178 cmd_scu.result = &cmd_result;
068e94ea 6179 rc = scu_command(dev_addr, &cmd_scu);
9482354f 6180 if (rc != 0) {
068e94ea
MCC
6181 pr_err("error %d\n", rc);
6182 goto rw_error;
6183 }
443f18d0 6184
244c0e06 6185 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
9482354f 6186 if (rc != 0) {
068e94ea
MCC
6187 pr_err("error %d\n", rc);
6188 goto rw_error;
6189 }
244c0e06 6190 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
9482354f 6191 if (rc != 0) {
068e94ea
MCC
6192 pr_err("error %d\n", rc);
6193 goto rw_error;
6194 }
244c0e06 6195 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
9482354f 6196 if (rc != 0) {
068e94ea
MCC
6197 pr_err("error %d\n", rc);
6198 goto rw_error;
6199 }
443f18d0 6200
9482354f 6201 return 0;
38b2df95 6202rw_error:
30741871 6203 return rc;
38b2df95
DH
6204}
6205
34eb9751 6206/*
57afe2f0 6207* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
38b2df95
DH
6208* \brief Get the values of packet error in 8VSB mode
6209* \return Error code
6210*/
69832578 6211static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
d591590e 6212 u32 *pck_errs, u32 *pck_count)
443f18d0 6213{
068e94ea 6214 int rc;
43a431e4
MCC
6215 u16 data = 0;
6216 u16 period = 0;
6217 u16 prescale = 0;
e33f2193
MCC
6218 u16 packet_errors_mant = 0;
6219 u16 packet_errors_exp = 0;
443f18d0 6220
244c0e06 6221 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
9482354f 6222 if (rc != 0) {
068e94ea
MCC
6223 pr_err("error %d\n", rc);
6224 goto rw_error;
6225 }
e33f2193
MCC
6226 packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
6227 packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
443f18d0
MCC
6228 >> FEC_RS_NR_FAILURES_EXP__B;
6229 period = FEC_RS_MEASUREMENT_PERIOD;
6230 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6231 /* packet error rate = (error packet number) per second */
6232 /* 77.3 us is time for per packet */
068e94ea
MCC
6233 if (period * prescale == 0) {
6234 pr_err("error: period and/or prescale is zero!\n");
9482354f 6235 return -EIO;
068e94ea 6236 }
69832578
MCC
6237 *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
6238 *pck_count = period * prescale * 77;
443f18d0 6239
9482354f 6240 return 0;
38b2df95 6241rw_error:
30741871 6242 return rc;
38b2df95
DH
6243}
6244
34eb9751 6245/*
57afe2f0 6246* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
38b2df95
DH
6247* \brief Get the values of ber in VSB mode
6248* \return Error code
6249*/
69832578
MCC
6250static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
6251 u32 *ber, u32 *cnt)
443f18d0 6252{
068e94ea 6253 int rc;
43a431e4
MCC
6254 u16 data = 0;
6255 u16 period = 0;
6256 u16 prescale = 0;
57afe2f0
MCC
6257 u16 bit_errors_mant = 0;
6258 u16 bit_errors_exp = 0;
443f18d0 6259
244c0e06 6260 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
9482354f 6261 if (rc != 0) {
068e94ea
MCC
6262 pr_err("error %d\n", rc);
6263 goto rw_error;
6264 }
443f18d0
MCC
6265 period = FEC_RS_MEASUREMENT_PERIOD;
6266 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6267
57afe2f0
MCC
6268 bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
6269 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
443f18d0
MCC
6270 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
6271
69832578
MCC
6272 *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
6273
57afe2f0 6274 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
69832578 6275 *ber = (*cnt) * 26570;
443f18d0 6276 else {
068e94ea
MCC
6277 if (period * prescale == 0) {
6278 pr_err("error: period and/or prescale is zero!\n");
9482354f 6279 return -EIO;
068e94ea 6280 }
69832578
MCC
6281 *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
6282 (bit_errors_exp - 3) : bit_errors_exp);
443f18d0 6283 }
38b2df95 6284
9482354f 6285 return 0;
38b2df95 6286rw_error:
30741871 6287 return rc;
38b2df95
DH
6288}
6289
34eb9751 6290/*
57afe2f0 6291* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
38b2df95
DH
6292* \brief Get the values of ber in VSB mode
6293* \return Error code
6294*/
69832578
MCC
6295static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
6296 u32 *ber, u32 *cnt)
38b2df95 6297{
43a431e4 6298 u16 data = 0;
068e94ea 6299 int rc;
38b2df95 6300
244c0e06 6301 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
9482354f 6302 if (rc != 0) {
068e94ea 6303 pr_err("error %d\n", rc);
69832578 6304 return -EIO;
068e94ea 6305 }
69832578
MCC
6306 *ber = data;
6307 *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
38b2df95 6308
9482354f 6309 return 0;
38b2df95
DH
6310}
6311
34eb9751 6312/*
b6c4065e
MCC
6313* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6314* \brief Get the values of MER
38b2df95
DH
6315* \return Error code
6316*/
b6c4065e 6317static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
38b2df95 6318{
068e94ea 6319 int rc;
b6c4065e 6320 u16 data_hi = 0;
38b2df95 6321
b6c4065e 6322 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
9482354f 6323 if (rc != 0) {
068e94ea
MCC
6324 pr_err("error %d\n", rc);
6325 goto rw_error;
6326 }
b6c4065e
MCC
6327 *mer =
6328 (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
38b2df95 6329
9482354f 6330 return 0;
38b2df95 6331rw_error:
30741871 6332 return rc;
38b2df95 6333}
38b2df95 6334
443f18d0 6335
38b2df95
DH
6336/*============================================================================*/
6337/*== END 8VSB DATAPATH FUNCTIONS ==*/
6338/*============================================================================*/
6339
6340/*============================================================================*/
6341/*============================================================================*/
6342/*== QAM DATAPATH FUNCTIONS ==*/
6343/*============================================================================*/
6344/*============================================================================*/
6345
34eb9751 6346/*
57afe2f0 6347* \fn int power_down_qam ()
38b2df95
DH
6348* \brief Powr down QAM related blocks.
6349* \param demod instance of demodulator.
6350* \param channel pointer to channel data.
61263c75 6351* \return int.
38b2df95 6352*/
1bfc9e15 6353static int power_down_qam(struct drx_demod_instance *demod, bool primary)
38b2df95 6354{
b3ce3a83 6355 struct drxjscu_cmd cmd_scu = { /* command */ 0,
57afe2f0
MCC
6356 /* parameter_len */ 0,
6357 /* result_len */ 0,
443f18d0
MCC
6358 /* *parameter */ NULL,
6359 /* *result */ NULL
6360 };
068e94ea 6361 int rc;
4d7bb0eb 6362 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
1bfc9e15 6363 struct drx_cfg_mpeg_output cfg_mpeg_output;
41b5cc0c 6364 struct drx_common_attr *common_attr = demod->my_common_attr;
068e94ea 6365 u16 cmd_result = 0;
443f18d0 6366
443f18d0
MCC
6367 /*
6368 STOP demodulator
6369 resets IQM, QAM and FEC HW blocks
6370 */
6371 /* stop all comm_exec */
244c0e06 6372 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9482354f 6373 if (rc != 0) {
068e94ea
MCC
6374 pr_err("error %d\n", rc);
6375 goto rw_error;
6376 }
244c0e06 6377 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
9482354f 6378 if (rc != 0) {
068e94ea
MCC
6379 pr_err("error %d\n", rc);
6380 goto rw_error;
6381 }
443f18d0 6382
57afe2f0 6383 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 6384 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
57afe2f0
MCC
6385 cmd_scu.parameter_len = 0;
6386 cmd_scu.result_len = 1;
6387 cmd_scu.parameter = NULL;
6388 cmd_scu.result = &cmd_result;
068e94ea 6389 rc = scu_command(dev_addr, &cmd_scu);
9482354f 6390 if (rc != 0) {
068e94ea
MCC
6391 pr_err("error %d\n", rc);
6392 goto rw_error;
6393 }
443f18d0 6394
259f380e 6395 if (primary) {
244c0e06 6396 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9482354f 6397 if (rc != 0) {
068e94ea
MCC
6398 pr_err("error %d\n", rc);
6399 goto rw_error;
6400 }
6401 rc = set_iqm_af(demod, false);
9482354f 6402 if (rc != 0) {
068e94ea
MCC
6403 pr_err("error %d\n", rc);
6404 goto rw_error;
6405 }
443f18d0 6406 } else {
244c0e06 6407 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 6408 if (rc != 0) {
068e94ea
MCC
6409 pr_err("error %d\n", rc);
6410 goto rw_error;
6411 }
244c0e06 6412 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 6413 if (rc != 0) {
068e94ea
MCC
6414 pr_err("error %d\n", rc);
6415 goto rw_error;
6416 }
244c0e06 6417 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 6418 if (rc != 0) {
068e94ea
MCC
6419 pr_err("error %d\n", rc);
6420 goto rw_error;
6421 }
244c0e06 6422 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 6423 if (rc != 0) {
068e94ea
MCC
6424 pr_err("error %d\n", rc);
6425 goto rw_error;
6426 }
244c0e06 6427 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 6428 if (rc != 0) {
068e94ea
MCC
6429 pr_err("error %d\n", rc);
6430 goto rw_error;
6431 }
443f18d0
MCC
6432 }
6433
41b5cc0c 6434 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
57afe2f0 6435 cfg_mpeg_output.enable_mpeg_output = false;
41b5cc0c 6436
068e94ea 6437 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 6438 if (rc != 0) {
068e94ea
MCC
6439 pr_err("error %d\n", rc);
6440 goto rw_error;
6441 }
38b2df95 6442
9482354f 6443 return 0;
38b2df95 6444rw_error:
30741871 6445 return rc;
38b2df95
DH
6446}
6447
6448/*============================================================================*/
6449
34eb9751 6450/*
57afe2f0 6451* \fn int set_qam_measurement ()
38b2df95
DH
6452* \brief Setup of the QAM Measuremnt intervals for signal quality
6453* \param demod instance of demod.
6454* \param constellation current constellation.
61263c75 6455* \return int.
38b2df95
DH
6456*
6457* NOTE:
6458* Take into account that for certain settings the errorcounters can overflow.
6459* The implementation does not check this.
6460*
57afe2f0
MCC
6461* TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
6462* constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
38b2df95
DH
6463* field ?
6464*
6465*/
6466#ifndef DRXJ_VSB_ONLY
61263c75 6467static int
1bfc9e15 6468set_qam_measurement(struct drx_demod_instance *demod,
22892268 6469 enum drx_modulation constellation, u32 symbol_rate)
57afe2f0
MCC
6470{
6471 struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */
69bb7ab6 6472 struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specific data */
068e94ea 6473 int rc;
57afe2f0
MCC
6474 u32 fec_bits_desired = 0; /* BER accounting period */
6475 u16 fec_rs_plen = 0; /* defines RS BER measurement period */
6476 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
6477 u32 fec_rs_period = 0; /* Value for corresponding I2C register */
6478 u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
6479 u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
6480 u32 qam_vd_period = 0; /* Value for corresponding I2C register */
6481 u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
6482 u16 fec_vd_plen = 0; /* no of trellis symbols: VD SER measur period */
6483 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
6484
6485 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 6486 ext_attr = (struct drxj_data *) demod->my_ext_attr;
57afe2f0
MCC
6487
6488 fec_bits_desired = ext_attr->fec_bits_desired;
6489 fec_rs_prescale = ext_attr->fec_rs_prescale;
443f18d0
MCC
6490
6491 switch (constellation) {
6492 case DRX_CONSTELLATION_QAM16:
57afe2f0 6493 fec_bits_desired = 4 * symbol_rate;
443f18d0
MCC
6494 break;
6495 case DRX_CONSTELLATION_QAM32:
57afe2f0 6496 fec_bits_desired = 5 * symbol_rate;
443f18d0
MCC
6497 break;
6498 case DRX_CONSTELLATION_QAM64:
57afe2f0 6499 fec_bits_desired = 6 * symbol_rate;
443f18d0
MCC
6500 break;
6501 case DRX_CONSTELLATION_QAM128:
57afe2f0 6502 fec_bits_desired = 7 * symbol_rate;
443f18d0
MCC
6503 break;
6504 case DRX_CONSTELLATION_QAM256:
57afe2f0 6505 fec_bits_desired = 8 * symbol_rate;
443f18d0
MCC
6506 break;
6507 default:
9482354f 6508 return -EINVAL;
443f18d0
MCC
6509 }
6510
6511 /* Parameters for Reed-Solomon Decoder */
6512 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
6513 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
6514 /* result is within 32 bit arithmetic -> */
6515 /* no need for mult or frac functions */
6516
57afe2f0
MCC
6517 /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
6518 switch (ext_attr->standard) {
443f18d0
MCC
6519 case DRX_STANDARD_ITU_A:
6520 case DRX_STANDARD_ITU_C:
57afe2f0 6521 fec_rs_plen = 204 * 8;
443f18d0
MCC
6522 break;
6523 case DRX_STANDARD_ITU_B:
57afe2f0 6524 fec_rs_plen = 128 * 7;
443f18d0
MCC
6525 break;
6526 default:
9482354f 6527 return -EINVAL;
443f18d0
MCC
6528 }
6529
57afe2f0
MCC
6530 ext_attr->fec_rs_plen = fec_rs_plen; /* for getSigQual */
6531 fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage */
068e94ea
MCC
6532 if (fec_rs_bit_cnt == 0) {
6533 pr_err("error: fec_rs_bit_cnt is zero!\n");
9482354f 6534 return -EIO;
068e94ea 6535 }
57afe2f0
MCC
6536 fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1; /* ceil */
6537 if (ext_attr->standard != DRX_STANDARD_ITU_B)
6538 fec_oc_snc_fail_period = fec_rs_period;
443f18d0
MCC
6539
6540 /* limit to max 16 bit value (I2C register width) if needed */
57afe2f0
MCC
6541 if (fec_rs_period > 0xFFFF)
6542 fec_rs_period = 0xFFFF;
443f18d0
MCC
6543
6544 /* write corresponding registers */
57afe2f0 6545 switch (ext_attr->standard) {
443f18d0
MCC
6546 case DRX_STANDARD_ITU_A:
6547 case DRX_STANDARD_ITU_C:
6548 break;
6549 case DRX_STANDARD_ITU_B:
6550 switch (constellation) {
6551 case DRX_CONSTELLATION_QAM64:
57afe2f0
MCC
6552 fec_rs_period = 31581;
6553 fec_oc_snc_fail_period = 17932;
443f18d0
MCC
6554 break;
6555 case DRX_CONSTELLATION_QAM256:
57afe2f0
MCC
6556 fec_rs_period = 45446;
6557 fec_oc_snc_fail_period = 25805;
443f18d0
MCC
6558 break;
6559 default:
9482354f 6560 return -EINVAL;
443f18d0
MCC
6561 }
6562 break;
6563 default:
9482354f 6564 return -EINVAL;
443f18d0
MCC
6565 }
6566
244c0e06 6567 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
9482354f 6568 if (rc != 0) {
068e94ea
MCC
6569 pr_err("error %d\n", rc);
6570 goto rw_error;
6571 }
244c0e06 6572 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
9482354f 6573 if (rc != 0) {
068e94ea
MCC
6574 pr_err("error %d\n", rc);
6575 goto rw_error;
6576 }
244c0e06 6577 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
9482354f 6578 if (rc != 0) {
068e94ea
MCC
6579 pr_err("error %d\n", rc);
6580 goto rw_error;
6581 }
57afe2f0
MCC
6582 ext_attr->fec_rs_period = (u16) fec_rs_period;
6583 ext_attr->fec_rs_prescale = fec_rs_prescale;
244c0e06 6584 rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
9482354f 6585 if (rc != 0) {
068e94ea
MCC
6586 pr_err("error %d\n", rc);
6587 goto rw_error;
6588 }
244c0e06 6589 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
9482354f 6590 if (rc != 0) {
068e94ea
MCC
6591 pr_err("error %d\n", rc);
6592 goto rw_error;
6593 }
244c0e06 6594 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
9482354f 6595 if (rc != 0) {
068e94ea
MCC
6596 pr_err("error %d\n", rc);
6597 goto rw_error;
6598 }
443f18d0 6599
57afe2f0 6600 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
443f18d0
MCC
6601 /* Parameters for Viterbi Decoder */
6602 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
6603 /* (qamvd_prescale*plen*(qam_constellation+1))) */
6604 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
6605 /* result is within 32 bit arithmetic -> */
6606 /* no need for mult or frac functions */
6607
57afe2f0
MCC
6608 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
6609 fec_vd_plen = ext_attr->fec_vd_plen;
6610 qam_vd_prescale = ext_attr->qam_vd_prescale;
6611 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
443f18d0
MCC
6612
6613 switch (constellation) {
6614 case DRX_CONSTELLATION_QAM64:
57afe2f0
MCC
6615 /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
6616 qam_vd_period =
6617 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
443f18d0
MCC
6618 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
6619 break;
6620 case DRX_CONSTELLATION_QAM256:
57afe2f0
MCC
6621 /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
6622 qam_vd_period =
6623 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
443f18d0
MCC
6624 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
6625 break;
6626 default:
9482354f 6627 return -EINVAL;
443f18d0 6628 }
068e94ea
MCC
6629 if (qam_vd_period == 0) {
6630 pr_err("error: qam_vd_period is zero!\n");
9482354f 6631 return -EIO;
068e94ea 6632 }
57afe2f0 6633 qam_vd_period = fec_bits_desired / qam_vd_period;
443f18d0 6634 /* limit to max 16 bit value (I2C register width) if needed */
57afe2f0
MCC
6635 if (qam_vd_period > 0xFFFF)
6636 qam_vd_period = 0xFFFF;
443f18d0 6637
57afe2f0
MCC
6638 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
6639 qam_vd_bit_cnt *= qam_vd_period;
443f18d0 6640
244c0e06 6641 rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
9482354f 6642 if (rc != 0) {
068e94ea
MCC
6643 pr_err("error %d\n", rc);
6644 goto rw_error;
6645 }
244c0e06 6646 rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
9482354f 6647 if (rc != 0) {
068e94ea
MCC
6648 pr_err("error %d\n", rc);
6649 goto rw_error;
6650 }
57afe2f0
MCC
6651 ext_attr->qam_vd_period = (u16) qam_vd_period;
6652 ext_attr->qam_vd_prescale = qam_vd_prescale;
443f18d0
MCC
6653 }
6654
9482354f 6655 return 0;
38b2df95 6656rw_error:
30741871 6657 return rc;
38b2df95
DH
6658}
6659
6660/*============================================================================*/
6661
34eb9751 6662/*
57afe2f0 6663* \fn int set_qam16 ()
38b2df95
DH
6664* \brief QAM16 specific setup
6665* \param demod instance of demod.
61263c75 6666* \return int.
38b2df95 6667*/
1bfc9e15 6668static int set_qam16(struct drx_demod_instance *demod)
443f18d0 6669{
57afe2f0 6670 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 6671 int rc;
679cfbb1 6672 static const u8 qam_dq_qual_fun[] = {
443f18d0
MCC
6673 DRXJ_16TO8(2), /* fun0 */
6674 DRXJ_16TO8(2), /* fun1 */
6675 DRXJ_16TO8(2), /* fun2 */
6676 DRXJ_16TO8(2), /* fun3 */
6677 DRXJ_16TO8(3), /* fun4 */
6678 DRXJ_16TO8(3), /* fun5 */
6679 };
679cfbb1 6680 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
6681 DRXJ_16TO8(13517), /* RAD0 */
6682 DRXJ_16TO8(13517), /* RAD1 */
6683 DRXJ_16TO8(13517), /* RAD2 */
6684 DRXJ_16TO8(13517), /* RAD3 */
6685 DRXJ_16TO8(13517), /* RAD4 */
6686 DRXJ_16TO8(13517), /* RAD5 */
6687 };
6688
244c0e06 6689 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 6690 if (rc != 0) {
068e94ea
MCC
6691 pr_err("error %d\n", rc);
6692 goto rw_error;
6693 }
244c0e06 6694 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 6695 if (rc != 0) {
068e94ea
MCC
6696 pr_err("error %d\n", rc);
6697 goto rw_error;
6698 }
6699
244c0e06 6700 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
9482354f 6701 if (rc != 0) {
068e94ea
MCC
6702 pr_err("error %d\n", rc);
6703 goto rw_error;
6704 }
244c0e06 6705 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
9482354f 6706 if (rc != 0) {
068e94ea
MCC
6707 pr_err("error %d\n", rc);
6708 goto rw_error;
6709 }
244c0e06 6710 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
9482354f 6711 if (rc != 0) {
068e94ea
MCC
6712 pr_err("error %d\n", rc);
6713 goto rw_error;
6714 }
244c0e06 6715 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
9482354f 6716 if (rc != 0) {
068e94ea
MCC
6717 pr_err("error %d\n", rc);
6718 goto rw_error;
6719 }
244c0e06 6720 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
9482354f 6721 if (rc != 0) {
068e94ea
MCC
6722 pr_err("error %d\n", rc);
6723 goto rw_error;
6724 }
244c0e06 6725 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
9482354f 6726 if (rc != 0) {
068e94ea
MCC
6727 pr_err("error %d\n", rc);
6728 goto rw_error;
6729 }
6730
244c0e06 6731 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 6732 if (rc != 0) {
068e94ea
MCC
6733 pr_err("error %d\n", rc);
6734 goto rw_error;
6735 }
244c0e06 6736 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
9482354f 6737 if (rc != 0) {
068e94ea
MCC
6738 pr_err("error %d\n", rc);
6739 goto rw_error;
6740 }
244c0e06 6741 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 6742 if (rc != 0) {
068e94ea
MCC
6743 pr_err("error %d\n", rc);
6744 goto rw_error;
6745 }
6746
244c0e06 6747 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
9482354f 6748 if (rc != 0) {
068e94ea
MCC
6749 pr_err("error %d\n", rc);
6750 goto rw_error;
6751 }
244c0e06 6752 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
9482354f 6753 if (rc != 0) {
068e94ea
MCC
6754 pr_err("error %d\n", rc);
6755 goto rw_error;
6756 }
244c0e06 6757 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
9482354f 6758 if (rc != 0) {
068e94ea
MCC
6759 pr_err("error %d\n", rc);
6760 goto rw_error;
6761 }
244c0e06 6762 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
9482354f 6763 if (rc != 0) {
068e94ea
MCC
6764 pr_err("error %d\n", rc);
6765 goto rw_error;
6766 }
244c0e06 6767 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
9482354f 6768 if (rc != 0) {
068e94ea
MCC
6769 pr_err("error %d\n", rc);
6770 goto rw_error;
6771 }
244c0e06 6772 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
9482354f 6773 if (rc != 0) {
068e94ea
MCC
6774 pr_err("error %d\n", rc);
6775 goto rw_error;
6776 }
244c0e06 6777 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
9482354f 6778 if (rc != 0) {
068e94ea
MCC
6779 pr_err("error %d\n", rc);
6780 goto rw_error;
6781 }
6782
244c0e06 6783 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 6784 if (rc != 0) {
068e94ea
MCC
6785 pr_err("error %d\n", rc);
6786 goto rw_error;
6787 }
244c0e06 6788 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 6789 if (rc != 0) {
068e94ea
MCC
6790 pr_err("error %d\n", rc);
6791 goto rw_error;
6792 }
244c0e06 6793 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 6794 if (rc != 0) {
068e94ea
MCC
6795 pr_err("error %d\n", rc);
6796 goto rw_error;
6797 }
244c0e06 6798 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
9482354f 6799 if (rc != 0) {
068e94ea
MCC
6800 pr_err("error %d\n", rc);
6801 goto rw_error;
6802 }
244c0e06 6803 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 6804 if (rc != 0) {
068e94ea
MCC
6805 pr_err("error %d\n", rc);
6806 goto rw_error;
6807 }
244c0e06 6808 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 6809 if (rc != 0) {
068e94ea
MCC
6810 pr_err("error %d\n", rc);
6811 goto rw_error;
6812 }
244c0e06 6813 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
9482354f 6814 if (rc != 0) {
068e94ea
MCC
6815 pr_err("error %d\n", rc);
6816 goto rw_error;
6817 }
244c0e06 6818 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
9482354f 6819 if (rc != 0) {
068e94ea
MCC
6820 pr_err("error %d\n", rc);
6821 goto rw_error;
6822 }
244c0e06 6823 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 6824 if (rc != 0) {
068e94ea
MCC
6825 pr_err("error %d\n", rc);
6826 goto rw_error;
6827 }
244c0e06 6828 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 6829 if (rc != 0) {
068e94ea
MCC
6830 pr_err("error %d\n", rc);
6831 goto rw_error;
6832 }
244c0e06 6833 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 6834 if (rc != 0) {
068e94ea
MCC
6835 pr_err("error %d\n", rc);
6836 goto rw_error;
6837 }
244c0e06 6838 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 6839 if (rc != 0) {
068e94ea
MCC
6840 pr_err("error %d\n", rc);
6841 goto rw_error;
6842 }
244c0e06 6843 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 6844 if (rc != 0) {
068e94ea
MCC
6845 pr_err("error %d\n", rc);
6846 goto rw_error;
6847 }
244c0e06 6848 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 6849 if (rc != 0) {
068e94ea
MCC
6850 pr_err("error %d\n", rc);
6851 goto rw_error;
6852 }
244c0e06 6853 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 6854 if (rc != 0) {
068e94ea
MCC
6855 pr_err("error %d\n", rc);
6856 goto rw_error;
6857 }
244c0e06 6858 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
9482354f 6859 if (rc != 0) {
068e94ea
MCC
6860 pr_err("error %d\n", rc);
6861 goto rw_error;
6862 }
244c0e06 6863 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
9482354f 6864 if (rc != 0) {
068e94ea
MCC
6865 pr_err("error %d\n", rc);
6866 goto rw_error;
6867 }
244c0e06 6868 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 6869 if (rc != 0) {
068e94ea
MCC
6870 pr_err("error %d\n", rc);
6871 goto rw_error;
6872 }
244c0e06 6873 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 6874 if (rc != 0) {
068e94ea
MCC
6875 pr_err("error %d\n", rc);
6876 goto rw_error;
6877 }
244c0e06 6878 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
9482354f 6879 if (rc != 0) {
068e94ea
MCC
6880 pr_err("error %d\n", rc);
6881 goto rw_error;
6882 }
6883
244c0e06 6884 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
9482354f 6885 if (rc != 0) {
068e94ea
MCC
6886 pr_err("error %d\n", rc);
6887 goto rw_error;
6888 }
443f18d0 6889
9482354f 6890 return 0;
38b2df95 6891rw_error:
30741871 6892 return rc;
38b2df95
DH
6893}
6894
6895/*============================================================================*/
6896
34eb9751 6897/*
57afe2f0 6898* \fn int set_qam32 ()
38b2df95
DH
6899* \brief QAM32 specific setup
6900* \param demod instance of demod.
61263c75 6901* \return int.
38b2df95 6902*/
1bfc9e15 6903static int set_qam32(struct drx_demod_instance *demod)
443f18d0 6904{
57afe2f0 6905 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 6906 int rc;
679cfbb1 6907 static const u8 qam_dq_qual_fun[] = {
443f18d0
MCC
6908 DRXJ_16TO8(3), /* fun0 */
6909 DRXJ_16TO8(3), /* fun1 */
6910 DRXJ_16TO8(3), /* fun2 */
6911 DRXJ_16TO8(3), /* fun3 */
6912 DRXJ_16TO8(4), /* fun4 */
6913 DRXJ_16TO8(4), /* fun5 */
6914 };
679cfbb1 6915 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
6916 DRXJ_16TO8(6707), /* RAD0 */
6917 DRXJ_16TO8(6707), /* RAD1 */
6918 DRXJ_16TO8(6707), /* RAD2 */
6919 DRXJ_16TO8(6707), /* RAD3 */
6920 DRXJ_16TO8(6707), /* RAD4 */
6921 DRXJ_16TO8(6707), /* RAD5 */
6922 };
6923
244c0e06 6924 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 6925 if (rc != 0) {
068e94ea
MCC
6926 pr_err("error %d\n", rc);
6927 goto rw_error;
6928 }
244c0e06 6929 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 6930 if (rc != 0) {
068e94ea
MCC
6931 pr_err("error %d\n", rc);
6932 goto rw_error;
6933 }
6934
244c0e06 6935 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
9482354f 6936 if (rc != 0) {
068e94ea
MCC
6937 pr_err("error %d\n", rc);
6938 goto rw_error;
6939 }
244c0e06 6940 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
9482354f 6941 if (rc != 0) {
068e94ea
MCC
6942 pr_err("error %d\n", rc);
6943 goto rw_error;
6944 }
244c0e06 6945 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9482354f 6946 if (rc != 0) {
068e94ea
MCC
6947 pr_err("error %d\n", rc);
6948 goto rw_error;
6949 }
244c0e06 6950 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
9482354f 6951 if (rc != 0) {
068e94ea
MCC
6952 pr_err("error %d\n", rc);
6953 goto rw_error;
6954 }
244c0e06 6955 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9482354f 6956 if (rc != 0) {
068e94ea
MCC
6957 pr_err("error %d\n", rc);
6958 goto rw_error;
6959 }
244c0e06 6960 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
9482354f 6961 if (rc != 0) {
068e94ea
MCC
6962 pr_err("error %d\n", rc);
6963 goto rw_error;
6964 }
6965
244c0e06 6966 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 6967 if (rc != 0) {
068e94ea
MCC
6968 pr_err("error %d\n", rc);
6969 goto rw_error;
6970 }
244c0e06 6971 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
9482354f 6972 if (rc != 0) {
068e94ea
MCC
6973 pr_err("error %d\n", rc);
6974 goto rw_error;
6975 }
244c0e06 6976 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 6977 if (rc != 0) {
068e94ea
MCC
6978 pr_err("error %d\n", rc);
6979 goto rw_error;
6980 }
6981
244c0e06 6982 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
9482354f 6983 if (rc != 0) {
068e94ea
MCC
6984 pr_err("error %d\n", rc);
6985 goto rw_error;
6986 }
244c0e06 6987 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
9482354f 6988 if (rc != 0) {
068e94ea
MCC
6989 pr_err("error %d\n", rc);
6990 goto rw_error;
6991 }
244c0e06 6992 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
9482354f 6993 if (rc != 0) {
068e94ea
MCC
6994 pr_err("error %d\n", rc);
6995 goto rw_error;
6996 }
244c0e06 6997 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
9482354f 6998 if (rc != 0) {
068e94ea
MCC
6999 pr_err("error %d\n", rc);
7000 goto rw_error;
7001 }
244c0e06 7002 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
9482354f 7003 if (rc != 0) {
068e94ea
MCC
7004 pr_err("error %d\n", rc);
7005 goto rw_error;
7006 }
244c0e06 7007 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
9482354f 7008 if (rc != 0) {
068e94ea
MCC
7009 pr_err("error %d\n", rc);
7010 goto rw_error;
7011 }
244c0e06 7012 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
9482354f 7013 if (rc != 0) {
068e94ea
MCC
7014 pr_err("error %d\n", rc);
7015 goto rw_error;
7016 }
7017
244c0e06 7018 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 7019 if (rc != 0) {
068e94ea
MCC
7020 pr_err("error %d\n", rc);
7021 goto rw_error;
7022 }
244c0e06 7023 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 7024 if (rc != 0) {
068e94ea
MCC
7025 pr_err("error %d\n", rc);
7026 goto rw_error;
7027 }
244c0e06 7028 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 7029 if (rc != 0) {
068e94ea
MCC
7030 pr_err("error %d\n", rc);
7031 goto rw_error;
7032 }
244c0e06 7033 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
9482354f 7034 if (rc != 0) {
068e94ea
MCC
7035 pr_err("error %d\n", rc);
7036 goto rw_error;
7037 }
244c0e06 7038 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 7039 if (rc != 0) {
068e94ea
MCC
7040 pr_err("error %d\n", rc);
7041 goto rw_error;
7042 }
244c0e06 7043 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 7044 if (rc != 0) {
068e94ea
MCC
7045 pr_err("error %d\n", rc);
7046 goto rw_error;
7047 }
244c0e06 7048 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
9482354f 7049 if (rc != 0) {
068e94ea
MCC
7050 pr_err("error %d\n", rc);
7051 goto rw_error;
7052 }
244c0e06 7053 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
9482354f 7054 if (rc != 0) {
068e94ea
MCC
7055 pr_err("error %d\n", rc);
7056 goto rw_error;
7057 }
244c0e06 7058 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 7059 if (rc != 0) {
068e94ea
MCC
7060 pr_err("error %d\n", rc);
7061 goto rw_error;
7062 }
244c0e06 7063 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 7064 if (rc != 0) {
068e94ea
MCC
7065 pr_err("error %d\n", rc);
7066 goto rw_error;
7067 }
244c0e06 7068 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 7069 if (rc != 0) {
068e94ea
MCC
7070 pr_err("error %d\n", rc);
7071 goto rw_error;
7072 }
244c0e06 7073 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 7074 if (rc != 0) {
068e94ea
MCC
7075 pr_err("error %d\n", rc);
7076 goto rw_error;
7077 }
244c0e06 7078 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 7079 if (rc != 0) {
068e94ea
MCC
7080 pr_err("error %d\n", rc);
7081 goto rw_error;
7082 }
244c0e06 7083 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 7084 if (rc != 0) {
068e94ea
MCC
7085 pr_err("error %d\n", rc);
7086 goto rw_error;
7087 }
244c0e06 7088 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 7089 if (rc != 0) {
068e94ea
MCC
7090 pr_err("error %d\n", rc);
7091 goto rw_error;
7092 }
244c0e06 7093 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
9482354f 7094 if (rc != 0) {
068e94ea
MCC
7095 pr_err("error %d\n", rc);
7096 goto rw_error;
7097 }
244c0e06 7098 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
9482354f 7099 if (rc != 0) {
068e94ea
MCC
7100 pr_err("error %d\n", rc);
7101 goto rw_error;
7102 }
244c0e06 7103 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 7104 if (rc != 0) {
068e94ea
MCC
7105 pr_err("error %d\n", rc);
7106 goto rw_error;
7107 }
244c0e06 7108 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 7109 if (rc != 0) {
068e94ea
MCC
7110 pr_err("error %d\n", rc);
7111 goto rw_error;
7112 }
244c0e06 7113 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
9482354f 7114 if (rc != 0) {
068e94ea
MCC
7115 pr_err("error %d\n", rc);
7116 goto rw_error;
7117 }
7118
244c0e06 7119 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
9482354f 7120 if (rc != 0) {
068e94ea
MCC
7121 pr_err("error %d\n", rc);
7122 goto rw_error;
7123 }
443f18d0 7124
9482354f 7125 return 0;
38b2df95 7126rw_error:
30741871 7127 return rc;
38b2df95
DH
7128}
7129
7130/*============================================================================*/
7131
34eb9751 7132/*
57afe2f0 7133* \fn int set_qam64 ()
38b2df95
DH
7134* \brief QAM64 specific setup
7135* \param demod instance of demod.
61263c75 7136* \return int.
38b2df95 7137*/
1bfc9e15 7138static int set_qam64(struct drx_demod_instance *demod)
443f18d0 7139{
57afe2f0 7140 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 7141 int rc;
679cfbb1
CIK
7142 static const u8 qam_dq_qual_fun[] = {
7143 /* this is hw reset value. no necessary to re-write */
443f18d0
MCC
7144 DRXJ_16TO8(4), /* fun0 */
7145 DRXJ_16TO8(4), /* fun1 */
7146 DRXJ_16TO8(4), /* fun2 */
7147 DRXJ_16TO8(4), /* fun3 */
7148 DRXJ_16TO8(6), /* fun4 */
7149 DRXJ_16TO8(6), /* fun5 */
7150 };
679cfbb1 7151 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
7152 DRXJ_16TO8(13336), /* RAD0 */
7153 DRXJ_16TO8(12618), /* RAD1 */
7154 DRXJ_16TO8(11988), /* RAD2 */
7155 DRXJ_16TO8(13809), /* RAD3 */
7156 DRXJ_16TO8(13809), /* RAD4 */
7157 DRXJ_16TO8(15609), /* RAD5 */
7158 };
7159
244c0e06 7160 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 7161 if (rc != 0) {
068e94ea
MCC
7162 pr_err("error %d\n", rc);
7163 goto rw_error;
7164 }
244c0e06 7165 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 7166 if (rc != 0) {
068e94ea
MCC
7167 pr_err("error %d\n", rc);
7168 goto rw_error;
7169 }
7170
244c0e06 7171 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
9482354f 7172 if (rc != 0) {
068e94ea
MCC
7173 pr_err("error %d\n", rc);
7174 goto rw_error;
7175 }
244c0e06 7176 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9482354f 7177 if (rc != 0) {
068e94ea
MCC
7178 pr_err("error %d\n", rc);
7179 goto rw_error;
7180 }
244c0e06 7181 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9482354f 7182 if (rc != 0) {
068e94ea
MCC
7183 pr_err("error %d\n", rc);
7184 goto rw_error;
7185 }
244c0e06 7186 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
9482354f 7187 if (rc != 0) {
068e94ea
MCC
7188 pr_err("error %d\n", rc);
7189 goto rw_error;
7190 }
244c0e06 7191 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9482354f 7192 if (rc != 0) {
068e94ea
MCC
7193 pr_err("error %d\n", rc);
7194 goto rw_error;
7195 }
244c0e06 7196 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
9482354f 7197 if (rc != 0) {
068e94ea
MCC
7198 pr_err("error %d\n", rc);
7199 goto rw_error;
7200 }
7201
244c0e06 7202 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 7203 if (rc != 0) {
068e94ea
MCC
7204 pr_err("error %d\n", rc);
7205 goto rw_error;
7206 }
244c0e06 7207 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
9482354f 7208 if (rc != 0) {
068e94ea
MCC
7209 pr_err("error %d\n", rc);
7210 goto rw_error;
7211 }
244c0e06 7212 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 7213 if (rc != 0) {
068e94ea
MCC
7214 pr_err("error %d\n", rc);
7215 goto rw_error;
7216 }
7217
244c0e06 7218 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
9482354f 7219 if (rc != 0) {
068e94ea
MCC
7220 pr_err("error %d\n", rc);
7221 goto rw_error;
7222 }
244c0e06 7223 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
9482354f 7224 if (rc != 0) {
068e94ea
MCC
7225 pr_err("error %d\n", rc);
7226 goto rw_error;
7227 }
244c0e06 7228 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
9482354f 7229 if (rc != 0) {
068e94ea
MCC
7230 pr_err("error %d\n", rc);
7231 goto rw_error;
7232 }
244c0e06 7233 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
9482354f 7234 if (rc != 0) {
068e94ea
MCC
7235 pr_err("error %d\n", rc);
7236 goto rw_error;
7237 }
244c0e06 7238 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
9482354f 7239 if (rc != 0) {
068e94ea
MCC
7240 pr_err("error %d\n", rc);
7241 goto rw_error;
7242 }
244c0e06 7243 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
9482354f 7244 if (rc != 0) {
068e94ea
MCC
7245 pr_err("error %d\n", rc);
7246 goto rw_error;
7247 }
244c0e06 7248 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
9482354f 7249 if (rc != 0) {
068e94ea
MCC
7250 pr_err("error %d\n", rc);
7251 goto rw_error;
7252 }
7253
244c0e06 7254 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 7255 if (rc != 0) {
068e94ea
MCC
7256 pr_err("error %d\n", rc);
7257 goto rw_error;
7258 }
244c0e06 7259 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 7260 if (rc != 0) {
068e94ea
MCC
7261 pr_err("error %d\n", rc);
7262 goto rw_error;
7263 }
244c0e06 7264 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 7265 if (rc != 0) {
068e94ea
MCC
7266 pr_err("error %d\n", rc);
7267 goto rw_error;
7268 }
244c0e06 7269 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
9482354f 7270 if (rc != 0) {
068e94ea
MCC
7271 pr_err("error %d\n", rc);
7272 goto rw_error;
7273 }
244c0e06 7274 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 7275 if (rc != 0) {
068e94ea
MCC
7276 pr_err("error %d\n", rc);
7277 goto rw_error;
7278 }
244c0e06 7279 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 7280 if (rc != 0) {
068e94ea
MCC
7281 pr_err("error %d\n", rc);
7282 goto rw_error;
7283 }
244c0e06 7284 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
9482354f 7285 if (rc != 0) {
068e94ea
MCC
7286 pr_err("error %d\n", rc);
7287 goto rw_error;
7288 }
244c0e06 7289 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9482354f 7290 if (rc != 0) {
068e94ea
MCC
7291 pr_err("error %d\n", rc);
7292 goto rw_error;
7293 }
244c0e06 7294 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 7295 if (rc != 0) {
068e94ea
MCC
7296 pr_err("error %d\n", rc);
7297 goto rw_error;
7298 }
244c0e06 7299 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 7300 if (rc != 0) {
068e94ea
MCC
7301 pr_err("error %d\n", rc);
7302 goto rw_error;
7303 }
244c0e06 7304 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 7305 if (rc != 0) {
068e94ea
MCC
7306 pr_err("error %d\n", rc);
7307 goto rw_error;
7308 }
244c0e06 7309 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 7310 if (rc != 0) {
068e94ea
MCC
7311 pr_err("error %d\n", rc);
7312 goto rw_error;
7313 }
244c0e06 7314 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 7315 if (rc != 0) {
068e94ea
MCC
7316 pr_err("error %d\n", rc);
7317 goto rw_error;
7318 }
244c0e06 7319 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 7320 if (rc != 0) {
068e94ea
MCC
7321 pr_err("error %d\n", rc);
7322 goto rw_error;
7323 }
244c0e06 7324 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 7325 if (rc != 0) {
068e94ea
MCC
7326 pr_err("error %d\n", rc);
7327 goto rw_error;
7328 }
244c0e06 7329 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
9482354f 7330 if (rc != 0) {
068e94ea
MCC
7331 pr_err("error %d\n", rc);
7332 goto rw_error;
7333 }
244c0e06 7334 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
9482354f 7335 if (rc != 0) {
068e94ea
MCC
7336 pr_err("error %d\n", rc);
7337 goto rw_error;
7338 }
244c0e06 7339 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 7340 if (rc != 0) {
068e94ea
MCC
7341 pr_err("error %d\n", rc);
7342 goto rw_error;
7343 }
244c0e06 7344 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 7345 if (rc != 0) {
068e94ea
MCC
7346 pr_err("error %d\n", rc);
7347 goto rw_error;
7348 }
244c0e06 7349 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
9482354f 7350 if (rc != 0) {
068e94ea
MCC
7351 pr_err("error %d\n", rc);
7352 goto rw_error;
7353 }
7354
244c0e06 7355 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
9482354f 7356 if (rc != 0) {
068e94ea
MCC
7357 pr_err("error %d\n", rc);
7358 goto rw_error;
7359 }
443f18d0 7360
9482354f 7361 return 0;
38b2df95 7362rw_error:
30741871 7363 return rc;
38b2df95
DH
7364}
7365
7366/*============================================================================*/
7367
34eb9751 7368/*
57afe2f0 7369* \fn int set_qam128 ()
38b2df95
DH
7370* \brief QAM128 specific setup
7371* \param demod: instance of demod.
61263c75 7372* \return int.
38b2df95 7373*/
1bfc9e15 7374static int set_qam128(struct drx_demod_instance *demod)
443f18d0 7375{
57afe2f0 7376 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 7377 int rc;
679cfbb1 7378 static const u8 qam_dq_qual_fun[] = {
443f18d0
MCC
7379 DRXJ_16TO8(6), /* fun0 */
7380 DRXJ_16TO8(6), /* fun1 */
7381 DRXJ_16TO8(6), /* fun2 */
7382 DRXJ_16TO8(6), /* fun3 */
7383 DRXJ_16TO8(9), /* fun4 */
7384 DRXJ_16TO8(9), /* fun5 */
7385 };
679cfbb1 7386 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
7387 DRXJ_16TO8(6164), /* RAD0 */
7388 DRXJ_16TO8(6598), /* RAD1 */
7389 DRXJ_16TO8(6394), /* RAD2 */
7390 DRXJ_16TO8(6409), /* RAD3 */
7391 DRXJ_16TO8(6656), /* RAD4 */
7392 DRXJ_16TO8(7238), /* RAD5 */
7393 };
7394
244c0e06 7395 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 7396 if (rc != 0) {
068e94ea
MCC
7397 pr_err("error %d\n", rc);
7398 goto rw_error;
7399 }
244c0e06 7400 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 7401 if (rc != 0) {
068e94ea
MCC
7402 pr_err("error %d\n", rc);
7403 goto rw_error;
7404 }
7405
244c0e06 7406 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
9482354f 7407 if (rc != 0) {
068e94ea
MCC
7408 pr_err("error %d\n", rc);
7409 goto rw_error;
7410 }
244c0e06 7411 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9482354f 7412 if (rc != 0) {
068e94ea
MCC
7413 pr_err("error %d\n", rc);
7414 goto rw_error;
7415 }
244c0e06 7416 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9482354f 7417 if (rc != 0) {
068e94ea
MCC
7418 pr_err("error %d\n", rc);
7419 goto rw_error;
7420 }
244c0e06 7421 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
9482354f 7422 if (rc != 0) {
068e94ea
MCC
7423 pr_err("error %d\n", rc);
7424 goto rw_error;
7425 }
244c0e06 7426 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9482354f 7427 if (rc != 0) {
068e94ea
MCC
7428 pr_err("error %d\n", rc);
7429 goto rw_error;
7430 }
244c0e06 7431 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
9482354f 7432 if (rc != 0) {
068e94ea
MCC
7433 pr_err("error %d\n", rc);
7434 goto rw_error;
7435 }
7436
244c0e06 7437 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 7438 if (rc != 0) {
068e94ea
MCC
7439 pr_err("error %d\n", rc);
7440 goto rw_error;
7441 }
244c0e06 7442 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
9482354f 7443 if (rc != 0) {
068e94ea
MCC
7444 pr_err("error %d\n", rc);
7445 goto rw_error;
7446 }
244c0e06 7447 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 7448 if (rc != 0) {
068e94ea
MCC
7449 pr_err("error %d\n", rc);
7450 goto rw_error;
7451 }
7452
244c0e06 7453 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
9482354f 7454 if (rc != 0) {
068e94ea
MCC
7455 pr_err("error %d\n", rc);
7456 goto rw_error;
7457 }
244c0e06 7458 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
9482354f 7459 if (rc != 0) {
068e94ea
MCC
7460 pr_err("error %d\n", rc);
7461 goto rw_error;
7462 }
244c0e06 7463 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
9482354f 7464 if (rc != 0) {
068e94ea
MCC
7465 pr_err("error %d\n", rc);
7466 goto rw_error;
7467 }
244c0e06 7468 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
9482354f 7469 if (rc != 0) {
068e94ea
MCC
7470 pr_err("error %d\n", rc);
7471 goto rw_error;
7472 }
244c0e06 7473 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
9482354f 7474 if (rc != 0) {
068e94ea
MCC
7475 pr_err("error %d\n", rc);
7476 goto rw_error;
7477 }
244c0e06 7478 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
9482354f 7479 if (rc != 0) {
068e94ea
MCC
7480 pr_err("error %d\n", rc);
7481 goto rw_error;
7482 }
244c0e06 7483 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
9482354f 7484 if (rc != 0) {
068e94ea
MCC
7485 pr_err("error %d\n", rc);
7486 goto rw_error;
7487 }
7488
244c0e06 7489 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 7490 if (rc != 0) {
068e94ea
MCC
7491 pr_err("error %d\n", rc);
7492 goto rw_error;
7493 }
244c0e06 7494 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 7495 if (rc != 0) {
068e94ea
MCC
7496 pr_err("error %d\n", rc);
7497 goto rw_error;
7498 }
244c0e06 7499 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 7500 if (rc != 0) {
068e94ea
MCC
7501 pr_err("error %d\n", rc);
7502 goto rw_error;
7503 }
244c0e06 7504 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
9482354f 7505 if (rc != 0) {
068e94ea
MCC
7506 pr_err("error %d\n", rc);
7507 goto rw_error;
7508 }
244c0e06 7509 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 7510 if (rc != 0) {
068e94ea
MCC
7511 pr_err("error %d\n", rc);
7512 goto rw_error;
7513 }
244c0e06 7514 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 7515 if (rc != 0) {
068e94ea
MCC
7516 pr_err("error %d\n", rc);
7517 goto rw_error;
7518 }
244c0e06 7519 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
9482354f 7520 if (rc != 0) {
068e94ea
MCC
7521 pr_err("error %d\n", rc);
7522 goto rw_error;
7523 }
244c0e06 7524 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9482354f 7525 if (rc != 0) {
068e94ea
MCC
7526 pr_err("error %d\n", rc);
7527 goto rw_error;
7528 }
244c0e06 7529 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 7530 if (rc != 0) {
068e94ea
MCC
7531 pr_err("error %d\n", rc);
7532 goto rw_error;
7533 }
244c0e06 7534 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 7535 if (rc != 0) {
068e94ea
MCC
7536 pr_err("error %d\n", rc);
7537 goto rw_error;
7538 }
244c0e06 7539 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 7540 if (rc != 0) {
068e94ea
MCC
7541 pr_err("error %d\n", rc);
7542 goto rw_error;
7543 }
244c0e06 7544 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 7545 if (rc != 0) {
068e94ea
MCC
7546 pr_err("error %d\n", rc);
7547 goto rw_error;
7548 }
244c0e06 7549 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 7550 if (rc != 0) {
068e94ea
MCC
7551 pr_err("error %d\n", rc);
7552 goto rw_error;
7553 }
244c0e06 7554 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 7555 if (rc != 0) {
068e94ea
MCC
7556 pr_err("error %d\n", rc);
7557 goto rw_error;
7558 }
244c0e06 7559 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 7560 if (rc != 0) {
068e94ea
MCC
7561 pr_err("error %d\n", rc);
7562 goto rw_error;
7563 }
244c0e06 7564 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
9482354f 7565 if (rc != 0) {
068e94ea
MCC
7566 pr_err("error %d\n", rc);
7567 goto rw_error;
7568 }
244c0e06 7569 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
9482354f 7570 if (rc != 0) {
068e94ea
MCC
7571 pr_err("error %d\n", rc);
7572 goto rw_error;
7573 }
244c0e06 7574 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 7575 if (rc != 0) {
068e94ea
MCC
7576 pr_err("error %d\n", rc);
7577 goto rw_error;
7578 }
244c0e06 7579 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 7580 if (rc != 0) {
068e94ea
MCC
7581 pr_err("error %d\n", rc);
7582 goto rw_error;
7583 }
244c0e06 7584 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9482354f 7585 if (rc != 0) {
068e94ea
MCC
7586 pr_err("error %d\n", rc);
7587 goto rw_error;
7588 }
7589
244c0e06 7590 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
9482354f 7591 if (rc != 0) {
068e94ea
MCC
7592 pr_err("error %d\n", rc);
7593 goto rw_error;
7594 }
443f18d0 7595
9482354f 7596 return 0;
38b2df95 7597rw_error:
30741871 7598 return rc;
38b2df95
DH
7599}
7600
7601/*============================================================================*/
7602
34eb9751 7603/*
57afe2f0 7604* \fn int set_qam256 ()
38b2df95
DH
7605* \brief QAM256 specific setup
7606* \param demod: instance of demod.
61263c75 7607* \return int.
38b2df95 7608*/
1bfc9e15 7609static int set_qam256(struct drx_demod_instance *demod)
443f18d0 7610{
57afe2f0 7611 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 7612 int rc;
679cfbb1 7613 static const u8 qam_dq_qual_fun[] = {
443f18d0
MCC
7614 DRXJ_16TO8(8), /* fun0 */
7615 DRXJ_16TO8(8), /* fun1 */
7616 DRXJ_16TO8(8), /* fun2 */
7617 DRXJ_16TO8(8), /* fun3 */
7618 DRXJ_16TO8(12), /* fun4 */
7619 DRXJ_16TO8(12), /* fun5 */
7620 };
679cfbb1 7621 static const u8 qam_eq_cma_rad[] = {
443f18d0
MCC
7622 DRXJ_16TO8(12345), /* RAD0 */
7623 DRXJ_16TO8(12345), /* RAD1 */
7624 DRXJ_16TO8(13626), /* RAD2 */
7625 DRXJ_16TO8(12931), /* RAD3 */
7626 DRXJ_16TO8(14719), /* RAD4 */
7627 DRXJ_16TO8(15356), /* RAD5 */
7628 };
7629
244c0e06 7630 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9482354f 7631 if (rc != 0) {
068e94ea
MCC
7632 pr_err("error %d\n", rc);
7633 goto rw_error;
7634 }
244c0e06 7635 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 7636 if (rc != 0) {
068e94ea
MCC
7637 pr_err("error %d\n", rc);
7638 goto rw_error;
7639 }
7640
244c0e06 7641 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
9482354f 7642 if (rc != 0) {
068e94ea
MCC
7643 pr_err("error %d\n", rc);
7644 goto rw_error;
7645 }
244c0e06 7646 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9482354f 7647 if (rc != 0) {
068e94ea
MCC
7648 pr_err("error %d\n", rc);
7649 goto rw_error;
7650 }
244c0e06 7651 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9482354f 7652 if (rc != 0) {
068e94ea
MCC
7653 pr_err("error %d\n", rc);
7654 goto rw_error;
7655 }
244c0e06 7656 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
9482354f 7657 if (rc != 0) {
068e94ea
MCC
7658 pr_err("error %d\n", rc);
7659 goto rw_error;
7660 }
244c0e06 7661 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9482354f 7662 if (rc != 0) {
068e94ea
MCC
7663 pr_err("error %d\n", rc);
7664 goto rw_error;
7665 }
244c0e06 7666 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
9482354f 7667 if (rc != 0) {
068e94ea
MCC
7668 pr_err("error %d\n", rc);
7669 goto rw_error;
7670 }
7671
244c0e06 7672 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9482354f 7673 if (rc != 0) {
068e94ea
MCC
7674 pr_err("error %d\n", rc);
7675 goto rw_error;
7676 }
244c0e06 7677 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
9482354f 7678 if (rc != 0) {
068e94ea
MCC
7679 pr_err("error %d\n", rc);
7680 goto rw_error;
7681 }
244c0e06 7682 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9482354f 7683 if (rc != 0) {
068e94ea
MCC
7684 pr_err("error %d\n", rc);
7685 goto rw_error;
7686 }
7687
244c0e06 7688 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
9482354f 7689 if (rc != 0) {
068e94ea
MCC
7690 pr_err("error %d\n", rc);
7691 goto rw_error;
7692 }
244c0e06 7693 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
9482354f 7694 if (rc != 0) {
068e94ea
MCC
7695 pr_err("error %d\n", rc);
7696 goto rw_error;
7697 }
244c0e06 7698 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
9482354f 7699 if (rc != 0) {
068e94ea
MCC
7700 pr_err("error %d\n", rc);
7701 goto rw_error;
7702 }
244c0e06 7703 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
9482354f 7704 if (rc != 0) {
068e94ea
MCC
7705 pr_err("error %d\n", rc);
7706 goto rw_error;
7707 }
244c0e06 7708 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
9482354f 7709 if (rc != 0) {
068e94ea
MCC
7710 pr_err("error %d\n", rc);
7711 goto rw_error;
7712 }
244c0e06 7713 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
9482354f 7714 if (rc != 0) {
068e94ea
MCC
7715 pr_err("error %d\n", rc);
7716 goto rw_error;
7717 }
244c0e06 7718 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
9482354f 7719 if (rc != 0) {
068e94ea
MCC
7720 pr_err("error %d\n", rc);
7721 goto rw_error;
7722 }
7723
244c0e06 7724 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9482354f 7725 if (rc != 0) {
068e94ea
MCC
7726 pr_err("error %d\n", rc);
7727 goto rw_error;
7728 }
244c0e06 7729 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9482354f 7730 if (rc != 0) {
068e94ea
MCC
7731 pr_err("error %d\n", rc);
7732 goto rw_error;
7733 }
244c0e06 7734 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9482354f 7735 if (rc != 0) {
068e94ea
MCC
7736 pr_err("error %d\n", rc);
7737 goto rw_error;
7738 }
244c0e06 7739 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
9482354f 7740 if (rc != 0) {
068e94ea
MCC
7741 pr_err("error %d\n", rc);
7742 goto rw_error;
7743 }
244c0e06 7744 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9482354f 7745 if (rc != 0) {
068e94ea
MCC
7746 pr_err("error %d\n", rc);
7747 goto rw_error;
7748 }
244c0e06 7749 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9482354f 7750 if (rc != 0) {
068e94ea
MCC
7751 pr_err("error %d\n", rc);
7752 goto rw_error;
7753 }
244c0e06 7754 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
9482354f 7755 if (rc != 0) {
068e94ea
MCC
7756 pr_err("error %d\n", rc);
7757 goto rw_error;
7758 }
244c0e06 7759 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9482354f 7760 if (rc != 0) {
068e94ea
MCC
7761 pr_err("error %d\n", rc);
7762 goto rw_error;
7763 }
244c0e06 7764 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9482354f 7765 if (rc != 0) {
068e94ea
MCC
7766 pr_err("error %d\n", rc);
7767 goto rw_error;
7768 }
244c0e06 7769 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9482354f 7770 if (rc != 0) {
068e94ea
MCC
7771 pr_err("error %d\n", rc);
7772 goto rw_error;
7773 }
244c0e06 7774 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9482354f 7775 if (rc != 0) {
068e94ea
MCC
7776 pr_err("error %d\n", rc);
7777 goto rw_error;
7778 }
244c0e06 7779 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9482354f 7780 if (rc != 0) {
068e94ea
MCC
7781 pr_err("error %d\n", rc);
7782 goto rw_error;
7783 }
244c0e06 7784 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9482354f 7785 if (rc != 0) {
068e94ea
MCC
7786 pr_err("error %d\n", rc);
7787 goto rw_error;
7788 }
244c0e06 7789 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9482354f 7790 if (rc != 0) {
068e94ea
MCC
7791 pr_err("error %d\n", rc);
7792 goto rw_error;
7793 }
244c0e06 7794 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9482354f 7795 if (rc != 0) {
068e94ea
MCC
7796 pr_err("error %d\n", rc);
7797 goto rw_error;
7798 }
244c0e06 7799 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
9482354f 7800 if (rc != 0) {
068e94ea
MCC
7801 pr_err("error %d\n", rc);
7802 goto rw_error;
7803 }
244c0e06 7804 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
9482354f 7805 if (rc != 0) {
068e94ea
MCC
7806 pr_err("error %d\n", rc);
7807 goto rw_error;
7808 }
244c0e06 7809 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9482354f 7810 if (rc != 0) {
068e94ea
MCC
7811 pr_err("error %d\n", rc);
7812 goto rw_error;
7813 }
244c0e06 7814 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9482354f 7815 if (rc != 0) {
068e94ea
MCC
7816 pr_err("error %d\n", rc);
7817 goto rw_error;
7818 }
244c0e06 7819 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9482354f 7820 if (rc != 0) {
068e94ea
MCC
7821 pr_err("error %d\n", rc);
7822 goto rw_error;
7823 }
7824
244c0e06 7825 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
9482354f 7826 if (rc != 0) {
068e94ea
MCC
7827 pr_err("error %d\n", rc);
7828 goto rw_error;
7829 }
443f18d0 7830
9482354f 7831 return 0;
38b2df95 7832rw_error:
30741871 7833 return rc;
38b2df95
DH
7834}
7835
7836/*============================================================================*/
7837#define QAM_SET_OP_ALL 0x1
7838#define QAM_SET_OP_CONSTELLATION 0x2
7839#define QAM_SET_OP_SPECTRUM 0X4
7840
34eb9751 7841/*
57afe2f0 7842* \fn int set_qam ()
38b2df95
DH
7843* \brief Set QAM demod.
7844* \param demod: instance of demod.
7845* \param channel: pointer to channel data.
61263c75 7846* \return int.
38b2df95 7847*/
61263c75 7848static int
1bfc9e15
MCC
7849set_qam(struct drx_demod_instance *demod,
7850 struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
57afe2f0
MCC
7851{
7852 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 7853 struct drxj_data *ext_attr = NULL;
1bfc9e15 7854 struct drx_common_attr *common_attr = NULL;
068e94ea 7855 int rc;
57afe2f0
MCC
7856 u32 adc_frequency = 0;
7857 u32 iqm_rc_rate = 0;
068e94ea 7858 u16 cmd_result = 0;
57afe2f0
MCC
7859 u16 lc_symbol_freq = 0;
7860 u16 iqm_rc_stretch = 0;
7861 u16 set_env_parameters = 0;
7862 u16 set_param_parameters[2] = { 0 };
b3ce3a83 7863 struct drxjscu_cmd cmd_scu = { /* command */ 0,
57afe2f0
MCC
7864 /* parameter_len */ 0,
7865 /* result_len */ 0,
443f18d0
MCC
7866 /* parameter */ NULL,
7867 /* result */ NULL
7868 };
679cfbb1 7869 static const u8 qam_a_taps[] = {
443f18d0
MCC
7870 DRXJ_16TO8(-1), /* re0 */
7871 DRXJ_16TO8(1), /* re1 */
7872 DRXJ_16TO8(1), /* re2 */
7873 DRXJ_16TO8(-1), /* re3 */
7874 DRXJ_16TO8(-1), /* re4 */
7875 DRXJ_16TO8(2), /* re5 */
7876 DRXJ_16TO8(1), /* re6 */
7877 DRXJ_16TO8(-2), /* re7 */
7878 DRXJ_16TO8(0), /* re8 */
7879 DRXJ_16TO8(3), /* re9 */
7880 DRXJ_16TO8(-1), /* re10 */
7881 DRXJ_16TO8(-3), /* re11 */
7882 DRXJ_16TO8(4), /* re12 */
7883 DRXJ_16TO8(1), /* re13 */
7884 DRXJ_16TO8(-8), /* re14 */
7885 DRXJ_16TO8(4), /* re15 */
7886 DRXJ_16TO8(13), /* re16 */
7887 DRXJ_16TO8(-13), /* re17 */
7888 DRXJ_16TO8(-19), /* re18 */
7889 DRXJ_16TO8(28), /* re19 */
7890 DRXJ_16TO8(25), /* re20 */
7891 DRXJ_16TO8(-53), /* re21 */
7892 DRXJ_16TO8(-31), /* re22 */
7893 DRXJ_16TO8(96), /* re23 */
7894 DRXJ_16TO8(37), /* re24 */
7895 DRXJ_16TO8(-190), /* re25 */
7896 DRXJ_16TO8(-40), /* re26 */
7897 DRXJ_16TO8(619) /* re27 */
7898 };
679cfbb1 7899 static const u8 qam_b64_taps[] = {
443f18d0
MCC
7900 DRXJ_16TO8(0), /* re0 */
7901 DRXJ_16TO8(-2), /* re1 */
7902 DRXJ_16TO8(1), /* re2 */
7903 DRXJ_16TO8(2), /* re3 */
7904 DRXJ_16TO8(-2), /* re4 */
7905 DRXJ_16TO8(0), /* re5 */
7906 DRXJ_16TO8(4), /* re6 */
7907 DRXJ_16TO8(-2), /* re7 */
7908 DRXJ_16TO8(-4), /* re8 */
7909 DRXJ_16TO8(4), /* re9 */
7910 DRXJ_16TO8(3), /* re10 */
7911 DRXJ_16TO8(-6), /* re11 */
7912 DRXJ_16TO8(0), /* re12 */
7913 DRXJ_16TO8(6), /* re13 */
7914 DRXJ_16TO8(-5), /* re14 */
7915 DRXJ_16TO8(-3), /* re15 */
7916 DRXJ_16TO8(11), /* re16 */
7917 DRXJ_16TO8(-4), /* re17 */
7918 DRXJ_16TO8(-19), /* re18 */
7919 DRXJ_16TO8(19), /* re19 */
7920 DRXJ_16TO8(28), /* re20 */
7921 DRXJ_16TO8(-45), /* re21 */
7922 DRXJ_16TO8(-36), /* re22 */
7923 DRXJ_16TO8(90), /* re23 */
7924 DRXJ_16TO8(42), /* re24 */
7925 DRXJ_16TO8(-185), /* re25 */
7926 DRXJ_16TO8(-46), /* re26 */
7927 DRXJ_16TO8(614) /* re27 */
7928 };
679cfbb1 7929 static const u8 qam_b256_taps[] = {
443f18d0
MCC
7930 DRXJ_16TO8(-2), /* re0 */
7931 DRXJ_16TO8(4), /* re1 */
7932 DRXJ_16TO8(1), /* re2 */
7933 DRXJ_16TO8(-4), /* re3 */
7934 DRXJ_16TO8(0), /* re4 */
7935 DRXJ_16TO8(4), /* re5 */
7936 DRXJ_16TO8(-2), /* re6 */
7937 DRXJ_16TO8(-4), /* re7 */
7938 DRXJ_16TO8(5), /* re8 */
7939 DRXJ_16TO8(2), /* re9 */
7940 DRXJ_16TO8(-8), /* re10 */
7941 DRXJ_16TO8(2), /* re11 */
7942 DRXJ_16TO8(11), /* re12 */
7943 DRXJ_16TO8(-8), /* re13 */
7944 DRXJ_16TO8(-15), /* re14 */
7945 DRXJ_16TO8(16), /* re15 */
7946 DRXJ_16TO8(19), /* re16 */
7947 DRXJ_16TO8(-27), /* re17 */
7948 DRXJ_16TO8(-22), /* re18 */
7949 DRXJ_16TO8(44), /* re19 */
7950 DRXJ_16TO8(26), /* re20 */
7951 DRXJ_16TO8(-69), /* re21 */
7952 DRXJ_16TO8(-28), /* re22 */
7953 DRXJ_16TO8(110), /* re23 */
7954 DRXJ_16TO8(31), /* re24 */
7955 DRXJ_16TO8(-201), /* re25 */
7956 DRXJ_16TO8(-32), /* re26 */
7957 DRXJ_16TO8(628) /* re27 */
7958 };
679cfbb1 7959 static const u8 qam_c_taps[] = {
443f18d0
MCC
7960 DRXJ_16TO8(-3), /* re0 */
7961 DRXJ_16TO8(3), /* re1 */
7962 DRXJ_16TO8(2), /* re2 */
7963 DRXJ_16TO8(-4), /* re3 */
7964 DRXJ_16TO8(0), /* re4 */
7965 DRXJ_16TO8(4), /* re5 */
7966 DRXJ_16TO8(-1), /* re6 */
7967 DRXJ_16TO8(-4), /* re7 */
7968 DRXJ_16TO8(3), /* re8 */
7969 DRXJ_16TO8(3), /* re9 */
7970 DRXJ_16TO8(-5), /* re10 */
7971 DRXJ_16TO8(0), /* re11 */
7972 DRXJ_16TO8(9), /* re12 */
7973 DRXJ_16TO8(-4), /* re13 */
7974 DRXJ_16TO8(-12), /* re14 */
7975 DRXJ_16TO8(10), /* re15 */
7976 DRXJ_16TO8(16), /* re16 */
7977 DRXJ_16TO8(-21), /* re17 */
7978 DRXJ_16TO8(-20), /* re18 */
7979 DRXJ_16TO8(37), /* re19 */
7980 DRXJ_16TO8(25), /* re20 */
7981 DRXJ_16TO8(-62), /* re21 */
7982 DRXJ_16TO8(-28), /* re22 */
7983 DRXJ_16TO8(105), /* re23 */
7984 DRXJ_16TO8(31), /* re24 */
7985 DRXJ_16TO8(-197), /* re25 */
7986 DRXJ_16TO8(-33), /* re26 */
7987 DRXJ_16TO8(626) /* re27 */
7988 };
7989
57afe2f0 7990 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 7991 ext_attr = (struct drxj_data *) demod->my_ext_attr;
1bfc9e15 7992 common_attr = (struct drx_common_attr *) demod->my_common_attr;
443f18d0
MCC
7993
7994 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
57afe2f0 7995 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
443f18d0
MCC
7996 switch (channel->constellation) {
7997 case DRX_CONSTELLATION_QAM256:
57afe2f0
MCC
7998 iqm_rc_rate = 0x00AE3562;
7999 lc_symbol_freq =
443f18d0
MCC
8000 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
8001 channel->symbolrate = 5360537;
57afe2f0 8002 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
443f18d0
MCC
8003 break;
8004 case DRX_CONSTELLATION_QAM64:
57afe2f0
MCC
8005 iqm_rc_rate = 0x00C05A0E;
8006 lc_symbol_freq = 409;
443f18d0 8007 channel->symbolrate = 5056941;
57afe2f0 8008 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
443f18d0
MCC
8009 break;
8010 default:
9482354f 8011 return -EINVAL;
443f18d0
MCC
8012 }
8013 } else {
57afe2f0 8014 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
068e94ea
MCC
8015 if (channel->symbolrate == 0) {
8016 pr_err("error: channel symbolrate is zero!\n");
9482354f 8017 return -EIO;
068e94ea 8018 }
57afe2f0
MCC
8019 iqm_rc_rate =
8020 (adc_frequency / channel->symbolrate) * (1 << 21) +
8021 (frac28
8022 ((adc_frequency % channel->symbolrate),
443f18d0 8023 channel->symbolrate) >> 7) - (1 << 23);
57afe2f0
MCC
8024 lc_symbol_freq =
8025 (u16) (frac28
443f18d0 8026 (channel->symbolrate +
57afe2f0
MCC
8027 (adc_frequency >> 13),
8028 adc_frequency) >> 16);
8029 if (lc_symbol_freq > 511)
8030 lc_symbol_freq = 511;
8031
8032 iqm_rc_stretch = 21;
8033 }
8034
8035 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8036 set_env_parameters = QAM_TOP_ANNEX_A; /* annex */
8037 set_param_parameters[0] = channel->constellation; /* constellation */
8038 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
8039 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8040 set_env_parameters = QAM_TOP_ANNEX_B; /* annex */
8041 set_param_parameters[0] = channel->constellation; /* constellation */
8042 set_param_parameters[1] = channel->interleavemode; /* interleave mode */
8043 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8044 set_env_parameters = QAM_TOP_ANNEX_C; /* annex */
8045 set_param_parameters[0] = channel->constellation; /* constellation */
8046 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
443f18d0 8047 } else {
9482354f 8048 return -EINVAL;
443f18d0
MCC
8049 }
8050 }
38b2df95 8051
443f18d0
MCC
8052 if (op & QAM_SET_OP_ALL) {
8053 /*
8054 STEP 1: reset demodulator
8055 resets IQM, QAM and FEC HW blocks
8056 resets SCU variables
8057 */
8058 /* stop all comm_exec */
244c0e06 8059 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9482354f 8060 if (rc != 0) {
068e94ea
MCC
8061 pr_err("error %d\n", rc);
8062 goto rw_error;
8063 }
244c0e06 8064 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
9482354f 8065 if (rc != 0) {
068e94ea
MCC
8066 pr_err("error %d\n", rc);
8067 goto rw_error;
8068 }
244c0e06 8069 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 8070 if (rc != 0) {
068e94ea
MCC
8071 pr_err("error %d\n", rc);
8072 goto rw_error;
8073 }
244c0e06 8074 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 8075 if (rc != 0) {
068e94ea
MCC
8076 pr_err("error %d\n", rc);
8077 goto rw_error;
8078 }
244c0e06 8079 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 8080 if (rc != 0) {
068e94ea
MCC
8081 pr_err("error %d\n", rc);
8082 goto rw_error;
8083 }
244c0e06 8084 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 8085 if (rc != 0) {
068e94ea
MCC
8086 pr_err("error %d\n", rc);
8087 goto rw_error;
8088 }
244c0e06 8089 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 8090 if (rc != 0) {
068e94ea
MCC
8091 pr_err("error %d\n", rc);
8092 goto rw_error;
8093 }
57afe2f0
MCC
8094
8095 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 8096 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
57afe2f0
MCC
8097 cmd_scu.parameter_len = 0;
8098 cmd_scu.result_len = 1;
8099 cmd_scu.parameter = NULL;
8100 cmd_scu.result = &cmd_result;
068e94ea 8101 rc = scu_command(dev_addr, &cmd_scu);
9482354f 8102 if (rc != 0) {
068e94ea
MCC
8103 pr_err("error %d\n", rc);
8104 goto rw_error;
8105 }
443f18d0 8106 }
38b2df95 8107
443f18d0
MCC
8108 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8109 /*
8110 STEP 2: configure demodulator
8111 -set env
8112 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
8113 */
57afe2f0 8114 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 8115 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
57afe2f0
MCC
8116 cmd_scu.parameter_len = 1;
8117 cmd_scu.result_len = 1;
8118 cmd_scu.parameter = &set_env_parameters;
8119 cmd_scu.result = &cmd_result;
068e94ea 8120 rc = scu_command(dev_addr, &cmd_scu);
9482354f 8121 if (rc != 0) {
068e94ea
MCC
8122 pr_err("error %d\n", rc);
8123 goto rw_error;
8124 }
443f18d0 8125
57afe2f0 8126 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 8127 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
57afe2f0
MCC
8128 cmd_scu.parameter_len = 2;
8129 cmd_scu.result_len = 1;
8130 cmd_scu.parameter = set_param_parameters;
8131 cmd_scu.result = &cmd_result;
068e94ea 8132 rc = scu_command(dev_addr, &cmd_scu);
9482354f 8133 if (rc != 0) {
068e94ea
MCC
8134 pr_err("error %d\n", rc);
8135 goto rw_error;
8136 }
443f18d0 8137 /* set symbol rate */
244c0e06 8138 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
9482354f 8139 if (rc != 0) {
068e94ea
MCC
8140 pr_err("error %d\n", rc);
8141 goto rw_error;
8142 }
57afe2f0 8143 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
068e94ea 8144 rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
9482354f 8145 if (rc != 0) {
068e94ea
MCC
8146 pr_err("error %d\n", rc);
8147 goto rw_error;
8148 }
443f18d0
MCC
8149 }
8150 /* STEP 3: enable the system in a mode where the ADC provides valid signal
8151 setup constellation independent registers */
8152 /* from qam_cmd.py script (qam_driver_b) */
8153 /* TODO: remove re-writes of HW reset values */
8154 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
068e94ea 8155 rc = set_frequency(demod, channel, tuner_freq_offset);
9482354f 8156 if (rc != 0) {
068e94ea
MCC
8157 pr_err("error %d\n", rc);
8158 goto rw_error;
8159 }
443f18d0 8160 }
38b2df95 8161
443f18d0 8162 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
38b2df95 8163
244c0e06 8164 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
9482354f 8165 if (rc != 0) {
068e94ea
MCC
8166 pr_err("error %d\n", rc);
8167 goto rw_error;
8168 }
244c0e06 8169 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
9482354f 8170 if (rc != 0) {
068e94ea
MCC
8171 pr_err("error %d\n", rc);
8172 goto rw_error;
8173 }
443f18d0 8174 }
38b2df95 8175
443f18d0 8176 if (op & QAM_SET_OP_ALL) {
259f380e 8177 if (!ext_attr->has_lna) {
244c0e06 8178 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
9482354f 8179 if (rc != 0) {
068e94ea
MCC
8180 pr_err("error %d\n", rc);
8181 goto rw_error;
8182 }
8183 }
244c0e06 8184 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
9482354f 8185 if (rc != 0) {
068e94ea
MCC
8186 pr_err("error %d\n", rc);
8187 goto rw_error;
8188 }
244c0e06 8189 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
9482354f 8190 if (rc != 0) {
068e94ea
MCC
8191 pr_err("error %d\n", rc);
8192 goto rw_error;
8193 }
244c0e06 8194 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
9482354f 8195 if (rc != 0) {
068e94ea
MCC
8196 pr_err("error %d\n", rc);
8197 goto rw_error;
57afe2f0 8198 }
57afe2f0 8199
244c0e06 8200 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
9482354f 8201 if (rc != 0) {
068e94ea
MCC
8202 pr_err("error %d\n", rc);
8203 goto rw_error;
8204 } /* scu temporary shut down agc */
57afe2f0 8205
244c0e06 8206 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
9482354f 8207 if (rc != 0) {
068e94ea
MCC
8208 pr_err("error %d\n", rc);
8209 goto rw_error;
8210 }
244c0e06 8211 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
9482354f 8212 if (rc != 0) {
068e94ea
MCC
8213 pr_err("error %d\n", rc);
8214 goto rw_error;
8215 }
244c0e06 8216 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
9482354f 8217 if (rc != 0) {
068e94ea
MCC
8218 pr_err("error %d\n", rc);
8219 goto rw_error;
8220 }
244c0e06 8221 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
9482354f 8222 if (rc != 0) {
068e94ea
MCC
8223 pr_err("error %d\n", rc);
8224 goto rw_error;
8225 }
244c0e06 8226 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, 4, 0);
9482354f 8227 if (rc != 0) {
068e94ea
MCC
8228 pr_err("error %d\n", rc);
8229 goto rw_error;
8230 }
244c0e06 8231 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
9482354f 8232 if (rc != 0) {
068e94ea
MCC
8233 pr_err("error %d\n", rc);
8234 goto rw_error;
8235 }
244c0e06 8236 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
9482354f 8237 if (rc != 0) {
068e94ea
MCC
8238 pr_err("error %d\n", rc);
8239 goto rw_error;
8240 }
57afe2f0 8241
244c0e06 8242 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
9482354f 8243 if (rc != 0) {
068e94ea
MCC
8244 pr_err("error %d\n", rc);
8245 goto rw_error;
8246 }
244c0e06 8247 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
9482354f 8248 if (rc != 0) {
068e94ea
MCC
8249 pr_err("error %d\n", rc);
8250 goto rw_error;
8251 } /*! reset default val ! */
8252
244c0e06 8253 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
9482354f 8254 if (rc != 0) {
068e94ea
MCC
8255 pr_err("error %d\n", rc);
8256 goto rw_error;
8257 } /*! reset default val ! */
57afe2f0 8258 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
244c0e06 8259 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
9482354f 8260 if (rc != 0) {
068e94ea
MCC
8261 pr_err("error %d\n", rc);
8262 goto rw_error;
8263 } /*! reset default val ! */
244c0e06 8264 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
9482354f 8265 if (rc != 0) {
068e94ea
MCC
8266 pr_err("error %d\n", rc);
8267 goto rw_error;
8268 } /*! reset default val ! */
244c0e06 8269 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9482354f 8270 if (rc != 0) {
068e94ea
MCC
8271 pr_err("error %d\n", rc);
8272 goto rw_error;
8273 } /*! reset default val ! */
443f18d0
MCC
8274 } else {
8275 switch (channel->constellation) {
8276 case DRX_CONSTELLATION_QAM16:
8277 case DRX_CONSTELLATION_QAM64:
8278 case DRX_CONSTELLATION_QAM256:
244c0e06 8279 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9482354f 8280 if (rc != 0) {
068e94ea
MCC
8281 pr_err("error %d\n", rc);
8282 goto rw_error;
8283 }
244c0e06 8284 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
9482354f 8285 if (rc != 0) {
068e94ea
MCC
8286 pr_err("error %d\n", rc);
8287 goto rw_error;
8288 }
244c0e06 8289 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9482354f 8290 if (rc != 0) {
068e94ea
MCC
8291 pr_err("error %d\n", rc);
8292 goto rw_error;
8293 } /*! reset default val ! */
443f18d0
MCC
8294 break;
8295 case DRX_CONSTELLATION_QAM32:
8296 case DRX_CONSTELLATION_QAM128:
244c0e06 8297 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9482354f 8298 if (rc != 0) {
068e94ea
MCC
8299 pr_err("error %d\n", rc);
8300 goto rw_error;
8301 }
244c0e06 8302 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
9482354f 8303 if (rc != 0) {
068e94ea
MCC
8304 pr_err("error %d\n", rc);
8305 goto rw_error;
8306 }
244c0e06 8307 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
9482354f 8308 if (rc != 0) {
068e94ea
MCC
8309 pr_err("error %d\n", rc);
8310 goto rw_error;
8311 }
443f18d0
MCC
8312 break;
8313 default:
9482354f 8314 return -EIO;
443f18d0
MCC
8315 } /* switch */
8316 }
8317
244c0e06 8318 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
9482354f 8319 if (rc != 0) {
068e94ea
MCC
8320 pr_err("error %d\n", rc);
8321 goto rw_error;
8322 } /*! reset default val ! */
244c0e06 8323 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
9482354f 8324 if (rc != 0) {
068e94ea
MCC
8325 pr_err("error %d\n", rc);
8326 goto rw_error;
8327 }
244c0e06 8328 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
9482354f 8329 if (rc != 0) {
068e94ea
MCC
8330 pr_err("error %d\n", rc);
8331 goto rw_error;
8332 }
244c0e06 8333 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
9482354f 8334 if (rc != 0) {
068e94ea
MCC
8335 pr_err("error %d\n", rc);
8336 goto rw_error;
8337 }
244c0e06 8338 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, 7, 0);
9482354f 8339 if (rc != 0) {
068e94ea
MCC
8340 pr_err("error %d\n", rc);
8341 goto rw_error;
8342 }
244c0e06 8343 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
9482354f 8344 if (rc != 0) {
068e94ea
MCC
8345 pr_err("error %d\n", rc);
8346 goto rw_error;
8347 }
244c0e06 8348 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
9482354f 8349 if (rc != 0) {
068e94ea
MCC
8350 pr_err("error %d\n", rc);
8351 goto rw_error;
8352 }
244c0e06 8353 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
9482354f 8354 if (rc != 0) {
068e94ea
MCC
8355 pr_err("error %d\n", rc);
8356 goto rw_error;
8357 }
244c0e06 8358 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
9482354f 8359 if (rc != 0) {
068e94ea
MCC
8360 pr_err("error %d\n", rc);
8361 goto rw_error;
8362 }
244c0e06 8363 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
9482354f 8364 if (rc != 0) {
068e94ea
MCC
8365 pr_err("error %d\n", rc);
8366 goto rw_error;
8367 }
244c0e06 8368 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
9482354f 8369 if (rc != 0) {
068e94ea
MCC
8370 pr_err("error %d\n", rc);
8371 goto rw_error;
8372 }
244c0e06 8373 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
9482354f 8374 if (rc != 0) {
068e94ea
MCC
8375 pr_err("error %d\n", rc);
8376 goto rw_error;
8377 }
244c0e06 8378 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
9482354f 8379 if (rc != 0) {
068e94ea
MCC
8380 pr_err("error %d\n", rc);
8381 goto rw_error;
8382 }
244c0e06 8383 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
9482354f 8384 if (rc != 0) {
068e94ea
MCC
8385 pr_err("error %d\n", rc);
8386 goto rw_error;
8387 }
244c0e06 8388 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
9482354f 8389 if (rc != 0) {
068e94ea
MCC
8390 pr_err("error %d\n", rc);
8391 goto rw_error;
8392 }
244c0e06 8393 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
9482354f 8394 if (rc != 0) {
068e94ea
MCC
8395 pr_err("error %d\n", rc);
8396 goto rw_error;
8397 }
244c0e06 8398 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
9482354f 8399 if (rc != 0) {
068e94ea
MCC
8400 pr_err("error %d\n", rc);
8401 goto rw_error;
8402 }
244c0e06 8403 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
9482354f 8404 if (rc != 0) {
068e94ea
MCC
8405 pr_err("error %d\n", rc);
8406 goto rw_error;
8407 }
244c0e06 8408 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
9482354f 8409 if (rc != 0) {
068e94ea
MCC
8410 pr_err("error %d\n", rc);
8411 goto rw_error;
8412 }
244c0e06 8413 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
9482354f 8414 if (rc != 0) {
068e94ea
MCC
8415 pr_err("error %d\n", rc);
8416 goto rw_error;
8417 }
8418
244c0e06 8419 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
9482354f 8420 if (rc != 0) {
068e94ea
MCC
8421 pr_err("error %d\n", rc);
8422 goto rw_error;
8423 }
244c0e06 8424 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
9482354f 8425 if (rc != 0) {
068e94ea
MCC
8426 pr_err("error %d\n", rc);
8427 goto rw_error;
8428 }
244c0e06 8429 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
9482354f 8430 if (rc != 0) {
068e94ea
MCC
8431 pr_err("error %d\n", rc);
8432 goto rw_error;
8433 }
244c0e06 8434 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
9482354f 8435 if (rc != 0) {
068e94ea
MCC
8436 pr_err("error %d\n", rc);
8437 goto rw_error;
8438 }
244c0e06 8439 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
9482354f 8440 if (rc != 0) {
068e94ea
MCC
8441 pr_err("error %d\n", rc);
8442 goto rw_error;
8443 }
443f18d0
MCC
8444
8445 /* No more resets of the IQM, current standard correctly set =>
8446 now AGCs can be configured. */
8447 /* turn on IQMAF. It has to be in front of setAgc**() */
068e94ea 8448 rc = set_iqm_af(demod, true);
9482354f 8449 if (rc != 0) {
068e94ea
MCC
8450 pr_err("error %d\n", rc);
8451 goto rw_error;
8452 }
8453 rc = adc_synchronization(demod);
9482354f 8454 if (rc != 0) {
068e94ea
MCC
8455 pr_err("error %d\n", rc);
8456 goto rw_error;
8457 }
443f18d0 8458
068e94ea 8459 rc = init_agc(demod);
9482354f 8460 if (rc != 0) {
068e94ea
MCC
8461 pr_err("error %d\n", rc);
8462 goto rw_error;
8463 }
8464 rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
9482354f 8465 if (rc != 0) {
068e94ea
MCC
8466 pr_err("error %d\n", rc);
8467 goto rw_error;
8468 }
8469 rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
9482354f 8470 if (rc != 0) {
068e94ea
MCC
8471 pr_err("error %d\n", rc);
8472 goto rw_error;
8473 }
443f18d0 8474 {
b3ce3a83 8475 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
443f18d0 8476 of only the gain */
b3ce3a83 8477 struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
443f18d0 8478
57afe2f0 8479 qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
068e94ea 8480 rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
9482354f 8481 if (rc != 0) {
068e94ea
MCC
8482 pr_err("error %d\n", rc);
8483 goto rw_error;
8484 }
8485 }
8486 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
9482354f 8487 if (rc != 0) {
068e94ea
MCC
8488 pr_err("error %d\n", rc);
8489 goto rw_error;
443f18d0 8490 }
443f18d0 8491 }
38b2df95 8492
443f18d0 8493 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
57afe2f0 8494 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
244c0e06 8495 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9482354f 8496 if (rc != 0) {
068e94ea
MCC
8497 pr_err("error %d\n", rc);
8498 goto rw_error;
8499 }
244c0e06 8500 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9482354f 8501 if (rc != 0) {
068e94ea
MCC
8502 pr_err("error %d\n", rc);
8503 goto rw_error;
8504 }
57afe2f0 8505 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
443f18d0
MCC
8506 switch (channel->constellation) {
8507 case DRX_CONSTELLATION_QAM64:
244c0e06 8508 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9482354f 8509 if (rc != 0) {
068e94ea
MCC
8510 pr_err("error %d\n", rc);
8511 goto rw_error;
8512 }
244c0e06 8513 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9482354f 8514 if (rc != 0) {
068e94ea
MCC
8515 pr_err("error %d\n", rc);
8516 goto rw_error;
8517 }
443f18d0
MCC
8518 break;
8519 case DRX_CONSTELLATION_QAM256:
244c0e06 8520 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9482354f 8521 if (rc != 0) {
068e94ea
MCC
8522 pr_err("error %d\n", rc);
8523 goto rw_error;
8524 }
244c0e06 8525 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9482354f 8526 if (rc != 0) {
068e94ea
MCC
8527 pr_err("error %d\n", rc);
8528 goto rw_error;
8529 }
443f18d0
MCC
8530 break;
8531 default:
9482354f 8532 return -EIO;
443f18d0 8533 }
57afe2f0 8534 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
244c0e06 8535 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9482354f 8536 if (rc != 0) {
068e94ea
MCC
8537 pr_err("error %d\n", rc);
8538 goto rw_error;
8539 }
244c0e06 8540 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9482354f 8541 if (rc != 0) {
068e94ea
MCC
8542 pr_err("error %d\n", rc);
8543 goto rw_error;
8544 }
443f18d0
MCC
8545 }
8546
8547 /* SETP 4: constellation specific setup */
8548 switch (channel->constellation) {
8549 case DRX_CONSTELLATION_QAM16:
068e94ea 8550 rc = set_qam16(demod);
9482354f 8551 if (rc != 0) {
068e94ea
MCC
8552 pr_err("error %d\n", rc);
8553 goto rw_error;
8554 }
443f18d0
MCC
8555 break;
8556 case DRX_CONSTELLATION_QAM32:
068e94ea 8557 rc = set_qam32(demod);
9482354f 8558 if (rc != 0) {
068e94ea
MCC
8559 pr_err("error %d\n", rc);
8560 goto rw_error;
8561 }
443f18d0
MCC
8562 break;
8563 case DRX_CONSTELLATION_QAM64:
068e94ea 8564 rc = set_qam64(demod);
9482354f 8565 if (rc != 0) {
068e94ea
MCC
8566 pr_err("error %d\n", rc);
8567 goto rw_error;
8568 }
443f18d0
MCC
8569 break;
8570 case DRX_CONSTELLATION_QAM128:
068e94ea 8571 rc = set_qam128(demod);
9482354f 8572 if (rc != 0) {
068e94ea
MCC
8573 pr_err("error %d\n", rc);
8574 goto rw_error;
8575 }
443f18d0
MCC
8576 break;
8577 case DRX_CONSTELLATION_QAM256:
068e94ea 8578 rc = set_qam256(demod);
9482354f 8579 if (rc != 0) {
068e94ea
MCC
8580 pr_err("error %d\n", rc);
8581 goto rw_error;
8582 }
443f18d0
MCC
8583 break;
8584 default:
9482354f 8585 return -EIO;
443f18d0
MCC
8586 } /* switch */
8587 }
38b2df95 8588
443f18d0 8589 if ((op & QAM_SET_OP_ALL)) {
244c0e06 8590 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
9482354f 8591 if (rc != 0) {
068e94ea
MCC
8592 pr_err("error %d\n", rc);
8593 goto rw_error;
8594 }
443f18d0
MCC
8595
8596 /* Mpeg output has to be in front of FEC active */
068e94ea 8597 rc = set_mpegtei_handling(demod);
9482354f 8598 if (rc != 0) {
068e94ea
MCC
8599 pr_err("error %d\n", rc);
8600 goto rw_error;
8601 }
8602 rc = bit_reverse_mpeg_output(demod);
9482354f 8603 if (rc != 0) {
068e94ea
MCC
8604 pr_err("error %d\n", rc);
8605 goto rw_error;
8606 }
8607 rc = set_mpeg_start_width(demod);
9482354f 8608 if (rc != 0) {
068e94ea
MCC
8609 pr_err("error %d\n", rc);
8610 goto rw_error;
8611 }
443f18d0 8612 {
57afe2f0 8613 /* TODO: move to set_standard after hardware reset value problem is solved */
443f18d0 8614 /* Configure initial MPEG output */
1bfc9e15 8615 struct drx_cfg_mpeg_output cfg_mpeg_output;
443f18d0 8616
41b5cc0c 8617 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
57afe2f0 8618 cfg_mpeg_output.enable_mpeg_output = true;
41b5cc0c 8619
068e94ea 8620 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 8621 if (rc != 0) {
068e94ea
MCC
8622 pr_err("error %d\n", rc);
8623 goto rw_error;
8624 }
443f18d0
MCC
8625 }
8626 }
38b2df95 8627
443f18d0 8628 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
38b2df95 8629
443f18d0 8630 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
57afe2f0 8631 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
443f18d0 8632 SCU_RAM_COMMAND_CMD_DEMOD_START;
57afe2f0
MCC
8633 cmd_scu.parameter_len = 0;
8634 cmd_scu.result_len = 1;
8635 cmd_scu.parameter = NULL;
8636 cmd_scu.result = &cmd_result;
068e94ea 8637 rc = scu_command(dev_addr, &cmd_scu);
9482354f 8638 if (rc != 0) {
068e94ea
MCC
8639 pr_err("error %d\n", rc);
8640 goto rw_error;
8641 }
443f18d0
MCC
8642 }
8643
244c0e06 8644 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
9482354f 8645 if (rc != 0) {
068e94ea
MCC
8646 pr_err("error %d\n", rc);
8647 goto rw_error;
8648 }
244c0e06 8649 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
9482354f 8650 if (rc != 0) {
068e94ea
MCC
8651 pr_err("error %d\n", rc);
8652 goto rw_error;
8653 }
244c0e06 8654 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
9482354f 8655 if (rc != 0) {
068e94ea
MCC
8656 pr_err("error %d\n", rc);
8657 goto rw_error;
8658 }
443f18d0 8659
9482354f 8660 return 0;
443f18d0 8661rw_error:
30741871 8662 return rc;
443f18d0
MCC
8663}
8664
8665/*============================================================================*/
03fdfbfd
MCC
8666static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
8667
1bfc9e15 8668static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
443f18d0 8669{
03fdfbfd
MCC
8670 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8671 struct drxj_data *ext_attr = demod->my_ext_attr;
068e94ea 8672 int rc;
57afe2f0
MCC
8673 u32 iqm_fs_rate_ofs = 0;
8674 u32 iqm_fs_rate_lo = 0;
8675 u16 qam_ctl_ena = 0;
43a431e4 8676 u16 data = 0;
57afe2f0
MCC
8677 u16 equ_mode = 0;
8678 u16 fsm_state = 0;
443f18d0
MCC
8679 int i = 0;
8680 int ofsofs = 0;
443f18d0
MCC
8681
8682 /* Silence the controlling of lc, equ, and the acquisition state machine */
244c0e06 8683 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
9482354f 8684 if (rc != 0) {
068e94ea
MCC
8685 pr_err("error %d\n", rc);
8686 goto rw_error;
8687 }
244c0e06 8688 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 8689 if (rc != 0) {
068e94ea
MCC
8690 pr_err("error %d\n", rc);
8691 goto rw_error;
8692 }
443f18d0
MCC
8693
8694 /* freeze the frequency control loop */
244c0e06 8695 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, 0, 0);
9482354f 8696 if (rc != 0) {
068e94ea
MCC
8697 pr_err("error %d\n", rc);
8698 goto rw_error;
8699 }
244c0e06 8700 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, 0, 0);
9482354f 8701 if (rc != 0) {
068e94ea
MCC
8702 pr_err("error %d\n", rc);
8703 goto rw_error;
8704 }
443f18d0 8705
068e94ea 8706 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
9482354f 8707 if (rc != 0) {
068e94ea
MCC
8708 pr_err("error %d\n", rc);
8709 goto rw_error;
8710 }
8711 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
9482354f 8712 if (rc != 0) {
068e94ea
MCC
8713 pr_err("error %d\n", rc);
8714 goto rw_error;
8715 }
57afe2f0
MCC
8716 ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
8717 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
8718 iqm_fs_rate_ofs -= 2 * ofsofs;
443f18d0
MCC
8719
8720 /* freeze dq/fq updating */
244c0e06 8721 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
9482354f 8722 if (rc != 0) {
068e94ea
MCC
8723 pr_err("error %d\n", rc);
8724 goto rw_error;
8725 }
443f18d0 8726 data = (data & 0xfff9);
244c0e06 8727 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
9482354f 8728 if (rc != 0) {
068e94ea
MCC
8729 pr_err("error %d\n", rc);
8730 goto rw_error;
8731 }
244c0e06 8732 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
9482354f 8733 if (rc != 0) {
068e94ea
MCC
8734 pr_err("error %d\n", rc);
8735 goto rw_error;
8736 }
443f18d0
MCC
8737
8738 /* lc_cp / _ci / _ca */
244c0e06 8739 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, 0, 0);
9482354f 8740 if (rc != 0) {
068e94ea
MCC
8741 pr_err("error %d\n", rc);
8742 goto rw_error;
8743 }
244c0e06 8744 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, 0, 0);
9482354f 8745 if (rc != 0) {
068e94ea
MCC
8746 pr_err("error %d\n", rc);
8747 goto rw_error;
8748 }
244c0e06 8749 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
9482354f 8750 if (rc != 0) {
068e94ea
MCC
8751 pr_err("error %d\n", rc);
8752 goto rw_error;
8753 }
443f18d0
MCC
8754
8755 /* flip the spec */
244c0e06 8756 rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
9482354f 8757 if (rc != 0) {
068e94ea
MCC
8758 pr_err("error %d\n", rc);
8759 goto rw_error;
8760 }
57afe2f0
MCC
8761 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
8762 ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
443f18d0
MCC
8763
8764 /* freeze dq/fq updating */
244c0e06 8765 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
9482354f 8766 if (rc != 0) {
068e94ea
MCC
8767 pr_err("error %d\n", rc);
8768 goto rw_error;
8769 }
57afe2f0 8770 equ_mode = data;
443f18d0 8771 data = (data & 0xfff9);
244c0e06 8772 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
9482354f 8773 if (rc != 0) {
068e94ea
MCC
8774 pr_err("error %d\n", rc);
8775 goto rw_error;
8776 }
244c0e06 8777 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
9482354f 8778 if (rc != 0) {
068e94ea
MCC
8779 pr_err("error %d\n", rc);
8780 goto rw_error;
8781 }
443f18d0
MCC
8782
8783 for (i = 0; i < 28; i++) {
244c0e06 8784 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
9482354f 8785 if (rc != 0) {
068e94ea
MCC
8786 pr_err("error %d\n", rc);
8787 goto rw_error;
8788 }
244c0e06 8789 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
9482354f 8790 if (rc != 0) {
068e94ea
MCC
8791 pr_err("error %d\n", rc);
8792 goto rw_error;
8793 }
443f18d0
MCC
8794 }
8795
8796 for (i = 0; i < 24; i++) {
244c0e06 8797 rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
9482354f 8798 if (rc != 0) {
068e94ea
MCC
8799 pr_err("error %d\n", rc);
8800 goto rw_error;
8801 }
244c0e06 8802 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
9482354f 8803 if (rc != 0) {
068e94ea
MCC
8804 pr_err("error %d\n", rc);
8805 goto rw_error;
8806 }
443f18d0
MCC
8807 }
8808
57afe2f0 8809 data = equ_mode;
244c0e06 8810 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
9482354f 8811 if (rc != 0) {
068e94ea
MCC
8812 pr_err("error %d\n", rc);
8813 goto rw_error;
8814 }
244c0e06 8815 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
9482354f 8816 if (rc != 0) {
068e94ea
MCC
8817 pr_err("error %d\n", rc);
8818 goto rw_error;
8819 }
443f18d0 8820
244c0e06 8821 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
9482354f 8822 if (rc != 0) {
068e94ea
MCC
8823 pr_err("error %d\n", rc);
8824 goto rw_error;
8825 }
38b2df95 8826
443f18d0 8827 i = 0;
57afe2f0 8828 while ((fsm_state != 4) && (i++ < 100)) {
244c0e06 8829 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
9482354f 8830 if (rc != 0) {
068e94ea
MCC
8831 pr_err("error %d\n", rc);
8832 goto rw_error;
8833 }
8834 }
244c0e06 8835 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
9482354f 8836 if (rc != 0) {
068e94ea
MCC
8837 pr_err("error %d\n", rc);
8838 goto rw_error;
443f18d0 8839 }
443f18d0 8840
9482354f 8841 return 0;
38b2df95 8842rw_error:
30741871 8843 return rc;
38b2df95
DH
8844
8845}
8846
8847#define NO_LOCK 0x0
8848#define DEMOD_LOCKED 0x1
8849#define SYNC_FLIPPED 0x2
8850#define SPEC_MIRRORED 0x4
34eb9751 8851/*
57afe2f0 8852* \fn int qam64auto ()
38b2df95
DH
8853* \brief auto do sync pattern switching and mirroring.
8854* \param demod: instance of demod.
8855* \param channel: pointer to channel data.
57afe2f0
MCC
8856* \param tuner_freq_offset: tuner frequency offset.
8857* \param lock_status: pointer to lock status.
61263c75 8858* \return int.
38b2df95 8859*/
61263c75 8860static int
1bfc9e15
MCC
8861qam64auto(struct drx_demod_instance *demod,
8862 struct drx_channel *channel,
8863 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
443f18d0 8864{
03fdfbfd
MCC
8865 struct drxj_data *ext_attr = demod->my_ext_attr;
8866 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8867 struct drx39xxj_state *state = dev_addr->user_data;
8868 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
068e94ea 8869 int rc;
6f64c522 8870 u32 lck_state = NO_LOCK;
57afe2f0
MCC
8871 u32 start_time = 0;
8872 u32 d_locked_time = 0;
57afe2f0 8873 u32 timeout_ofs = 0;
068e94ea 8874 u16 data = 0;
443f18d0 8875
69bb7ab6 8876 /* external attributes for storing acquired channel constellation */
57afe2f0 8877 *lock_status = DRX_NOT_LOCKED;
d7b0631e 8878 start_time = jiffies_to_msecs(jiffies);
6f64c522 8879 lck_state = NO_LOCK;
443f18d0 8880 do {
068e94ea 8881 rc = ctrl_lock_status(demod, lock_status);
9482354f 8882 if (rc != 0) {
068e94ea
MCC
8883 pr_err("error %d\n", rc);
8884 goto rw_error;
8885 }
443f18d0 8886
6f64c522 8887 switch (lck_state) {
443f18d0 8888 case NO_LOCK:
57afe2f0 8889 if (*lock_status == DRXJ_DEMOD_LOCK) {
03fdfbfd 8890 rc = ctrl_get_qam_sig_quality(demod);
9482354f 8891 if (rc != 0) {
068e94ea
MCC
8892 pr_err("error %d\n", rc);
8893 goto rw_error;
8894 }
03fdfbfd 8895 if (p->cnr.stat[0].svalue > 20800) {
6f64c522 8896 lck_state = DEMOD_LOCKED;
443f18d0 8897 /* some delay to see if fec_lock possible TODO find the right value */
57afe2f0 8898 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
d7b0631e 8899 d_locked_time = jiffies_to_msecs(jiffies);
443f18d0
MCC
8900 }
8901 }
8902 break;
8903 case DEMOD_LOCKED:
57afe2f0 8904 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
d7b0631e 8905 ((jiffies_to_msecs(jiffies) - d_locked_time) >
443f18d0 8906 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
244c0e06 8907 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
9482354f 8908 if (rc != 0) {
068e94ea
MCC
8909 pr_err("error %d\n", rc);
8910 goto rw_error;
8911 }
244c0e06 8912 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
9482354f 8913 if (rc != 0) {
068e94ea
MCC
8914 pr_err("error %d\n", rc);
8915 goto rw_error;
8916 }
6f64c522 8917 lck_state = SYNC_FLIPPED;
d7b0631e 8918 msleep(10);
443f18d0
MCC
8919 }
8920 break;
8921 case SYNC_FLIPPED:
57afe2f0 8922 if (*lock_status == DRXJ_DEMOD_LOCK) {
443f18d0
MCC
8923 if (channel->mirror == DRX_MIRROR_AUTO) {
8924 /* flip sync pattern back */
244c0e06 8925 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
9482354f 8926 if (rc != 0) {
068e94ea
MCC
8927 pr_err("error %d\n", rc);
8928 goto rw_error;
8929 }
244c0e06 8930 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
9482354f 8931 if (rc != 0) {
068e94ea
MCC
8932 pr_err("error %d\n", rc);
8933 goto rw_error;
8934 }
443f18d0 8935 /* flip spectrum */
57afe2f0 8936 ext_attr->mirror = DRX_MIRROR_YES;
068e94ea 8937 rc = qam_flip_spec(demod, channel);
9482354f 8938 if (rc != 0) {
068e94ea
MCC
8939 pr_err("error %d\n", rc);
8940 goto rw_error;
8941 }
6f64c522 8942 lck_state = SPEC_MIRRORED;
443f18d0 8943 /* reset timer TODO: still need 500ms? */
57afe2f0 8944 start_time = d_locked_time =
d7b0631e 8945 jiffies_to_msecs(jiffies);
57afe2f0 8946 timeout_ofs = 0;
443f18d0
MCC
8947 } else { /* no need to wait lock */
8948
57afe2f0 8949 start_time =
d7b0631e 8950 jiffies_to_msecs(jiffies) -
57afe2f0 8951 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
443f18d0
MCC
8952 }
8953 }
8954 break;
8955 case SPEC_MIRRORED:
57afe2f0 8956 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
d7b0631e 8957 ((jiffies_to_msecs(jiffies) - d_locked_time) >
443f18d0 8958 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
03fdfbfd 8959 rc = ctrl_get_qam_sig_quality(demod);
9482354f 8960 if (rc != 0) {
068e94ea
MCC
8961 pr_err("error %d\n", rc);
8962 goto rw_error;
8963 }
03fdfbfd 8964 if (p->cnr.stat[0].svalue > 20800) {
244c0e06 8965 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
9482354f 8966 if (rc != 0) {
068e94ea
MCC
8967 pr_err("error %d\n", rc);
8968 goto rw_error;
8969 }
244c0e06 8970 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
9482354f 8971 if (rc != 0) {
068e94ea
MCC
8972 pr_err("error %d\n", rc);
8973 goto rw_error;
8974 }
443f18d0 8975 /* no need to wait lock */
57afe2f0 8976 start_time =
d7b0631e 8977 jiffies_to_msecs(jiffies) -
57afe2f0 8978 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
443f18d0
MCC
8979 }
8980 }
8981 break;
8982 default:
8983 break;
8984 }
d7b0631e 8985 msleep(10);
443f18d0 8986 } while
57afe2f0
MCC
8987 ((*lock_status != DRX_LOCKED) &&
8988 (*lock_status != DRX_NEVER_LOCK) &&
d7b0631e 8989 ((jiffies_to_msecs(jiffies) - start_time) <
57afe2f0 8990 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
443f18d0
MCC
8991 );
8992 /* Returning control to apllication ... */
8993
9482354f 8994 return 0;
38b2df95 8995rw_error:
30741871 8996 return rc;
38b2df95
DH
8997}
8998
34eb9751 8999/*
57afe2f0 9000* \fn int qam256auto ()
38b2df95
DH
9001* \brief auto do sync pattern switching and mirroring.
9002* \param demod: instance of demod.
9003* \param channel: pointer to channel data.
57afe2f0
MCC
9004* \param tuner_freq_offset: tuner frequency offset.
9005* \param lock_status: pointer to lock status.
61263c75 9006* \return int.
38b2df95 9007*/
61263c75 9008static int
1bfc9e15
MCC
9009qam256auto(struct drx_demod_instance *demod,
9010 struct drx_channel *channel,
9011 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
443f18d0 9012{
03fdfbfd
MCC
9013 struct drxj_data *ext_attr = demod->my_ext_attr;
9014 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9015 struct drx39xxj_state *state = dev_addr->user_data;
9016 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
068e94ea 9017 int rc;
6f64c522 9018 u32 lck_state = NO_LOCK;
57afe2f0
MCC
9019 u32 start_time = 0;
9020 u32 d_locked_time = 0;
57afe2f0 9021 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
443f18d0 9022
69bb7ab6 9023 /* external attributes for storing acquired channel constellation */
57afe2f0 9024 *lock_status = DRX_NOT_LOCKED;
d7b0631e 9025 start_time = jiffies_to_msecs(jiffies);
6f64c522 9026 lck_state = NO_LOCK;
443f18d0 9027 do {
068e94ea 9028 rc = ctrl_lock_status(demod, lock_status);
9482354f 9029 if (rc != 0) {
068e94ea
MCC
9030 pr_err("error %d\n", rc);
9031 goto rw_error;
9032 }
6f64c522 9033 switch (lck_state) {
443f18d0 9034 case NO_LOCK:
57afe2f0 9035 if (*lock_status == DRXJ_DEMOD_LOCK) {
03fdfbfd 9036 rc = ctrl_get_qam_sig_quality(demod);
9482354f 9037 if (rc != 0) {
068e94ea
MCC
9038 pr_err("error %d\n", rc);
9039 goto rw_error;
9040 }
03fdfbfd 9041 if (p->cnr.stat[0].svalue > 26800) {
6f64c522 9042 lck_state = DEMOD_LOCKED;
57afe2f0 9043 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
d7b0631e 9044 d_locked_time = jiffies_to_msecs(jiffies);
443f18d0
MCC
9045 }
9046 }
9047 break;
9048 case DEMOD_LOCKED:
57afe2f0 9049 if (*lock_status == DRXJ_DEMOD_LOCK) {
443f18d0 9050 if ((channel->mirror == DRX_MIRROR_AUTO) &&
d7b0631e 9051 ((jiffies_to_msecs(jiffies) - d_locked_time) >
443f18d0 9052 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
57afe2f0 9053 ext_attr->mirror = DRX_MIRROR_YES;
068e94ea 9054 rc = qam_flip_spec(demod, channel);
9482354f 9055 if (rc != 0) {
068e94ea
MCC
9056 pr_err("error %d\n", rc);
9057 goto rw_error;
9058 }
6f64c522 9059 lck_state = SPEC_MIRRORED;
443f18d0 9060 /* reset timer TODO: still need 300ms? */
d7b0631e 9061 start_time = jiffies_to_msecs(jiffies);
57afe2f0 9062 timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
443f18d0
MCC
9063 }
9064 }
9065 break;
9066 case SPEC_MIRRORED:
9067 break;
9068 default:
9069 break;
9070 }
d7b0631e 9071 msleep(10);
443f18d0 9072 } while
57afe2f0
MCC
9073 ((*lock_status < DRX_LOCKED) &&
9074 (*lock_status != DRX_NEVER_LOCK) &&
d7b0631e 9075 ((jiffies_to_msecs(jiffies) - start_time) <
57afe2f0 9076 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
443f18d0 9077
9482354f 9078 return 0;
38b2df95 9079rw_error:
30741871 9080 return rc;
38b2df95
DH
9081}
9082
34eb9751 9083/*
e33f2193 9084* \fn int set_qam_channel ()
38b2df95
DH
9085* \brief Set QAM channel according to the requested constellation.
9086* \param demod: instance of demod.
9087* \param channel: pointer to channel data.
61263c75 9088* \return int.
38b2df95 9089*/
61263c75 9090static int
e33f2193 9091set_qam_channel(struct drx_demod_instance *demod,
1bfc9e15 9092 struct drx_channel *channel, s32 tuner_freq_offset)
443f18d0 9093{
b3ce3a83 9094 struct drxj_data *ext_attr = NULL;
068e94ea
MCC
9095 int rc;
9096 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
57afe2f0 9097 bool auto_flag = false;
443f18d0 9098
69bb7ab6 9099 /* external attributes for storing acquired channel constellation */
b3ce3a83 9100 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0
MCC
9101
9102 /* set QAM channel constellation */
9103 switch (channel->constellation) {
9104 case DRX_CONSTELLATION_QAM16:
9105 case DRX_CONSTELLATION_QAM32:
443f18d0 9106 case DRX_CONSTELLATION_QAM128:
938f11fa
MCC
9107 return -EINVAL;
9108 case DRX_CONSTELLATION_QAM64:
443f18d0 9109 case DRX_CONSTELLATION_QAM256:
938f11fa
MCC
9110 if (ext_attr->standard != DRX_STANDARD_ITU_B)
9111 return -EINVAL;
9112
57afe2f0 9113 ext_attr->constellation = channel->constellation;
63713517 9114 if (channel->mirror == DRX_MIRROR_AUTO)
57afe2f0 9115 ext_attr->mirror = DRX_MIRROR_NO;
63713517 9116 else
57afe2f0 9117 ext_attr->mirror = channel->mirror;
938f11fa 9118
068e94ea 9119 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
9482354f 9120 if (rc != 0) {
068e94ea
MCC
9121 pr_err("error %d\n", rc);
9122 goto rw_error;
9123 }
443f18d0 9124
938f11fa
MCC
9125 if (channel->constellation == DRX_CONSTELLATION_QAM64)
9126 rc = qam64auto(demod, channel, tuner_freq_offset,
9127 &lock_status);
9128 else
9129 rc = qam256auto(demod, channel, tuner_freq_offset,
9130 &lock_status);
9131 if (rc != 0) {
9132 pr_err("error %d\n", rc);
9133 goto rw_error;
9134 }
9135 break;
9136 case DRX_CONSTELLATION_AUTO: /* for channel scan */
9137 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9138 u16 qam_ctl_ena = 0;
9139
9140 auto_flag = true;
9141
9142 /* try to lock default QAM constellation: QAM256 */
9143 channel->constellation = DRX_CONSTELLATION_QAM256;
9144 ext_attr->constellation = DRX_CONSTELLATION_QAM256;
9145 if (channel->mirror == DRX_MIRROR_AUTO)
9146 ext_attr->mirror = DRX_MIRROR_NO;
9147 else
9148 ext_attr->mirror = channel->mirror;
9149 rc = set_qam(demod, channel, tuner_freq_offset,
9150 QAM_SET_OP_ALL);
9482354f 9151 if (rc != 0) {
068e94ea
MCC
9152 pr_err("error %d\n", rc);
9153 goto rw_error;
9154 }
938f11fa
MCC
9155 rc = qam256auto(demod, channel, tuner_freq_offset,
9156 &lock_status);
9482354f 9157 if (rc != 0) {
068e94ea
MCC
9158 pr_err("error %d\n", rc);
9159 goto rw_error;
9160 }
938f11fa
MCC
9161
9162 if (lock_status >= DRX_LOCKED) {
9163 channel->constellation = DRX_CONSTELLATION_AUTO;
9164 break;
9165 }
9166
9167 /* QAM254 not locked. Try QAM64 constellation */
9168 channel->constellation = DRX_CONSTELLATION_QAM64;
9169 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
63713517 9170 if (channel->mirror == DRX_MIRROR_AUTO)
57afe2f0 9171 ext_attr->mirror = DRX_MIRROR_NO;
63713517 9172 else
57afe2f0 9173 ext_attr->mirror = channel->mirror;
938f11fa 9174
244c0e06 9175 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9176 SCU_RAM_QAM_CTL_ENA__A,
9177 &qam_ctl_ena, 0);
9482354f 9178 if (rc != 0) {
068e94ea
MCC
9179 pr_err("error %d\n", rc);
9180 goto rw_error;
9181 }
244c0e06 9182 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9183 SCU_RAM_QAM_CTL_ENA__A,
9184 qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9482354f 9185 if (rc != 0) {
068e94ea
MCC
9186 pr_err("error %d\n", rc);
9187 goto rw_error;
9188 }
244c0e06 9189 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9190 SCU_RAM_QAM_FSM_STATE_TGT__A,
9191 0x2, 0);
9192 if (rc != 0) {
9193 pr_err("error %d\n", rc);
9194 goto rw_error;
9195 } /* force to rate hunting */
443f18d0 9196
938f11fa
MCC
9197 rc = set_qam(demod, channel, tuner_freq_offset,
9198 QAM_SET_OP_CONSTELLATION);
9199 if (rc != 0) {
9200 pr_err("error %d\n", rc);
9201 goto rw_error;
9202 }
244c0e06 9203 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9204 SCU_RAM_QAM_CTL_ENA__A,
9205 qam_ctl_ena, 0);
9206 if (rc != 0) {
9207 pr_err("error %d\n", rc);
9208 goto rw_error;
9209 }
068e94ea 9210
938f11fa
MCC
9211 rc = qam64auto(demod, channel, tuner_freq_offset,
9212 &lock_status);
9213 if (rc != 0) {
9214 pr_err("error %d\n", rc);
9215 goto rw_error;
443f18d0 9216 }
938f11fa 9217
443f18d0 9218 channel->constellation = DRX_CONSTELLATION_AUTO;
57afe2f0 9219 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
938f11fa
MCC
9220 u16 qam_ctl_ena = 0;
9221
443f18d0 9222 channel->constellation = DRX_CONSTELLATION_QAM64;
57afe2f0
MCC
9223 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9224 auto_flag = true;
443f18d0 9225
63713517 9226 if (channel->mirror == DRX_MIRROR_AUTO)
57afe2f0 9227 ext_attr->mirror = DRX_MIRROR_NO;
63713517 9228 else
57afe2f0 9229 ext_attr->mirror = channel->mirror;
244c0e06 9230 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9231 SCU_RAM_QAM_CTL_ENA__A,
9232 &qam_ctl_ena, 0);
9233 if (rc != 0) {
9234 pr_err("error %d\n", rc);
9235 goto rw_error;
9236 }
244c0e06 9237 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9238 SCU_RAM_QAM_CTL_ENA__A,
9239 qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9240 if (rc != 0) {
9241 pr_err("error %d\n", rc);
9242 goto rw_error;
9243 }
244c0e06 9244 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9245 SCU_RAM_QAM_FSM_STATE_TGT__A,
9246 0x2, 0);
9247 if (rc != 0) {
9248 pr_err("error %d\n", rc);
9249 goto rw_error;
9250 } /* force to rate hunting */
068e94ea 9251
938f11fa
MCC
9252 rc = set_qam(demod, channel, tuner_freq_offset,
9253 QAM_SET_OP_CONSTELLATION);
9254 if (rc != 0) {
9255 pr_err("error %d\n", rc);
9256 goto rw_error;
068e94ea 9257 }
244c0e06 9258 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
938f11fa
MCC
9259 SCU_RAM_QAM_CTL_ENA__A,
9260 qam_ctl_ena, 0);
9261 if (rc != 0) {
9262 pr_err("error %d\n", rc);
9263 goto rw_error;
9264 }
9265 rc = qam64auto(demod, channel, tuner_freq_offset,
9266 &lock_status);
9482354f 9267 if (rc != 0) {
068e94ea
MCC
9268 pr_err("error %d\n", rc);
9269 goto rw_error;
9270 }
443f18d0
MCC
9271 channel->constellation = DRX_CONSTELLATION_AUTO;
9272 } else {
9482354f 9273 return -EINVAL;
443f18d0
MCC
9274 }
9275 break;
9276 default:
9482354f 9277 return -EINVAL;
443f18d0 9278 }
38b2df95 9279
9482354f 9280 return 0;
38b2df95 9281rw_error:
443f18d0 9282 /* restore starting value */
57afe2f0 9283 if (auto_flag)
443f18d0 9284 channel->constellation = DRX_CONSTELLATION_AUTO;
30741871 9285 return rc;
38b2df95
DH
9286}
9287
9288/*============================================================================*/
9289
34eb9751 9290/*
e33f2193 9291* \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
38b2df95
DH
9292* \brief Get RS error count in QAM mode (used for post RS BER calculation)
9293* \return Error code
9294*
9295* precondition: measurement period & measurement prescale must be set
9296*
9297*/
61263c75 9298static int
69832578
MCC
9299get_qamrs_err_count(struct i2c_device_addr *dev_addr,
9300 struct drxjrs_errors *rs_errors)
38b2df95 9301{
068e94ea 9302 int rc;
57afe2f0
MCC
9303 u16 nr_bit_errors = 0,
9304 nr_symbol_errors = 0,
9305 nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
443f18d0
MCC
9306
9307 /* check arguments */
63713517 9308 if (dev_addr == NULL)
9482354f 9309 return -EINVAL;
443f18d0
MCC
9310
9311 /* all reported errors are received in the */
9312 /* most recently finished measurment period */
9313 /* no of pre RS bit errors */
244c0e06 9314 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
9482354f 9315 if (rc != 0) {
068e94ea
MCC
9316 pr_err("error %d\n", rc);
9317 goto rw_error;
9318 }
443f18d0 9319 /* no of symbol errors */
244c0e06 9320 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
9482354f 9321 if (rc != 0) {
068e94ea
MCC
9322 pr_err("error %d\n", rc);
9323 goto rw_error;
9324 }
443f18d0 9325 /* no of packet errors */
244c0e06 9326 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
9482354f 9327 if (rc != 0) {
068e94ea
MCC
9328 pr_err("error %d\n", rc);
9329 goto rw_error;
9330 }
443f18d0 9331 /* no of failures to decode */
244c0e06 9332 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
9482354f 9333 if (rc != 0) {
068e94ea
MCC
9334 pr_err("error %d\n", rc);
9335 goto rw_error;
9336 }
443f18d0 9337 /* no of post RS bit erros */
244c0e06 9338 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
9482354f 9339 if (rc != 0) {
068e94ea
MCC
9340 pr_err("error %d\n", rc);
9341 goto rw_error;
9342 }
443f18d0
MCC
9343 /* TODO: NOTE */
9344 /* These register values are fetched in non-atomic fashion */
9345 /* It is possible that the read values contain unrelated information */
9346
57afe2f0
MCC
9347 rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
9348 rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
9349 rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
9350 rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
9351 rs_errors->nr_snc_par_fail_count =
9352 nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
443f18d0 9353
9482354f 9354 return 0;
38b2df95 9355rw_error:
30741871 9356 return rc;
38b2df95
DH
9357}
9358
9359/*============================================================================*/
9360
34eb9751 9361/*
80e5ed14
MCC
9362 * \fn int get_sig_strength()
9363 * \brief Retrieve signal strength for VSB and QAM.
9364 * \param demod Pointer to demod instance
9365 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
9366 * \return int.
9367 * \retval 0 sig_strength contains valid data.
9368 * \retval -EINVAL sig_strength is NULL.
9369 * \retval -EIO Erroneous data, sig_strength contains invalid data.
9370 */
9371#define DRXJ_AGC_TOP 0x2800
9372#define DRXJ_AGC_SNS 0x1600
9373#define DRXJ_RFAGC_MAX 0x3fff
9374#define DRXJ_RFAGC_MIN 0x800
9375
9376static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
9377{
9378 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9379 int rc;
9380 u16 rf_gain = 0;
9381 u16 if_gain = 0;
9382 u16 if_agc_sns = 0;
9383 u16 if_agc_top = 0;
9384 u16 rf_agc_max = 0;
9385 u16 rf_agc_min = 0;
9386
9387 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
9388 if (rc != 0) {
9389 pr_err("error %d\n", rc);
9390 goto rw_error;
9391 }
9392 if_gain &= IQM_AF_AGC_IF__M;
9393 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
9394 if (rc != 0) {
9395 pr_err("error %d\n", rc);
9396 goto rw_error;
9397 }
9398 rf_gain &= IQM_AF_AGC_RF__M;
9399
9400 if_agc_sns = DRXJ_AGC_SNS;
9401 if_agc_top = DRXJ_AGC_TOP;
9402 rf_agc_max = DRXJ_RFAGC_MAX;
9403 rf_agc_min = DRXJ_RFAGC_MIN;
9404
9405 if (if_gain > if_agc_top) {
9406 if (rf_gain > rf_agc_max)
9407 *sig_strength = 100;
9408 else if (rf_gain > rf_agc_min) {
9409 if (rf_agc_max == rf_agc_min) {
9410 pr_err("error: rf_agc_max == rf_agc_min\n");
9411 return -EIO;
9412 }
9413 *sig_strength =
9414 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
9415 rf_agc_min);
9416 } else
9417 *sig_strength = 75;
9418 } else if (if_gain > if_agc_sns) {
9419 if (if_agc_top == if_agc_sns) {
9420 pr_err("error: if_agc_top == if_agc_sns\n");
9421 return -EIO;
9422 }
9423 *sig_strength =
9424 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
9425 } else {
9426 if (!if_agc_sns) {
9427 pr_err("error: if_agc_sns is zero!\n");
9428 return -EIO;
9429 }
9430 *sig_strength = (20 * if_gain / if_agc_sns);
9431 }
9432
80846a5c
MCC
9433 if (*sig_strength <= 7)
9434 *sig_strength = 0;
9435
80e5ed14 9436 return 0;
30741871
SK
9437rw_error:
9438 return rc;
80e5ed14
MCC
9439}
9440
34eb9751 9441/*
57afe2f0 9442* \fn int ctrl_get_qam_sig_quality()
69bb7ab6 9443* \brief Retrieve QAM signal quality from device.
38b2df95 9444* \param devmod Pointer to demodulator instance.
57afe2f0 9445* \param sig_quality Pointer to signal quality data.
61263c75 9446* \return int.
9482354f
MCC
9447* \retval 0 sig_quality contains valid data.
9448* \retval -EINVAL sig_quality is NULL.
9449* \retval -EIO Erroneous data, sig_quality contains invalid data.
38b2df95
DH
9450
9451* Pre-condition: Device must be started and in lock.
9452*/
61263c75 9453static int
03fdfbfd 9454ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
443f18d0 9455{
03fdfbfd
MCC
9456 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9457 struct drxj_data *ext_attr = demod->my_ext_attr;
9458 struct drx39xxj_state *state = dev_addr->user_data;
9459 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
b3ce3a83 9460 struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
03fdfbfd
MCC
9461 enum drx_modulation constellation = ext_attr->constellation;
9462 int rc;
57afe2f0
MCC
9463
9464 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
9465 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
9466 u32 pkt_errs = 0; /* no of packet errors in RS */
9467 u16 qam_sl_err_power = 0; /* accumulated error between raw and sliced symbols */
9468 u16 qsym_err_vd = 0; /* quadrature symbol errors in QAM_VD */
9469 u16 fec_oc_period = 0; /* SNC sync failure measurement period */
9470 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
9471 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
443f18d0 9472 /* calculation constants */
57afe2f0
MCC
9473 u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
9474 u32 qam_sl_sig_power = 0; /* used for MER, depends of QAM constellation */
443f18d0 9475 /* intermediate results */
43a431e4
MCC
9476 u32 e = 0; /* exponent value used for QAM BER/SER */
9477 u32 m = 0; /* mantisa value used for QAM BER/SER */
57afe2f0 9478 u32 ber_cnt = 0; /* BER count */
443f18d0 9479 /* signal quality info */
57afe2f0
MCC
9480 u32 qam_sl_mer = 0; /* QAM MER */
9481 u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
9482 u32 qam_post_rs_ber = 0; /* Post RedSolomon BER */
9483 u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
9484 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
9485 u16 qam_vd_period = 0; /* Viterbi Measurement period */
9486 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
443f18d0 9487
69832578
MCC
9488 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9489
443f18d0
MCC
9490 /* read the physical registers */
9491 /* Get the RS error data */
e33f2193 9492 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
9482354f 9493 if (rc != 0) {
068e94ea
MCC
9494 pr_err("error %d\n", rc);
9495 goto rw_error;
9496 }
443f18d0 9497 /* get the register value needed for MER */
244c0e06 9498 rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
9482354f 9499 if (rc != 0) {
068e94ea
MCC
9500 pr_err("error %d\n", rc);
9501 goto rw_error;
9502 }
443f18d0 9503 /* get the register value needed for post RS BER */
244c0e06 9504 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
9482354f 9505 if (rc != 0) {
068e94ea
MCC
9506 pr_err("error %d\n", rc);
9507 goto rw_error;
9508 }
443f18d0
MCC
9509
9510 /* get constants needed for signal quality calculation */
57afe2f0
MCC
9511 fec_rs_period = ext_attr->fec_rs_period;
9512 fec_rs_prescale = ext_attr->fec_rs_prescale;
9513 rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
9514 qam_vd_period = ext_attr->qam_vd_period;
9515 qam_vd_prescale = ext_attr->qam_vd_prescale;
9516 vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
443f18d0
MCC
9517
9518 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
9519 switch (constellation) {
9520 case DRX_CONSTELLATION_QAM16:
57afe2f0 9521 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
443f18d0
MCC
9522 break;
9523 case DRX_CONSTELLATION_QAM32:
57afe2f0 9524 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
443f18d0
MCC
9525 break;
9526 case DRX_CONSTELLATION_QAM64:
57afe2f0 9527 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
443f18d0
MCC
9528 break;
9529 case DRX_CONSTELLATION_QAM128:
57afe2f0 9530 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
443f18d0
MCC
9531 break;
9532 case DRX_CONSTELLATION_QAM256:
57afe2f0 9533 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
443f18d0
MCC
9534 break;
9535 default:
9482354f 9536 return -EIO;
443f18d0 9537 }
38b2df95 9538
443f18d0
MCC
9539 /* ------------------------------ */
9540 /* MER Calculation */
9541 /* ------------------------------ */
9542 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
9543
9544 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
57afe2f0
MCC
9545 if (qam_sl_err_power == 0)
9546 qam_sl_mer = 0;
443f18d0 9547 else
63713517 9548 qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
443f18d0
MCC
9549
9550 /* ----------------------------------------- */
9551 /* Pre Viterbi Symbol Error Rate Calculation */
9552 /* ----------------------------------------- */
5a13e40b 9553 /* pre viterbi SER is good if it is below 0.025 */
443f18d0
MCC
9554
9555 /* get the register value */
9556 /* no of quadrature symbol errors */
244c0e06 9557 rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
9482354f 9558 if (rc != 0) {
068e94ea
MCC
9559 pr_err("error %d\n", rc);
9560 goto rw_error;
9561 }
443f18d0
MCC
9562 /* Extract the Exponent and the Mantisa */
9563 /* of number of quadrature symbol errors */
57afe2f0 9564 e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
443f18d0 9565 QAM_VD_NR_QSYM_ERRORS_EXP__B;
57afe2f0 9566 m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
443f18d0
MCC
9567 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
9568
63713517 9569 if ((m << e) >> 3 > 549752)
69832578 9570 qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
63713517 9571 else
69832578 9572 qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
38b2df95 9573
443f18d0
MCC
9574 /* --------------------------------------- */
9575 /* pre and post RedSolomon BER Calculation */
9576 /* --------------------------------------- */
9577 /* pre RS BER is good if it is below 3.5e-4 */
9578
9579 /* get the register values */
57afe2f0
MCC
9580 pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
9581 pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
443f18d0
MCC
9582
9583 /* Extract the Exponent and the Mantisa of the */
9584 /* pre Reed-Solomon bit error count */
57afe2f0 9585 e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
443f18d0 9586 FEC_RS_NR_BIT_ERRORS_EXP__B;
57afe2f0 9587 m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
443f18d0
MCC
9588 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
9589
57afe2f0 9590 ber_cnt = m << e;
443f18d0 9591
57afe2f0 9592 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
63713517 9593 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
69832578 9594 qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
63713517 9595 else
ee0f4a14 9596 qam_pre_rs_ber = ber_cnt;
38b2df95 9597
443f18d0
MCC
9598 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
9599 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
9600 /*
9601 => c = (1000000*100*11.17)/1504 =
9602 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
9603 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
9604 *100 and /100 is for more precision.
9605 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
38b2df95 9606
443f18d0
MCC
9607 Precision errors still possible.
9608 */
b6554ea5 9609 if (!fec_oc_period) {
57afe2f0 9610 qam_post_rs_ber = 0xFFFFFFFF;
b6554ea5
MCC
9611 } else {
9612 e = post_bit_err_rs * 742686;
9613 m = fec_oc_period * 100;
57afe2f0 9614 qam_post_rs_ber = e / m;
b6554ea5 9615 }
443f18d0
MCC
9616
9617 /* fill signal quality data structure */
03fdfbfd
MCC
9618 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9619 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9620 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9621 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9622 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
9623 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
9624
9625 p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
69832578 9626 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
03fdfbfd 9627 p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
69832578
MCC
9628 p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9629 } else {
03fdfbfd 9630 p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
69832578
MCC
9631 p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9632 }
03fdfbfd 9633
0d49e776
MCC
9634 p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;
9635 p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
03fdfbfd 9636
03fdfbfd
MCC
9637 p->block_error.stat[0].uvalue += pkt_errs;
9638
38b2df95 9639#ifdef DRXJ_SIGNAL_ACCUM_ERR
068e94ea 9640 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
9482354f 9641 if (rc != 0) {
068e94ea
MCC
9642 pr_err("error %d\n", rc);
9643 goto rw_error;
9644 }
38b2df95
DH
9645#endif
9646
9482354f 9647 return 0;
443f18d0 9648rw_error:
03fdfbfd
MCC
9649 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9650 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9651 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9652 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9653 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9654 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9655
30741871 9656 return rc;
38b2df95
DH
9657}
9658
38b2df95
DH
9659#endif /* #ifndef DRXJ_VSB_ONLY */
9660
9661/*============================================================================*/
9662/*== END QAM DATAPATH FUNCTIONS ==*/
9663/*============================================================================*/
9664
9665/*============================================================================*/
9666/*============================================================================*/
9667/*== ATV DATAPATH FUNCTIONS ==*/
9668/*============================================================================*/
9669/*============================================================================*/
9670
9671/*
9672 Implementation notes.
9673
9674 NTSC/FM AGCs
9675
9676 Four AGCs are used for NTSC:
9677 (1) RF (used to attenuate the input signal in case of to much power)
9678 (2) IF (used to attenuate the input signal in case of to much power)
9679 (3) Video AGC (used to amplify the output signal in case input to low)
9680 (4) SIF AGC (used to amplify the output signal in case input to low)
9681
9682 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
9683 that the coupling between Video AGC and the RF and IF AGCs also works in
9684 favor of the SIF AGC.
9685
9686 Three AGCs are used for FM:
9687 (1) RF (used to attenuate the input signal in case of to much power)
9688 (2) IF (used to attenuate the input signal in case of to much power)
9689 (3) SIF AGC (used to amplify the output signal in case input to low)
9690
9691 The SIF AGC is now coupled to the RF/IF AGCs.
9692 The SIF AGC is needed for both SIF ouput and the internal SIF signal to
9693 the AUD block.
9694
9695 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
9696 the ATV block. The AGC control algorithms are all implemented in
9697 microcode.
9698
9699 ATV SETTINGS
9700
9701 (Shadow settings will not be used for now, they will be implemented
9702 later on because of the schedule)
9703
9704 Several HW/SCU "settings" can be used for ATV. The standard selection
9705 will reset most of these settings. To avoid that the end user apllication
9706 has to perform these settings each time the ATV or FM standards is
9707 selected the driver will shadow these settings. This enables the end user
57afe2f0 9708 to perform the settings only once after a drx_open(). The driver must
38b2df95
DH
9709 write the shadow settings to HW/SCU incase:
9710 ( setstandard FM/ATV) ||
9711 ( settings have changed && FM/ATV standard is active)
9712 The shadow settings will be stored in the device specific data container.
9713 A set of flags will be defined to flag changes in shadow settings.
9714 A routine will be implemented to write all changed shadow settings to
9715 HW/SCU.
9716
9717 The "settings" will consist of: AGC settings, filter settings etc.
9718
9719 Disadvantage of use of shadow settings:
9720 Direct changes in HW/SCU registers will not be reflected in the
9721 shadow settings and these changes will be overwritten during a next
9722 update. This can happen during evaluation. This will not be a problem
9723 for normal customer usage.
9724*/
9725/* -------------------------------------------------------------------------- */
9726
34eb9751 9727/*
b6c4065e
MCC
9728* \fn int power_down_atv ()
9729* \brief Power down ATV.
38b2df95 9730* \param demod instance of demodulator
b6c4065e 9731* \param standard either NTSC or FM (sub strandard for ATV )
61263c75 9732* \return int.
38b2df95 9733*
b6c4065e
MCC
9734* Stops and thus resets ATV and IQM block
9735* SIF and CVBS ADC are powered down
9736* Calls audio power down
38b2df95 9737*/
61263c75 9738static int
b6c4065e 9739power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
38b2df95 9740{
b6c4065e
MCC
9741 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9742 struct drxjscu_cmd cmd_scu = { /* command */ 0,
9743 /* parameter_len */ 0,
9744 /* result_len */ 0,
9745 /* *parameter */ NULL,
9746 /* *result */ NULL
9747 };
068e94ea 9748 int rc;
b6c4065e 9749 u16 cmd_result = 0;
38b2df95 9750
b6c4065e 9751 /* ATV NTSC */
38b2df95 9752
b6c4065e
MCC
9753 /* Stop ATV SCU (will reset ATV and IQM hardware */
9754 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
9755 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9756 cmd_scu.parameter_len = 0;
9757 cmd_scu.result_len = 1;
9758 cmd_scu.parameter = NULL;
9759 cmd_scu.result = &cmd_result;
9760 rc = scu_command(dev_addr, &cmd_scu);
9761 if (rc != 0) {
9762 pr_err("error %d\n", rc);
9763 goto rw_error;
9764 }
9765 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
9766 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);
9767 if (rc != 0) {
9768 pr_err("error %d\n", rc);
9769 goto rw_error;
443f18d0 9770 }
38b2df95 9771
b6c4065e
MCC
9772 rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
9773 if (rc != 0) {
9774 pr_err("error %d\n", rc);
9775 goto rw_error;
9776 }
9777 if (primary) {
9778 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9482354f 9779 if (rc != 0) {
068e94ea
MCC
9780 pr_err("error %d\n", rc);
9781 goto rw_error;
9782 }
b6c4065e 9783 rc = set_iqm_af(demod, false);
9482354f 9784 if (rc != 0) {
068e94ea
MCC
9785 pr_err("error %d\n", rc);
9786 goto rw_error;
9787 }
b6c4065e
MCC
9788 } else {
9789 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9482354f 9790 if (rc != 0) {
068e94ea
MCC
9791 pr_err("error %d\n", rc);
9792 goto rw_error;
9793 }
b6c4065e 9794 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9482354f 9795 if (rc != 0) {
068e94ea
MCC
9796 pr_err("error %d\n", rc);
9797 goto rw_error;
9798 }
b6c4065e 9799 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9482354f 9800 if (rc != 0) {
068e94ea
MCC
9801 pr_err("error %d\n", rc);
9802 goto rw_error;
9803 }
b6c4065e 9804 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9482354f 9805 if (rc != 0) {
068e94ea
MCC
9806 pr_err("error %d\n", rc);
9807 goto rw_error;
9808 }
b6c4065e 9809 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9482354f 9810 if (rc != 0) {
068e94ea
MCC
9811 pr_err("error %d\n", rc);
9812 goto rw_error;
9813 }
443f18d0 9814 }
b6c4065e
MCC
9815 rc = power_down_aud(demod);
9816 if (rc != 0) {
9817 pr_err("error %d\n", rc);
9818 goto rw_error;
9819 }
443f18d0 9820
9482354f 9821 return 0;
38b2df95 9822rw_error:
30741871 9823 return rc;
38b2df95
DH
9824}
9825
b6c4065e
MCC
9826/*============================================================================*/
9827
34eb9751 9828/*
b6c4065e 9829* \brief Power up AUD.
38b2df95 9830* \param demod instance of demodulator
61263c75 9831* \return int.
38b2df95
DH
9832*
9833*/
b6c4065e 9834static int power_down_aud(struct drx_demod_instance *demod)
38b2df95 9835{
b6c4065e 9836 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 9837 struct drxj_data *ext_attr = NULL;
068e94ea 9838 int rc;
38b2df95 9839
b6c4065e 9840 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
b3ce3a83 9841 ext_attr = (struct drxj_data *) demod->my_ext_attr;
443f18d0 9842
b6c4065e 9843 rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
9482354f 9844 if (rc != 0) {
068e94ea
MCC
9845 pr_err("error %d\n", rc);
9846 goto rw_error;
9847 }
38b2df95 9848
b6c4065e
MCC
9849 ext_attr->aud_data.audio_is_active = false;
9850
9482354f 9851 return 0;
38b2df95 9852rw_error:
30741871 9853 return rc;
38b2df95
DH
9854}
9855
34eb9751 9856/*
b6c4065e
MCC
9857* \fn int set_orx_nsu_aox()
9858* \brief Configure OrxNsuAox for OOB
9859* \param demod instance of demodulator.
9860* \param active
61263c75 9861* \return int.
38b2df95 9862*/
b6c4065e 9863static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
38b2df95 9864{
b6c4065e 9865 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 9866 int rc;
b6c4065e 9867 u16 data = 0;
38b2df95 9868
b6c4065e
MCC
9869 /* Configure NSU_AOX */
9870 rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
9482354f 9871 if (rc != 0) {
068e94ea
MCC
9872 pr_err("error %d\n", rc);
9873 goto rw_error;
9874 }
b6c4065e
MCC
9875 if (!active)
9876 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));
9877 else
9878 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);
9879 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
9482354f 9880 if (rc != 0) {
068e94ea
MCC
9881 pr_err("error %d\n", rc);
9882 goto rw_error;
9883 }
38b2df95 9884
9482354f 9885 return 0;
38b2df95 9886rw_error:
30741871 9887 return rc;
38b2df95
DH
9888}
9889
34eb9751 9890/*
b6c4065e
MCC
9891* \fn int ctrl_set_oob()
9892* \brief Set OOB channel to be used.
38b2df95 9893* \param demod instance of demodulator
b6c4065e
MCC
9894* \param oob_param OOB parameters for channel setting.
9895* \frequency should be in KHz
61263c75 9896* \return int.
38b2df95 9897*
b6c4065e
MCC
9898* Accepts only. Returns error otherwise.
9899* Demapper value is written after scu_command START
9900* because START command causes COMM_EXEC transition
9901* from 0 to 1 which causes all registers to be
9902* overwritten with initial value
38b2df95
DH
9903*
9904*/
38b2df95 9905
b6c4065e
MCC
9906/* Nyquist filter impulse response */
9907#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 */
9908#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 */
9909#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 9910
b6c4065e
MCC
9911/* Coefficients for the nyquist fitler (total: 27 taps) */
9912#define NYQFILTERLEN 27
38b2df95 9913
b6c4065e 9914static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
38b2df95 9915{
068e94ea 9916 int rc;
b6c4065e
MCC
9917 s32 freq = 0; /* KHz */
9918 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 9919 struct drxj_data *ext_attr = NULL;
b6c4065e
MCC
9920 u16 i = 0;
9921 bool mirror_freq_spect_oob = false;
9922 u16 trk_filter_value = 0;
9923 struct drxjscu_cmd scu_cmd;
9924 u16 set_param_parameters[3];
9925 u16 cmd_result[2] = { 0, 0 };
9926 s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
9927 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
9928 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
9929 IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
9930 IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
9931 };
9932 u8 mode_val[4] = { 2, 2, 0, 1 };
9933 u8 pfi_coeffs[4][6] = {
9934 {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) */
9935 {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) */
9936 {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) */
9937 {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) */
9938 };
9939 u16 mode_index;
38b2df95 9940
b6c4065e 9941 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 9942 ext_attr = (struct drxj_data *) demod->my_ext_attr;
b6c4065e 9943 mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
38b2df95 9944
b6c4065e
MCC
9945 /* Check parameters */
9946 if (oob_param == NULL) {
9947 /* power off oob module */
9948 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
9949 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9950 scu_cmd.parameter_len = 0;
9951 scu_cmd.result_len = 1;
9952 scu_cmd.result = cmd_result;
9953 rc = scu_command(dev_addr, &scu_cmd);
9954 if (rc != 0) {
9955 pr_err("error %d\n", rc);
9956 goto rw_error;
9957 }
9958 rc = set_orx_nsu_aox(demod, false);
9959 if (rc != 0) {
9960 pr_err("error %d\n", rc);
9961 goto rw_error;
9962 }
9963 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
9482354f 9964 if (rc != 0) {
068e94ea
MCC
9965 pr_err("error %d\n", rc);
9966 goto rw_error;
9967 }
38b2df95 9968
b6c4065e
MCC
9969 ext_attr->oob_power_on = false;
9970 return 0;
9971 }
443f18d0 9972
b6c4065e
MCC
9973 freq = oob_param->frequency;
9974 if ((freq < 70000) || (freq > 130000))
9975 return -EIO;
9976 freq = (freq - 50000) / 50;
443f18d0 9977
b6c4065e
MCC
9978 {
9979 u16 index = 0;
9980 u16 remainder = 0;
9981 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
443f18d0 9982
b6c4065e
MCC
9983 index = (u16) ((freq - 400) / 200);
9984 remainder = (u16) ((freq - 400) % 200);
9985 trk_filter_value =
9986 trk_filtercfg[index] - (trk_filtercfg[index] -
9987 trk_filtercfg[index +
9988 1]) / 10 * remainder /
9989 20;
068e94ea 9990 }
443f18d0 9991
34eb9751 9992 /********/
b6c4065e 9993 /* Stop */
34eb9751 9994 /********/
b6c4065e 9995 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
9482354f 9996 if (rc != 0) {
068e94ea
MCC
9997 pr_err("error %d\n", rc);
9998 goto rw_error;
9999 }
b6c4065e
MCC
10000 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10001 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
10002 scu_cmd.parameter_len = 0;
10003 scu_cmd.result_len = 1;
10004 scu_cmd.result = cmd_result;
10005 rc = scu_command(dev_addr, &scu_cmd);
9482354f 10006 if (rc != 0) {
068e94ea
MCC
10007 pr_err("error %d\n", rc);
10008 goto rw_error;
10009 }
34eb9751 10010 /********/
b6c4065e 10011 /* Reset */
34eb9751 10012 /********/
b6c4065e
MCC
10013 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10014 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
10015 scu_cmd.parameter_len = 0;
10016 scu_cmd.result_len = 1;
10017 scu_cmd.result = cmd_result;
10018 rc = scu_command(dev_addr, &scu_cmd);
10019 if (rc != 0) {
068e94ea
MCC
10020 pr_err("error %d\n", rc);
10021 goto rw_error;
10022 }
34eb9751 10023 /**********/
b6c4065e 10024 /* SET_ENV */
34eb9751 10025 /**********/
b6c4065e
MCC
10026 /* set frequency, spectrum inversion and data rate */
10027 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10028 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
10029 scu_cmd.parameter_len = 3;
10030 /* 1-data rate;2-frequency */
10031 switch (oob_param->standard) {
10032 case DRX_OOB_MODE_A:
10033 if (
10034 /* signal is transmitted inverted */
10035 ((oob_param->spectrum_inverted == true) &&
10036 /* and tuner is not mirroring the signal */
10037 (!mirror_freq_spect_oob)) |
10038 /* or */
10039 /* signal is transmitted noninverted */
10040 ((oob_param->spectrum_inverted == false) &&
10041 /* and tuner is mirroring the signal */
10042 (mirror_freq_spect_oob))
10043 )
10044 set_param_parameters[0] =
10045 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
10046 else
10047 set_param_parameters[0] =
10048 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
10049 break;
10050 case DRX_OOB_MODE_B_GRADE_A:
10051 if (
10052 /* signal is transmitted inverted */
10053 ((oob_param->spectrum_inverted == true) &&
10054 /* and tuner is not mirroring the signal */
10055 (!mirror_freq_spect_oob)) |
10056 /* or */
10057 /* signal is transmitted noninverted */
10058 ((oob_param->spectrum_inverted == false) &&
10059 /* and tuner is mirroring the signal */
10060 (mirror_freq_spect_oob))
10061 )
10062 set_param_parameters[0] =
10063 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
10064 else
10065 set_param_parameters[0] =
10066 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
10067 break;
10068 case DRX_OOB_MODE_B_GRADE_B:
10069 default:
10070 if (
10071 /* signal is transmitted inverted */
10072 ((oob_param->spectrum_inverted == true) &&
10073 /* and tuner is not mirroring the signal */
10074 (!mirror_freq_spect_oob)) |
10075 /* or */
10076 /* signal is transmitted noninverted */
10077 ((oob_param->spectrum_inverted == false) &&
10078 /* and tuner is mirroring the signal */
10079 (mirror_freq_spect_oob))
10080 )
10081 set_param_parameters[0] =
10082 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
10083 else
10084 set_param_parameters[0] =
10085 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
10086 break;
10087 }
10088 set_param_parameters[1] = (u16) (freq & 0xFFFF);
10089 set_param_parameters[2] = trk_filter_value;
10090 scu_cmd.parameter = set_param_parameters;
10091 scu_cmd.result_len = 1;
10092 scu_cmd.result = cmd_result;
10093 mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
10094 rc = scu_command(dev_addr, &scu_cmd);
9482354f 10095 if (rc != 0) {
068e94ea
MCC
10096 pr_err("error %d\n", rc);
10097 goto rw_error;
10098 }
38b2df95 10099
b6c4065e
MCC
10100 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
10101 if (rc != 0) {
10102 pr_err("error %d\n", rc);
10103 goto rw_error;
10104 } /* Write magic word to enable pdr reg write */
10105 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);
10106 if (rc != 0) {
10107 pr_err("error %d\n", rc);
10108 goto rw_error;
10109 }
10110 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);
10111 if (rc != 0) {
10112 pr_err("error %d\n", rc);
10113 goto rw_error;
10114 }
10115 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
10116 if (rc != 0) {
10117 pr_err("error %d\n", rc);
10118 goto rw_error;
10119 } /* Write magic word to disable pdr reg write */
38b2df95 10120
b6c4065e 10121 rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
9482354f 10122 if (rc != 0) {
068e94ea
MCC
10123 pr_err("error %d\n", rc);
10124 goto rw_error;
10125 }
b6c4065e 10126 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
9482354f 10127 if (rc != 0) {
068e94ea
MCC
10128 pr_err("error %d\n", rc);
10129 goto rw_error;
10130 }
b6c4065e 10131 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
9482354f 10132 if (rc != 0) {
068e94ea
MCC
10133 pr_err("error %d\n", rc);
10134 goto rw_error;
10135 }
38b2df95 10136
b6c4065e
MCC
10137 /* ddc */
10138 rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
9482354f 10139 if (rc != 0) {
068e94ea
MCC
10140 pr_err("error %d\n", rc);
10141 goto rw_error;
10142 }
38b2df95 10143
b6c4065e
MCC
10144 /* nsu */
10145 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
10146 if (rc != 0) {
10147 pr_err("error %d\n", rc);
10148 goto rw_error;
10149 }
443f18d0 10150
b6c4065e
MCC
10151 /* initialization for target mode */
10152 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
9482354f 10153 if (rc != 0) {
068e94ea
MCC
10154 pr_err("error %d\n", rc);
10155 goto rw_error;
10156 }
b6c4065e 10157 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
9482354f 10158 if (rc != 0) {
068e94ea
MCC
10159 pr_err("error %d\n", rc);
10160 goto rw_error;
10161 }
443f18d0 10162
b6c4065e
MCC
10163 /* Reset bits for timing and freq. recovery */
10164 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
9482354f 10165 if (rc != 0) {
068e94ea
MCC
10166 pr_err("error %d\n", rc);
10167 goto rw_error;
10168 }
b6c4065e
MCC
10169 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
10170 if (rc != 0) {
10171 pr_err("error %d\n", rc);
10172 goto rw_error;
068e94ea 10173 }
b6c4065e
MCC
10174 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
10175 if (rc != 0) {
10176 pr_err("error %d\n", rc);
10177 goto rw_error;
10178 }
10179 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
9482354f 10180 if (rc != 0) {
068e94ea
MCC
10181 pr_err("error %d\n", rc);
10182 goto rw_error;
443f18d0 10183 }
443f18d0 10184
b6c4065e
MCC
10185 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
10186 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
10187 if (rc != 0) {
10188 pr_err("error %d\n", rc);
10189 goto rw_error;
10190 }
10191 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
10192 if (rc != 0) {
10193 pr_err("error %d\n", rc);
10194 goto rw_error;
10195 }
10196 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
10197 if (rc != 0) {
10198 pr_err("error %d\n", rc);
10199 goto rw_error;
10200 }
10201 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
10202 if (rc != 0) {
10203 pr_err("error %d\n", rc);
10204 goto rw_error;
10205 }
10206 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
10207 if (rc != 0) {
10208 pr_err("error %d\n", rc);
10209 goto rw_error;
10210 }
443f18d0 10211
b6c4065e
MCC
10212 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
10213 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
10214 if (rc != 0) {
10215 pr_err("error %d\n", rc);
10216 goto rw_error;
10217 }
10218 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
10219 if (rc != 0) {
10220 pr_err("error %d\n", rc);
10221 goto rw_error;
10222 }
10223 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
10224 if (rc != 0) {
10225 pr_err("error %d\n", rc);
10226 goto rw_error;
10227 }
10228 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
10229 if (rc != 0) {
10230 pr_err("error %d\n", rc);
10231 goto rw_error;
10232 }
10233 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
10234 if (rc != 0) {
10235 pr_err("error %d\n", rc);
10236 goto rw_error;
10237 }
38b2df95 10238
b6c4065e
MCC
10239 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
10240 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
10241 if (rc != 0) {
10242 pr_err("error %d\n", rc);
10243 goto rw_error;
10244 }
10245 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
10246 if (rc != 0) {
10247 pr_err("error %d\n", rc);
10248 goto rw_error;
10249 }
10250 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
10251 if (rc != 0) {
10252 pr_err("error %d\n", rc);
10253 goto rw_error;
10254 }
10255 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
10256 if (rc != 0) {
10257 pr_err("error %d\n", rc);
10258 goto rw_error;
10259 }
10260 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
10261 if (rc != 0) {
10262 pr_err("error %d\n", rc);
10263 goto rw_error;
10264 }
38b2df95 10265
b6c4065e
MCC
10266 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
10267 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
9482354f 10268 if (rc != 0) {
63713517
MCC
10269 pr_err("error %d\n", rc);
10270 goto rw_error;
068e94ea 10271 }
b6c4065e 10272 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
9482354f 10273 if (rc != 0) {
63713517
MCC
10274 pr_err("error %d\n", rc);
10275 goto rw_error;
068e94ea 10276 }
b6c4065e 10277 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
9482354f 10278 if (rc != 0) {
63713517
MCC
10279 pr_err("error %d\n", rc);
10280 goto rw_error;
068e94ea 10281 }
b6c4065e 10282 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
9482354f 10283 if (rc != 0) {
63713517
MCC
10284 pr_err("error %d\n", rc);
10285 goto rw_error;
068e94ea 10286 }
b6c4065e 10287 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
9482354f 10288 if (rc != 0) {
63713517
MCC
10289 pr_err("error %d\n", rc);
10290 goto rw_error;
068e94ea 10291 }
b6c4065e
MCC
10292
10293 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
10294 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
9482354f 10295 if (rc != 0) {
63713517
MCC
10296 pr_err("error %d\n", rc);
10297 goto rw_error;
068e94ea 10298 }
b6c4065e
MCC
10299 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
10300 if (rc != 0) {
10301 pr_err("error %d\n", rc);
10302 goto rw_error;
10303 }
10304 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
10305 if (rc != 0) {
10306 pr_err("error %d\n", rc);
10307 goto rw_error;
10308 }
10309 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
10310 if (rc != 0) {
10311 pr_err("error %d\n", rc);
10312 goto rw_error;
10313 }
10314 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
9482354f 10315 if (rc != 0) {
068e94ea
MCC
10316 pr_err("error %d\n", rc);
10317 goto rw_error;
10318 }
443f18d0 10319
b6c4065e
MCC
10320 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
10321 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
10322 if (rc != 0) {
10323 pr_err("error %d\n", rc);
10324 goto rw_error;
10325 }
10326 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
10327 if (rc != 0) {
10328 pr_err("error %d\n", rc);
10329 goto rw_error;
10330 }
10331 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
10332 if (rc != 0) {
10333 pr_err("error %d\n", rc);
10334 goto rw_error;
10335 }
10336 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
10337 if (rc != 0) {
10338 pr_err("error %d\n", rc);
10339 goto rw_error;
10340 }
10341 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
9482354f 10342 if (rc != 0) {
63713517
MCC
10343 pr_err("error %d\n", rc);
10344 goto rw_error;
068e94ea 10345 }
443f18d0 10346
b6c4065e
MCC
10347 /* PRE-Filter coefficients (PFI) */
10348 rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
10349 if (rc != 0) {
10350 pr_err("error %d\n", rc);
10351 goto rw_error;
10352 }
10353 rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
10354 if (rc != 0) {
10355 pr_err("error %d\n", rc);
10356 goto rw_error;
10357 }
443f18d0 10358
b6c4065e
MCC
10359 /* NYQUIST-Filter coefficients (NYQ) */
10360 for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
10361 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
9482354f 10362 if (rc != 0) {
63713517
MCC
10363 pr_err("error %d\n", rc);
10364 goto rw_error;
068e94ea 10365 }
b6c4065e 10366 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
9482354f 10367 if (rc != 0) {
63713517
MCC
10368 pr_err("error %d\n", rc);
10369 goto rw_error;
068e94ea 10370 }
b6c4065e
MCC
10371 }
10372 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
10373 if (rc != 0) {
10374 pr_err("error %d\n", rc);
10375 goto rw_error;
10376 }
10377 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
10378 if (rc != 0) {
10379 pr_err("error %d\n", rc);
10380 goto rw_error;
10381 }
34eb9751 10382 /********/
b6c4065e 10383 /* Start */
34eb9751 10384 /********/
b6c4065e
MCC
10385 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10386 | SCU_RAM_COMMAND_CMD_DEMOD_START;
10387 scu_cmd.parameter_len = 0;
10388 scu_cmd.result_len = 1;
10389 scu_cmd.result = cmd_result;
10390 rc = scu_command(dev_addr, &scu_cmd);
10391 if (rc != 0) {
10392 pr_err("error %d\n", rc);
10393 goto rw_error;
10394 }
068e94ea 10395
b6c4065e
MCC
10396 rc = set_orx_nsu_aox(demod, true);
10397 if (rc != 0) {
10398 pr_err("error %d\n", rc);
10399 goto rw_error;
10400 }
10401 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
10402 if (rc != 0) {
10403 pr_err("error %d\n", rc);
10404 goto rw_error;
10405 }
068e94ea 10406
b6c4065e 10407 ext_attr->oob_power_on = true;
aafdbaa6 10408
b6c4065e
MCC
10409 return 0;
10410rw_error:
30741871 10411 return rc;
aafdbaa6
MCC
10412}
10413
b6c4065e
MCC
10414/*============================================================================*/
10415/*== END OOB DATAPATH FUNCTIONS ==*/
10416/*============================================================================*/
10417
10418/*=============================================================================
10419 ===== MC command related functions ==========================================
10420 ===========================================================================*/
10421
10422/*=============================================================================
10423 ===== ctrl_set_channel() ==========================================================
10424 ===========================================================================*/
34eb9751 10425/*
b6c4065e
MCC
10426* \fn int ctrl_set_channel()
10427* \brief Select a new transmission channel.
10428* \param demod instance of demod.
10429* \param channel Pointer to channel data.
61263c75 10430* \return int.
38b2df95 10431*
b6c4065e
MCC
10432* In case the tuner module is not used and in case of NTSC/FM the pogrammer
10433* must tune the tuner to the centre frequency of the NTSC/FM channel.
38b2df95
DH
10434*
10435*/
61263c75 10436static int
b6c4065e 10437ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
38b2df95 10438{
068e94ea 10439 int rc;
b6c4065e 10440 s32 tuner_freq_offset = 0;
b6c4065e
MCC
10441 struct drxj_data *ext_attr = NULL;
10442 struct i2c_device_addr *dev_addr = NULL;
10443 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
b6c4065e
MCC
10444#ifndef DRXJ_VSB_ONLY
10445 u32 min_symbol_rate = 0;
10446 u32 max_symbol_rate = 0;
10447 int bandwidth_temp = 0;
10448 int bandwidth = 0;
10449#endif
10450 /*== check arguments ======================================================*/
10451 if ((demod == NULL) || (channel == NULL))
10452 return -EINVAL;
38b2df95 10453
57afe2f0 10454 dev_addr = demod->my_i2c_dev_addr;
b6c4065e
MCC
10455 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10456 standard = ext_attr->standard;
38b2df95 10457
b6c4065e
MCC
10458 /* check valid standards */
10459 switch (standard) {
10460 case DRX_STANDARD_8VSB:
10461#ifndef DRXJ_VSB_ONLY
10462 case DRX_STANDARD_ITU_A:
10463 case DRX_STANDARD_ITU_B:
10464 case DRX_STANDARD_ITU_C:
10465#endif /* DRXJ_VSB_ONLY */
443f18d0 10466 break;
b6c4065e 10467 case DRX_STANDARD_UNKNOWN:
443f18d0 10468 default:
9482354f 10469 return -EINVAL;
443f18d0 10470 }
38b2df95 10471
b6c4065e
MCC
10472 /* check bandwidth QAM annex B, NTSC and 8VSB */
10473 if ((standard == DRX_STANDARD_ITU_B) ||
10474 (standard == DRX_STANDARD_8VSB) ||
10475 (standard == DRX_STANDARD_NTSC)) {
10476 switch (channel->bandwidth) {
10477 case DRX_BANDWIDTH_6MHZ:
10478 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
10479 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10480 break;
10481 case DRX_BANDWIDTH_8MHZ: /* fall through */
10482 case DRX_BANDWIDTH_7MHZ: /* fall through */
10483 default:
10484 return -EINVAL;
10485 }
10486 }
10487
10488 /* For QAM annex A and annex C:
10489 -check symbolrate and constellation
10490 -derive bandwidth from symbolrate (input bandwidth is ignored)
10491 */
10492#ifndef DRXJ_VSB_ONLY
10493 if ((standard == DRX_STANDARD_ITU_A) ||
10494 (standard == DRX_STANDARD_ITU_C)) {
10495 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
10496 int bw_rolloff_factor = 0;
10497
10498 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
10499 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
10500 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
10501 /* config SMA_TX pin to SAW switch mode */
10502 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
9482354f 10503 if (rc != 0) {
068e94ea
MCC
10504 pr_err("error %d\n", rc);
10505 goto rw_error;
10506 }
443f18d0 10507
b6c4065e
MCC
10508 if (channel->symbolrate < min_symbol_rate ||
10509 channel->symbolrate > max_symbol_rate) {
10510 return -EINVAL;
10511 }
aafdbaa6 10512
b6c4065e
MCC
10513 switch (channel->constellation) {
10514 case DRX_CONSTELLATION_QAM16: /* fall through */
10515 case DRX_CONSTELLATION_QAM32: /* fall through */
10516 case DRX_CONSTELLATION_QAM64: /* fall through */
10517 case DRX_CONSTELLATION_QAM128: /* fall through */
10518 case DRX_CONSTELLATION_QAM256:
10519 bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
10520 bandwidth = bandwidth_temp / 100;
443f18d0 10521
b6c4065e
MCC
10522 if ((bandwidth_temp % 100) >= 50)
10523 bandwidth++;
10524
10525 if (bandwidth <= 6100000) {
10526 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10527 } else if ((bandwidth > 6100000)
10528 && (bandwidth <= 7100000)) {
10529 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
10530 } else if (bandwidth > 7100000) {
10531 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
068e94ea 10532 }
443f18d0 10533 break;
b6c4065e
MCC
10534 default:
10535 return -EINVAL;
10536 }
10537 }
10538
10539 /* For QAM annex B:
10540 -check constellation
10541 */
10542 if (standard == DRX_STANDARD_ITU_B) {
10543 switch (channel->constellation) {
10544 case DRX_CONSTELLATION_AUTO:
10545 case DRX_CONSTELLATION_QAM256:
10546 case DRX_CONSTELLATION_QAM64:
443f18d0 10547 break;
b6c4065e
MCC
10548 default:
10549 return -EINVAL;
10550 }
10551
10552 switch (channel->interleavemode) {
10553 case DRX_INTERLEAVEMODE_I128_J1:
10554 case DRX_INTERLEAVEMODE_I128_J1_V2:
10555 case DRX_INTERLEAVEMODE_I128_J2:
10556 case DRX_INTERLEAVEMODE_I64_J2:
10557 case DRX_INTERLEAVEMODE_I128_J3:
10558 case DRX_INTERLEAVEMODE_I32_J4:
10559 case DRX_INTERLEAVEMODE_I128_J4:
10560 case DRX_INTERLEAVEMODE_I16_J8:
10561 case DRX_INTERLEAVEMODE_I128_J5:
10562 case DRX_INTERLEAVEMODE_I8_J16:
10563 case DRX_INTERLEAVEMODE_I128_J6:
10564 case DRX_INTERLEAVEMODE_I128_J7:
10565 case DRX_INTERLEAVEMODE_I128_J8:
10566 case DRX_INTERLEAVEMODE_I12_J17:
10567 case DRX_INTERLEAVEMODE_I5_J4:
10568 case DRX_INTERLEAVEMODE_B52_M240:
10569 case DRX_INTERLEAVEMODE_B52_M720:
10570 case DRX_INTERLEAVEMODE_UNKNOWN:
10571 case DRX_INTERLEAVEMODE_AUTO:
443f18d0 10572 break;
443f18d0 10573 default:
b6c4065e 10574 return -EINVAL;
443f18d0 10575 }
d7a5478a 10576 }
443f18d0 10577
b6c4065e
MCC
10578 if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
10579 /* SAW SW, user UIO is used for switchable SAW */
10580 struct drxuio_data uio1 = { DRX_UIO1, false };
10581
10582 switch (channel->bandwidth) {
10583 case DRX_BANDWIDTH_8MHZ:
10584 uio1.value = true;
10585 break;
10586 case DRX_BANDWIDTH_7MHZ:
10587 uio1.value = false;
10588 break;
10589 case DRX_BANDWIDTH_6MHZ:
10590 uio1.value = false;
10591 break;
10592 case DRX_BANDWIDTH_UNKNOWN:
10593 default:
10594 return -EINVAL;
d7a5478a 10595 }
b6c4065e
MCC
10596
10597 rc = ctrl_uio_write(demod, &uio1);
d7a5478a
MCC
10598 if (rc != 0) {
10599 pr_err("error %d\n", rc);
10600 goto rw_error;
10601 }
b6c4065e
MCC
10602 }
10603#endif /* DRXJ_VSB_ONLY */
10604 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
10605 if (rc != 0) {
10606 pr_err("error %d\n", rc);
10607 goto rw_error;
443f18d0
MCC
10608 }
10609
b6c4065e 10610 tuner_freq_offset = 0;
443f18d0 10611
b6c4065e
MCC
10612 /*== Setup demod for specific standard ====================================*/
10613 switch (standard) {
10614 case DRX_STANDARD_8VSB:
10615 if (channel->mirror == DRX_MIRROR_AUTO)
10616 ext_attr->mirror = DRX_MIRROR_NO;
10617 else
10618 ext_attr->mirror = channel->mirror;
10619 rc = set_vsb(demod);
9482354f 10620 if (rc != 0) {
068e94ea
MCC
10621 pr_err("error %d\n", rc);
10622 goto rw_error;
10623 }
b6c4065e 10624 rc = set_frequency(demod, channel, tuner_freq_offset);
9482354f 10625 if (rc != 0) {
068e94ea
MCC
10626 pr_err("error %d\n", rc);
10627 goto rw_error;
10628 }
b6c4065e
MCC
10629 break;
10630#ifndef DRXJ_VSB_ONLY
10631 case DRX_STANDARD_ITU_A: /* fallthrough */
10632 case DRX_STANDARD_ITU_B: /* fallthrough */
10633 case DRX_STANDARD_ITU_C:
10634 rc = set_qam_channel(demod, channel, tuner_freq_offset);
9482354f 10635 if (rc != 0) {
068e94ea
MCC
10636 pr_err("error %d\n", rc);
10637 goto rw_error;
10638 }
b6c4065e
MCC
10639 break;
10640#endif
10641 case DRX_STANDARD_UNKNOWN:
10642 default:
10643 return -EIO;
443f18d0 10644 }
38b2df95 10645
b6c4065e
MCC
10646 /* flag the packet error counter reset */
10647 ext_attr->reset_pkt_err_acc = true;
38b2df95 10648
b6c4065e 10649 return 0;
443f18d0 10650rw_error:
30741871 10651 return rc;
38b2df95
DH
10652}
10653
b6c4065e
MCC
10654/*=============================================================================
10655 ===== SigQuality() ==========================================================
10656 ===========================================================================*/
10657
34eb9751 10658/*
b6c4065e 10659* \fn int ctrl_sig_quality()
69bb7ab6 10660* \brief Retrieve signal quality form device.
38b2df95 10661* \param devmod Pointer to demodulator instance.
b6c4065e 10662* \param sig_quality Pointer to signal quality data.
61263c75 10663* \return int.
b6c4065e
MCC
10664* \retval 0 sig_quality contains valid data.
10665* \retval -EINVAL sig_quality is NULL.
10666* \retval -EIO Erroneous data, sig_quality contains invalid data.
38b2df95
DH
10667
10668*/
61263c75 10669static int
03fdfbfd
MCC
10670ctrl_sig_quality(struct drx_demod_instance *demod,
10671 enum drx_lock_status lock_status)
38b2df95 10672{
03fdfbfd
MCC
10673 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
10674 struct drxj_data *ext_attr = demod->my_ext_attr;
10675 struct drx39xxj_state *state = dev_addr->user_data;
10676 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
10677 enum drx_standard standard = ext_attr->standard;
068e94ea 10678 int rc;
d591590e 10679 u32 ber, cnt, err, pkt;
4182438e 10680 u16 mer, strength = 0;
38b2df95 10681
03fdfbfd
MCC
10682 rc = get_sig_strength(demod, &strength);
10683 if (rc < 0) {
10684 pr_err("error getting signal strength %d\n", rc);
10685 p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10686 } else {
10687 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
10688 p->strength.stat[0].uvalue = 65535UL * strength/ 100;
b6c4065e 10689 }
03fdfbfd 10690
443f18d0 10691 switch (standard) {
b6c4065e
MCC
10692 case DRX_STANDARD_8VSB:
10693#ifdef DRXJ_SIGNAL_ACCUM_ERR
03fdfbfd 10694 rc = get_acc_pkt_err(demod, &pkt);
b6c4065e
MCC
10695 if (rc != 0) {
10696 pr_err("error %d\n", rc);
10697 goto rw_error;
10698 }
10699#endif
10700 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
03fdfbfd 10701 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
03fdfbfd 10702 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
69832578 10703 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
03fdfbfd 10704 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
69832578 10705 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
03fdfbfd
MCC
10706 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10707 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
b6c4065e 10708 } else {
69832578 10709 rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);
03fdfbfd
MCC
10710 if (rc != 0) {
10711 pr_err("error %d getting UCB\n", rc);
10712 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10713 } else {
10714 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
69832578
MCC
10715 p->block_error.stat[0].uvalue += err;
10716 p->block_count.stat[0].scale = FE_SCALE_COUNTER;
10717 p->block_count.stat[0].uvalue += pkt;
03fdfbfd
MCC
10718 }
10719
b6c4065e 10720 /* PostViterbi is compute in steps of 10^(-6) */
69832578 10721 rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);
b6c4065e 10722 if (rc != 0) {
03fdfbfd
MCC
10723 pr_err("error %d getting pre-ber\n", rc);
10724 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10725 } else {
10726 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10727 p->pre_bit_error.stat[0].uvalue += ber;
10728 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
69832578 10729 p->pre_bit_count.stat[0].uvalue += cnt;
b6c4065e 10730 }
03fdfbfd 10731
69832578 10732 rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);
b6c4065e 10733 if (rc != 0) {
03fdfbfd
MCC
10734 pr_err("error %d getting post-ber\n", rc);
10735 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10736 } else {
10737 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10738 p->post_bit_error.stat[0].uvalue += ber;
10739 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
69832578 10740 p->post_bit_count.stat[0].uvalue += cnt;
b6c4065e 10741 }
03fdfbfd 10742 rc = get_vsbmer(dev_addr, &mer);
b6c4065e 10743 if (rc != 0) {
03fdfbfd
MCC
10744 pr_err("error %d getting MER\n", rc);
10745 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10746 } else {
10747 p->cnr.stat[0].svalue = mer * 100;
10748 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
b6c4065e
MCC
10749 }
10750 }
b6c4065e 10751 break;
38b2df95 10752#ifndef DRXJ_VSB_ONLY
b6c4065e
MCC
10753 case DRX_STANDARD_ITU_A:
10754 case DRX_STANDARD_ITU_B:
443f18d0 10755 case DRX_STANDARD_ITU_C:
03fdfbfd 10756 rc = ctrl_get_qam_sig_quality(demod);
9482354f 10757 if (rc != 0) {
068e94ea
MCC
10758 pr_err("error %d\n", rc);
10759 goto rw_error;
10760 }
443f18d0 10761 break;
b6c4065e 10762#endif
443f18d0 10763 default:
b6c4065e 10764 return -EIO;
443f18d0
MCC
10765 }
10766
9482354f 10767 return 0;
443f18d0 10768rw_error:
30741871 10769 return rc;
38b2df95
DH
10770}
10771
10772/*============================================================================*/
38b2df95 10773
34eb9751 10774/*
b6c4065e 10775* \fn int ctrl_lock_status()
69bb7ab6 10776* \brief Retrieve lock status .
b6c4065e
MCC
10777* \param dev_addr Pointer to demodulator device address.
10778* \param lock_stat Pointer to lock status structure.
61263c75 10779* \return int.
38b2df95
DH
10780*
10781*/
61263c75 10782static int
b6c4065e 10783ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
38b2df95 10784{
b6c4065e
MCC
10785 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10786 struct drxj_data *ext_attr = NULL;
57afe2f0 10787 struct i2c_device_addr *dev_addr = NULL;
b6c4065e
MCC
10788 struct drxjscu_cmd cmd_scu = { /* command */ 0,
10789 /* parameter_len */ 0,
10790 /* result_len */ 0,
10791 /* *parameter */ NULL,
10792 /* *result */ NULL
10793 };
068e94ea 10794 int rc;
b6c4065e
MCC
10795 u16 cmd_result[2] = { 0, 0 };
10796 u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
38b2df95 10797
443f18d0 10798 /* check arguments */
b6c4065e 10799 if ((demod == NULL) || (lock_stat == NULL))
9482354f 10800 return -EINVAL;
63713517 10801
57afe2f0 10802 dev_addr = demod->my_i2c_dev_addr;
b6c4065e
MCC
10803 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10804 standard = ext_attr->standard;
38b2df95 10805
b6c4065e 10806 *lock_stat = DRX_NOT_LOCKED;
443f18d0 10807
b6c4065e
MCC
10808 /* define the SCU command code */
10809 switch (standard) {
10810 case DRX_STANDARD_8VSB:
10811 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
10812 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10813 demod_lock |= 0x6;
443f18d0 10814 break;
38b2df95 10815#ifndef DRXJ_VSB_ONLY
b6c4065e
MCC
10816 case DRX_STANDARD_ITU_A:
10817 case DRX_STANDARD_ITU_B:
443f18d0 10818 case DRX_STANDARD_ITU_C:
b6c4065e
MCC
10819 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10820 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10821 break;
38b2df95 10822#endif
b6c4065e 10823 case DRX_STANDARD_UNKNOWN: /* fallthrough */
443f18d0 10824 default:
b6c4065e 10825 return -EIO;
443f18d0 10826 }
38b2df95 10827
69bb7ab6 10828 /* define the SCU command parameters and execute the command */
b6c4065e
MCC
10829 cmd_scu.parameter_len = 0;
10830 cmd_scu.result_len = 2;
10831 cmd_scu.parameter = NULL;
10832 cmd_scu.result = cmd_result;
10833 rc = scu_command(dev_addr, &cmd_scu);
10834 if (rc != 0) {
10835 pr_err("error %d\n", rc);
10836 goto rw_error;
443f18d0
MCC
10837 }
10838
b6c4065e
MCC
10839 /* set the lock status */
10840 if (cmd_scu.result[1] < demod_lock) {
10841 /* 0x0000 NOT LOCKED */
10842 *lock_stat = DRX_NOT_LOCKED;
10843 } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
10844 *lock_stat = DRXJ_DEMOD_LOCK;
10845 } else if (cmd_scu.result[1] <
10846 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
10847 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
10848 *lock_stat = DRX_LOCKED;
10849 } else {
10850 /* 0xC000 NEVER LOCKED */
10851 /* (system will never be able to lock to the signal) */
10852 *lock_stat = DRX_NEVER_LOCK;
443f18d0 10853 }
38b2df95 10854
9482354f 10855 return 0;
b6c4065e 10856rw_error:
30741871 10857 return rc;
38b2df95
DH
10858}
10859
10860/*============================================================================*/
10861
34eb9751 10862/*
b6c4065e
MCC
10863* \fn int ctrl_set_standard()
10864* \brief Set modulation standard to be used.
10865* \param standard Modulation standard.
61263c75 10866* \return int.
38b2df95 10867*
b6c4065e
MCC
10868* Setup stuff for the desired demodulation standard.
10869* Disable and power down the previous selected demodulation standard
38b2df95
DH
10870*
10871*/
61263c75 10872static int
b6c4065e 10873ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
38b2df95 10874{
b6c4065e
MCC
10875 struct drxj_data *ext_attr = NULL;
10876 int rc;
10877 enum drx_standard prev_standard;
10878
443f18d0 10879 /* check arguments */
b6c4065e 10880 if ((standard == NULL) || (demod == NULL))
9482354f 10881 return -EINVAL;
38b2df95 10882
b6c4065e
MCC
10883 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10884 prev_standard = ext_attr->standard;
10885
10886 /*
10887 Stop and power down previous standard
10888 */
10889 switch (prev_standard) {
38b2df95 10890#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
10891 case DRX_STANDARD_ITU_A: /* fallthrough */
10892 case DRX_STANDARD_ITU_B: /* fallthrough */
10893 case DRX_STANDARD_ITU_C:
b6c4065e
MCC
10894 rc = power_down_qam(demod, false);
10895 if (rc != 0) {
10896 pr_err("error %d\n", rc);
10897 goto rw_error;
10898 }
10899 break;
38b2df95 10900#endif
b6c4065e
MCC
10901 case DRX_STANDARD_8VSB:
10902 rc = power_down_vsb(demod, false);
10903 if (rc != 0) {
10904 pr_err("error %d\n", rc);
10905 goto rw_error;
10906 }
10907 break;
443f18d0 10908 case DRX_STANDARD_UNKNOWN:
b6c4065e
MCC
10909 /* Do nothing */
10910 break;
10911 case DRX_STANDARD_AUTO: /* fallthrough */
10912 default:
10913 return -EINVAL;
10914 }
10915
10916 /*
10917 Initialize channel independent registers
10918 Power up new standard
10919 */
10920 ext_attr->standard = *standard;
10921
10922 switch (*standard) {
10923#ifndef DRXJ_VSB_ONLY
10924 case DRX_STANDARD_ITU_A: /* fallthrough */
10925 case DRX_STANDARD_ITU_B: /* fallthrough */
10926 case DRX_STANDARD_ITU_C:
10927 do {
10928 u16 dummy;
10929 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
10930 if (rc != 0) {
10931 pr_err("error %d\n", rc);
10932 goto rw_error;
10933 }
10934 } while (0);
10935 break;
10936#endif
10937 case DRX_STANDARD_8VSB:
10938 rc = set_vsb_leak_n_gain(demod);
10939 if (rc != 0) {
10940 pr_err("error %d\n", rc);
10941 goto rw_error;
10942 }
10943 break;
443f18d0 10944 default:
b6c4065e 10945 ext_attr->standard = DRX_STANDARD_UNKNOWN;
9482354f 10946 return -EINVAL;
b6c4065e 10947 break;
443f18d0 10948 }
38b2df95 10949
9482354f 10950 return 0;
b6c4065e
MCC
10951rw_error:
10952 /* Don't know what the standard is now ... try again */
10953 ext_attr->standard = DRX_STANDARD_UNKNOWN;
30741871 10954 return rc;
38b2df95
DH
10955}
10956
38b2df95
DH
10957/*============================================================================*/
10958
b6c4065e
MCC
10959static void drxj_reset_mode(struct drxj_data *ext_attr)
10960{
2c149601 10961 /* Initialize default AFE configuration for QAM */
b6c4065e
MCC
10962 if (ext_attr->has_lna) {
10963 /* IF AGC off, PGA active */
10964#ifndef DRXJ_VSB_ONLY
10965 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10966 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10967 ext_attr->qam_pga_cfg = 140 + (11 * 13);
10968#endif
10969 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10970 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10971 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
10972 } else {
10973 /* IF AGC on, PGA not active */
10974#ifndef DRXJ_VSB_ONLY
10975 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10976 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10977 ext_attr->qam_if_agc_cfg.min_output_level = 0;
10978 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
10979 ext_attr->qam_if_agc_cfg.speed = 3;
10980 ext_attr->qam_if_agc_cfg.top = 1297;
10981 ext_attr->qam_pga_cfg = 140;
10982#endif
10983 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10984 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10985 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
10986 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
10987 ext_attr->vsb_if_agc_cfg.speed = 3;
10988 ext_attr->vsb_if_agc_cfg.top = 1024;
10989 ext_attr->vsb_pga_cfg = 140;
10990 }
10991 /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
10992 /* mc has not used them */
10993#ifndef DRXJ_VSB_ONLY
10994 ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
10995 ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10996 ext_attr->qam_rf_agc_cfg.min_output_level = 0;
10997 ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
10998 ext_attr->qam_rf_agc_cfg.speed = 3;
10999 ext_attr->qam_rf_agc_cfg.top = 9500;
11000 ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
11001 ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
11002 ext_attr->qam_pre_saw_cfg.reference = 0x07;
11003 ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
11004#endif
2c149601 11005 /* Initialize default AFE configuration for VSB */
b6c4065e
MCC
11006 ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
11007 ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11008 ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
11009 ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
11010 ext_attr->vsb_rf_agc_cfg.speed = 3;
11011 ext_attr->vsb_rf_agc_cfg.top = 9500;
11012 ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
11013 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
11014 ext_attr->vsb_pre_saw_cfg.reference = 0x07;
11015 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
11016}
11017
34eb9751 11018/*
b6c4065e
MCC
11019* \fn int ctrl_power_mode()
11020* \brief Set the power mode of the device to the specified power mode
11021* \param demod Pointer to demodulator instance.
11022* \param mode Pointer to new power mode.
61263c75 11023* \return int.
b6c4065e
MCC
11024* \retval 0 Success
11025* \retval -EIO I2C error or other failure
11026* \retval -EINVAL Invalid mode argument.
38b2df95 11027*
38b2df95
DH
11028*
11029*/
61263c75 11030static int
b6c4065e 11031ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
38b2df95 11032{
b6c4065e
MCC
11033 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
11034 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
11035 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
068e94ea 11036 int rc;
b6c4065e 11037 u16 sio_cc_pwd_mode = 0;
38b2df95 11038
b6c4065e 11039 common_attr = (struct drx_common_attr *) demod->my_common_attr;
b3ce3a83 11040 ext_attr = (struct drxj_data *) demod->my_ext_attr;
b6c4065e 11041 dev_addr = demod->my_i2c_dev_addr;
443f18d0 11042
b6c4065e
MCC
11043 /* Check arguments */
11044 if (mode == NULL)
11045 return -EINVAL;
11046
11047 /* If already in requested power mode, do nothing */
11048 if (common_attr->current_power_mode == *mode)
9482354f 11049 return 0;
443f18d0 11050
b6c4065e
MCC
11051 switch (*mode) {
11052 case DRX_POWER_UP:
11053 case DRXJ_POWER_DOWN_MAIN_PATH:
11054 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
443f18d0 11055 break;
b6c4065e
MCC
11056 case DRXJ_POWER_DOWN_CORE:
11057 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
11058 break;
11059 case DRXJ_POWER_DOWN_PLL:
11060 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
11061 break;
11062 case DRX_POWER_DOWN:
11063 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
11064 break;
11065 default:
11066 /* Unknow sleep mode */
11067 return -EINVAL;
11068 break;
11069 }
11070
11071 /* Check if device needs to be powered up */
11072 if ((common_attr->current_power_mode != DRX_POWER_UP)) {
11073 rc = power_up_device(demod);
11074 if (rc != 0) {
11075 pr_err("error %d\n", rc);
11076 goto rw_error;
11077 }
11078 }
11079
7369bbf2 11080 if (*mode == DRX_POWER_UP) {
2c149601 11081 /* Restore analog & pin configuration */
b6c4065e 11082
2c149601 11083 /* Initialize default AFE configuration for VSB */
b6c4065e
MCC
11084 drxj_reset_mode(ext_attr);
11085 } else {
11086 /* Power down to requested mode */
11087 /* Backup some register settings */
11088 /* Set pins with possible pull-ups connected to them in input mode */
11089 /* Analog power down */
11090 /* ADC power down */
11091 /* Power down device */
11092 /* stop all comm_exec */
11093 /*
11094 Stop and power down previous standard
11095 */
11096
11097 switch (ext_attr->standard) {
11098 case DRX_STANDARD_ITU_A:
11099 case DRX_STANDARD_ITU_B:
11100 case DRX_STANDARD_ITU_C:
11101 rc = power_down_qam(demod, true);
11102 if (rc != 0) {
11103 pr_err("error %d\n", rc);
11104 goto rw_error;
11105 }
11106 break;
11107 case DRX_STANDARD_8VSB:
11108 rc = power_down_vsb(demod, true);
11109 if (rc != 0) {
11110 pr_err("error %d\n", rc);
11111 goto rw_error;
11112 }
11113 break;
11114 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
11115 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
11116 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
11117 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
11118 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
11119 case DRX_STANDARD_NTSC: /* fallthrough */
11120 case DRX_STANDARD_FM:
11121 rc = power_down_atv(demod, ext_attr->standard, true);
11122 if (rc != 0) {
11123 pr_err("error %d\n", rc);
11124 goto rw_error;
11125 }
443f18d0 11126 break;
b6c4065e
MCC
11127 case DRX_STANDARD_UNKNOWN:
11128 /* Do nothing */
443f18d0 11129 break;
b6c4065e 11130 case DRX_STANDARD_AUTO: /* fallthrough */
443f18d0 11131 default:
9482354f 11132 return -EIO;
443f18d0 11133 }
b6c4065e 11134 ext_attr->standard = DRX_STANDARD_UNKNOWN;
443f18d0
MCC
11135 }
11136
b6c4065e
MCC
11137 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
11138 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
11139 if (rc != 0) {
11140 pr_err("error %d\n", rc);
11141 goto rw_error;
11142 }
11143 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
11144 if (rc != 0) {
11145 pr_err("error %d\n", rc);
11146 goto rw_error;
11147 }
11148
11149 if ((*mode != DRX_POWER_UP)) {
11150 /* Initialize HI, wakeup key especially before put IC to sleep */
11151 rc = init_hi(demod);
11152 if (rc != 0) {
11153 pr_err("error %d\n", rc);
11154 goto rw_error;
11155 }
11156
11157 ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
11158 rc = hi_cfg_command(demod);
11159 if (rc != 0) {
11160 pr_err("error %d\n", rc);
11161 goto rw_error;
11162 }
11163 }
068e94ea 11164 }
b6c4065e
MCC
11165
11166 common_attr->current_power_mode = *mode;
443f18d0 11167
9482354f 11168 return 0;
38b2df95 11169rw_error:
b6c4065e 11170 return rc;
38b2df95
DH
11171}
11172
11173/*============================================================================*/
b6c4065e
MCC
11174/*== CTRL Set/Get Config related functions ===================================*/
11175/*============================================================================*/
38b2df95 11176
34eb9751 11177/*
57afe2f0 11178* \fn int ctrl_set_cfg_pre_saw()
38b2df95
DH
11179* \brief Set Pre-saw reference.
11180* \param demod demod instance
43a431e4 11181* \param u16 *
61263c75 11182* \return int.
38b2df95
DH
11183*
11184* Check arguments
11185* Dispatch handling to standard specific function.
11186*
11187*/
61263c75 11188static int
b3ce3a83 11189ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
38b2df95 11190{
57afe2f0 11191 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 11192 struct drxj_data *ext_attr = NULL;
068e94ea 11193 int rc;
38b2df95 11194
57afe2f0 11195 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 11196 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 11197
443f18d0 11198 /* check arguments */
57afe2f0 11199 if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
443f18d0 11200 ) {
9482354f 11201 return -EINVAL;
443f18d0
MCC
11202 }
11203
11204 /* Only if standard is currently active */
57afe2f0
MCC
11205 if ((ext_attr->standard == pre_saw->standard) ||
11206 (DRXJ_ISQAMSTD(ext_attr->standard) &&
11207 DRXJ_ISQAMSTD(pre_saw->standard)) ||
11208 (DRXJ_ISATVSTD(ext_attr->standard) &&
11209 DRXJ_ISATVSTD(pre_saw->standard))) {
244c0e06 11210 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
9482354f 11211 if (rc != 0) {
068e94ea
MCC
11212 pr_err("error %d\n", rc);
11213 goto rw_error;
11214 }
443f18d0
MCC
11215 }
11216
11217 /* Store pre-saw settings */
57afe2f0 11218 switch (pre_saw->standard) {
443f18d0 11219 case DRX_STANDARD_8VSB:
57afe2f0 11220 ext_attr->vsb_pre_saw_cfg = *pre_saw;
443f18d0 11221 break;
38b2df95 11222#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
11223 case DRX_STANDARD_ITU_A: /* fallthrough */
11224 case DRX_STANDARD_ITU_B: /* fallthrough */
11225 case DRX_STANDARD_ITU_C:
57afe2f0 11226 ext_attr->qam_pre_saw_cfg = *pre_saw;
443f18d0 11227 break;
38b2df95 11228#endif
443f18d0 11229 default:
9482354f 11230 return -EINVAL;
443f18d0 11231 }
38b2df95 11232
9482354f 11233 return 0;
38b2df95 11234rw_error:
30741871 11235 return rc;
38b2df95
DH
11236}
11237
11238/*============================================================================*/
11239
34eb9751 11240/*
57afe2f0 11241* \fn int ctrl_set_cfg_afe_gain()
38b2df95
DH
11242* \brief Set AFE Gain.
11243* \param demod demod instance
43a431e4 11244* \param u16 *
61263c75 11245* \return int.
38b2df95
DH
11246*
11247* Check arguments
11248* Dispatch handling to standard specific function.
11249*
11250*/
61263c75 11251static int
b3ce3a83 11252ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
38b2df95 11253{
57afe2f0 11254 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 11255 struct drxj_data *ext_attr = NULL;
068e94ea 11256 int rc;
43a431e4 11257 u8 gain = 0;
38b2df95 11258
443f18d0 11259 /* check arguments */
63713517 11260 if (afe_gain == NULL)
9482354f 11261 return -EINVAL;
38b2df95 11262
57afe2f0 11263 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 11264 ext_attr = (struct drxj_data *) demod->my_ext_attr;
38b2df95 11265
57afe2f0 11266 switch (afe_gain->standard) {
443f18d0 11267 case DRX_STANDARD_8VSB: /* fallthrough */
38b2df95 11268#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
11269 case DRX_STANDARD_ITU_A: /* fallthrough */
11270 case DRX_STANDARD_ITU_B: /* fallthrough */
11271 case DRX_STANDARD_ITU_C:
38b2df95 11272#endif
443f18d0
MCC
11273 /* Do nothing */
11274 break;
11275 default:
9482354f 11276 return -EINVAL;
443f18d0 11277 }
38b2df95 11278
443f18d0 11279 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
38b2df95
DH
11280 So I (PJ) think interface requires choice between auto, user mode */
11281
57afe2f0 11282 if (afe_gain->gain >= 329)
443f18d0 11283 gain = 15;
57afe2f0 11284 else if (afe_gain->gain <= 147)
443f18d0
MCC
11285 gain = 0;
11286 else
57afe2f0 11287 gain = (afe_gain->gain - 140 + 6) / 13;
443f18d0
MCC
11288
11289 /* Only if standard is currently active */
63713517 11290 if (ext_attr->standard == afe_gain->standard) {
244c0e06 11291 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
9482354f 11292 if (rc != 0) {
068e94ea
MCC
11293 pr_err("error %d\n", rc);
11294 goto rw_error;
11295 }
11296 }
443f18d0
MCC
11297
11298 /* Store AFE Gain settings */
57afe2f0 11299 switch (afe_gain->standard) {
443f18d0 11300 case DRX_STANDARD_8VSB:
57afe2f0 11301 ext_attr->vsb_pga_cfg = gain * 13 + 140;
443f18d0 11302 break;
38b2df95 11303#ifndef DRXJ_VSB_ONLY
443f18d0
MCC
11304 case DRX_STANDARD_ITU_A: /* fallthrough */
11305 case DRX_STANDARD_ITU_B: /* fallthrough */
11306 case DRX_STANDARD_ITU_C:
57afe2f0 11307 ext_attr->qam_pga_cfg = gain * 13 + 140;
443f18d0 11308 break;
38b2df95 11309#endif
443f18d0 11310 default:
9482354f 11311 return -EIO;
443f18d0 11312 }
38b2df95 11313
9482354f 11314 return 0;
38b2df95 11315rw_error:
30741871 11316 return rc;
38b2df95
DH
11317}
11318
11319/*============================================================================*/
11320
38b2df95
DH
11321
11322/*=============================================================================
11323===== EXPORTED FUNCTIONS ====================================================*/
aafdbaa6 11324
dc5a91d4
MCC
11325static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11326 struct drxu_code_info *mc_info,
11327 enum drxu_code_action action);
998819d2 11328static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
dc5a91d4 11329
34eb9751 11330/*
57afe2f0 11331* \fn drxj_open()
38b2df95
DH
11332* \brief Open the demod instance, configure device, configure drxdriver
11333* \return Status_t Return status.
11334*
57afe2f0
MCC
11335* drxj_open() can be called with a NULL ucode image => no ucode upload.
11336* This means that drxj_open() must NOT contain SCU commands or, in general,
38b2df95
DH
11337* rely on SCU or AUD ucode to be present.
11338*
11339*/
dc5a91d4 11340
01473146 11341static int drxj_open(struct drx_demod_instance *demod)
38b2df95 11342{
57afe2f0 11343 struct i2c_device_addr *dev_addr = NULL;
b3ce3a83 11344 struct drxj_data *ext_attr = NULL;
1bfc9e15 11345 struct drx_common_attr *common_attr = NULL;
57afe2f0 11346 u32 driver_version = 0;
1bfc9e15
MCC
11347 struct drxu_code_info ucode_info;
11348 struct drx_cfg_mpeg_output cfg_mpeg_output;
068e94ea 11349 int rc;
d7a5478a 11350 enum drx_power_mode power_mode = DRX_POWER_UP;
b78359a6
MCC
11351
11352 if ((demod == NULL) ||
11353 (demod->my_common_attr == NULL) ||
11354 (demod->my_ext_attr == NULL) ||
11355 (demod->my_i2c_dev_addr == NULL) ||
11356 (demod->my_common_attr->is_opened)) {
11357 return -EINVAL;
11358 }
11359
443f18d0 11360 /* Check arguments */
068e94ea 11361 if (demod->my_ext_attr == NULL)
9482354f 11362 return -EINVAL;
38b2df95 11363
57afe2f0 11364 dev_addr = demod->my_i2c_dev_addr;
b3ce3a83 11365 ext_attr = (struct drxj_data *) demod->my_ext_attr;
1bfc9e15 11366 common_attr = (struct drx_common_attr *) demod->my_common_attr;
38b2df95 11367
d7a5478a 11368 rc = ctrl_power_mode(demod, &power_mode);
9482354f 11369 if (rc != 0) {
068e94ea
MCC
11370 pr_err("error %d\n", rc);
11371 goto rw_error;
11372 }
d7a5478a
MCC
11373 if (power_mode != DRX_POWER_UP) {
11374 rc = -EINVAL;
11375 pr_err("failed to powerup device\n");
11376 goto rw_error;
11377 }
38b2df95 11378
443f18d0 11379 /* has to be in front of setIqmAf and setOrxNsuAox */
068e94ea 11380 rc = get_device_capabilities(demod);
9482354f 11381 if (rc != 0) {
068e94ea
MCC
11382 pr_err("error %d\n", rc);
11383 goto rw_error;
11384 }
38b2df95 11385
8afff9a2
MCC
11386 /*
11387 * Soft reset of sys- and osc-clockdomain
11388 *
11389 * HACK: On windows, it writes a 0x07 here, instead of just 0x03.
11390 * As we didn't load the firmware here yet, we should do the same.
11391 * Btw, this is coherent with DRX-K, where we send reset codes
11392 * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.
11393 */
11394 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 11395 if (rc != 0) {
068e94ea
MCC
11396 pr_err("error %d\n", rc);
11397 goto rw_error;
11398 }
244c0e06 11399 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
9482354f 11400 if (rc != 0) {
068e94ea
MCC
11401 pr_err("error %d\n", rc);
11402 goto rw_error;
11403 }
d7b0631e 11404 msleep(1);
38b2df95 11405
443f18d0
MCC
11406 /* TODO first make sure that everything keeps working before enabling this */
11407 /* PowerDownAnalogBlocks() */
244c0e06 11408 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 11409 if (rc != 0) {
068e94ea
MCC
11410 pr_err("error %d\n", rc);
11411 goto rw_error;
11412 }
38b2df95 11413
068e94ea 11414 rc = set_iqm_af(demod, false);
9482354f 11415 if (rc != 0) {
068e94ea
MCC
11416 pr_err("error %d\n", rc);
11417 goto rw_error;
11418 }
11419 rc = set_orx_nsu_aox(demod, false);
9482354f 11420 if (rc != 0) {
068e94ea
MCC
11421 pr_err("error %d\n", rc);
11422 goto rw_error;
11423 }
38b2df95 11424
068e94ea 11425 rc = init_hi(demod);
9482354f 11426 if (rc != 0) {
068e94ea
MCC
11427 pr_err("error %d\n", rc);
11428 goto rw_error;
11429 }
38b2df95 11430
443f18d0 11431 /* disable mpegoutput pins */
41b5cc0c 11432 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
57afe2f0 11433 cfg_mpeg_output.enable_mpeg_output = false;
41b5cc0c 11434
068e94ea 11435 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
9482354f 11436 if (rc != 0) {
068e94ea
MCC
11437 pr_err("error %d\n", rc);
11438 goto rw_error;
11439 }
443f18d0 11440 /* Stop AUD Inform SetAudio it will need to do all setting */
068e94ea 11441 rc = power_down_aud(demod);
9482354f 11442 if (rc != 0) {
068e94ea
MCC
11443 pr_err("error %d\n", rc);
11444 goto rw_error;
11445 }
443f18d0 11446 /* Stop SCU */
244c0e06 11447 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
9482354f 11448 if (rc != 0) {
068e94ea
MCC
11449 pr_err("error %d\n", rc);
11450 goto rw_error;
11451 }
38b2df95 11452
443f18d0 11453 /* Upload microcode */
b48293db 11454 if (common_attr->microcode_file != NULL) {
443f18d0
MCC
11455 /* Dirty trick to use common ucode upload & verify,
11456 pretend device is already open */
57afe2f0 11457 common_attr->is_opened = true;
b48293db 11458 ucode_info.mc_file = common_attr->microcode_file;
38b2df95 11459
dc5a91d4
MCC
11460 if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
11461 pr_err("Should powerup before loading the firmware.");
11462 return -EINVAL;
11463 }
11464
11465 rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);
9482354f 11466 if (rc != 0) {
dc5a91d4 11467 pr_err("error %d while uploading the firmware\n", rc);
068e94ea
MCC
11468 goto rw_error;
11469 }
57afe2f0 11470 if (common_attr->verify_microcode == true) {
dc5a91d4 11471 rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_VERIFY);
9482354f 11472 if (rc != 0) {
dc5a91d4
MCC
11473 pr_err("error %d while verifying the firmware\n",
11474 rc);
068e94ea
MCC
11475 goto rw_error;
11476 }
443f18d0 11477 }
57afe2f0 11478 common_attr->is_opened = false;
443f18d0 11479 }
38b2df95 11480
443f18d0 11481 /* Run SCU for a little while to initialize microcode version numbers */
244c0e06 11482 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
9482354f 11483 if (rc != 0) {
068e94ea
MCC
11484 pr_err("error %d\n", rc);
11485 goto rw_error;
11486 }
38b2df95 11487
443f18d0 11488 /* Initialize scan timeout */
57afe2f0
MCC
11489 common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
11490 common_attr->scan_desired_lock = DRX_LOCKED;
443f18d0 11491
aafdbaa6 11492 drxj_reset_mode(ext_attr);
57afe2f0 11493 ext_attr->standard = DRX_STANDARD_UNKNOWN;
443f18d0 11494
068e94ea 11495 rc = smart_ant_init(demod);
9482354f 11496 if (rc != 0) {
068e94ea
MCC
11497 pr_err("error %d\n", rc);
11498 goto rw_error;
11499 }
443f18d0
MCC
11500
11501 /* Stamp driver version number in SCU data RAM in BCD code
69bb7ab6 11502 Done to enable field application engineers to retrieve drxdriver version
443f18d0
MCC
11503 via I2C from SCU RAM
11504 */
57afe2f0
MCC
11505 driver_version = (VERSION_MAJOR / 100) % 10;
11506 driver_version <<= 4;
11507 driver_version += (VERSION_MAJOR / 10) % 10;
11508 driver_version <<= 4;
11509 driver_version += (VERSION_MAJOR % 10);
11510 driver_version <<= 4;
11511 driver_version += (VERSION_MINOR % 10);
11512 driver_version <<= 4;
11513 driver_version += (VERSION_PATCH / 1000) % 10;
11514 driver_version <<= 4;
11515 driver_version += (VERSION_PATCH / 100) % 10;
11516 driver_version <<= 4;
11517 driver_version += (VERSION_PATCH / 10) % 10;
11518 driver_version <<= 4;
11519 driver_version += (VERSION_PATCH % 10);
244c0e06 11520 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
9482354f 11521 if (rc != 0) {
068e94ea
MCC
11522 pr_err("error %d\n", rc);
11523 goto rw_error;
11524 }
244c0e06 11525 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
9482354f 11526 if (rc != 0) {
068e94ea
MCC
11527 pr_err("error %d\n", rc);
11528 goto rw_error;
11529 }
443f18d0 11530
bf9b94ab
MCC
11531 rc = ctrl_set_oob(demod, NULL);
11532 if (rc != 0) {
11533 pr_err("error %d\n", rc);
11534 goto rw_error;
11535 }
11536
443f18d0 11537 /* refresh the audio data structure with default */
57afe2f0 11538 ext_attr->aud_data = drxj_default_aud_data_g;
443f18d0 11539
b78359a6 11540 demod->my_common_attr->is_opened = true;
998819d2 11541 drxj_set_lna_state(demod, false);
9482354f 11542 return 0;
38b2df95 11543rw_error:
57afe2f0 11544 common_attr->is_opened = false;
30741871 11545 return rc;
38b2df95
DH
11546}
11547
11548/*============================================================================*/
34eb9751 11549/*
57afe2f0 11550* \fn drxj_close()
38b2df95
DH
11551* \brief Close the demod instance, power down the device
11552* \return Status_t Return status.
11553*
11554*/
01473146 11555static int drxj_close(struct drx_demod_instance *demod)
38b2df95 11556{
4d7bb0eb 11557 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
068e94ea 11558 int rc;
1bfc9e15 11559 enum drx_power_mode power_mode = DRX_POWER_UP;
38b2df95 11560
1e5ec31a 11561 if ((demod->my_common_attr == NULL) ||
b78359a6
MCC
11562 (demod->my_ext_attr == NULL) ||
11563 (demod->my_i2c_dev_addr == NULL) ||
11564 (!demod->my_common_attr->is_opened)) {
11565 return -EINVAL;
11566 }
11567
443f18d0 11568 /* power up */
068e94ea 11569 rc = ctrl_power_mode(demod, &power_mode);
9482354f 11570 if (rc != 0) {
068e94ea
MCC
11571 pr_err("error %d\n", rc);
11572 goto rw_error;
11573 }
38b2df95 11574
244c0e06 11575 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
9482354f 11576 if (rc != 0) {
068e94ea
MCC
11577 pr_err("error %d\n", rc);
11578 goto rw_error;
11579 }
57afe2f0 11580 power_mode = DRX_POWER_DOWN;
068e94ea 11581 rc = ctrl_power_mode(demod, &power_mode);
9482354f 11582 if (rc != 0) {
068e94ea
MCC
11583 pr_err("error %d\n", rc);
11584 goto rw_error;
11585 }
443f18d0 11586
b78359a6
MCC
11587 DRX_ATTR_ISOPENED(demod) = false;
11588
9482354f 11589 return 0;
38b2df95 11590rw_error:
b78359a6
MCC
11591 DRX_ATTR_ISOPENED(demod) = false;
11592
30741871 11593 return rc;
38b2df95
DH
11594}
11595
b240eacd
MCC
11596/*
11597 * Microcode related functions
11598 */
11599
34eb9751 11600/*
b240eacd
MCC
11601 * drx_u_code_compute_crc - Compute CRC of block of microcode data.
11602 * @block_data: Pointer to microcode data.
11603 * @nr_words: Size of microcode block (number of 16 bits words).
11604 *
11605 * returns The computed CRC residue.
11606 */
11607static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
11608{
11609 u16 i = 0;
11610 u16 j = 0;
11611 u32 crc_word = 0;
11612 u32 carry = 0;
11613
11614 while (i < nr_words) {
4182438e 11615 crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
b240eacd
MCC
11616 for (j = 0; j < 16; j++) {
11617 crc_word <<= 1;
11618 if (carry != 0)
11619 crc_word ^= 0x80050000UL;
11620 carry = crc_word & 0x80000000UL;
11621 }
11622 i++;
11623 block_data += (sizeof(u16));
11624 }
11625 return (u16)(crc_word >> 16);
11626}
11627
34eb9751 11628/*
b240eacd
MCC
11629 * drx_check_firmware - checks if the loaded firmware is valid
11630 *
11631 * @demod: demod structure
11632 * @mc_data: pointer to the start of the firmware
11633 * @size: firmware size
11634 */
11635static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
11636 unsigned size)
11637{
11638 struct drxu_code_block_hdr block_hdr;
11639 int i;
11640 unsigned count = 2 * sizeof(u16);
11641 u32 mc_dev_type, mc_version, mc_base_version;
4182438e 11642 u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
b240eacd
MCC
11643
11644 /*
11645 * Scan microcode blocks first for version info
11646 * and firmware check
11647 */
11648
11649 /* Clear version block */
11650 DRX_ATTR_MCRECORD(demod).aux_type = 0;
11651 DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
11652 DRX_ATTR_MCRECORD(demod).mc_version = 0;
11653 DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
11654
11655 for (i = 0; i < mc_nr_of_blks; i++) {
11656 if (count + 3 * sizeof(u16) + sizeof(u32) > size)
11657 goto eof;
11658
11659 /* Process block header */
4182438e 11660 block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
b240eacd 11661 count += sizeof(u32);
4182438e 11662 block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
b240eacd 11663 count += sizeof(u16);
4182438e 11664 block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
b240eacd 11665 count += sizeof(u16);
4182438e 11666 block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
b240eacd
MCC
11667 count += sizeof(u16);
11668
11669 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11670 count, block_hdr.addr, block_hdr.size, block_hdr.flags,
11671 block_hdr.CRC);
11672
11673 if (block_hdr.flags & 0x8) {
11674 u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
11675 u16 auxtype;
11676
11677 if (block_hdr.addr + sizeof(u16) > size)
11678 goto eof;
11679
4182438e 11680 auxtype = be16_to_cpu(*(__be16 *)(auxblk));
b240eacd
MCC
11681
11682 /* Aux block. Check type */
11683 if (DRX_ISMCVERTYPE(auxtype)) {
11684 if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
11685 goto eof;
11686
11687 auxblk += sizeof(u16);
4182438e 11688 mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
b240eacd 11689 auxblk += sizeof(u32);
4182438e 11690 mc_version = be32_to_cpu(*(__be32 *)(auxblk));
b240eacd 11691 auxblk += sizeof(u32);
4182438e 11692 mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
b240eacd
MCC
11693
11694 DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
11695 DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
11696 DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
11697 DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
11698
11699 pr_info("Firmware dev %x, ver %x, base ver %x\n",
11700 mc_dev_type, mc_version, mc_base_version);
11701
11702 }
11703 } else if (count + block_hdr.size * sizeof(u16) > size)
11704 goto eof;
11705
11706 count += block_hdr.size * sizeof(u16);
11707 }
11708 return 0;
11709eof:
11710 pr_err("Firmware is truncated at pos %u/%u\n", count, size);
11711 return -EINVAL;
11712}
11713
34eb9751 11714/*
b240eacd
MCC
11715 * drx_ctrl_u_code - Handle microcode upload or verify.
11716 * @dev_addr: Address of device.
11717 * @mc_info: Pointer to information about microcode data.
11718 * @action: Either UCODE_UPLOAD or UCODE_VERIFY
11719 *
11720 * This function returns:
11721 * 0:
11722 * - In case of UCODE_UPLOAD: code is successfully uploaded.
11723 * - In case of UCODE_VERIFY: image on device is equal to
11724 * image provided to this control function.
11725 * -EIO:
11726 * - In case of UCODE_UPLOAD: I2C error.
11727 * - In case of UCODE_VERIFY: I2C error or image on device
11728 * is not equal to image provided to this control function.
4a3fad70 11729 * -EINVAL:
b240eacd
MCC
11730 * - Invalid arguments.
11731 * - Provided image is corrupt
11732 */
11733static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11734 struct drxu_code_info *mc_info,
11735 enum drxu_code_action action)
11736{
11737 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11738 int rc;
11739 u16 i = 0;
11740 u16 mc_nr_of_blks = 0;
11741 u16 mc_magic_word = 0;
11742 const u8 *mc_data_init = NULL;
11743 u8 *mc_data = NULL;
11744 unsigned size;
1d001c3f 11745 char *mc_file;
b240eacd
MCC
11746
11747 /* Check arguments */
1d001c3f 11748 if (!mc_info || !mc_info->mc_file)
b240eacd
MCC
11749 return -EINVAL;
11750
1d001c3f
MCC
11751 mc_file = mc_info->mc_file;
11752
b240eacd
MCC
11753 if (!demod->firmware) {
11754 const struct firmware *fw = NULL;
11755
11756 rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
11757 if (rc < 0) {
11758 pr_err("Couldn't read firmware %s\n", mc_file);
691cbbe3 11759 return rc;
b240eacd
MCC
11760 }
11761 demod->firmware = fw;
11762
11763 if (demod->firmware->size < 2 * sizeof(u16)) {
11764 rc = -EINVAL;
11765 pr_err("Firmware is too short!\n");
11766 goto release;
11767 }
11768
11769 pr_info("Firmware %s, size %zu\n",
11770 mc_file, demod->firmware->size);
11771 }
11772
11773 mc_data_init = demod->firmware->data;
11774 size = demod->firmware->size;
11775
11776 mc_data = (void *)mc_data_init;
11777 /* Check data */
4182438e 11778 mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd 11779 mc_data += sizeof(u16);
4182438e 11780 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd
MCC
11781 mc_data += sizeof(u16);
11782
11783 if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
11784 rc = -EINVAL;
11785 pr_err("Firmware magic word doesn't match\n");
11786 goto release;
11787 }
11788
11789 if (action == UCODE_UPLOAD) {
11790 rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
11791 if (rc)
11792 goto release;
b240eacd 11793 pr_info("Uploading firmware %s\n", mc_file);
dc5a91d4 11794 } else {
b240eacd
MCC
11795 pr_info("Verifying if firmware upload was ok.\n");
11796 }
11797
11798 /* Process microcode blocks */
11799 for (i = 0; i < mc_nr_of_blks; i++) {
11800 struct drxu_code_block_hdr block_hdr;
11801 u16 mc_block_nr_bytes = 0;
11802
11803 /* Process block header */
4182438e 11804 block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
b240eacd 11805 mc_data += sizeof(u32);
4182438e 11806 block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd 11807 mc_data += sizeof(u16);
4182438e 11808 block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd 11809 mc_data += sizeof(u16);
4182438e 11810 block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
b240eacd
MCC
11811 mc_data += sizeof(u16);
11812
c4f04796
MCC
11813 pr_debug("%zd: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11814 (mc_data - mc_data_init), block_hdr.addr,
b240eacd
MCC
11815 block_hdr.size, block_hdr.flags, block_hdr.CRC);
11816
11817 /* Check block header on:
11818 - data larger than 64Kb
11819 - if CRC enabled check CRC
11820 */
11821 if ((block_hdr.size > 0x7FFF) ||
11822 (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
11823 (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
11824 ) {
11825 /* Wrong data ! */
11826 rc = -EINVAL;
11827 pr_err("firmware CRC is wrong\n");
11828 goto release;
11829 }
11830
11831 if (!block_hdr.size)
11832 continue;
11833
11834 mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
11835
11836 /* Perform the desired action */
11837 switch (action) {
11838 case UCODE_UPLOAD: /* Upload microcode */
244c0e06 11839 if (drxdap_fasi_write_block(dev_addr,
b240eacd
MCC
11840 block_hdr.addr,
11841 mc_block_nr_bytes,
11842 mc_data, 0x0000)) {
11843 rc = -EIO;
c4f04796
MCC
11844 pr_err("error writing firmware at pos %zd\n",
11845 mc_data - mc_data_init);
b240eacd
MCC
11846 goto release;
11847 }
11848 break;
11849 case UCODE_VERIFY: { /* Verify uploaded microcode */
11850 int result = 0;
11851 u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
11852 u32 bytes_to_comp = 0;
11853 u32 bytes_left = mc_block_nr_bytes;
11854 u32 curr_addr = block_hdr.addr;
11855 u8 *curr_ptr = mc_data;
11856
11857 while (bytes_left != 0) {
11858 if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
11859 bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
11860 else
11861 bytes_to_comp = bytes_left;
11862
244c0e06 11863 if (drxdap_fasi_read_block(dev_addr,
b240eacd
MCC
11864 curr_addr,
11865 (u16)bytes_to_comp,
11866 (u8 *)mc_data_buffer,
11867 0x0000)) {
c4f04796
MCC
11868 pr_err("error reading firmware at pos %zd\n",
11869 mc_data - mc_data_init);
b240eacd
MCC
11870 return -EIO;
11871 }
11872
d7b0631e
MCC
11873 result = memcmp(curr_ptr, mc_data_buffer,
11874 bytes_to_comp);
b240eacd
MCC
11875
11876 if (result) {
c4f04796
MCC
11877 pr_err("error verifying firmware at pos %zd\n",
11878 mc_data - mc_data_init);
b240eacd
MCC
11879 return -EIO;
11880 }
11881
11882 curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
11883 curr_ptr =&(curr_ptr[bytes_to_comp]);
11884 bytes_left -=((u32) bytes_to_comp);
11885 }
11886 break;
11887 }
11888 default:
11889 return -EINVAL;
11890 break;
11891
11892 }
11893 mc_data += mc_block_nr_bytes;
11894 }
11895
11896 return 0;
11897
11898release:
11899 release_firmware(demod->firmware);
11900 demod->firmware = NULL;
11901
11902 return rc;
11903}
19013747 11904
69bb7ab6 11905/* caller is expected to check if lna is supported before enabling */
998819d2
SK
11906static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
11907{
11908 struct drxuio_cfg uio_cfg;
11909 struct drxuio_data uio_data;
11910 int result;
11911
11912 uio_cfg.uio = DRX_UIO1;
11913 uio_cfg.mode = DRX_UIO_MODE_READWRITE;
11914 /* Configure user-I/O #3: enable read/write */
11915 result = ctrl_set_uio_cfg(demod, &uio_cfg);
11916 if (result) {
11917 pr_err("Failed to setup LNA GPIO!\n");
11918 return result;
11919 }
11920
11921 uio_data.uio = DRX_UIO1;
11922 uio_data.value = state;
11923 result = ctrl_uio_write(demod, &uio_data);
11924 if (result != 0) {
11925 pr_err("Failed to %sable LNA!\n",
11926 state ? "en" : "dis");
11927 return result;
11928 }
11929 return 0;
11930}
11931
19013747
MCC
11932/*
11933 * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
11934 *
11935 * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
11936 */
11937
11938static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
11939{
11940 struct drx39xxj_state *state = fe->demodulator_priv;
11941 struct drx_demod_instance *demod = state->demod;
11942 int result;
11943 enum drx_power_mode power_mode;
11944
11945 if (enable)
11946 power_mode = DRX_POWER_UP;
11947 else
11948 power_mode = DRX_POWER_DOWN;
11949
b0baeb49 11950 result = ctrl_power_mode(demod, &power_mode);
19013747
MCC
11951 if (result != 0) {
11952 pr_err("Power state change failed\n");
11953 return 0;
11954 }
11955
19013747
MCC
11956 return 0;
11957}
11958
0df289a2 11959static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)
19013747
MCC
11960{
11961 struct drx39xxj_state *state = fe->demodulator_priv;
11962 struct drx_demod_instance *demod = state->demod;
11963 int result;
11964 enum drx_lock_status lock_status;
11965
11966 *status = 0;
11967
b0baeb49 11968 result = ctrl_lock_status(demod, &lock_status);
19013747
MCC
11969 if (result != 0) {
11970 pr_err("drx39xxj: could not get lock status!\n");
11971 *status = 0;
11972 }
11973
11974 switch (lock_status) {
11975 case DRX_NEVER_LOCK:
11976 *status = 0;
11977 pr_err("drx says NEVER_LOCK\n");
11978 break;
11979 case DRX_NOT_LOCKED:
11980 *status = 0;
11981 break;
11982 case DRX_LOCK_STATE_1:
11983 case DRX_LOCK_STATE_2:
11984 case DRX_LOCK_STATE_3:
11985 case DRX_LOCK_STATE_4:
11986 case DRX_LOCK_STATE_5:
11987 case DRX_LOCK_STATE_6:
11988 case DRX_LOCK_STATE_7:
11989 case DRX_LOCK_STATE_8:
11990 case DRX_LOCK_STATE_9:
11991 *status = FE_HAS_SIGNAL
11992 | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
11993 break;
11994 case DRX_LOCKED:
11995 *status = FE_HAS_SIGNAL
11996 | FE_HAS_CARRIER
11997 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
11998 break;
11999 default:
12000 pr_err("Lock state unknown %d\n", lock_status);
12001 }
03fdfbfd 12002 ctrl_sig_quality(demod, lock_status);
19013747
MCC
12003
12004 return 0;
12005}
12006
12007static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
12008{
03fdfbfd 12009 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
19013747 12010
03fdfbfd 12011 if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
19013747
MCC
12012 *ber = 0;
12013 return 0;
12014 }
12015
69832578
MCC
12016 if (!p->pre_bit_count.stat[0].uvalue) {
12017 if (!p->pre_bit_error.stat[0].uvalue)
12018 *ber = 0;
12019 else
12020 *ber = 1000000;
12021 } else {
12022 *ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,
12023 p->pre_bit_count.stat[0].uvalue);
12024 }
19013747
MCC
12025 return 0;
12026}
12027
12028static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
12029 u16 *strength)
12030{
03fdfbfd 12031 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
19013747 12032
03fdfbfd 12033 if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
19013747
MCC
12034 *strength = 0;
12035 return 0;
12036 }
12037
03fdfbfd 12038 *strength = p->strength.stat[0].uvalue;
19013747
MCC
12039 return 0;
12040}
12041
12042static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
12043{
03fdfbfd 12044 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
90d9c3e1 12045 u64 tmp64;
19013747 12046
03fdfbfd 12047 if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
19013747
MCC
12048 *snr = 0;
12049 return 0;
12050 }
12051
90d9c3e1
GG
12052 tmp64 = p->cnr.stat[0].svalue;
12053 do_div(tmp64, 10);
12054 *snr = tmp64;
19013747
MCC
12055 return 0;
12056}
12057
03fdfbfd 12058static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
19013747 12059{
03fdfbfd 12060 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
19013747 12061
03fdfbfd
MCC
12062 if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12063 *ucb = 0;
19013747
MCC
12064 return 0;
12065 }
12066
03fdfbfd 12067 *ucb = p->block_error.stat[0].uvalue;
19013747
MCC
12068 return 0;
12069}
12070
12071static int drx39xxj_set_frontend(struct dvb_frontend *fe)
12072{
12073#ifdef DJH_DEBUG
12074 int i;
12075#endif
12076 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12077 struct drx39xxj_state *state = fe->demodulator_priv;
12078 struct drx_demod_instance *demod = state->demod;
12079 enum drx_standard standard = DRX_STANDARD_8VSB;
12080 struct drx_channel channel;
12081 int result;
19013747
MCC
12082 static const struct drx_channel def_channel = {
12083 /* frequency */ 0,
12084 /* bandwidth */ DRX_BANDWIDTH_6MHZ,
12085 /* mirror */ DRX_MIRROR_NO,
12086 /* constellation */ DRX_CONSTELLATION_AUTO,
12087 /* hierarchy */ DRX_HIERARCHY_UNKNOWN,
12088 /* priority */ DRX_PRIORITY_UNKNOWN,
12089 /* coderate */ DRX_CODERATE_UNKNOWN,
12090 /* guard */ DRX_GUARD_UNKNOWN,
12091 /* fftmode */ DRX_FFTMODE_UNKNOWN,
12092 /* classification */ DRX_CLASSIFICATION_AUTO,
12093 /* symbolrate */ 5057000,
12094 /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,
12095 /* ldpc */ DRX_LDPC_UNKNOWN,
12096 /* carrier */ DRX_CARRIER_UNKNOWN,
12097 /* frame mode */ DRX_FRAMEMODE_UNKNOWN
12098 };
12099 u32 constellation = DRX_CONSTELLATION_AUTO;
12100
12101 /* Bring the demod out of sleep */
12102 drx39xxj_set_powerstate(fe, 1);
12103
19013747 12104 if (fe->ops.tuner_ops.set_params) {
7abc7a54
MCC
12105 u32 int_freq;
12106
19013747
MCC
12107 if (fe->ops.i2c_gate_ctrl)
12108 fe->ops.i2c_gate_ctrl(fe, 1);
7abc7a54
MCC
12109
12110 /* Set tuner to desired frequency and standard */
19013747 12111 fe->ops.tuner_ops.set_params(fe);
7abc7a54
MCC
12112
12113 /* Use the tuner's IF */
12114 if (fe->ops.tuner_ops.get_if_frequency) {
12115 fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);
12116 demod->my_common_attr->intermediate_freq = int_freq / 1000;
12117 }
12118
19013747
MCC
12119 if (fe->ops.i2c_gate_ctrl)
12120 fe->ops.i2c_gate_ctrl(fe, 0);
12121 }
12122
12123 switch (p->delivery_system) {
12124 case SYS_ATSC:
12125 standard = DRX_STANDARD_8VSB;
12126 break;
12127 case SYS_DVBC_ANNEX_B:
12128 standard = DRX_STANDARD_ITU_B;
12129
12130 switch (p->modulation) {
12131 case QAM_64:
12132 constellation = DRX_CONSTELLATION_QAM64;
12133 break;
12134 case QAM_256:
12135 constellation = DRX_CONSTELLATION_QAM256;
12136 break;
12137 default:
12138 constellation = DRX_CONSTELLATION_AUTO;
12139 break;
12140 }
12141 break;
12142 default:
12143 return -EINVAL;
12144 }
c4dc6f92
MCC
12145 /* Set the standard (will be powered up if necessary */
12146 result = ctrl_set_standard(demod, &standard);
12147 if (result != 0) {
12148 pr_err("Failed to set standard! result=%02x\n",
12149 result);
12150 return -EINVAL;
19013747
MCC
12151 }
12152
12153 /* set channel parameters */
12154 channel = def_channel;
12155 channel.frequency = p->frequency / 1000;
12156 channel.bandwidth = DRX_BANDWIDTH_6MHZ;
12157 channel.constellation = constellation;
12158
12159 /* program channel */
b0baeb49 12160 result = ctrl_set_channel(demod, &channel);
19013747
MCC
12161 if (result != 0) {
12162 pr_err("Failed to set channel!\n");
12163 return -EINVAL;
12164 }
12165 /* Just for giggles, let's shut off the LNA again.... */
b601fe56 12166 drxj_set_lna_state(demod, false);
03fdfbfd
MCC
12167
12168 /* After set_frontend, except for strength, stats aren't available */
12169 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
19013747
MCC
12170
12171 return 0;
12172}
12173
12174static int drx39xxj_sleep(struct dvb_frontend *fe)
12175{
12176 /* power-down the demodulator */
12177 return drx39xxj_set_powerstate(fe, 0);
12178}
12179
12180static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
12181{
12182 struct drx39xxj_state *state = fe->demodulator_priv;
12183 struct drx_demod_instance *demod = state->demod;
12184 bool i2c_gate_state;
12185 int result;
12186
12187#ifdef DJH_DEBUG
6c955b8b 12188 pr_debug("i2c gate call: enable=%d state=%d\n", enable,
19013747
MCC
12189 state->i2c_gate_open);
12190#endif
12191
12192 if (enable)
12193 i2c_gate_state = true;
12194 else
12195 i2c_gate_state = false;
12196
12197 if (state->i2c_gate_open == enable) {
12198 /* We're already in the desired state */
12199 return 0;
12200 }
12201
b0baeb49 12202 result = ctrl_i2c_bridge(demod, &i2c_gate_state);
19013747
MCC
12203 if (result != 0) {
12204 pr_err("drx39xxj: could not open i2c gate [%d]\n",
12205 result);
12206 dump_stack();
12207 } else {
12208 state->i2c_gate_open = enable;
12209 }
12210 return 0;
12211}
12212
12213static int drx39xxj_init(struct dvb_frontend *fe)
12214{
998819d2
SK
12215 struct drx39xxj_state *state = fe->demodulator_priv;
12216 struct drx_demod_instance *demod = state->demod;
12217 int rc = 0;
19013747 12218
998819d2
SK
12219 if (fe->exit == DVB_FE_DEVICE_RESUME) {
12220 /* so drxj_open() does what it needs to do */
12221 demod->my_common_attr->is_opened = false;
12222 rc = drxj_open(demod);
12223 if (rc != 0)
12224 pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
12225 } else
12226 drx39xxj_set_powerstate(fe, 1);
12227
12228 return rc;
19013747
MCC
12229}
12230
ea8f3c2c
MCC
12231static int drx39xxj_set_lna(struct dvb_frontend *fe)
12232{
ea8f3c2c
MCC
12233 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
12234 struct drx39xxj_state *state = fe->demodulator_priv;
12235 struct drx_demod_instance *demod = state->demod;
12236 struct drxj_data *ext_attr = demod->my_ext_attr;
ea8f3c2c
MCC
12237
12238 if (c->lna) {
12239 if (!ext_attr->has_lna) {
12240 pr_err("LNA is not supported on this device!\n");
12241 return -EINVAL;
12242
12243 }
12244 }
12245
b601fe56 12246 return drxj_set_lna_state(demod, c->lna);
ea8f3c2c
MCC
12247}
12248
19013747
MCC
12249static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
12250 struct dvb_frontend_tune_settings *tune)
12251{
12252 tune->min_delay_ms = 1000;
12253 return 0;
12254}
12255
12256static void drx39xxj_release(struct dvb_frontend *fe)
12257{
12258 struct drx39xxj_state *state = fe->demodulator_priv;
12259 struct drx_demod_instance *demod = state->demod;
12260
5b22b1a4
SK
12261 /* if device is removed don't access it */
12262 if (fe->exit != DVB_FE_DEVICE_REMOVED)
12263 drxj_close(demod);
1e5ec31a 12264
19013747
MCC
12265 kfree(demod->my_ext_attr);
12266 kfree(demod->my_common_attr);
12267 kfree(demod->my_i2c_dev_addr);
9bc2dd7e 12268 release_firmware(demod->firmware);
19013747
MCC
12269 kfree(demod);
12270 kfree(state);
12271}
12272
bd336e63 12273static const struct dvb_frontend_ops drx39xxj_ops;
19013747
MCC
12274
12275struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
12276{
12277 struct drx39xxj_state *state = NULL;
19013747
MCC
12278 struct i2c_device_addr *demod_addr = NULL;
12279 struct drx_common_attr *demod_comm_attr = NULL;
12280 struct drxj_data *demod_ext_attr = NULL;
12281 struct drx_demod_instance *demod = NULL;
d591590e 12282 struct dtv_frontend_properties *p;
19013747
MCC
12283 int result;
12284
12285 /* allocate memory for the internal state */
12286 state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL);
12287 if (state == NULL)
12288 goto error;
12289
12290 demod = kmalloc(sizeof(struct drx_demod_instance), GFP_KERNEL);
12291 if (demod == NULL)
12292 goto error;
12293
20f63150
BT
12294 demod_addr = kmemdup(&drxj_default_addr_g,
12295 sizeof(struct i2c_device_addr), GFP_KERNEL);
19013747
MCC
12296 if (demod_addr == NULL)
12297 goto error;
19013747 12298
20f63150
BT
12299 demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,
12300 sizeof(struct drx_common_attr), GFP_KERNEL);
19013747
MCC
12301 if (demod_comm_attr == NULL)
12302 goto error;
19013747 12303
20f63150
BT
12304 demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),
12305 GFP_KERNEL);
19013747
MCC
12306 if (demod_ext_attr == NULL)
12307 goto error;
19013747
MCC
12308
12309 /* setup the state */
12310 state->i2c = i2c;
12311 state->demod = demod;
12312
12313 /* setup the demod data */
12314 memcpy(demod, &drxj_default_demod_g, sizeof(struct drx_demod_instance));
12315
12316 demod->my_i2c_dev_addr = demod_addr;
12317 demod->my_common_attr = demod_comm_attr;
12318 demod->my_i2c_dev_addr->user_data = state;
12319 demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;
12320 demod->my_common_attr->verify_microcode = true;
12321 demod->my_common_attr->intermediate_freq = 5000;
d7a5478a 12322 demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;
19013747
MCC
12323 demod->my_ext_attr = demod_ext_attr;
12324 ((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;
19013747
MCC
12325 demod->i2c = i2c;
12326
12327 result = drxj_open(demod);
12328 if (result != 0) {
12329 pr_err("DRX open failed! Aborting\n");
12330 goto error;
12331 }
12332
19013747
MCC
12333 /* create dvb_frontend */
12334 memcpy(&state->frontend.ops, &drx39xxj_ops,
12335 sizeof(struct dvb_frontend_ops));
12336
12337 state->frontend.demodulator_priv = state;
d591590e
MCC
12338
12339 /* Initialize stats - needed for DVBv5 stats to work */
12340 p = &state->frontend.dtv_property_cache;
12341 p->strength.len = 1;
12342 p->pre_bit_count.len = 1;
12343 p->pre_bit_error.len = 1;
12344 p->post_bit_count.len = 1;
12345 p->post_bit_error.len = 1;
12346 p->block_count.len = 1;
12347 p->block_error.len = 1;
12348 p->cnr.len = 1;
12349
12350 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12351 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12352 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12353 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12354 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12355 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12356 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12357 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12358
19013747
MCC
12359 return &state->frontend;
12360
12361error:
12362 kfree(demod_ext_attr);
12363 kfree(demod_comm_attr);
12364 kfree(demod_addr);
12365 kfree(demod);
12366 kfree(state);
12367
12368 return NULL;
12369}
12370EXPORT_SYMBOL(drx39xxj_attach);
12371
bd336e63 12372static const struct dvb_frontend_ops drx39xxj_ops = {
19013747
MCC
12373 .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
12374 .info = {
12375 .name = "Micronas DRX39xxj family Frontend",
f1b1eabf
MCC
12376 .frequency_min_hz = 51 * MHz,
12377 .frequency_max_hz = 858 * MHz,
12378 .frequency_stepsize_hz = 62500,
19013747
MCC
12379 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
12380 },
12381
12382 .init = drx39xxj_init,
12383 .i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,
12384 .sleep = drx39xxj_sleep,
12385 .set_frontend = drx39xxj_set_frontend,
12386 .get_tune_settings = drx39xxj_get_tune_settings,
12387 .read_status = drx39xxj_read_status,
12388 .read_ber = drx39xxj_read_ber,
12389 .read_signal_strength = drx39xxj_read_signal_strength,
12390 .read_snr = drx39xxj_read_snr,
12391 .read_ucblocks = drx39xxj_read_ucblocks,
12392 .release = drx39xxj_release,
ea8f3c2c 12393 .set_lna = drx39xxj_set_lna,
19013747
MCC
12394};
12395
12396MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
12397MODULE_AUTHOR("Devin Heitmueller");
12398MODULE_LICENSE("GPL");
12399MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);