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.
29
30 DRXJ specific implementation of DRX driver
31 authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
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.
50*/
51
52/*-----------------------------------------------------------------------------
53INCLUDE FILES
54----------------------------------------------------------------------------*/
55
56#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
57
58#include <linux/module.h>
59#include <linux/init.h>
60#include <linux/string.h>
61#include <linux/slab.h>
62#include <asm/div64.h>
63
64#include <media/dvb_frontend.h>
65#include "drx39xxj.h"
66
67#include "drxj.h"
68#include "drxj_map.h"
69
70/*============================================================================*/
71/*=== DEFINES ================================================================*/
72/*============================================================================*/
73
74#define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
75
76/*
77* \brief Maximum u32 value.
78*/
79#ifndef MAX_U32
80#define MAX_U32 ((u32) (0xFFFFFFFFL))
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
103/*** START DJCOMBO patches to DRXJ registermap constants *********************/
104/*** registermap 200706071303 from drxj **************************************/
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
191/*** END DJCOMBO patches to DRXJ registermap *********************************/
192
193#include "drx_driver_version.h"
194
195/* #define DRX_DEBUG */
196#ifdef DRX_DEBUG
197#include <stdio.h>
198#endif
199
200/*-----------------------------------------------------------------------------
201ENUMS
202----------------------------------------------------------------------------*/
203
204/*-----------------------------------------------------------------------------
205DEFINES
206----------------------------------------------------------------------------*/
207#ifndef DRXJ_WAKE_UP_KEY
208#define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
209#endif
210
211/*
212* \def DRXJ_DEF_I2C_ADDR
213* \brief Default I2C address of a demodulator instance.
214*/
215#define DRXJ_DEF_I2C_ADDR (0x52)
216
217/*
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
223/*
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
229/*
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
237/*
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
245/*
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
251/*
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
263/*
264* \brief Min supported symbolrates.
265*/
266#ifndef DRXJ_QAM_SYMBOLRATE_MIN
267#define DRXJ_QAM_SYMBOLRATE_MIN (520000)
268#endif
269
270/*
271* \brief Max supported symbolrates.
272*/
273#ifndef DRXJ_QAM_SYMBOLRATE_MAX
274#define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
275#endif
276
277/*
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
293/*
294* \def SCU status and results
295* \brief SCU
296*/
297#define DRX_SCU_READY 0
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 */
301
302/*
303* \def DRX_AUD_MAX_DEVIATION
304* \brief Needed for calculation of prescale feature in AUD
305*/
306#ifndef DRXJ_AUD_MAX_FM_DEVIATION
307#define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
308#endif
309
310/*
311* \brief Needed for calculation of NICAM prescale feature in AUD
312*/
313#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
314#define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
315#endif
316
317/*
318* \brief Needed for calculation of NICAM prescale feature in AUD
319*/
320#ifndef DRXJ_AUD_MAX_WAITTIME
321#define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
322#endif
323
324/* ATV config changed flags */
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)
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
335/*
336 * MICROCODE RELATED DEFINES
337 */
338
339/* Magic word for checking correct Endianness of microcode data */
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
369/* Pin safe mode macro */
370#define DRXJ_PIN_SAFE_MODE 0x0000
371/*============================================================================*/
372/*=== GLOBAL VARIABLEs =======================================================*/
373/*============================================================================*/
374/*
375*/
376
377/*
378* \brief Temporary register definitions.
379* (register definitions that are not yet available in register master)
380*/
381
382/*****************************************************************************/
383/* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
384/* RAM addresses directly. This must be READ ONLY to avoid problems. */
385/* Writing to the interface addresses are more than only writing the RAM */
386/* locations */
387/*****************************************************************************/
388/*
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
397/*
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
403/*
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
411/*
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
418/*
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
424/*
425* \brief FM Matrix register fix
426*/
427#ifdef AUD_DEM_WR_FM_MATRIX__A
428#undef AUD_DEM_WR_FM_MATRIX__A
429#endif
430#define AUD_DEM_WR_FM_MATRIX__A 0x105006F
431
432/*============================================================================*/
433/*
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
446/*
447* \brief Needed for calculation of prescale feature in AUD
448*/
449#ifndef DRX_AUD_MAX_FM_DEVIATION
450#define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
451#endif
452
453/*
454* \brief Needed for calculation of NICAM prescale feature in AUD
455*/
456#ifndef DRX_AUD_MAX_NICAM_PRESCALE
457#define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
458#endif
459
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
481/*
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*/
487#define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
488 ((u8)((((u16)x)>>8)&0xFF))
489/*
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*/
494#define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
495
496/*============================================================================*/
497/*=== MISC DEFINES ===========================================================*/
498/*============================================================================*/
499
500/*============================================================================*/
501/*=== HI COMMAND RELATED DEFINES =============================================*/
502/*============================================================================*/
503
504/*
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
513#define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
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) || \
519 (std == DRX_STANDARD_FM))
520
521#define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
522 (std == DRX_STANDARD_ITU_B) || \
523 (std == DRX_STANDARD_ITU_C) || \
524 (std == DRX_STANDARD_ITU_D))
525
526/*-----------------------------------------------------------------------------
527GLOBAL VARIABLES
528----------------------------------------------------------------------------*/
529/*
530 * DRXJ DAP structures
531 */
532
533static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
534 u32 addr,
535 u16 datasize,
536 u8 *data, u32 flags);
537
538
539static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
540 u32 waddr,
541 u32 raddr,
542 u16 wdata, u16 *rdata);
543
544static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
545 u32 addr,
546 u16 *data, u32 flags);
547
548static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
549 u32 addr,
550 u32 *data, u32 flags);
551
552static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
553 u32 addr,
554 u16 datasize,
555 u8 *data, u32 flags);
556
557static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
558 u32 addr,
559 u16 data, u32 flags);
560
561static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
562 u32 addr,
563 u32 data, u32 flags);
564
565static struct drxj_data drxj_data_g = {
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 */
574 0, /* mfx A1/A2/A... */
575
576 /* tuner settings */
577 false, /* tuner mirrors RF signal */
578 /* standard/channel settings */
579 DRX_STANDARD_UNKNOWN, /* current standard */
580 DRX_CONSTELLATION_AUTO, /* constellation */
581 0, /* frequency in KHz */
582 DRX_BANDWIDTH_UNKNOWN, /* curr_bandwidth */
583 DRX_MIRROR_NO, /* mirror */
584
585 /* signal quality information: */
586 /* default values taken from the QAM Programming guide */
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 */
591 0xFFFF, /* qamVDPeriod */
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 */
596 0, /* pkt_err_acc_start */
597
598 /* HI configuration */
599 0, /* hi_cfg_timing_div */
600 0, /* hi_cfg_bridge_delay */
601 0, /* hi_cfg_wake_up_key */
602 0, /* hi_cfg_ctrl */
603 0, /* HICfgTimeout */
604 /* UIO configuration */
605 DRX_UIO_MODE_DISABLE, /* uio_sma_rx_mode */
606 DRX_UIO_MODE_DISABLE, /* uio_sma_tx_mode */
607 DRX_UIO_MODE_DISABLE, /* uioASELMode */
608 DRX_UIO_MODE_DISABLE, /* uio_irqn_mode */
609 /* FS setting */
610 0UL, /* iqm_fs_rate_ofs */
611 false, /* pos_image */
612 /* RC setting */
613 0UL, /* iqm_rc_rate_ofs */
614 /* AUD information */
615/* false, * flagSetAUDdone */
616/* false, * detectedRDS */
617/* true, * flagASDRequest */
618/* false, * flagHDevClear */
619/* false, * flagHDevSet */
620/* (u16) 0xFFF, * rdsLastCount */
621
622 /* ATV configuration */
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},
656 false, /* flag: true=bypass */
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 */
659 true, /* flag CVBS output enable */
660 false, /* flag SIF output enable */
661 DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
662 { /* qam_rf_agc_cfg */
663 .standard: DRX_STANDARD_ITU_B, /* standard */
664 .ctrl_mode: DRX_AGC_CTRL_AUTO, /* ctrl_mode */
665 .output_level: 0, /* output_level */
666 .min_output_level: 0, /* min_output_level */
667 .max_output_level: 0xFFFF, /* max_output_level */
668 .speed: 0x0000, /* speed */
669 .top: 0x0000, /* top */
670 .cut_off_current: 0x0000 /* c.o.c. */
671 },
672 { /* qam_if_agc_cfg */
673 DRX_STANDARD_ITU_B, /* standard */
674 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
675 0, /* output_level */
676 0, /* min_output_level */
677 0xFFFF, /* max_output_level */
678 0x0000, /* speed */
679 0x0000, /* top (don't care) */
680 0x0000 /* c.o.c. (don't care) */
681 },
682 { /* vsb_rf_agc_cfg */
683 DRX_STANDARD_8VSB, /* standard */
684 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
685 0, /* output_level */
686 0, /* min_output_level */
687 0xFFFF, /* max_output_level */
688 0x0000, /* speed */
689 0x0000, /* top (don't care) */
690 0x0000 /* c.o.c. (don't care) */
691 },
692 { /* vsb_if_agc_cfg */
693 DRX_STANDARD_8VSB, /* standard */
694 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
695 0, /* output_level */
696 0, /* min_output_level */
697 0xFFFF, /* max_output_level */
698 0x0000, /* speed */
699 0x0000, /* top (don't care) */
700 0x0000 /* c.o.c. (don't care) */
701 },
702 0, /* qam_pga_cfg */
703 0, /* vsb_pga_cfg */
704 { /* qam_pre_saw_cfg */
705 DRX_STANDARD_ITU_B, /* standard */
706 0, /* reference */
707 false /* use_pre_saw */
708 },
709 { /* vsb_pre_saw_cfg */
710 DRX_STANDARD_8VSB, /* standard */
711 0, /* reference */
712 false /* use_pre_saw */
713 },
714
715 /* Version information */
716#ifndef _CH_
717 {
718 "01234567890", /* human readable version microcode */
719 "01234567890" /* human readable version device specific code */
720 },
721 {
722 { /* struct drx_version for microcode */
723 .module_type: DRX_MODULE_UNKNOWN,
724 .module_name: (char *)(NULL),
725 .v_major: 0,
726 .v_minor: 0,
727 .v_patch: 0,
728 .v_string: (char *)(NULL)
729 },
730 { /* struct drx_version for device specific code */
731 DRX_MODULE_UNKNOWN,
732 (char *)(NULL),
733 0,
734 0,
735 0,
736 (char *)(NULL)
737 }
738 },
739 {
740 { /* struct drx_version_list for microcode */
741 (struct drx_version *) (NULL),
742 (struct drx_version_list *) (NULL)
743 },
744 { /* struct drx_version_list for device specific code */
745 (struct drx_version *) (NULL),
746 (struct drx_version_list *) (NULL)
747 }
748 },
749#endif
750 false, /* smart_ant_inverted */
751 /* Tracking filter setting for OOB */
752 {
753 12000,
754 9300,
755 6600,
756 5280,
757 3700,
758 3000,
759 2000,
760 0},
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 */
767
768 /* Pre SAW & Agc configuration for ATV */
769 {
770 .standard: DRX_STANDARD_NTSC, /* standard */
771 .reference: 7, /* reference */
772 .use_pre_saw: true /* use_pre_saw */
773 },
774 { /* ATV RF-AGC */
775 DRX_STANDARD_NTSC, /* standard */
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.) */
780 3, /* speed */
781 9500, /* top */
782 4000 /* cut-off current */
783 },
784 { /* ATV IF-AGC */
785 DRX_STANDARD_NTSC, /* standard */
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.) */
790 3, /* speed */
791 2400, /* top */
792 0 /* c.o.c. (d.c.) */
793 },
794 140, /* ATV PGA config */
795 0, /* curr_symbol_rate */
796
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 */
802
803 4, /* oob_pre_saw */
804 DRXJ_OOB_LO_POW_MINUS10DB, /* oob_lo_pow */
805 {
806 .audio_is_active: false /* aud_data, only first member */
807 },
808};
809
810/*
811* \var drxj_default_addr_g
812* \brief Default I2C address and device identifier.
813*/
814static struct i2c_device_addr drxj_default_addr_g = {
815 DRXJ_DEF_I2C_ADDR, /* i2c address */
816 DRXJ_DEF_DEMOD_DEV_ID /* device id */
817};
818
819/*
820* \var drxj_default_comm_attr_g
821* \brief Default common attributes of a drxj demodulator instance.
822*/
823static struct drx_common_attr drxj_default_comm_attr_g = {
824 NULL, /* ucode file */
825 true, /* ucode verify switch */
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 */
832 false, /* If true mirror frequency spectrum */
833 {
834 /* MPEG output configuration */
835 true, /* If true, enable MPEG output */
836 false, /* If true, insert RS byte */
837 false, /* If true, parallel out otherwise serial */
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
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 },
850 /* Initilisations below can be omitted, they require no user input and
851 are initially 0, NULL or false. The compiler will initialize them to these
852 values when omitted. */
853 false, /* is_opened */
854
855 /* SCAN */
856 NULL, /* no scan params yet */
857 0, /* current scan index */
858 0, /* next scan frequency */
859 false, /* scan ready flag */
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 */
866 false,
867
868 /* Power management */
869 DRX_POWER_UP,
870
871 /* Tuner */
872 1, /* nr of I2C port to which tuner is */
873 0L, /* minimum RF input frequency, in kHz */
874 0L, /* maximum RF input frequency, in kHz */
875 false, /* Rf Agc Polarity */
876 false, /* If Agc Polarity */
877 false, /* tuner slow mode */
878
879 { /* current channel (all 0) */
880 0UL /* channel.frequency */
881 },
882 DRX_STANDARD_UNKNOWN, /* current standard */
883 DRX_STANDARD_UNKNOWN, /* previous standard */
884 DRX_STANDARD_UNKNOWN, /* di_cache_standard */
885 false, /* use_bootloader */
886 0UL, /* capabilities */
887 0 /* mfx */
888};
889
890/*
891* \var drxj_default_demod_g
892* \brief Default drxj demodulator instance.
893*/
894static struct drx_demod_instance drxj_default_demod_g = {
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 */
898};
899
900/*
901* \brief Default audio data structure for DRK demodulator instance.
902*
903* This structure is DRXK specific.
904*
905*/
906static struct drx_aud_data drxj_default_aud_data_g = {
907 false, /* audio_is_active */
908 DRX_AUD_STANDARD_AUTO, /* audio_standard */
909
910 /* i2sdata */
911 {
912 .output_enable: false, /* output_enable */
913 .frequency: 48000, /* frequency */
914 .mode: DRX_I2S_MODE_MASTER, /* mode */
915 .word_length: DRX_I2S_WORDLENGTH_32, /* word_length */
916 .polarity: DRX_I2S_POLARITY_RIGHT, /* polarity */
917 .format: DRX_I2S_FORMAT_WS_WITH_DATA /* format */
918 },
919 /* volume */
920 {
921 true, /* mute; */
922 0, /* volume */
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 */
929 },
930 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
931 /* ass_thresholds */
932 {
933 .a2: 440, /* A2 */
934 .btsc: 12, /* BTSC */
935 .nicam: 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 {
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 */
960 },
961 DRX_AUD_DEVIATION_NORMAL, /* deviation */
962 DRX_AUD_AVSYNC_OFF, /* av_sync */
963
964 /* prescale */
965 {
966 DRX_AUD_MAX_FM_DEVIATION, /* fm_deviation */
967 DRX_AUD_MAX_NICAM_PRESCALE /* nicam_gain */
968 },
969 DRX_AUD_FM_DEEMPH_75US, /* deemph */
970 DRX_BTSC_STEREO, /* btsc_detect */
971 0, /* rds_data_counter */
972 false /* rds_data_present */
973};
974
975/*-----------------------------------------------------------------------------
976STRUCTURES
977----------------------------------------------------------------------------*/
978struct drxjeq_stat {
979 u16 eq_mse;
980 u8 eq_mode;
981 u8 eq_ctrl;
982 u8 eq_stat;
983};
984
985/* HI command */
986struct drxj_hi_cmd {
987 u16 cmd;
988 u16 param1;
989 u16 param2;
990 u16 param3;
991 u16 param4;
992 u16 param5;
993 u16 param6;
994};
995
996/*============================================================================*/
997/*=== MICROCODE RELATED STRUCTURES ===========================================*/
998/*============================================================================*/
999
1000/*
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 */
1009struct drxu_code_block_hdr {
1010 u32 addr;
1011 u16 size;
1012 u16 flags;
1013 u16 CRC;
1014};
1015
1016/*-----------------------------------------------------------------------------
1017FUNCTIONS
1018----------------------------------------------------------------------------*/
1019/* Some prototypes */
1020static int
1021hi_command(struct i2c_device_addr *dev_addr,
1022 const struct drxj_hi_cmd *cmd, u16 *result);
1023
1024static int
1025ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
1026
1027static int
1028ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
1029
1030static int power_down_aud(struct drx_demod_instance *demod);
1031
1032static int
1033ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1034
1035static int
1036ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
1037
1038/*============================================================================*/
1039/*============================================================================*/
1040/*== HELPER FUNCTIONS ==*/
1041/*============================================================================*/
1042/*============================================================================*/
1043
1044
1045/*============================================================================*/
1046
1047/*
1048* \fn u32 frac28(u32 N, u32 D)
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
1056* frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
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*/
1067static u32 frac28(u32 N, u32 D)
1068{
1069 int i = 0;
1070 u32 Q1 = 0;
1071 u32 R0 = 0;
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;
1087}
1088
1089/*
1090* \fn u32 log1_times100( u32 x)
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
1105static u32 log1_times100(u32 x)
1106{
1107 static const u8 scale = 15;
1108 static const u8 index_width = 5;
1109 /*
1110 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1111 0 <= n < ((1<<INDEXWIDTH)+1)
1112 */
1113
1114 static const u32 log2lut[] = {
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
1150 u8 i = 0;
1151 u32 y = 0;
1152 u32 d = 0;
1153 u32 k = 0;
1154 u32 r = 0;
1155
1156 if (x == 0)
1157 return 0;
1158
1159 /* Scale x (normalize) */
1160 /* computing y in log(x/y) = log(x) - log(y) */
1161 if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
1162 for (k = scale; k > 0; k--) {
1163 if (x & (((u32) 1) << scale))
1164 break;
1165 x <<= 1;
1166 }
1167 } else {
1168 for (k = scale; k < 31; k++) {
1169 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
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
1178 /* correction for division: log(x) = log(x/y)+log(y) */
1179 y = k * ((((u32) 1) << scale) * 200);
1180
1181 /* remove integer part */
1182 x &= ((((u32) 1) << scale) - 1);
1183 /* get index */
1184 i = (u8) (x >> (scale - index_width));
1185 /* compute delta (x-a) */
1186 d = x & ((((u32) 1) << (scale - index_width)) - 1);
1187 /* compute log, multiplication ( d* (.. )) must be within range ! */
1188 y += log2lut[i] +
1189 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
1190 /* Conver to log10() */
1191 y /= 108853; /* (log2(10) << scale) */
1192 r = (y >> 1);
1193 /* rounding */
1194 if (y & ((u32)1))
1195 r++;
1196
1197 return r;
1198
1199}
1200
1201/*
1202* \fn u32 frac_times1e6( u16 N, u32 D)
1203* \brief Compute: (N/D) * 1000000.
1204* \param N nominator 16-bits.
1205* \param D denominator 32-bits.
1206* \return u32
1207* \retval ((N/D) * 1000000), 32 bits
1208*
1209* No check on D=0!
1210*/
1211static u32 frac_times1e6(u32 N, u32 D)
1212{
1213 u32 remainder = 0;
1214 u32 frac = 0;
1215
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 */
1223 frac = (((u32) N) * (1000000 >> 4)) / D;
1224 frac <<= 4;
1225 remainder = (((u32) N) * (1000000 >> 4)) % D;
1226 remainder <<= 4;
1227 frac += remainder / D;
1228 remainder = remainder % D;
1229 if ((remainder * 2) > D)
1230 frac++;
1231
1232 return frac;
1233}
1234
1235/*============================================================================*/
1236
1237
1238/*
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*/
1243#if 0
1244/* Currently, unused as we lack support for analog TV */
1245static const u16 nicam_presc_table_val[43] = {
1246 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
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};
1251#endif
1252
1253/*============================================================================*/
1254/*== END HELPER FUNCTIONS ==*/
1255/*============================================================================*/
1256
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
1276 TODO: check ignoring single/multimaster is ok for AUD access ?
1277*/
1278
1279#define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1280#define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
1281/*============================================================================*/
1282
1283/*
1284* \fn bool is_handled_by_aud_tr_if( u32 addr )
1285* \brief Check if this address is handled by the audio token ring interface.
1286* \param addr
1287* \return bool
1288* \retval true Yes, handled by audio token ring interface
1289* \retval false No, not handled by audio token ring interface
1290*
1291*/
1292static
1293bool is_handled_by_aud_tr_if(u32 addr)
1294{
1295 bool retval = false;
1296
1297 if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1298 (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1299 (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1300 retval = true;
1301 }
1302
1303 return retval;
1304}
1305
1306/*============================================================================*/
1307
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(adap: state->i2c, msgs: msg, num: num_msgs) != num_msgs) {
1353 pr_warn("drx3933: I2C write/read failed\n");
1354 return -EREMOTEIO;
1355 }
1356
1357#ifdef DJH_DEBUG
1358 if (w_dev_addr == NULL || r_dev_addr == NULL)
1359 return 0;
1360
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;
1375
1376 pr_debug("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
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
1389/*****************************
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 */
1483 rc = drxbsp_i2c_write_read(w_dev_addr: dev_addr, w_count: bufx, wData: buf,
1484 NULL, r_count: 0, NULL);
1485 if (rc == 0)
1486 rc = drxbsp_i2c_write_read(NULL, w_count: 0, NULL, r_dev_addr: dev_addr, r_count: todo, r_data: data);
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
1501/*****************************
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, datasize: sizeof(*data), data: buf, flags);
1530 *data = buf[0] + (((u16) buf[1]) << 8);
1531 return rc;
1532}
1533
1534/*****************************
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, datasize: sizeof(*data), 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
1569/*****************************
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...
1659 Address must be rewritten because HI is reset after data transport and
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(w_dev_addr: dev_addr,
1674 w_count: (u16) (bufx),
1675 wData: buf,
1676 r_dev_addr: (struct i2c_device_addr *)(NULL),
1677 r_count: 0, r_data: (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(w_dev_addr: dev_addr,
1691 w_count: (u16) (bufx + todo),
1692 wData: buf,
1693 r_dev_addr: (struct i2c_device_addr *)(NULL),
1694 r_count: 0, r_data: (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
1708/*****************************
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, datasize: sizeof(data), data: buf, flags);
1735}
1736
1737/*****************************
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, addr: waddr, data: wdata, DRXDAP_FASI_RMW);
1774 if (rc == 0)
1775 rc = drxdap_fasi_read_reg16(dev_addr, addr: raddr, data: rdata, flags: 0);
1776#endif
1777
1778 return rc;
1779}
1780
1781/*****************************
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, datasize: sizeof(data), data: buf, flags);
1810}
1811
1812/*============================================================================*/
1813
1814/*
1815* \fn int drxj_dap_rm_write_reg16short
1816* \brief Read modify write 16 bits audio register using short format only.
1817* \param dev_addr
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
1822* \return int
1823* \retval 0 Success
1824* \retval -EIO Timeout, I2C error, illegal bank
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 )
1833 See comments drxj_dap_read_modify_write_reg16 */
1834#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
1835static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1836 u32 waddr,
1837 u32 raddr,
1838 u16 wdata, u16 *rdata)
1839{
1840 int rc;
1841
1842 if (rdata == NULL)
1843 return -EINVAL;
1844
1845 /* Set RMW flag */
1846 rc = drxdap_fasi_write_reg16(dev_addr,
1847 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1848 SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1849 0x0000);
1850 if (rc == 0) {
1851 /* Write new data: triggers RMW */
1852 rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
1853 0x0000);
1854 }
1855 if (rc == 0) {
1856 /* Read old data */
1857 rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
1858 0x0000);
1859 }
1860 if (rc == 0) {
1861 /* Reset RMW flag */
1862 rc = drxdap_fasi_write_reg16(dev_addr,
1863 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1864 0, 0x0000);
1865 }
1866
1867 return rc;
1868}
1869#endif
1870
1871/*============================================================================*/
1872
1873static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1874 u32 waddr,
1875 u32 raddr,
1876 u16 wdata, u16 *rdata)
1877{
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 */
1881#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1882 return drxdap_fasi_read_modify_write_reg16(dev_addr,
1883 waddr,
1884 raddr, wdata, rdata);
1885#else
1886 return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
1887#endif
1888}
1889
1890
1891/*============================================================================*/
1892
1893/*
1894* \fn int drxj_dap_read_aud_reg16
1895* \brief Read 16 bits audio register
1896* \param dev_addr
1897* \param addr
1898* \param data
1899* \return int
1900* \retval 0 Success
1901* \retval -EIO Timeout, I2C error, illegal bank
1902*
1903* 16 bits register read access via audio token ring interface.
1904*
1905*/
1906static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1907 u32 addr, u16 *data)
1908{
1909 u32 start_timer = 0;
1910 u32 current_timer = 0;
1911 u32 delta_timer = 0;
1912 u16 tr_status = 0;
1913 int stat = -EIO;
1914
1915 /* No read possible for bank 3, return with error */
1916 if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1917 stat = -EINVAL;
1918 } else {
1919 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1920
1921 /* Force reset write bit */
1922 addr &= (~write_bit);
1923
1924 /* Set up read */
1925 start_timer = jiffies_to_msecs(j: jiffies);
1926 do {
1927 /* RMW to aud TR IF until request is granted or timeout */
1928 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1929 waddr: addr,
1930 SIO_HI_RA_RAM_S0_RMWBUF__A,
1931 wdata: 0x0000, rdata: &tr_status);
1932
1933 if (stat != 0)
1934 break;
1935
1936 current_timer = jiffies_to_msecs(j: jiffies);
1937 delta_timer = current_timer - start_timer;
1938 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1939 stat = -EIO;
1940 break;
1941 }
1942
1943 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1944 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1945 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1946 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1947 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1948
1949 /* Wait for read ready status or timeout */
1950 if (stat == 0) {
1951 start_timer = jiffies_to_msecs(j: jiffies);
1952
1953 while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1954 AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1955 stat = drxj_dap_read_reg16(dev_addr,
1956 AUD_TOP_TR_CTR__A,
1957 data: &tr_status, flags: 0x0000);
1958 if (stat != 0)
1959 break;
1960
1961 current_timer = jiffies_to_msecs(j: jiffies);
1962 delta_timer = current_timer - start_timer;
1963 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1964 stat = -EIO;
1965 break;
1966 }
1967 } /* while ( ... ) */
1968 }
1969
1970 /* Read value */
1971 if (stat == 0)
1972 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1973 AUD_TOP_TR_RD_REG__A,
1974 SIO_HI_RA_RAM_S0_RMWBUF__A,
1975 wdata: 0x0000, rdata: data);
1976 return stat;
1977}
1978
1979/*============================================================================*/
1980
1981static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1982 u32 addr,
1983 u16 *data, u32 flags)
1984{
1985 int stat = -EIO;
1986
1987 /* Check param */
1988 if ((dev_addr == NULL) || (data == NULL))
1989 return -EINVAL;
1990
1991 if (is_handled_by_aud_tr_if(addr))
1992 stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
1993 else
1994 stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);
1995
1996 return stat;
1997}
1998/*============================================================================*/
1999
2000/*
2001* \fn int drxj_dap_write_aud_reg16
2002* \brief Write 16 bits audio register
2003* \param dev_addr
2004* \param addr
2005* \param data
2006* \return int
2007* \retval 0 Success
2008* \retval -EIO Timeout, I2C error, illegal bank
2009*
2010* 16 bits register write access via audio token ring interface.
2011*
2012*/
2013static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
2014 u32 addr, u16 data)
2015{
2016 int stat = -EIO;
2017
2018 /* No write possible for bank 2, return with error */
2019 if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
2020 stat = -EINVAL;
2021 } else {
2022 u32 start_timer = 0;
2023 u32 current_timer = 0;
2024 u32 delta_timer = 0;
2025 u16 tr_status = 0;
2026 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
2027
2028 /* Force write bit */
2029 addr |= write_bit;
2030 start_timer = jiffies_to_msecs(j: jiffies);
2031 do {
2032 /* RMW to aud TR IF until request is granted or timeout */
2033 stat = drxj_dap_read_modify_write_reg16(dev_addr,
2034 waddr: addr,
2035 SIO_HI_RA_RAM_S0_RMWBUF__A,
2036 wdata: data, rdata: &tr_status);
2037 if (stat != 0)
2038 break;
2039
2040 current_timer = jiffies_to_msecs(j: jiffies);
2041 delta_timer = current_timer - start_timer;
2042 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
2043 stat = -EIO;
2044 break;
2045 }
2046
2047 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
2048 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
2049 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
2050 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
2051
2052 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
2053
2054 return stat;
2055}
2056
2057/*============================================================================*/
2058
2059static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
2060 u32 addr,
2061 u16 data, u32 flags)
2062{
2063 int stat = -EIO;
2064
2065 /* Check param */
2066 if (dev_addr == NULL)
2067 return -EINVAL;
2068
2069 if (is_handled_by_aud_tr_if(addr))
2070 stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
2071 else
2072 stat = drxdap_fasi_write_reg16(dev_addr,
2073 addr, data, flags);
2074
2075 return stat;
2076}
2077
2078/*============================================================================*/
2079
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
2089/*
2090* \fn int drxj_dap_atomic_read_write_block()
2091* \brief Basic access routine for atomic read or write access
2092* \param dev_addr pointer to i2c dev address
2093* \param addr destination/source address
2094* \param datasize size of data buffer in bytes
2095* \param data pointer to data buffer
2096* \return int
2097* \retval 0 Success
2098* \retval -EIO Timeout, I2C error, illegal bank
2099*
2100*/
2101static
2102int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2103 u32 addr,
2104 u16 datasize,
2105 u8 *data, bool read_flag)
2106{
2107 struct drxj_hi_cmd hi_cmd;
2108 int rc;
2109 u16 word;
2110 u16 dummy = 0;
2111 u16 i = 0;
2112
2113 /* Parameter check */
2114 if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
2115 return -EINVAL;
2116
2117 /* Set up HI parameters to read or write n bytes */
2118 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2119 hi_cmd.param1 =
2120 (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2121 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2122 hi_cmd.param2 =
2123 (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2124 hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2125 if (!read_flag)
2126 hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2127 else
2128 hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
2129 hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2130 DRXDAP_FASI_ADDR2BANK(addr));
2131 hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
2132
2133 if (!read_flag) {
2134 /* write data to buffer */
2135 for (i = 0; i < (datasize / 2); i++) {
2136
2137 word = ((u16) data[2 * i]);
2138 word += (((u16) data[(2 * i) + 1]) << 8);
2139 drxj_dap_write_reg16(dev_addr,
2140 addr: (DRXJ_HI_ATOMIC_BUF_START + i),
2141 data: word, flags: 0);
2142 }
2143 }
2144
2145 rc = hi_command(dev_addr, cmd: &hi_cmd, result: &dummy);
2146 if (rc != 0) {
2147 pr_err("error %d\n", rc);
2148 goto rw_error;
2149 }
2150
2151 if (read_flag) {
2152 /* read data from buffer */
2153 for (i = 0; i < (datasize / 2); i++) {
2154 rc = drxj_dap_read_reg16(dev_addr,
2155 addr: (DRXJ_HI_ATOMIC_BUF_START + i),
2156 data: &word, flags: 0);
2157 if (rc) {
2158 pr_err("error %d\n", rc);
2159 goto rw_error;
2160 }
2161 data[2 * i] = (u8) (word & 0xFF);
2162 data[(2 * i) + 1] = (u8) (word >> 8);
2163 }
2164 }
2165
2166 return 0;
2167
2168rw_error:
2169 return rc;
2170
2171}
2172
2173/*============================================================================*/
2174
2175/*
2176* \fn int drxj_dap_atomic_read_reg32()
2177* \brief Atomic read of 32 bits words
2178*/
2179static
2180int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2181 u32 addr,
2182 u32 *data, u32 flags)
2183{
2184 u8 buf[sizeof(*data)] = { 0 };
2185 int rc;
2186 u32 word = 0;
2187
2188 if (!data)
2189 return -EINVAL;
2190
2191 rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
2192 datasize: sizeof(*data), data: buf, read_flag: true);
2193
2194 if (rc < 0)
2195 return 0;
2196
2197 word = (u32) buf[3];
2198 word <<= 8;
2199 word |= (u32) buf[2];
2200 word <<= 8;
2201 word |= (u32) buf[1];
2202 word <<= 8;
2203 word |= (u32) buf[0];
2204
2205 *data = word;
2206
2207 return rc;
2208}
2209
2210/*============================================================================*/
2211
2212/*============================================================================*/
2213/*== END DRXJ DAP FUNCTIONS ==*/
2214/*============================================================================*/
2215
2216/*============================================================================*/
2217/*============================================================================*/
2218/*== HOST INTERFACE FUNCTIONS ==*/
2219/*============================================================================*/
2220/*============================================================================*/
2221
2222/*
2223* \fn int hi_cfg_command()
2224* \brief Configure HI with settings stored in the demod structure.
2225* \param demod Demodulator.
2226* \return int.
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*/
2233static int hi_cfg_command(const struct drx_demod_instance *demod)
2234{
2235 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2236 struct drxj_hi_cmd hi_cmd;
2237 u16 result = 0;
2238 int rc;
2239
2240 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2241
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;
2249
2250 rc = hi_command(dev_addr: demod->my_i2c_dev_addr, cmd: &hi_cmd, result: &result);
2251 if (rc != 0) {
2252 pr_err("error %d\n", rc);
2253 goto rw_error;
2254 }
2255
2256 /* Reset power down flag (set one call only) */
2257 ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2258
2259 return 0;
2260
2261rw_error:
2262 return rc;
2263}
2264
2265/*
2266* \fn int hi_command()
2267* \brief Configure HI with settings stored in the demod structure.
2268* \param dev_addr I2C address.
2269* \param cmd HI command.
2270* \param result HI command result.
2271* \return int.
2272*
2273* Sends command to HI
2274*
2275*/
2276static int
2277hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
2278{
2279 u16 wait_cmd = 0;
2280 u16 nr_retries = 0;
2281 bool powerdown_cmd = false;
2282 int rc;
2283
2284 /* Write parameters */
2285 switch (cmd->cmd) {
2286
2287 case SIO_HI_RA_RAM_CMD_CONFIG:
2288 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2289 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, data: cmd->param6, flags: 0);
2290 if (rc != 0) {
2291 pr_err("error %d\n", rc);
2292 goto rw_error;
2293 }
2294 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, data: cmd->param5, flags: 0);
2295 if (rc != 0) {
2296 pr_err("error %d\n", rc);
2297 goto rw_error;
2298 }
2299 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, data: cmd->param4, flags: 0);
2300 if (rc != 0) {
2301 pr_err("error %d\n", rc);
2302 goto rw_error;
2303 }
2304 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, data: cmd->param3, flags: 0);
2305 if (rc != 0) {
2306 pr_err("error %d\n", rc);
2307 goto rw_error;
2308 }
2309 fallthrough;
2310 case SIO_HI_RA_RAM_CMD_BRDCTRL:
2311 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, data: cmd->param2, flags: 0);
2312 if (rc != 0) {
2313 pr_err("error %d\n", rc);
2314 goto rw_error;
2315 }
2316 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, data: cmd->param1, flags: 0);
2317 if (rc != 0) {
2318 pr_err("error %d\n", rc);
2319 goto rw_error;
2320 }
2321 fallthrough;
2322 case SIO_HI_RA_RAM_CMD_NULL:
2323 /* No parameters */
2324 break;
2325
2326 default:
2327 return -EINVAL;
2328 }
2329
2330 /* Write command */
2331 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, data: cmd->cmd, flags: 0);
2332 if (rc != 0) {
2333 pr_err("error %d\n", rc);
2334 goto rw_error;
2335 }
2336
2337 if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
2338 msleep(msecs: 1);
2339
2340 /* Detect power down to omit reading result */
2341 powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2342 (((cmd->
2343 param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2344 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2345 if (!powerdown_cmd) {
2346 /* Wait until command rdy */
2347 do {
2348 nr_retries++;
2349 if (nr_retries > DRXJ_MAX_RETRIES) {
2350 rc = -ETIMEDOUT;
2351 pr_err("timeout\n");
2352 goto rw_error;
2353 }
2354
2355 rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, data: &wait_cmd, flags: 0);
2356 if (rc != 0) {
2357 pr_err("error %d\n", rc);
2358 goto rw_error;
2359 }
2360 } while (wait_cmd != 0);
2361
2362 /* Read result */
2363 rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, data: result, flags: 0);
2364 if (rc != 0) {
2365 pr_err("error %d\n", rc);
2366 goto rw_error;
2367 }
2368
2369 }
2370 /* if ( powerdown_cmd == true ) */
2371 return 0;
2372rw_error:
2373 return rc;
2374}
2375
2376/*
2377* \fn int init_hi( const struct drx_demod_instance *demod )
2378* \brief Initialise and configurate HI.
2379* \param demod pointer to demod data.
2380* \return int Return status.
2381* \retval 0 Success.
2382* \retval -EIO Failure.
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*/
2389static int init_hi(const struct drx_demod_instance *demod)
2390{
2391 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2392 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2393 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2394 int rc;
2395
2396 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2397 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2398 dev_addr = demod->my_i2c_dev_addr;
2399
2400 /* PATCH for bug 5003, HI ucode v3.1.0 */
2401 rc = drxj_dap_write_reg16(dev_addr, addr: 0x4301D7, data: 0x801, flags: 0);
2402 if (rc != 0) {
2403 pr_err("error %d\n", rc);
2404 goto rw_error;
2405 }
2406
2407 /* Timing div, 250ns/Psys */
2408 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2409 ext_attr->hi_cfg_timing_div =
2410 (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
2411 /* Clipping */
2412 if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
2413 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2414 /* Bridge delay, uses oscilator clock */
2415 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2416 /* SDA brdige delay */
2417 ext_attr->hi_cfg_bridge_delay =
2418 (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
2419 1000;
2420 /* Clipping */
2421 if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
2422 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2423 /* SCL bridge delay, same as SDA for now */
2424 ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
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 . */
2429 ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
2430 /* port/bridge/power down ctrl */
2431 ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2432 /* transit mode time out delay and watch dog divider */
2433 ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
2434
2435 rc = hi_cfg_command(demod);
2436 if (rc != 0) {
2437 pr_err("error %d\n", rc);
2438 goto rw_error;
2439 }
2440
2441 return 0;
2442
2443rw_error:
2444 return rc;
2445}
2446
2447/*============================================================================*/
2448/*== END HOST INTERFACE FUNCTIONS ==*/
2449/*============================================================================*/
2450
2451/*============================================================================*/
2452/*============================================================================*/
2453/*== AUXILIARY FUNCTIONS ==*/
2454/*============================================================================*/
2455/*============================================================================*/
2456
2457/*
2458* \fn int get_device_capabilities()
2459* \brief Get and store device capabilities.
2460* \param demod Pointer to demodulator instance.
2461* \return int.
2462* \return 0 Success
2463* \retval -EIO Failure
2464*
2465* Depending on pulldowns on MDx pins the following internals are set:
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
2471*
2472*/
2473static int get_device_capabilities(struct drx_demod_instance *demod)
2474{
2475 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2476 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
2477 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2478 u16 sio_pdr_ohw_cfg = 0;
2479 u32 sio_top_jtagid_lo = 0;
2480 u16 bid = 0;
2481 int rc;
2482
2483 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2484 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2485 dev_addr = demod->my_i2c_dev_addr;
2486
2487 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, flags: 0);
2488 if (rc != 0) {
2489 pr_err("error %d\n", rc);
2490 goto rw_error;
2491 }
2492 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, data: &sio_pdr_ohw_cfg, flags: 0);
2493 if (rc != 0) {
2494 pr_err("error %d\n", rc);
2495 goto rw_error;
2496 }
2497 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, flags: 0);
2498 if (rc != 0) {
2499 pr_err("error %d\n", rc);
2500 goto rw_error;
2501 }
2502
2503 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2504 case 0:
2505 /* ignore (bypass ?) */
2506 break;
2507 case 1:
2508 /* 27 MHz */
2509 common_attr->osc_clock_freq = 27000;
2510 break;
2511 case 2:
2512 /* 20.25 MHz */
2513 common_attr->osc_clock_freq = 20250;
2514 break;
2515 case 3:
2516 /* 4 MHz */
2517 common_attr->osc_clock_freq = 4000;
2518 break;
2519 default:
2520 return -EIO;
2521 }
2522
2523 /*
2524 Determine device capabilities
2525 Based on pinning v47
2526 */
2527 rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, data: &sio_top_jtagid_lo, flags: 0);
2528 if (rc != 0) {
2529 pr_err("error %d\n", rc);
2530 goto rw_error;
2531 }
2532 ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
2533
2534 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
2535 case 0x31:
2536 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, flags: 0);
2537 if (rc != 0) {
2538 pr_err("error %d\n", rc);
2539 goto rw_error;
2540 }
2541 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, data: &bid, flags: 0);
2542 if (rc != 0) {
2543 pr_err("error %d\n", rc);
2544 goto rw_error;
2545 }
2546 bid = (bid >> 10) & 0xf;
2547 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, flags: 0);
2548 if (rc != 0) {
2549 pr_err("error %d\n", rc);
2550 goto rw_error;
2551 }
2552
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;
2561 break;
2562 case 0x33:
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;
2571 break;
2572 case 0x45:
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;
2581 break;
2582 case 0x46:
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;
2591 break;
2592 case 0x41:
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;
2601 break;
2602 case 0x43:
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;
2611 break;
2612 case 0x32:
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;
2621 break;
2622 case 0x34:
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;
2631 break;
2632 case 0x42:
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;
2641 break;
2642 case 0x44:
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;
2651 break;
2652 default:
2653 /* Unknown device variant */
2654 return -EIO;
2655 break;
2656 }
2657
2658 return 0;
2659rw_error:
2660 return rc;
2661}
2662
2663/*
2664* \fn int power_up_device()
2665* \brief Power up device.
2666* \param demod Pointer to demodulator instance.
2667* \return int.
2668* \return 0 Success
2669* \retval -EIO Failure, I2C or max retries reached
2670*
2671*/
2672
2673#ifndef DRXJ_MAX_RETRIES_POWERUP
2674#define DRXJ_MAX_RETRIES_POWERUP 10
2675#endif
2676
2677static int power_up_device(struct drx_demod_instance *demod)
2678{
2679 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2680 u8 data = 0;
2681 u16 retry_count = 0;
2682 struct i2c_device_addr wake_up_addr;
2683
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;
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 */
2693 do {
2694 data = 0;
2695 drxbsp_i2c_write_read(w_dev_addr: &wake_up_addr, w_count: 1, wData: &data,
2696 r_dev_addr: (struct i2c_device_addr *)(NULL), r_count: 0,
2697 r_data: (u8 *)(NULL));
2698 msleep(msecs: 10);
2699 retry_count++;
2700 } while ((drxbsp_i2c_write_read
2701 (w_dev_addr: (struct i2c_device_addr *) (NULL), w_count: 0, wData: (u8 *)(NULL), r_dev_addr: dev_addr, r_count: 1,
2702 r_data: &data)
2703 != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
2704
2705 /* Need some recovery time .... */
2706 msleep(msecs: 10);
2707
2708 if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
2709 return -EIO;
2710
2711 return 0;
2712}
2713
2714/*----------------------------------------------------------------------------*/
2715/* MPEG Output Configuration Functions - begin */
2716/*----------------------------------------------------------------------------*/
2717/*
2718* \fn int ctrl_set_cfg_mpeg_output()
2719* \brief Set MPEG output configuration of the device.
2720* \param devmod Pointer to demodulator instance.
2721* \param cfg_data Pointer to mpeg output configuaration.
2722* \return int.
2723*
2724* Configure MPEG output parameters.
2725*
2726*/
2727static int
2728ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
2729{
2730 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2731 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2732 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2733 int rc;
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;
2741 /* data mask for the output data byte */
2742 u16 invert_data_mask =
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;
2747
2748 /* check arguments */
2749 if ((demod == NULL) || (cfg_data == NULL))
2750 return -EINVAL;
2751
2752 dev_addr = demod->my_i2c_dev_addr;
2753 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2754 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2755
2756 if (cfg_data->enable_mpeg_output == true) {
2757 /* quick and dirty patch to set MPEG in case current std is not
2758 producing MPEG */
2759 switch (ext_attr->standard) {
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:
2766 return 0;
2767 }
2768
2769 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, data: 0, flags: 0);
2770 if (rc != 0) {
2771 pr_err("error %d\n", rc);
2772 goto rw_error;
2773 }
2774 switch (ext_attr->standard) {
2775 case DRX_STANDARD_8VSB:
2776 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, data: 7, flags: 0);
2777 if (rc != 0) {
2778 pr_err("error %d\n", rc);
2779 goto rw_error;
2780 } /* 2048 bytes fifo ram */
2781 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, data: 10, flags: 0);
2782 if (rc != 0) {
2783 pr_err("error %d\n", rc);
2784 goto rw_error;
2785 }
2786 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, data: 10, flags: 0);
2787 if (rc != 0) {
2788 pr_err("error %d\n", rc);
2789 goto rw_error;
2790 }
2791 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, data: 5, flags: 0);
2792 if (rc != 0) {
2793 pr_err("error %d\n", rc);
2794 goto rw_error;
2795 }
2796 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, data: 7, flags: 0);
2797 if (rc != 0) {
2798 pr_err("error %d\n", rc);
2799 goto rw_error;
2800 }
2801 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, data: 10, flags: 0);
2802 if (rc != 0) {
2803 pr_err("error %d\n", rc);
2804 goto rw_error;
2805 }
2806 /* Low Water Mark for synchronization */
2807 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, data: 3, flags: 0);
2808 if (rc != 0) {
2809 pr_err("error %d\n", rc);
2810 goto rw_error;
2811 }
2812 /* High Water Mark for synchronization */
2813 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, data: 5, flags: 0);
2814 if (rc != 0) {
2815 pr_err("error %d\n", rc);
2816 goto rw_error;
2817 }
2818 break;
2819 case DRX_STANDARD_ITU_A:
2820 case DRX_STANDARD_ITU_C:
2821 switch (ext_attr->constellation) {
2822 case DRX_CONSTELLATION_QAM256:
2823 nr_bits = 8;
2824 break;
2825 case DRX_CONSTELLATION_QAM128:
2826 nr_bits = 7;
2827 break;
2828 case DRX_CONSTELLATION_QAM64:
2829 nr_bits = 6;
2830 break;
2831 case DRX_CONSTELLATION_QAM32:
2832 nr_bits = 5;
2833 break;
2834 case DRX_CONSTELLATION_QAM16:
2835 nr_bits = 4;
2836 break;
2837 default:
2838 return -EIO;
2839 } /* ext_attr->constellation */
2840 /* max_bit_rate = symbol_rate * nr_bits * coef */
2841 /* coef = 188/204 */
2842 max_bit_rate =
2843 (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
2844 fallthrough; /* as b/c Annex A/C need following settings */
2845 case DRX_STANDARD_ITU_B:
2846 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, flags: 0);
2847 if (rc != 0) {
2848 pr_err("error %d\n", rc);
2849 goto rw_error;
2850 }
2851 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, flags: 0);
2852 if (rc != 0) {
2853 pr_err("error %d\n", rc);
2854 goto rw_error;
2855 }
2856 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, data: 5, flags: 0);
2857 if (rc != 0) {
2858 pr_err("error %d\n", rc);
2859 goto rw_error;
2860 }
2861 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, flags: 0);
2862 if (rc != 0) {
2863 pr_err("error %d\n", rc);
2864 goto rw_error;
2865 }
2866 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, flags: 0);
2867 if (rc != 0) {
2868 pr_err("error %d\n", rc);
2869 goto rw_error;
2870 }
2871 if (cfg_data->static_clk == true) {
2872 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, data: 0xD, flags: 0);
2873 if (rc != 0) {
2874 pr_err("error %d\n", rc);
2875 goto rw_error;
2876 }
2877 } else {
2878 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, flags: 0);
2879 if (rc != 0) {
2880 pr_err("error %d\n", rc);
2881 goto rw_error;
2882 }
2883 }
2884 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, data: 2, flags: 0);
2885 if (rc != 0) {
2886 pr_err("error %d\n", rc);
2887 goto rw_error;
2888 }
2889 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, data: 12, flags: 0);
2890 if (rc != 0) {
2891 pr_err("error %d\n", rc);
2892 goto rw_error;
2893 }
2894 break;
2895 default:
2896 break;
2897 } /* switch (standard) */
2898
2899 /* Check insertion of the Reed-Solomon parity bytes */
2900 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, data: &fec_oc_reg_mode, flags: 0);
2901 if (rc != 0) {
2902 pr_err("error %d\n", rc);
2903 goto rw_error;
2904 }
2905 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, data: &fec_oc_reg_ipr_mode, flags: 0);
2906 if (rc != 0) {
2907 pr_err("error %d\n", rc);
2908 goto rw_error;
2909 }
2910 if (cfg_data->insert_rs_byte == true) {
2911 /* enable parity symbol forward */
2912 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
2913 /* MVAL disable during parity bytes */
2914 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2915 switch (ext_attr->standard) {
2916 case DRX_STANDARD_8VSB:
2917 rcn_rate = 0x004854D3;
2918 break;
2919 case DRX_STANDARD_ITU_B:
2920 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2921 switch (ext_attr->constellation) {
2922 case DRX_CONSTELLATION_QAM256:
2923 rcn_rate = 0x008945E7;
2924 break;
2925 case DRX_CONSTELLATION_QAM64:
2926 rcn_rate = 0x005F64D4;
2927 break;
2928 default:
2929 return -EIO;
2930 }
2931 break;
2932 case DRX_STANDARD_ITU_A:
2933 case DRX_STANDARD_ITU_C:
2934 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2935 rcn_rate =
2936 (frac28
2937 (N: max_bit_rate,
2938 D: (u32) (common_attr->sys_clock_freq / 8))) /
2939 188;
2940 break;
2941 default:
2942 return -EIO;
2943 } /* ext_attr->standard */
2944 } else { /* insert_rs_byte == false */
2945
2946 /* disable parity symbol forward */
2947 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2948 /* MVAL enable during parity bytes */
2949 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2950 switch (ext_attr->standard) {
2951 case DRX_STANDARD_8VSB:
2952 rcn_rate = 0x0041605C;
2953 break;
2954 case DRX_STANDARD_ITU_B:
2955 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2956 switch (ext_attr->constellation) {
2957 case DRX_CONSTELLATION_QAM256:
2958 rcn_rate = 0x0082D6A0;
2959 break;
2960 case DRX_CONSTELLATION_QAM64:
2961 rcn_rate = 0x005AEC1A;
2962 break;
2963 default:
2964 return -EIO;
2965 }
2966 break;
2967 case DRX_STANDARD_ITU_A:
2968 case DRX_STANDARD_ITU_C:
2969 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2970 rcn_rate =
2971 (frac28
2972 (N: max_bit_rate,
2973 D: (u32) (common_attr->sys_clock_freq / 8))) /
2974 204;
2975 break;
2976 default:
2977 return -EIO;
2978 } /* ext_attr->standard */
2979 }
2980
2981 if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> clear ipr_mode[0] */
2982 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2983 } else { /* MPEG data output is serial -> set ipr_mode[0] */
2984 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
2985 }
2986
2987 /* Control slective inversion of output bits */
2988 if (cfg_data->invert_data == true)
2989 fec_oc_reg_ipr_invert |= invert_data_mask;
2990 else
2991 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2992
2993 if (cfg_data->invert_err == true)
2994 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2995 else
2996 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2997
2998 if (cfg_data->invert_str == true)
2999 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
3000 else
3001 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
3002
3003 if (cfg_data->invert_val == true)
3004 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
3005 else
3006 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
3007
3008 if (cfg_data->invert_clk == true)
3009 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
3010 else
3011 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
3012
3013
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;
3019
3020 fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
3021
3022 switch (ext_attr->standard) {
3023 case DRX_STANDARD_8VSB:
3024 fec_oc_dto_period = 4;
3025 if (cfg_data->insert_rs_byte == true)
3026 fec_oc_dto_burst_len = 208;
3027 break;
3028 case DRX_STANDARD_ITU_A:
3029 {
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;
3034 }
3035 if (ext_attr->curr_symbol_rate >=
3036 symbol_rate_th) {
3037 fec_oc_dto_period = 0;
3038 } else {
3039 fec_oc_dto_period = 1;
3040 }
3041 }
3042 break;
3043 case DRX_STANDARD_ITU_B:
3044 fec_oc_dto_period = 1;
3045 if (cfg_data->insert_rs_byte == true)
3046 fec_oc_dto_burst_len = 128;
3047 break;
3048 case DRX_STANDARD_ITU_C:
3049 fec_oc_dto_period = 1;
3050 if (cfg_data->insert_rs_byte == true)
3051 fec_oc_dto_burst_len = 204;
3052 break;
3053 default:
3054 return -EIO;
3055 }
3056 bit_rate =
3057 common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
3058 2);
3059 dto_rate =
3060 frac28(N: bit_rate, D: common_attr->sys_clock_freq * 1000);
3061 dto_rate >>= 3;
3062 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_HI__A, data: (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), flags: 0);
3063 if (rc != 0) {
3064 pr_err("error %d\n", rc);
3065 goto rw_error;
3066 }
3067 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_LO__A, data: (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), flags: 0);
3068 if (rc != 0) {
3069 pr_err("error %d\n", rc);
3070 goto rw_error;
3071 }
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, flags: 0);
3073 if (rc != 0) {
3074 pr_err("error %d\n", rc);
3075 goto rw_error;
3076 }
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, flags: 0);
3078 if (rc != 0) {
3079 pr_err("error %d\n", rc);
3080 goto rw_error;
3081 }
3082 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, data: fec_oc_dto_burst_len, flags: 0);
3083 if (rc != 0) {
3084 pr_err("error %d\n", rc);
3085 goto rw_error;
3086 }
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;
3089 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, data: fec_oc_dto_period, flags: 0);
3090 if (rc != 0) {
3091 pr_err("error %d\n", rc);
3092 goto rw_error;
3093 }
3094 } else { /* Dynamic mode */
3095
3096 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, flags: 0);
3097 if (rc != 0) {
3098 pr_err("error %d\n", rc);
3099 goto rw_error;
3100 }
3101 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, data: 0, flags: 0);
3102 if (rc != 0) {
3103 pr_err("error %d\n", rc);
3104 goto rw_error;
3105 }
3106 }
3107
3108 rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, data: rcn_rate, flags: 0);
3109 if (rc != 0) {
3110 pr_err("error %d\n", rc);
3111 goto rw_error;
3112 }
3113
3114 /* Write appropriate registers with requested configuration */
3115 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, data: fec_oc_reg_mode, flags: 0);
3116 if (rc != 0) {
3117 pr_err("error %d\n", rc);
3118 goto rw_error;
3119 }
3120 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, data: fec_oc_reg_ipr_mode, flags: 0);
3121 if (rc != 0) {
3122 pr_err("error %d\n", rc);
3123 goto rw_error;
3124 }
3125 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, data: fec_oc_reg_ipr_invert, flags: 0);
3126 if (rc != 0) {
3127 pr_err("error %d\n", rc);
3128 goto rw_error;
3129 }
3130
3131 /* enabling for both parallel and serial now */
3132 /* Write magic word to enable pdr reg write */
3133 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, data: 0xFABA, flags: 0);
3134 if (rc != 0) {
3135 pr_err("error %d\n", rc);
3136 goto rw_error;
3137 }
3138 /* Set MPEG TS pads to outputmode */
3139 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, data: 0x0013, flags: 0);
3140 if (rc != 0) {
3141 pr_err("error %d\n", rc);
3142 goto rw_error;
3143 }
3144 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, data: 0x0013, flags: 0);
3145 if (rc != 0) {
3146 pr_err("error %d\n", rc);
3147 goto rw_error;
3148 }
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, flags: 0);
3150 if (rc != 0) {
3151 pr_err("error %d\n", rc);
3152 goto rw_error;
3153 }
3154 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, data: 0x0013, flags: 0);
3155 if (rc != 0) {
3156 pr_err("error %d\n", rc);
3157 goto rw_error;
3158 }
3159 sio_pdr_md_cfg =
3160 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3161 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
3162 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3163 if (rc != 0) {
3164 pr_err("error %d\n", rc);
3165 goto rw_error;
3166 }
3167 if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> set MD1 to MD7 to output mode */
3168 sio_pdr_md_cfg =
3169 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3170 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3171 SIO_PDR_MD0_CFG_MODE__B;
3172 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3173 if (rc != 0) {
3174 pr_err("error %d\n", rc);
3175 goto rw_error;
3176 }
3177 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3178 if (rc != 0) {
3179 pr_err("error %d\n", rc);
3180 goto rw_error;
3181 }
3182 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3183 if (rc != 0) {
3184 pr_err("error %d\n", rc);
3185 goto rw_error;
3186 }
3187 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3188 if (rc != 0) {
3189 pr_err("error %d\n", rc);
3190 goto rw_error;
3191 }
3192 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3193 if (rc != 0) {
3194 pr_err("error %d\n", rc);
3195 goto rw_error;
3196 }
3197 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3198 if (rc != 0) {
3199 pr_err("error %d\n", rc);
3200 goto rw_error;
3201 }
3202 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3203 if (rc != 0) {
3204 pr_err("error %d\n", rc);
3205 goto rw_error;
3206 }
3207 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, data: sio_pdr_md_cfg, flags: 0);
3208 if (rc != 0) {
3209 pr_err("error %d\n", rc);
3210 goto rw_error;
3211 }
3212 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3213 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, data: 0x0000, flags: 0);
3214 if (rc != 0) {
3215 pr_err("error %d\n", rc);
3216 goto rw_error;
3217 }
3218 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, data: 0x0000, flags: 0);
3219 if (rc != 0) {
3220 pr_err("error %d\n", rc);
3221 goto rw_error;
3222 }
3223 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, data: 0x0000, flags: 0);
3224 if (rc != 0) {
3225 pr_err("error %d\n", rc);
3226 goto rw_error;
3227 }
3228 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, data: 0x0000, flags: 0);
3229 if (rc != 0) {
3230 pr_err("error %d\n", rc);
3231 goto rw_error;
3232 }
3233 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, data: 0x0000, flags: 0);
3234 if (rc != 0) {
3235 pr_err("error %d\n", rc);
3236 goto rw_error;
3237 }
3238 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, data: 0x0000, flags: 0);
3239 if (rc != 0) {
3240 pr_err("error %d\n", rc);
3241 goto rw_error;
3242 }
3243 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, data: 0x0000, flags: 0);
3244 if (rc != 0) {
3245 pr_err("error %d\n", rc);
3246 goto rw_error;
3247 }
3248 }
3249 /* Enable Monitor Bus output over MPEG pads and ctl input */
3250 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, data: 0x0000, flags: 0);
3251 if (rc != 0) {
3252 pr_err("error %d\n", rc);
3253 goto rw_error;
3254 }
3255 /* Write nomagic word to enable pdr reg write */
3256 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, data: 0x0000, flags: 0);
3257 if (rc != 0) {
3258 pr_err("error %d\n", rc);
3259 goto rw_error;
3260 }
3261 } else {
3262 /* Write magic word to enable pdr reg write */
3263 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, data: 0xFABA, flags: 0);
3264 if (rc != 0) {
3265 pr_err("error %d\n", rc);
3266 goto rw_error;
3267 }
3268 /* Set MPEG TS pads to inputmode */
3269 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, data: 0x0000, flags: 0);
3270 if (rc != 0) {
3271 pr_err("error %d\n", rc);
3272 goto rw_error;
3273 }
3274 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, data: 0x0000, flags: 0);
3275 if (rc != 0) {
3276 pr_err("error %d\n", rc);
3277 goto rw_error;
3278 }
3279 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, data: 0x0000, flags: 0);
3280 if (rc != 0) {
3281 pr_err("error %d\n", rc);
3282 goto rw_error;
3283 }
3284 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, data: 0x0000, flags: 0);
3285 if (rc != 0) {
3286 pr_err("error %d\n", rc);
3287 goto rw_error;
3288 }
3289 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, data: 0x0000, flags: 0);
3290 if (rc != 0) {
3291 pr_err("error %d\n", rc);
3292 goto rw_error;
3293 }
3294 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, data: 0x0000, flags: 0);
3295 if (rc != 0) {
3296 pr_err("error %d\n", rc);
3297 goto rw_error;
3298 }
3299 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, data: 0x0000, flags: 0);
3300 if (rc != 0) {
3301 pr_err("error %d\n", rc);
3302 goto rw_error;
3303 }
3304 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, data: 0x0000, flags: 0);
3305 if (rc != 0) {
3306 pr_err("error %d\n", rc);
3307 goto rw_error;
3308 }
3309 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, data: 0x0000, flags: 0);
3310 if (rc != 0) {
3311 pr_err("error %d\n", rc);
3312 goto rw_error;
3313 }
3314 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, data: 0x0000, flags: 0);
3315 if (rc != 0) {
3316 pr_err("error %d\n", rc);
3317 goto rw_error;
3318 }
3319 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, data: 0x0000, flags: 0);
3320 if (rc != 0) {
3321 pr_err("error %d\n", rc);
3322 goto rw_error;
3323 }
3324 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, data: 0x0000, flags: 0);
3325 if (rc != 0) {
3326 pr_err("error %d\n", rc);
3327 goto rw_error;
3328 }
3329 /* Enable Monitor Bus output over MPEG pads and ctl input */
3330 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, data: 0x0000, flags: 0);
3331 if (rc != 0) {
3332 pr_err("error %d\n", rc);
3333 goto rw_error;
3334 }
3335 /* Write nomagic word to enable pdr reg write */
3336 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, data: 0x0000, flags: 0);
3337 if (rc != 0) {
3338 pr_err("error %d\n", rc);
3339 goto rw_error;
3340 }
3341 }
3342
3343 /* save values for restore after re-acquire */
3344 common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3345
3346 return 0;
3347rw_error:
3348 return rc;
3349}
3350
3351/*----------------------------------------------------------------------------*/
3352
3353
3354/*----------------------------------------------------------------------------*/
3355/* MPEG Output Configuration Functions - end */
3356/*----------------------------------------------------------------------------*/
3357
3358/*----------------------------------------------------------------------------*/
3359/* miscellaneous configurations - begin */
3360/*----------------------------------------------------------------------------*/
3361
3362/*
3363* \fn int set_mpegtei_handling()
3364* \brief Activate MPEG TEI handling settings.
3365* \param devmod Pointer to demodulator instance.
3366* \return int.
3367*
3368* This routine should be called during a set channel of QAM/VSB
3369*
3370*/
3371static int set_mpegtei_handling(struct drx_demod_instance *demod)
3372{
3373 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3374 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3375 int rc;
3376 u16 fec_oc_dpr_mode = 0;
3377 u16 fec_oc_snc_mode = 0;
3378 u16 fec_oc_ems_mode = 0;
3379
3380 dev_addr = demod->my_i2c_dev_addr;
3381 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3382
3383 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, data: &fec_oc_dpr_mode, flags: 0);
3384 if (rc != 0) {
3385 pr_err("error %d\n", rc);
3386 goto rw_error;
3387 }
3388 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, data: &fec_oc_snc_mode, flags: 0);
3389 if (rc != 0) {
3390 pr_err("error %d\n", rc);
3391 goto rw_error;
3392 }
3393 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, data: &fec_oc_ems_mode, flags: 0);
3394 if (rc != 0) {
3395 pr_err("error %d\n", rc);
3396 goto rw_error;
3397 }
3398
3399 /* reset to default, allow TEI bit to be changed */
3400 fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3401 fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3402 FEC_OC_SNC_MODE_CORR_DISABLE__M));
3403 fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
3404
3405 if (ext_attr->disable_te_ihandling) {
3406 /* do not change TEI bit */
3407 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3408 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3409 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3410 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3411 }
3412
3413 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, data: fec_oc_dpr_mode, flags: 0);
3414 if (rc != 0) {
3415 pr_err("error %d\n", rc);
3416 goto rw_error;
3417 }
3418 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, data: fec_oc_snc_mode, flags: 0);
3419 if (rc != 0) {
3420 pr_err("error %d\n", rc);
3421 goto rw_error;
3422 }
3423 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, data: fec_oc_ems_mode, flags: 0);
3424 if (rc != 0) {
3425 pr_err("error %d\n", rc);
3426 goto rw_error;
3427 }
3428
3429 return 0;
3430rw_error:
3431 return rc;
3432}
3433
3434/*----------------------------------------------------------------------------*/
3435/*
3436* \fn int bit_reverse_mpeg_output()
3437* \brief Set MPEG output bit-endian settings.
3438* \param devmod Pointer to demodulator instance.
3439* \return int.
3440*
3441* This routine should be called during a set channel of QAM/VSB
3442*
3443*/
3444static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
3445{
3446 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3447 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3448 int rc;
3449 u16 fec_oc_ipr_mode = 0;
3450
3451 dev_addr = demod->my_i2c_dev_addr;
3452 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3453
3454 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, data: &fec_oc_ipr_mode, flags: 0);
3455 if (rc != 0) {
3456 pr_err("error %d\n", rc);
3457 goto rw_error;
3458 }
3459
3460 /* reset to default (normal bit order) */
3461 fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3462
3463 if (ext_attr->bit_reverse_mpeg_outout)
3464 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3465
3466 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, data: fec_oc_ipr_mode, flags: 0);
3467 if (rc != 0) {
3468 pr_err("error %d\n", rc);
3469 goto rw_error;
3470 }
3471
3472 return 0;
3473rw_error:
3474 return rc;
3475}
3476
3477/*----------------------------------------------------------------------------*/
3478/*
3479* \fn int set_mpeg_start_width()
3480* \brief Set MPEG start width.
3481* \param devmod Pointer to demodulator instance.
3482* \return int.
3483*
3484* This routine should be called during a set channel of QAM/VSB
3485*
3486*/
3487static int set_mpeg_start_width(struct drx_demod_instance *demod)
3488{
3489 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3490 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3491 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
3492 int rc;
3493 u16 fec_oc_comm_mb = 0;
3494
3495 dev_addr = demod->my_i2c_dev_addr;
3496 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3497 common_attr = demod->my_common_attr;
3498
3499 if ((common_attr->mpeg_cfg.static_clk == true)
3500 && (common_attr->mpeg_cfg.enable_parallel == false)) {
3501 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, data: &fec_oc_comm_mb, flags: 0);
3502 if (rc != 0) {
3503 pr_err("error %d\n", rc);
3504 goto rw_error;
3505 }
3506 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3507 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
3508 fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
3509 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_COMM_MB__A, data: fec_oc_comm_mb, flags: 0);
3510 if (rc != 0) {
3511 pr_err("error %d\n", rc);
3512 goto rw_error;
3513 }
3514 }
3515
3516 return 0;
3517rw_error:
3518 return rc;
3519}
3520
3521/*----------------------------------------------------------------------------*/
3522/* miscellaneous configurations - end */
3523/*----------------------------------------------------------------------------*/
3524
3525/*----------------------------------------------------------------------------*/
3526/* UIO Configuration Functions - begin */
3527/*----------------------------------------------------------------------------*/
3528/*
3529* \fn int ctrl_set_uio_cfg()
3530* \brief Configure modus oprandi UIO.
3531* \param demod Pointer to demodulator instance.
3532* \param uio_cfg Pointer to a configuration setting for a certain UIO.
3533* \return int.
3534*/
3535static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3536{
3537 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3538 int rc;
3539
3540 if ((uio_cfg == NULL) || (demod == NULL))
3541 return -EINVAL;
3542
3543 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3544
3545 /* Write magic word to enable pdr reg write */
3546 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, flags: 0);
3547 if (rc != 0) {
3548 pr_err("error %d\n", rc);
3549 goto rw_error;
3550 }
3551 switch (uio_cfg->uio) {
3552 /*====================================================================*/
3553 case DRX_UIO1:
3554 /* DRX_UIO1: SMA_TX UIO-1 */
3555 if (!ext_attr->has_smatx)
3556 return -EIO;
3557 switch (uio_cfg->mode) {
3558 case DRX_UIO_MODE_FIRMWARE_SMA:
3559 case DRX_UIO_MODE_FIRMWARE_SAW:
3560 case DRX_UIO_MODE_READWRITE:
3561 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3562 break;
3563 case DRX_UIO_MODE_DISABLE:
3564 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3565 /* pad configuration register is set 0 - input mode */
3566 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, data: 0, flags: 0);
3567 if (rc != 0) {
3568 pr_err("error %d\n", rc);
3569 goto rw_error;
3570 }
3571 break;
3572 default:
3573 return -EINVAL;
3574 } /* switch ( uio_cfg->mode ) */
3575 break;
3576 /*====================================================================*/
3577 case DRX_UIO2:
3578 /* DRX_UIO2: SMA_RX UIO-2 */
3579 if (!ext_attr->has_smarx)
3580 return -EIO;
3581 switch (uio_cfg->mode) {
3582 case DRX_UIO_MODE_FIRMWARE0:
3583 case DRX_UIO_MODE_READWRITE:
3584 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3585 break;
3586 case DRX_UIO_MODE_DISABLE:
3587 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3588 /* pad configuration register is set 0 - input mode */
3589 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, data: 0, flags: 0);
3590 if (rc != 0) {
3591 pr_err("error %d\n", rc);
3592 goto rw_error;
3593 }
3594 break;
3595 default:
3596 return -EINVAL;
3597 } /* switch ( uio_cfg->mode ) */
3598 break;
3599 /*====================================================================*/
3600 case DRX_UIO3:
3601 /* DRX_UIO3: GPIO UIO-3 */
3602 if (!ext_attr->has_gpio)
3603 return -EIO;
3604 switch (uio_cfg->mode) {
3605 case DRX_UIO_MODE_FIRMWARE0:
3606 case DRX_UIO_MODE_READWRITE:
3607 ext_attr->uio_gpio_mode = uio_cfg->mode;
3608 break;
3609 case DRX_UIO_MODE_DISABLE:
3610 ext_attr->uio_gpio_mode = uio_cfg->mode;
3611 /* pad configuration register is set 0 - input mode */
3612 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, data: 0, flags: 0);
3613 if (rc != 0) {
3614 pr_err("error %d\n", rc);
3615 goto rw_error;
3616 }
3617 break;
3618 default:
3619 return -EINVAL;
3620 } /* switch ( uio_cfg->mode ) */
3621 break;
3622 /*====================================================================*/
3623 case DRX_UIO4:
3624 /* DRX_UIO4: IRQN UIO-4 */
3625 if (!ext_attr->has_irqn)
3626 return -EIO;
3627 switch (uio_cfg->mode) {
3628 case DRX_UIO_MODE_READWRITE:
3629 ext_attr->uio_irqn_mode = uio_cfg->mode;
3630 break;
3631 case DRX_UIO_MODE_DISABLE:
3632 /* pad configuration register is set 0 - input mode */
3633 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, data: 0, flags: 0);
3634 if (rc != 0) {
3635 pr_err("error %d\n", rc);
3636 goto rw_error;
3637 }
3638 ext_attr->uio_irqn_mode = uio_cfg->mode;
3639 break;
3640 case DRX_UIO_MODE_FIRMWARE0:
3641 default:
3642 return -EINVAL;
3643 } /* switch ( uio_cfg->mode ) */
3644 break;
3645 /*====================================================================*/
3646 default:
3647 return -EINVAL;
3648 } /* switch ( uio_cfg->uio ) */
3649
3650 /* Write magic word to disable pdr reg write */
3651 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, data: 0x0000, flags: 0);
3652 if (rc != 0) {
3653 pr_err("error %d\n", rc);
3654 goto rw_error;
3655 }
3656
3657 return 0;
3658rw_error:
3659 return rc;
3660}
3661
3662/*
3663* \fn int ctrl_uio_write()
3664* \brief Write to a UIO.
3665* \param demod Pointer to demodulator instance.
3666* \param uio_data Pointer to data container for a certain UIO.
3667* \return int.
3668*/
3669static int
3670ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
3671{
3672 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3673 int rc;
3674 u16 pin_cfg_value = 0;
3675 u16 value = 0;
3676
3677 if ((uio_data == NULL) || (demod == NULL))
3678 return -EINVAL;
3679
3680 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3681
3682 /* Write magic word to enable pdr reg write */
3683 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, flags: 0);
3684 if (rc != 0) {
3685 pr_err("error %d\n", rc);
3686 goto rw_error;
3687 }
3688 switch (uio_data->uio) {
3689 /*====================================================================*/
3690 case DRX_UIO1:
3691 /* DRX_UIO1: SMA_TX UIO-1 */
3692 if (!ext_attr->has_smatx)
3693 return -EIO;
3694 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3695 && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3696 return -EIO;
3697 }
3698 pin_cfg_value = 0;
3699 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3700 pin_cfg_value |= 0x0113;
3701 /* io_pad_cfg_mode output mode is drive always */
3702 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3703
3704 /* write to io pad configuration register - output mode */
3705 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, data: pin_cfg_value, flags: 0);
3706 if (rc != 0) {
3707 pr_err("error %d\n", rc);
3708 goto rw_error;
3709 }
3710
3711 /* use corresponding bit in io data output registar */
3712 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, data: &value, flags: 0);
3713 if (rc != 0) {
3714 pr_err("error %d\n", rc);
3715 goto rw_error;
3716 }
3717 if (!uio_data->value)
3718 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
3719 else
3720 value |= 0x8000; /* write one to 15th bit - 1st UIO */
3721
3722 /* write back to io data output register */
3723 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, data: value, flags: 0);
3724 if (rc != 0) {
3725 pr_err("error %d\n", rc);
3726 goto rw_error;
3727 }
3728 break;
3729 /*======================================================================*/
3730 case DRX_UIO2:
3731 /* DRX_UIO2: SMA_RX UIO-2 */
3732 if (!ext_attr->has_smarx)
3733 return -EIO;
3734 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
3735 return -EIO;
3736
3737 pin_cfg_value = 0;
3738 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3739 pin_cfg_value |= 0x0113;
3740 /* io_pad_cfg_mode output mode is drive always */
3741 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3742
3743 /* write to io pad configuration register - output mode */
3744 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, data: pin_cfg_value, flags: 0);
3745 if (rc != 0) {
3746 pr_err("error %d\n", rc);
3747 goto rw_error;
3748 }
3749
3750 /* use corresponding bit in io data output registar */
3751 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, data: &value, flags: 0);
3752 if (rc != 0) {
3753 pr_err("error %d\n", rc);
3754 goto rw_error;
3755 }
3756 if (!uio_data->value)
3757 value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
3758 else
3759 value |= 0x4000; /* write one to 14th bit - 2nd UIO */
3760
3761 /* write back to io data output register */
3762 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, data: value, flags: 0);
3763 if (rc != 0) {
3764 pr_err("error %d\n", rc);
3765 goto rw_error;
3766 }
3767 break;
3768 /*====================================================================*/
3769 case DRX_UIO3:
3770 /* DRX_UIO3: ASEL UIO-3 */
3771 if (!ext_attr->has_gpio)
3772 return -EIO;
3773 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
3774 return -EIO;
3775
3776 pin_cfg_value = 0;
3777 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3778 pin_cfg_value |= 0x0113;
3779 /* io_pad_cfg_mode output mode is drive always */
3780 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3781
3782 /* write to io pad configuration register - output mode */
3783 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, data: pin_cfg_value, flags: 0);
3784 if (rc != 0) {
3785 pr_err("error %d\n", rc);
3786 goto rw_error;
3787 }
3788
3789 /* use corresponding bit in io data output registar */
3790 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, data: &value, flags: 0);
3791 if (rc != 0) {
3792 pr_err("error %d\n", rc);
3793 goto rw_error;
3794 }
3795 if (!uio_data->value)
3796 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
3797 else
3798 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
3799
3800 /* write back to io data output register */
3801 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, data: value, flags: 0);
3802 if (rc != 0) {
3803 pr_err("error %d\n", rc);
3804 goto rw_error;
3805 }
3806 break;
3807 /*=====================================================================*/
3808 case DRX_UIO4:
3809 /* DRX_UIO4: IRQN UIO-4 */
3810 if (!ext_attr->has_irqn)
3811 return -EIO;
3812
3813 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
3814 return -EIO;
3815
3816 pin_cfg_value = 0;
3817 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3818 pin_cfg_value |= 0x0113;
3819 /* io_pad_cfg_mode output mode is drive always */
3820 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3821
3822 /* write to io pad configuration register - output mode */
3823 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, data: pin_cfg_value, flags: 0);
3824 if (rc != 0) {
3825 pr_err("error %d\n", rc);
3826 goto rw_error;
3827 }
3828
3829 /* use corresponding bit in io data output registar */
3830 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, data: &value, flags: 0);
3831 if (rc != 0) {
3832 pr_err("error %d\n", rc);
3833 goto rw_error;
3834 }
3835 if (uio_data->value == false)
3836 value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
3837 else
3838 value |= 0x1000; /* write one to 12th bit - 4th UIO */
3839
3840 /* write back to io data output register */
3841 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, data: value, flags: 0);
3842 if (rc != 0) {
3843 pr_err("error %d\n", rc);
3844 goto rw_error;
3845 }
3846 break;
3847 /*=====================================================================*/
3848 default:
3849 return -EINVAL;
3850 } /* switch ( uio_data->uio ) */
3851
3852 /* Write magic word to disable pdr reg write */
3853 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, data: 0x0000, flags: 0);
3854 if (rc != 0) {
3855 pr_err("error %d\n", rc);
3856 goto rw_error;
3857 }
3858
3859 return 0;
3860rw_error:
3861 return rc;
3862}
3863
3864/*---------------------------------------------------------------------------*/
3865/* UIO Configuration Functions - end */
3866/*---------------------------------------------------------------------------*/
3867
3868/*----------------------------------------------------------------------------*/
3869/* I2C Bridge Functions - begin */
3870/*----------------------------------------------------------------------------*/
3871/*
3872* \fn int ctrl_i2c_bridge()
3873* \brief Open or close the I2C switch to tuner.
3874* \param demod Pointer to demodulator instance.
3875* \param bridge_closed Pointer to bool indication if bridge is closed not.
3876* \return int.
3877
3878*/
3879static int
3880ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
3881{
3882 struct drxj_hi_cmd hi_cmd;
3883 u16 result = 0;
3884
3885 /* check arguments */
3886 if (bridge_closed == NULL)
3887 return -EINVAL;
3888
3889 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
3890 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
3891 if (*bridge_closed)
3892 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
3893 else
3894 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
3895
3896 return hi_command(dev_addr: demod->my_i2c_dev_addr, cmd: &hi_cmd, result: &result);
3897}
3898
3899/*----------------------------------------------------------------------------*/
3900/* I2C Bridge Functions - end */
3901/*----------------------------------------------------------------------------*/
3902
3903/*----------------------------------------------------------------------------*/
3904/* Smart antenna Functions - begin */
3905/*----------------------------------------------------------------------------*/
3906/*
3907* \fn int smart_ant_init()
3908* \brief Initialize Smart Antenna.
3909* \param pointer to struct drx_demod_instance.
3910* \return int.
3911*
3912*/
3913static int smart_ant_init(struct drx_demod_instance *demod)
3914{
3915 struct drxj_data *ext_attr = NULL;
3916 struct i2c_device_addr *dev_addr = NULL;
3917 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
3918 int rc;
3919 u16 data = 0;
3920
3921 dev_addr = demod->my_i2c_dev_addr;
3922 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3923
3924 /* Write magic word to enable pdr reg write */
3925 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, flags: 0);
3926 if (rc != 0) {
3927 pr_err("error %d\n", rc);
3928 goto rw_error;
3929 }
3930 /* init smart antenna */
3931 rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, data: &data, flags: 0);
3932 if (rc != 0) {
3933 pr_err("error %d\n", rc);
3934 goto rw_error;
3935 }
3936 if (ext_attr->smart_ant_inverted) {
3937 rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, data: (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, flags: 0);
3938 if (rc != 0) {
3939 pr_err("error %d\n", rc);
3940 goto rw_error;
3941 }
3942 } else {
3943 rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, data: (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, flags: 0);
3944 if (rc != 0) {
3945 pr_err("error %d\n", rc);
3946 goto rw_error;
3947 }
3948 }
3949
3950 /* config SMA_TX pin to smart antenna mode */
3951 rc = ctrl_set_uio_cfg(demod, uio_cfg: &uio_cfg);
3952 if (rc != 0) {
3953 pr_err("error %d\n", rc);
3954 goto rw_error;
3955 }
3956 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, data: 0x13, flags: 0);
3957 if (rc != 0) {
3958 pr_err("error %d\n", rc);
3959 goto rw_error;
3960 }
3961 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, data: 0x03, flags: 0);
3962 if (rc != 0) {
3963 pr_err("error %d\n", rc);
3964 goto rw_error;
3965 }
3966
3967 /* Write magic word to disable pdr reg write */
3968 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, data: 0x0000, flags: 0);
3969 if (rc != 0) {
3970 pr_err("error %d\n", rc);
3971 goto rw_error;
3972 }
3973
3974 return 0;
3975rw_error:
3976 return rc;
3977}
3978
3979static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
3980{
3981 int rc;
3982 u16 cur_cmd = 0;
3983 unsigned long timeout;
3984
3985 /* Check param */
3986 if (cmd == NULL)
3987 return -EINVAL;
3988
3989 /* Wait until SCU command interface is ready to receive command */
3990 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, data: &cur_cmd, flags: 0);
3991 if (rc != 0) {
3992 pr_err("error %d\n", rc);
3993 goto rw_error;
3994 }
3995 if (cur_cmd != DRX_SCU_READY)
3996 return -EIO;
3997
3998 switch (cmd->parameter_len) {
3999 case 5:
4000 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, data: *(cmd->parameter + 4), flags: 0);
4001 if (rc != 0) {
4002 pr_err("error %d\n", rc);
4003 goto rw_error;
4004 }
4005 fallthrough;
4006 case 4:
4007 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, data: *(cmd->parameter + 3), flags: 0);
4008 if (rc != 0) {
4009 pr_err("error %d\n", rc);
4010 goto rw_error;
4011 }
4012 fallthrough;
4013 case 3:
4014 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, data: *(cmd->parameter + 2), flags: 0);
4015 if (rc != 0) {
4016 pr_err("error %d\n", rc);
4017 goto rw_error;
4018 }
4019 fallthrough;
4020 case 2:
4021 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, data: *(cmd->parameter + 1), flags: 0);
4022 if (rc != 0) {
4023 pr_err("error %d\n", rc);
4024 goto rw_error;
4025 }
4026 fallthrough;
4027 case 1:
4028 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, data: *(cmd->parameter + 0), flags: 0);
4029 if (rc != 0) {
4030 pr_err("error %d\n", rc);
4031 goto rw_error;
4032 }
4033 fallthrough;
4034 case 0:
4035 /* do nothing */
4036 break;
4037 default:
4038 /* this number of parameters is not supported */
4039 return -EIO;
4040 }
4041 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, data: cmd->command, flags: 0);
4042 if (rc != 0) {
4043 pr_err("error %d\n", rc);
4044 goto rw_error;
4045 }
4046
4047 /* Wait until SCU has processed command */
4048 timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);
4049 while (time_is_after_jiffies(timeout)) {
4050 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, data: &cur_cmd, flags: 0);
4051 if (rc != 0) {
4052 pr_err("error %d\n", rc);
4053 goto rw_error;
4054 }
4055 if (cur_cmd == DRX_SCU_READY)
4056 break;
4057 usleep_range(min: 1000, max: 2000);
4058 }
4059
4060 if (cur_cmd != DRX_SCU_READY)
4061 return -EIO;
4062
4063 /* read results */
4064 if ((cmd->result_len > 0) && (cmd->result != NULL)) {
4065 s16 err;
4066
4067 switch (cmd->result_len) {
4068 case 4:
4069 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, data: cmd->result + 3, flags: 0);
4070 if (rc != 0) {
4071 pr_err("error %d\n", rc);
4072 goto rw_error;
4073 }
4074 fallthrough;
4075 case 3:
4076 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, data: cmd->result + 2, flags: 0);
4077 if (rc != 0) {
4078 pr_err("error %d\n", rc);
4079 goto rw_error;
4080 }
4081 fallthrough;
4082 case 2:
4083 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, data: cmd->result + 1, flags: 0);
4084 if (rc != 0) {
4085 pr_err("error %d\n", rc);
4086 goto rw_error;
4087 }
4088 fallthrough;
4089 case 1:
4090 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, data: cmd->result + 0, flags: 0);
4091 if (rc != 0) {
4092 pr_err("error %d\n", rc);
4093 goto rw_error;
4094 }
4095 fallthrough;
4096 case 0:
4097 /* do nothing */
4098 break;
4099 default:
4100 /* this number of parameters is not supported */
4101 return -EIO;
4102 }
4103
4104 /* Check if an error was reported by SCU */
4105 err = cmd->result[0];
4106
4107 /* check a few fixed error codes */
4108 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4109 || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4110 || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4111 || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
4112 ) {
4113 return -EINVAL;
4114 }
4115 /* here it is assumed that negative means error, and positive no error */
4116 else if (err < 0)
4117 return -EIO;
4118 else
4119 return 0;
4120 }
4121
4122 return 0;
4123
4124rw_error:
4125 return rc;
4126}
4127
4128/*
4129* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4130* \brief Basic access routine for SCU atomic read or write access
4131* \param dev_addr pointer to i2c dev address
4132* \param addr destination/source address
4133* \param datasize size of data buffer in bytes
4134* \param data pointer to data buffer
4135* \return int
4136* \retval 0 Success
4137* \retval -EIO Timeout, I2C error, illegal bank
4138*
4139*/
4140#define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4141static
4142int 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 */
4143 u8 *data, bool read_flag)
4144{
4145 struct drxjscu_cmd scu_cmd;
4146 int rc;
4147 u16 set_param_parameters[18];
4148 u16 cmd_result[15];
4149
4150 /* Parameter check */
4151 if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
4152 return -EINVAL;
4153
4154 set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4155 if (read_flag) { /* read */
4156 set_param_parameters[0] = ((~(0x0080)) & datasize);
4157 scu_cmd.parameter_len = 2;
4158 scu_cmd.result_len = datasize / 2 + 2;
4159 } else {
4160 int i = 0;
4161
4162 set_param_parameters[0] = 0x0080 | datasize;
4163 for (i = 0; i < (datasize / 2); i++) {
4164 set_param_parameters[i + 2] =
4165 (data[2 * i] | (data[(2 * i) + 1] << 8));
4166 }
4167 scu_cmd.parameter_len = datasize / 2 + 2;
4168 scu_cmd.result_len = 1;
4169 }
4170
4171 scu_cmd.command =
4172 SCU_RAM_COMMAND_STANDARD_TOP |
4173 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4174 scu_cmd.result = cmd_result;
4175 scu_cmd.parameter = set_param_parameters;
4176 rc = scu_command(dev_addr, cmd: &scu_cmd);
4177 if (rc != 0) {
4178 pr_err("error %d\n", rc);
4179 goto rw_error;
4180 }
4181
4182 if (read_flag) {
4183 int i = 0;
4184 /* read data from buffer */
4185 for (i = 0; i < (datasize / 2); i++) {
4186 data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4187 data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
4188 }
4189 }
4190
4191 return 0;
4192
4193rw_error:
4194 return rc;
4195
4196}
4197
4198/*============================================================================*/
4199
4200/*
4201* \fn int DRXJ_DAP_AtomicReadReg16()
4202* \brief Atomic read of 16 bits words
4203*/
4204static
4205int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4206 u32 addr,
4207 u16 *data, u32 flags)
4208{
4209 u8 buf[2] = { 0 };
4210 int rc;
4211 u16 word = 0;
4212
4213 if (!data)
4214 return -EINVAL;
4215
4216 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, datasize: 2, data: buf, read_flag: true);
4217 if (rc < 0)
4218 return rc;
4219
4220 word = (u16) (buf[0] + (buf[1] << 8));
4221
4222 *data = word;
4223
4224 return rc;
4225}
4226
4227/*============================================================================*/
4228/*
4229* \fn int drxj_dap_scu_atomic_write_reg16()
4230* \brief Atomic read of 16 bits words
4231*/
4232static
4233int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4234 u32 addr,
4235 u16 data, u32 flags)
4236{
4237 u8 buf[2];
4238 int rc;
4239
4240 buf[0] = (u8) (data & 0xff);
4241 buf[1] = (u8) ((data >> 8) & 0xff);
4242
4243 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, datasize: 2, data: buf, read_flag: false);
4244
4245 return rc;
4246}
4247
4248/* -------------------------------------------------------------------------- */
4249/*
4250* \brief Measure result of ADC synchronisation
4251* \param demod demod instance
4252* \param count (returned) count
4253* \return int.
4254* \retval 0 Success
4255* \retval -EIO Failure: I2C error
4256*
4257*/
4258static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
4259{
4260 struct i2c_device_addr *dev_addr = NULL;
4261 int rc;
4262 u16 data = 0;
4263
4264 dev_addr = demod->my_i2c_dev_addr;
4265
4266 /* Start measurement */
4267 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, flags: 0);
4268 if (rc != 0) {
4269 pr_err("error %d\n", rc);
4270 goto rw_error;
4271 }
4272 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, data: 1, flags: 0);
4273 if (rc != 0) {
4274 pr_err("error %d\n", rc);
4275 goto rw_error;
4276 }
4277
4278 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4279 msleep(msecs: 1);
4280
4281 *count = 0;
4282 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, data: &data, flags: 0);
4283 if (rc != 0) {
4284 pr_err("error %d\n", rc);
4285 goto rw_error;
4286 }
4287 if (data == 127)
4288 *count = *count + 1;
4289 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, data: &data, flags: 0);
4290 if (rc != 0) {
4291 pr_err("error %d\n", rc);
4292 goto rw_error;
4293 }
4294 if (data == 127)
4295 *count = *count + 1;
4296 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, data: &data, flags: 0);
4297 if (rc != 0) {
4298 pr_err("error %d\n", rc);
4299 goto rw_error;
4300 }
4301 if (data == 127)
4302 *count = *count + 1;
4303
4304 return 0;
4305rw_error:
4306 return rc;
4307}
4308
4309/*
4310* \brief Synchronize analog and digital clock domains
4311* \param demod demod instance
4312* \return int.
4313* \retval 0 Success
4314* \retval -EIO Failure: I2C error or failure to synchronize
4315*
4316* An IQM reset will also reset the results of this synchronization.
4317* After an IQM reset this routine needs to be called again.
4318*
4319*/
4320
4321static int adc_synchronization(struct drx_demod_instance *demod)
4322{
4323 struct i2c_device_addr *dev_addr = NULL;
4324 int rc;
4325 u16 count = 0;
4326
4327 dev_addr = demod->my_i2c_dev_addr;
4328
4329 rc = adc_sync_measurement(demod, count: &count);
4330 if (rc != 0) {
4331 pr_err("error %d\n", rc);
4332 goto rw_error;
4333 }
4334
4335 if (count == 1) {
4336 /* Try sampling on a different edge */
4337 u16 clk_neg = 0;
4338
4339 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, data: &clk_neg, flags: 0);
4340 if (rc != 0) {
4341 pr_err("error %d\n", rc);
4342 goto rw_error;
4343 }
4344
4345 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4346 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, data: clk_neg, flags: 0);
4347 if (rc != 0) {
4348 pr_err("error %d\n", rc);
4349 goto rw_error;
4350 }
4351
4352 rc = adc_sync_measurement(demod, count: &count);
4353 if (rc != 0) {
4354 pr_err("error %d\n", rc);
4355 goto rw_error;
4356 }
4357 }
4358
4359 /* TODO: implement fallback scenarios */
4360 if (count < 2)
4361 return -EIO;
4362
4363 return 0;
4364rw_error:
4365 return rc;
4366}
4367
4368/*============================================================================*/
4369/*== END AUXILIARY FUNCTIONS ==*/
4370/*============================================================================*/
4371
4372/*============================================================================*/
4373/*============================================================================*/
4374/*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
4375/*============================================================================*/
4376/*============================================================================*/
4377/*
4378* \fn int init_agc ()
4379* \brief Initialize AGC for all standards.
4380* \param demod instance of demodulator.
4381* \param channel pointer to channel data.
4382* \return int.
4383*/
4384static int init_agc(struct drx_demod_instance *demod)
4385{
4386 struct i2c_device_addr *dev_addr = NULL;
4387 struct drx_common_attr *common_attr = NULL;
4388 struct drxj_data *ext_attr = NULL;
4389 struct drxj_cfg_agc *p_agc_rf_settings = NULL;
4390 struct drxj_cfg_agc *p_agc_if_settings = NULL;
4391 int rc;
4392 u16 ingain_tgt_max = 0;
4393 u16 clp_dir_to = 0;
4394 u16 sns_sum_max = 0;
4395 u16 clp_sum_max = 0;
4396 u16 sns_dir_to = 0;
4397 u16 ki_innergain_min = 0;
4398 u16 agc_ki = 0;
4399 u16 ki_max = 0;
4400 u16 if_iaccu_hi_tgt_min = 0;
4401 u16 data = 0;
4402 u16 agc_ki_dgain = 0;
4403 u16 ki_min = 0;
4404 u16 clp_ctrl_mode = 0;
4405 u16 agc_rf = 0;
4406 u16 agc_if = 0;
4407
4408 dev_addr = demod->my_i2c_dev_addr;
4409 common_attr = (struct drx_common_attr *) demod->my_common_attr;
4410 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4411
4412 switch (ext_attr->standard) {
4413 case DRX_STANDARD_8VSB:
4414 clp_sum_max = 1023;
4415 clp_dir_to = (u16) (-9);
4416 sns_sum_max = 1023;
4417 sns_dir_to = (u16) (-9);
4418 ki_innergain_min = (u16) (-32768);
4419 ki_max = 0x032C;
4420 agc_ki_dgain = 0xC;
4421 if_iaccu_hi_tgt_min = 2047;
4422 ki_min = 0x0117;
4423 ingain_tgt_max = 16383;
4424 clp_ctrl_mode = 0;
4425 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, data: 0x7fff, flags: 0);
4426 if (rc != 0) {
4427 pr_err("error %d\n", rc);
4428 goto rw_error;
4429 }
4430 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, data: 0x0, flags: 0);
4431 if (rc != 0) {
4432 pr_err("error %d\n", rc);
4433 goto rw_error;
4434 }
4435 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, data: 0, flags: 0);
4436 if (rc != 0) {
4437 pr_err("error %d\n", rc);
4438 goto rw_error;
4439 }
4440 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, data: 0, flags: 0);
4441 if (rc != 0) {
4442 pr_err("error %d\n", rc);
4443 goto rw_error;
4444 }
4445 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, data: 0, flags: 0);
4446 if (rc != 0) {
4447 pr_err("error %d\n", rc);
4448 goto rw_error;
4449 }
4450 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, data: 1, flags: 0);
4451 if (rc != 0) {
4452 pr_err("error %d\n", rc);
4453 goto rw_error;
4454 }
4455 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, data: 0, flags: 0);
4456 if (rc != 0) {
4457 pr_err("error %d\n", rc);
4458 goto rw_error;
4459 }
4460 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, data: 0, flags: 0);
4461 if (rc != 0) {
4462 pr_err("error %d\n", rc);
4463 goto rw_error;
4464 }
4465 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, data: 0, flags: 0);
4466 if (rc != 0) {
4467 pr_err("error %d\n", rc);
4468 goto rw_error;
4469 }
4470 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, data: 1, flags: 0);
4471 if (rc != 0) {
4472 pr_err("error %d\n", rc);
4473 goto rw_error;
4474 }
4475 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, data: 1024, flags: 0);
4476 if (rc != 0) {
4477 pr_err("error %d\n", rc);
4478 goto rw_error;
4479 }
4480 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, data: 22600, flags: 0);
4481 if (rc != 0) {
4482 pr_err("error %d\n", rc);
4483 goto rw_error;
4484 }
4485 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, data: 13200, flags: 0);
4486 if (rc != 0) {
4487 pr_err("error %d\n", rc);
4488 goto rw_error;
4489 }
4490 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
4491 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
4492 break;
4493#ifndef DRXJ_VSB_ONLY
4494 case DRX_STANDARD_ITU_A:
4495 case DRX_STANDARD_ITU_C:
4496 case DRX_STANDARD_ITU_B:
4497 ingain_tgt_max = 5119;
4498 clp_sum_max = 1023;
4499 clp_dir_to = (u16) (-5);
4500 sns_sum_max = 127;
4501 sns_dir_to = (u16) (-3);
4502 ki_innergain_min = 0;
4503 ki_max = 0x0657;
4504 if_iaccu_hi_tgt_min = 2047;
4505 agc_ki_dgain = 0x7;
4506 ki_min = 0x0117;
4507 clp_ctrl_mode = 0;
4508 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, data: 0x7fff, flags: 0);
4509 if (rc != 0) {
4510 pr_err("error %d\n", rc);
4511 goto rw_error;
4512 }
4513 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, data: 0x0, flags: 0);
4514 if (rc != 0) {
4515 pr_err("error %d\n", rc);
4516 goto rw_error;
4517 }
4518 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, data: 0, flags: 0);
4519 if (rc != 0) {
4520 pr_err("error %d\n", rc);
4521 goto rw_error;
4522 }
4523 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, data: 0, flags: 0);
4524 if (rc != 0) {
4525 pr_err("error %d\n", rc);
4526 goto rw_error;
4527 }
4528 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, data: 0, flags: 0);
4529 if (rc != 0) {
4530 pr_err("error %d\n", rc);
4531 goto rw_error;
4532 }
4533 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, data: 1, flags: 0);
4534 if (rc != 0) {
4535 pr_err("error %d\n", rc);
4536 goto rw_error;
4537 }
4538 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, data: 0, flags: 0);
4539 if (rc != 0) {
4540 pr_err("error %d\n", rc);
4541 goto rw_error;
4542 }
4543 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, data: 0, flags: 0);
4544 if (rc != 0) {
4545 pr_err("error %d\n", rc);
4546 goto rw_error;
4547 }
4548 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, data: 0, flags: 0);
4549 if (rc != 0) {
4550 pr_err("error %d\n", rc);
4551 goto rw_error;
4552 }
4553 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, data: 1, flags: 0);
4554 if (rc != 0) {
4555 pr_err("error %d\n", rc);
4556 goto rw_error;
4557 }
4558 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
4559 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
4560 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, data: p_agc_if_settings->top, flags: 0);
4561 if (rc != 0) {
4562 pr_err("error %d\n", rc);
4563 goto rw_error;
4564 }
4565
4566 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, data: &agc_ki, flags: 0);
4567 if (rc != 0) {
4568 pr_err("error %d\n", rc);
4569 goto rw_error;
4570 }
4571 agc_ki &= 0xf000;
4572 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data: agc_ki, flags: 0);
4573 if (rc != 0) {
4574 pr_err("error %d\n", rc);
4575 goto rw_error;
4576 }
4577 break;
4578#endif
4579 default:
4580 return -EINVAL;
4581 }
4582
4583 /* for new AGC interface */
4584 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, data: p_agc_if_settings->top, flags: 0);
4585 if (rc != 0) {
4586 pr_err("error %d\n", rc);
4587 goto rw_error;
4588 }
4589 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, data: p_agc_if_settings->top, flags: 0);
4590 if (rc != 0) {
4591 pr_err("error %d\n", rc);
4592 goto rw_error;
4593 } /* Gain fed from inner to outer AGC */
4594 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, data: ingain_tgt_max, flags: 0);
4595 if (rc != 0) {
4596 pr_err("error %d\n", rc);
4597 goto rw_error;
4598 }
4599 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, data: if_iaccu_hi_tgt_min, flags: 0);
4600 if (rc != 0) {
4601 pr_err("error %d\n", rc);
4602 goto rw_error;
4603 }
4604 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, data: 0, flags: 0);
4605 if (rc != 0) {
4606 pr_err("error %d\n", rc);
4607 goto rw_error;
4608 } /* set to p_agc_settings->top before */
4609 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, data: 0, flags: 0);
4610 if (rc != 0) {
4611 pr_err("error %d\n", rc);
4612 goto rw_error;
4613 }
4614 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, data: 0, flags: 0);
4615 if (rc != 0) {
4616 pr_err("error %d\n", rc);
4617 goto rw_error;
4618 }
4619 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, data: 0, flags: 0);
4620 if (rc != 0) {
4621 pr_err("error %d\n", rc);
4622 goto rw_error;
4623 }
4624 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, data: 32767, flags: 0);
4625 if (rc != 0) {
4626 pr_err("error %d\n", rc);
4627 goto rw_error;
4628 }
4629 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, data: clp_sum_max, flags: 0);
4630 if (rc != 0) {
4631 pr_err("error %d\n", rc);
4632 goto rw_error;
4633 }
4634 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, data: sns_sum_max, flags: 0);
4635 if (rc != 0) {
4636 pr_err("error %d\n", rc);
4637 goto rw_error;
4638 }
4639 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, data: ki_innergain_min, flags: 0);
4640 if (rc != 0) {
4641 pr_err("error %d\n", rc);
4642 goto rw_error;
4643 }
4644 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, data: 50, flags: 0);
4645 if (rc != 0) {
4646 pr_err("error %d\n", rc);
4647 goto rw_error;
4648 }
4649 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, data: 500, flags: 0);
4650 if (rc != 0) {
4651 pr_err("error %d\n", rc);
4652 goto rw_error;
4653 }
4654 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, data: 500, flags: 0);
4655 if (rc != 0) {
4656 pr_err("error %d\n", rc);
4657 goto rw_error;
4658 }
4659 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, data: 20, flags: 0);
4660 if (rc != 0) {
4661 pr_err("error %d\n", rc);
4662 goto rw_error;
4663 }
4664 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, data: ki_min, flags: 0);
4665 if (rc != 0) {
4666 pr_err("error %d\n", rc);
4667 goto rw_error;
4668 }
4669 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, data: ki_max, flags: 0);
4670 if (rc != 0) {
4671 pr_err("error %d\n", rc);
4672 goto rw_error;
4673 }
4674 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, data: 0, flags: 0);
4675 if (rc != 0) {
4676 pr_err("error %d\n", rc);
4677 goto rw_error;
4678 }
4679 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, data: 8, flags: 0);
4680 if (rc != 0) {
4681 pr_err("error %d\n", rc);
4682 goto rw_error;
4683 }
4684 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, data: 500, flags: 0);
4685 if (rc != 0) {
4686 pr_err("error %d\n", rc);
4687 goto rw_error;
4688 }
4689 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, data: clp_dir_to, flags: 0);
4690 if (rc != 0) {
4691 pr_err("error %d\n", rc);
4692 goto rw_error;
4693 }
4694 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, data: 8, flags: 0);
4695 if (rc != 0) {
4696 pr_err("error %d\n", rc);
4697 goto rw_error;
4698 }
4699 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, data: sns_dir_to, flags: 0);
4700 if (rc != 0) {
4701 pr_err("error %d\n", rc);
4702 goto rw_error;
4703 }
4704 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, data: 50, flags: 0);
4705 if (rc != 0) {
4706 pr_err("error %d\n", rc);
4707 goto rw_error;
4708 }
4709 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, data: clp_ctrl_mode, flags: 0);
4710 if (rc != 0) {
4711 pr_err("error %d\n", rc);
4712 goto rw_error;
4713 }
4714
4715 agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
4716 if (common_attr->tuner_rf_agc_pol == true)
4717 agc_rf = 0x87ff - agc_rf;
4718
4719 agc_if = 0x800;
4720 if (common_attr->tuner_if_agc_pol == true)
4721 agc_rf = 0x87ff - agc_rf;
4722
4723 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, data: agc_rf, flags: 0);
4724 if (rc != 0) {
4725 pr_err("error %d\n", rc);
4726 goto rw_error;
4727 }
4728 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, data: agc_if, flags: 0);
4729 if (rc != 0) {
4730 pr_err("error %d\n", rc);
4731 goto rw_error;
4732 }
4733
4734 /* Set/restore Ki DGAIN factor */
4735 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, data: &data, flags: 0);
4736 if (rc != 0) {
4737 pr_err("error %d\n", rc);
4738 goto rw_error;
4739 }
4740 data &= ~SCU_RAM_AGC_KI_DGAIN__M;
4741 data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
4742 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, flags: 0);
4743 if (rc != 0) {
4744 pr_err("error %d\n", rc);
4745 goto rw_error;
4746 }
4747
4748 return 0;
4749rw_error:
4750 return rc;
4751}
4752
4753/*
4754* \fn int set_frequency ()
4755* \brief Set frequency shift.
4756* \param demod instance of demodulator.
4757* \param channel pointer to channel data.
4758* \param tuner_freq_offset residual frequency from tuner.
4759* \return int.
4760*/
4761static int
4762set_frequency(struct drx_demod_instance *demod,
4763 struct drx_channel *channel, s32 tuner_freq_offset)
4764{
4765 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
4766 struct drxj_data *ext_attr = demod->my_ext_attr;
4767 int rc;
4768 s32 sampling_frequency = 0;
4769 s32 frequency_shift = 0;
4770 s32 if_freq_actual = 0;
4771 s32 rf_freq_residual = -1 * tuner_freq_offset;
4772 s32 adc_freq = 0;
4773 s32 intermediate_freq = 0;
4774 u32 iqm_fs_rate_ofs = 0;
4775 bool adc_flip = true;
4776 bool select_pos_image = false;
4777 bool rf_mirror;
4778 bool tuner_mirror;
4779 bool image_to_select;
4780 s32 fm_frequency_shift = 0;
4781
4782 rf_mirror = ext_attr->mirror == DRX_MIRROR_YES;
4783 tuner_mirror = !demod->my_common_attr->mirror_freq_spect;
4784 /*
4785 Program frequency shifter
4786 No need to account for mirroring on RF
4787 */
4788 switch (ext_attr->standard) {
4789 case DRX_STANDARD_ITU_A:
4790 case DRX_STANDARD_ITU_C:
4791 case DRX_STANDARD_PAL_SECAM_LP:
4792 case DRX_STANDARD_8VSB:
4793 select_pos_image = true;
4794 break;
4795 case DRX_STANDARD_FM:
4796 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
4797 Sound carrier is already 3Mhz above centre frequency due
4798 to tuner setting so now add an extra shift of 1MHz... */
4799 fm_frequency_shift = 1000;
4800 fallthrough;
4801 case DRX_STANDARD_ITU_B:
4802 case DRX_STANDARD_NTSC:
4803 case DRX_STANDARD_PAL_SECAM_BG:
4804 case DRX_STANDARD_PAL_SECAM_DK:
4805 case DRX_STANDARD_PAL_SECAM_I:
4806 case DRX_STANDARD_PAL_SECAM_L:
4807 select_pos_image = false;
4808 break;
4809 default:
4810 return -EINVAL;
4811 }
4812 intermediate_freq = demod->my_common_attr->intermediate_freq;
4813 sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
4814 if (tuner_mirror)
4815 if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
4816 else
4817 if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
4818 if (if_freq_actual > sampling_frequency / 2) {
4819 /* adc mirrors */
4820 adc_freq = sampling_frequency - if_freq_actual;
4821 adc_flip = true;
4822 } else {
4823 /* adc doesn't mirror */
4824 adc_freq = if_freq_actual;
4825 adc_flip = false;
4826 }
4827
4828 frequency_shift = adc_freq;
4829 image_to_select =
4830 (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
4831 iqm_fs_rate_ofs = frac28(N: frequency_shift, D: sampling_frequency);
4832
4833 if (image_to_select)
4834 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
4835
4836 /* Program frequency shifter with tuner offset compensation */
4837 /* frequency_shift += tuner_freq_offset; TODO */
4838 rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, data: iqm_fs_rate_ofs, flags: 0);
4839 if (rc != 0) {
4840 pr_err("error %d\n", rc);
4841 goto rw_error;
4842 }
4843 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
4844 ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
4845
4846 return 0;
4847rw_error:
4848 return rc;
4849}
4850
4851/*
4852* \fn int get_acc_pkt_err()
4853* \brief Retrieve signal strength for VSB and QAM.
4854* \param demod Pointer to demod instance
4855* \param packet_err Pointer to packet error
4856* \return int.
4857* \retval 0 sig_strength contains valid data.
4858* \retval -EINVAL sig_strength is NULL.
4859* \retval -EIO Erroneous data, sig_strength contains invalid data.
4860*/
4861#ifdef DRXJ_SIGNAL_ACCUM_ERR
4862static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
4863{
4864 int rc;
4865 static u16 pkt_err;
4866 static u16 last_pkt_err;
4867 u16 data = 0;
4868 struct drxj_data *ext_attr = NULL;
4869 struct i2c_device_addr *dev_addr = NULL;
4870
4871 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4872 dev_addr = demod->my_i2c_dev_addr;
4873
4874 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
4875 if (rc != 0) {
4876 pr_err("error %d\n", rc);
4877 goto rw_error;
4878 }
4879 if (ext_attr->reset_pkt_err_acc) {
4880 last_pkt_err = data;
4881 pkt_err = 0;
4882 ext_attr->reset_pkt_err_acc = false;
4883 }
4884
4885 if (data < last_pkt_err) {
4886 pkt_err += 0xffff - last_pkt_err;
4887 pkt_err += data;
4888 } else {
4889 pkt_err += (data - last_pkt_err);
4890 }
4891 *packet_err = pkt_err;
4892 last_pkt_err = data;
4893
4894 return 0;
4895rw_error:
4896 return rc;
4897}
4898#endif
4899
4900
4901/*============================================================================*/
4902
4903/*
4904* \fn int set_agc_rf ()
4905* \brief Configure RF AGC
4906* \param demod instance of demodulator.
4907* \param agc_settings AGC configuration structure
4908* \return int.
4909*/
4910static int
4911set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
4912{
4913 struct i2c_device_addr *dev_addr = NULL;
4914 struct drxj_data *ext_attr = NULL;
4915 struct drxj_cfg_agc *p_agc_settings = NULL;
4916 struct drx_common_attr *common_attr = NULL;
4917 int rc;
4918 drx_write_reg16func_t scu_wr16 = NULL;
4919 drx_read_reg16func_t scu_rr16 = NULL;
4920
4921 common_attr = (struct drx_common_attr *) demod->my_common_attr;
4922 dev_addr = demod->my_i2c_dev_addr;
4923 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4924
4925 if (atomic) {
4926 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
4927 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
4928 } else {
4929 scu_rr16 = drxj_dap_read_reg16;
4930 scu_wr16 = drxj_dap_write_reg16;
4931 }
4932
4933 /* Configure AGC only if standard is currently active */
4934 if ((ext_attr->standard == agc_settings->standard) ||
4935 (DRXJ_ISQAMSTD(ext_attr->standard) &&
4936 DRXJ_ISQAMSTD(agc_settings->standard)) ||
4937 (DRXJ_ISATVSTD(ext_attr->standard) &&
4938 DRXJ_ISATVSTD(agc_settings->standard))) {
4939 u16 data = 0;
4940
4941 switch (agc_settings->ctrl_mode) {
4942 case DRX_AGC_CTRL_AUTO:
4943
4944 /* Enable RF AGC DAC */
4945 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, data: &data, flags: 0);
4946 if (rc != 0) {
4947 pr_err("error %d\n", rc);
4948 goto rw_error;
4949 }
4950 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
4951 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, flags: 0);
4952 if (rc != 0) {
4953 pr_err("error %d\n", rc);
4954 goto rw_error;
4955 }
4956
4957 /* Enable SCU RF AGC loop */
4958 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
4959 if (rc != 0) {
4960 pr_err("error %d\n", rc);
4961 goto rw_error;
4962 }
4963 data &= ~SCU_RAM_AGC_KI_RF__M;
4964 if (ext_attr->standard == DRX_STANDARD_8VSB)
4965 data |= (2 << SCU_RAM_AGC_KI_RF__B);
4966 else if (DRXJ_ISQAMSTD(ext_attr->standard))
4967 data |= (5 << SCU_RAM_AGC_KI_RF__B);
4968 else
4969 data |= (4 << SCU_RAM_AGC_KI_RF__B);
4970
4971 if (common_attr->tuner_rf_agc_pol)
4972 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
4973 else
4974 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
4975 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
4976 if (rc != 0) {
4977 pr_err("error %d\n", rc);
4978 goto rw_error;
4979 }
4980
4981 /* Set speed ( using complementary reduction value ) */
4982 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
4983 if (rc != 0) {
4984 pr_err("error %d\n", rc);
4985 goto rw_error;
4986 }
4987 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
4988 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);
4989 if (rc != 0) {
4990 pr_err("error %d\n", rc);
4991 goto rw_error;
4992 }
4993
4994 if (agc_settings->standard == DRX_STANDARD_8VSB)
4995 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
4996 else if (DRXJ_ISQAMSTD(agc_settings->standard))
4997 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
4998 else if (DRXJ_ISATVSTD(agc_settings->standard))
4999 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
5000 else
5001 return -EINVAL;
5002
5003 /* Set TOP, only if IF-AGC is in AUTO mode */
5004 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5005 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
5006 if (rc != 0) {
5007 pr_err("error %d\n", rc);
5008 goto rw_error;
5009 }
5010 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
5011 if (rc != 0) {
5012 pr_err("error %d\n", rc);
5013 goto rw_error;
5014 }
5015 }
5016
5017 /* Cut-Off current */
5018 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
5019 if (rc != 0) {
5020 pr_err("error %d\n", rc);
5021 goto rw_error;
5022 }
5023 break;
5024 case DRX_AGC_CTRL_USER:
5025
5026 /* Enable RF AGC DAC */
5027 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, data: &data, flags: 0);
5028 if (rc != 0) {
5029 pr_err("error %d\n", rc);
5030 goto rw_error;
5031 }
5032 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
5033 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, flags: 0);
5034 if (rc != 0) {
5035 pr_err("error %d\n", rc);
5036 goto rw_error;
5037 }
5038
5039 /* Disable SCU RF AGC loop */
5040 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5041 if (rc != 0) {
5042 pr_err("error %d\n", rc);
5043 goto rw_error;
5044 }
5045 data &= ~SCU_RAM_AGC_KI_RF__M;
5046 if (common_attr->tuner_rf_agc_pol)
5047 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
5048 else
5049 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
5050 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5051 if (rc != 0) {
5052 pr_err("error %d\n", rc);
5053 goto rw_error;
5054 }
5055
5056 /* Write value to output pin */
5057 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
5058 if (rc != 0) {
5059 pr_err("error %d\n", rc);
5060 goto rw_error;
5061 }
5062 break;
5063 case DRX_AGC_CTRL_OFF:
5064
5065 /* Disable RF AGC DAC */
5066 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, data: &data, flags: 0);
5067 if (rc != 0) {
5068 pr_err("error %d\n", rc);
5069 goto rw_error;
5070 }
5071 data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
5072 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, flags: 0);
5073 if (rc != 0) {
5074 pr_err("error %d\n", rc);
5075 goto rw_error;
5076 }
5077
5078 /* Disable SCU RF AGC loop */
5079 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5080 if (rc != 0) {
5081 pr_err("error %d\n", rc);
5082 goto rw_error;
5083 }
5084 data &= ~SCU_RAM_AGC_KI_RF__M;
5085 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5086 if (rc != 0) {
5087 pr_err("error %d\n", rc);
5088 goto rw_error;
5089 }
5090 break;
5091 default:
5092 return -EINVAL;
5093 } /* switch ( agcsettings->ctrl_mode ) */
5094 }
5095
5096 /* Store rf agc settings */
5097 switch (agc_settings->standard) {
5098 case DRX_STANDARD_8VSB:
5099 ext_attr->vsb_rf_agc_cfg = *agc_settings;
5100 break;
5101#ifndef DRXJ_VSB_ONLY
5102 case DRX_STANDARD_ITU_A:
5103 case DRX_STANDARD_ITU_B:
5104 case DRX_STANDARD_ITU_C:
5105 ext_attr->qam_rf_agc_cfg = *agc_settings;
5106 break;
5107#endif
5108 default:
5109 return -EIO;
5110 }
5111
5112 return 0;
5113rw_error:
5114 return rc;
5115}
5116
5117/*
5118* \fn int set_agc_if ()
5119* \brief Configure If AGC
5120* \param demod instance of demodulator.
5121* \param agc_settings AGC configuration structure
5122* \return int.
5123*/
5124static int
5125set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
5126{
5127 struct i2c_device_addr *dev_addr = NULL;
5128 struct drxj_data *ext_attr = NULL;
5129 struct drxj_cfg_agc *p_agc_settings = NULL;
5130 struct drx_common_attr *common_attr = NULL;
5131 drx_write_reg16func_t scu_wr16 = NULL;
5132 drx_read_reg16func_t scu_rr16 = NULL;
5133 int rc;
5134
5135 common_attr = (struct drx_common_attr *) demod->my_common_attr;
5136 dev_addr = demod->my_i2c_dev_addr;
5137 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5138
5139 if (atomic) {
5140 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
5141 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
5142 } else {
5143 scu_rr16 = drxj_dap_read_reg16;
5144 scu_wr16 = drxj_dap_write_reg16;
5145 }
5146
5147 /* Configure AGC only if standard is currently active */
5148 if ((ext_attr->standard == agc_settings->standard) ||
5149 (DRXJ_ISQAMSTD(ext_attr->standard) &&
5150 DRXJ_ISQAMSTD(agc_settings->standard)) ||
5151 (DRXJ_ISATVSTD(ext_attr->standard) &&
5152 DRXJ_ISATVSTD(agc_settings->standard))) {
5153 u16 data = 0;
5154
5155 switch (agc_settings->ctrl_mode) {
5156 case DRX_AGC_CTRL_AUTO:
5157 /* Enable IF AGC DAC */
5158 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, data: &data, flags: 0);
5159 if (rc != 0) {
5160 pr_err("error %d\n", rc);
5161 goto rw_error;
5162 }
5163 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5164 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, flags: 0);
5165 if (rc != 0) {
5166 pr_err("error %d\n", rc);
5167 goto rw_error;
5168 }
5169
5170 /* Enable SCU IF AGC loop */
5171 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5172 if (rc != 0) {
5173 pr_err("error %d\n", rc);
5174 goto rw_error;
5175 }
5176 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5177 data &= ~SCU_RAM_AGC_KI_IF__M;
5178 if (ext_attr->standard == DRX_STANDARD_8VSB)
5179 data |= (3 << SCU_RAM_AGC_KI_IF__B);
5180 else if (DRXJ_ISQAMSTD(ext_attr->standard))
5181 data |= (6 << SCU_RAM_AGC_KI_IF__B);
5182 else
5183 data |= (5 << SCU_RAM_AGC_KI_IF__B);
5184
5185 if (common_attr->tuner_if_agc_pol)
5186 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5187 else
5188 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5189 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5190 if (rc != 0) {
5191 pr_err("error %d\n", rc);
5192 goto rw_error;
5193 }
5194
5195 /* Set speed (using complementary reduction value) */
5196 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
5197 if (rc != 0) {
5198 pr_err("error %d\n", rc);
5199 goto rw_error;
5200 }
5201 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
5202 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);
5203 if (rc != 0) {
5204 pr_err("error %d\n", rc);
5205 goto rw_error;
5206 }
5207
5208 if (agc_settings->standard == DRX_STANDARD_8VSB)
5209 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
5210 else if (DRXJ_ISQAMSTD(agc_settings->standard))
5211 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
5212 else if (DRXJ_ISATVSTD(agc_settings->standard))
5213 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
5214 else
5215 return -EINVAL;
5216
5217 /* Restore TOP */
5218 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5219 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
5220 if (rc != 0) {
5221 pr_err("error %d\n", rc);
5222 goto rw_error;
5223 }
5224 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
5225 if (rc != 0) {
5226 pr_err("error %d\n", rc);
5227 goto rw_error;
5228 }
5229 } else {
5230 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
5231 if (rc != 0) {
5232 pr_err("error %d\n", rc);
5233 goto rw_error;
5234 }
5235 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
5236 if (rc != 0) {
5237 pr_err("error %d\n", rc);
5238 goto rw_error;
5239 }
5240 }
5241 break;
5242
5243 case DRX_AGC_CTRL_USER:
5244
5245 /* Enable IF AGC DAC */
5246 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, data: &data, flags: 0);
5247 if (rc != 0) {
5248 pr_err("error %d\n", rc);
5249 goto rw_error;
5250 }
5251 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5252 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, flags: 0);
5253 if (rc != 0) {
5254 pr_err("error %d\n", rc);
5255 goto rw_error;
5256 }
5257
5258 /* Disable SCU IF AGC loop */
5259 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5260 if (rc != 0) {
5261 pr_err("error %d\n", rc);
5262 goto rw_error;
5263 }
5264 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5265 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5266 if (common_attr->tuner_if_agc_pol)
5267 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5268 else
5269 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5270 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5271 if (rc != 0) {
5272 pr_err("error %d\n", rc);
5273 goto rw_error;
5274 }
5275
5276 /* Write value to output pin */
5277 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
5278 if (rc != 0) {
5279 pr_err("error %d\n", rc);
5280 goto rw_error;
5281 }
5282 break;
5283
5284 case DRX_AGC_CTRL_OFF:
5285
5286 /* Disable If AGC DAC */
5287 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, data: &data, flags: 0);
5288 if (rc != 0) {
5289 pr_err("error %d\n", rc);
5290 goto rw_error;
5291 }
5292 data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
5293 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, flags: 0);
5294 if (rc != 0) {
5295 pr_err("error %d\n", rc);
5296 goto rw_error;
5297 }
5298
5299 /* Disable SCU IF AGC loop */
5300 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5301 if (rc != 0) {
5302 pr_err("error %d\n", rc);
5303 goto rw_error;
5304 }
5305 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5306 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5307 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5308 if (rc != 0) {
5309 pr_err("error %d\n", rc);
5310 goto rw_error;
5311 }
5312 break;
5313 default:
5314 return -EINVAL;
5315 } /* switch ( agcsettings->ctrl_mode ) */
5316
5317 /* always set the top to support configurations without if-loop */
5318 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
5319 if (rc != 0) {
5320 pr_err("error %d\n", rc);
5321 goto rw_error;
5322 }
5323 }
5324
5325 /* Store if agc settings */
5326 switch (agc_settings->standard) {
5327 case DRX_STANDARD_8VSB:
5328 ext_attr->vsb_if_agc_cfg = *agc_settings;
5329 break;
5330#ifndef DRXJ_VSB_ONLY
5331 case DRX_STANDARD_ITU_A:
5332 case DRX_STANDARD_ITU_B:
5333 case DRX_STANDARD_ITU_C:
5334 ext_attr->qam_if_agc_cfg = *agc_settings;
5335 break;
5336#endif
5337 default:
5338 return -EIO;
5339 }
5340
5341 return 0;
5342rw_error:
5343 return rc;
5344}
5345
5346/*
5347* \fn int set_iqm_af ()
5348* \brief Configure IQM AF registers
5349* \param demod instance of demodulator.
5350* \param active
5351* \return int.
5352*/
5353static int set_iqm_af(struct drx_demod_instance *demod, bool active)
5354{
5355 u16 data = 0;
5356 struct i2c_device_addr *dev_addr = NULL;
5357 int rc;
5358
5359 dev_addr = demod->my_i2c_dev_addr;
5360
5361 /* Configure IQM */
5362 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, data: &data, flags: 0);
5363 if (rc != 0) {
5364 pr_err("error %d\n", rc);
5365 goto rw_error;
5366 }
5367 if (!active)
5368 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));
5369 else
5370 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);
5371 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, flags: 0);
5372 if (rc != 0) {
5373 pr_err("error %d\n", rc);
5374 goto rw_error;
5375 }
5376
5377 return 0;
5378rw_error:
5379 return rc;
5380}
5381
5382/*============================================================================*/
5383/*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5384/*============================================================================*/
5385
5386/*============================================================================*/
5387/*============================================================================*/
5388/*== 8VSB DATAPATH FUNCTIONS ==*/
5389/*============================================================================*/
5390/*============================================================================*/
5391
5392/*
5393* \fn int power_down_vsb ()
5394* \brief Powr down QAM related blocks.
5395* \param demod instance of demodulator.
5396* \param channel pointer to channel data.
5397* \return int.
5398*/
5399static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
5400{
5401 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5402 struct drxjscu_cmd cmd_scu = { /* command */ 0,
5403 /* parameter_len */ 0,
5404 /* result_len */ 0,
5405 /* *parameter */ NULL,
5406 /* *result */ NULL
5407 };
5408 struct drx_cfg_mpeg_output cfg_mpeg_output;
5409 int rc;
5410 u16 cmd_result = 0;
5411
5412 /*
5413 STOP demodulator
5414 reset of FEC and VSB HW
5415 */
5416 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
5417 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
5418 cmd_scu.parameter_len = 0;
5419 cmd_scu.result_len = 1;
5420 cmd_scu.parameter = NULL;
5421 cmd_scu.result = &cmd_result;
5422 rc = scu_command(dev_addr, cmd: &cmd_scu);
5423 if (rc != 0) {
5424 pr_err("error %d\n", rc);
5425 goto rw_error;
5426 }
5427
5428 /* stop all comm_exec */
5429 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, flags: 0);
5430 if (rc != 0) {
5431 pr_err("error %d\n", rc);
5432 goto rw_error;
5433 }
5434 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, flags: 0);
5435 if (rc != 0) {
5436 pr_err("error %d\n", rc);
5437 goto rw_error;
5438 }
5439 if (primary) {
5440 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, flags: 0);
5441 if (rc != 0) {
5442 pr_err("error %d\n", rc);
5443 goto rw_error;
5444 }
5445 rc = set_iqm_af(demod, active: false);
5446 if (rc != 0) {
5447 pr_err("error %d\n", rc);
5448 goto rw_error;
5449 }
5450 } else {
5451 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, flags: 0);
5452 if (rc != 0) {
5453 pr_err("error %d\n", rc);
5454 goto rw_error;
5455 }
5456 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, flags: 0);
5457 if (rc != 0) {
5458 pr_err("error %d\n", rc);
5459 goto rw_error;
5460 }
5461 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, flags: 0);
5462 if (rc != 0) {
5463 pr_err("error %d\n", rc);
5464 goto rw_error;
5465 }
5466 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, flags: 0);
5467 if (rc != 0) {
5468 pr_err("error %d\n", rc);
5469 goto rw_error;
5470 }
5471 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, flags: 0);
5472 if (rc != 0) {
5473 pr_err("error %d\n", rc);
5474 goto rw_error;
5475 }
5476 }
5477
5478 cfg_mpeg_output.enable_mpeg_output = false;
5479 rc = ctrl_set_cfg_mpeg_output(demod, cfg_data: &cfg_mpeg_output);
5480 if (rc != 0) {
5481 pr_err("error %d\n", rc);
5482 goto rw_error;
5483 }
5484
5485 return 0;
5486rw_error:
5487 return rc;
5488}
5489
5490/*
5491* \fn int set_vsb_leak_n_gain ()
5492* \brief Set ATSC demod.
5493* \param demod instance of demodulator.
5494* \return int.
5495*/
5496static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
5497{
5498 struct i2c_device_addr *dev_addr = NULL;
5499 int rc;
5500
5501 static const u8 vsb_ffe_leak_gain_ram0[] = {
5502 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
5503 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
5504 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
5505 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
5506 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
5507 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
5508 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
5509 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
5510 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
5511 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
5512 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
5513 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
5514 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
5515 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
5516 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
5517 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
5518 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
5519 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
5520 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
5521 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
5522 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
5523 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
5524 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
5525 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
5526 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
5527 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
5528 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
5529 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
5530 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
5531 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
5532 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
5533 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
5534 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
5535 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
5536 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
5537 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
5538 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
5539 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
5540 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
5541 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
5542 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
5543 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
5544 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
5545 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
5546 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
5547 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
5548 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
5549 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
5550 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
5551 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
5552 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
5553 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
5554 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
5555 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
5556 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
5557 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
5558 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
5559 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
5560 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
5561 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
5562 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
5563 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
5564 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
5565 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
5566 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
5567 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
5568 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
5569 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
5570 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
5571 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
5572 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
5573 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
5574 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
5575 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
5576 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
5577 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
5578 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
5579 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
5580 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
5581 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
5582 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
5583 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
5584 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
5585 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
5586 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
5587 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
5588 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
5589 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
5590 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
5591 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
5592 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
5593 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
5594 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
5595 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
5596 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
5597 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
5598 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
5599 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
5600 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
5601 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
5602 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
5603 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
5604 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
5605 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
5606 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
5607 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
5608 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
5609 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
5610 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
5611 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
5612 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
5613 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
5614 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
5615 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
5616 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
5617 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
5618 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
5619 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
5620 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
5621 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
5622 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
5623 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
5624 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
5625 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
5626 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
5627 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
5628 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
5629 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
5630 };
5631
5632 static const u8 vsb_ffe_leak_gain_ram1[] = {
5633 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
5634 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
5635 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
5636 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
5637 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
5638 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
5639 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
5640 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
5641 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
5642 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
5643 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
5644 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
5645 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
5646 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
5647 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
5648 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
5649 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
5650 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
5651 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
5652 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
5653 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
5654 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
5655 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
5656 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
5657 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
5658 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
5659 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
5660 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
5661 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
5662 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
5663 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
5664 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
5665 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
5666 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
5667 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
5668 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
5669 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
5670 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
5671 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
5672 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
5673 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
5674 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
5675 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
5676 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
5677 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
5678 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
5679 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
5680 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
5681 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
5682 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
5683 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
5684 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
5685 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
5686 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
5687 };
5688
5689 dev_addr = demod->my_i2c_dev_addr;
5690 rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, datasize: sizeof(vsb_ffe_leak_gain_ram0), data: ((u8 *)vsb_ffe_leak_gain_ram0), flags: 0);
5691 if (rc != 0) {
5692 pr_err("error %d\n", rc);
5693 goto rw_error;
5694 }
5695 rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, datasize: sizeof(vsb_ffe_leak_gain_ram1), data: ((u8 *)vsb_ffe_leak_gain_ram1), flags: 0);
5696 if (rc != 0) {
5697 pr_err("error %d\n", rc);
5698 goto rw_error;
5699 }
5700
5701 return 0;
5702rw_error:
5703 return rc;
5704}
5705
5706/*
5707* \fn int set_vsb()
5708* \brief Set 8VSB demod.
5709* \param demod instance of demodulator.
5710* \return int.
5711*
5712*/
5713static int set_vsb(struct drx_demod_instance *demod)
5714{
5715 struct i2c_device_addr *dev_addr = NULL;
5716 int rc;
5717 struct drx_common_attr *common_attr = NULL;
5718 struct drxjscu_cmd cmd_scu;
5719 struct drxj_data *ext_attr = NULL;
5720 u16 cmd_result = 0;
5721 u16 cmd_param = 0;
5722 static const u8 vsb_taps_re[] = {
5723 DRXJ_16TO8(-2), /* re0 */
5724 DRXJ_16TO8(4), /* re1 */
5725 DRXJ_16TO8(1), /* re2 */
5726 DRXJ_16TO8(-4), /* re3 */
5727 DRXJ_16TO8(1), /* re4 */
5728 DRXJ_16TO8(4), /* re5 */
5729 DRXJ_16TO8(-3), /* re6 */
5730 DRXJ_16TO8(-3), /* re7 */
5731 DRXJ_16TO8(6), /* re8 */
5732 DRXJ_16TO8(1), /* re9 */
5733 DRXJ_16TO8(-9), /* re10 */
5734 DRXJ_16TO8(3), /* re11 */
5735 DRXJ_16TO8(12), /* re12 */
5736 DRXJ_16TO8(-9), /* re13 */
5737 DRXJ_16TO8(-15), /* re14 */
5738 DRXJ_16TO8(17), /* re15 */
5739 DRXJ_16TO8(19), /* re16 */
5740 DRXJ_16TO8(-29), /* re17 */
5741 DRXJ_16TO8(-22), /* re18 */
5742 DRXJ_16TO8(45), /* re19 */
5743 DRXJ_16TO8(25), /* re20 */
5744 DRXJ_16TO8(-70), /* re21 */
5745 DRXJ_16TO8(-28), /* re22 */
5746 DRXJ_16TO8(111), /* re23 */
5747 DRXJ_16TO8(30), /* re24 */
5748 DRXJ_16TO8(-201), /* re25 */
5749 DRXJ_16TO8(-31), /* re26 */
5750 DRXJ_16TO8(629) /* re27 */
5751 };
5752
5753 dev_addr = demod->my_i2c_dev_addr;
5754 common_attr = (struct drx_common_attr *) demod->my_common_attr;
5755 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5756
5757 /* stop all comm_exec */
5758 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, flags: 0);
5759 if (rc != 0) {
5760 pr_err("error %d\n", rc);
5761 goto rw_error;
5762 }
5763 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, flags: 0);
5764 if (rc != 0) {
5765 pr_err("error %d\n", rc);
5766 goto rw_error;
5767 }
5768 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, flags: 0);
5769 if (rc != 0) {
5770 pr_err("error %d\n", rc);
5771 goto rw_error;
5772 }
5773 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, flags: 0);
5774 if (rc != 0) {
5775 pr_err("error %d\n", rc);
5776 goto rw_error;
5777 }
5778 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, flags: 0);
5779 if (rc != 0) {
5780 pr_err("error %d\n", rc);
5781 goto rw_error;
5782 }
5783 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, flags: 0);
5784 if (rc != 0) {
5785 pr_err("error %d\n", rc);
5786 goto rw_error;
5787 }
5788 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, flags: 0);
5789 if (rc != 0) {
5790 pr_err("error %d\n", rc);
5791 goto rw_error;
5792 }
5793
5794 /* reset demodulator */
5795 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
5796 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
5797 cmd_scu.parameter_len = 0;
5798 cmd_scu.result_len = 1;
5799 cmd_scu.parameter = NULL;
5800 cmd_scu.result = &cmd_result;
5801 rc = scu_command(dev_addr, cmd: &cmd_scu);
5802 if (rc != 0) {
5803 pr_err("error %d\n", rc);
5804 goto rw_error;
5805 }
5806
5807 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, data: 1, flags: 0);
5808 if (rc != 0) {
5809 pr_err("error %d\n", rc);
5810 goto rw_error;
5811 }
5812 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, flags: 0);
5813 if (rc != 0) {
5814 pr_err("error %d\n", rc);
5815 goto rw_error;
5816 }
5817 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, flags: 0);
5818 if (rc != 0) {
5819 pr_err("error %d\n", rc);
5820 goto rw_error;
5821 }
5822 ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
5823 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, data: ext_attr->iqm_rc_rate_ofs, flags: 0);
5824 if (rc != 0) {
5825 pr_err("error %d\n", rc);
5826 goto rw_error;
5827 }
5828 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, data: 4, flags: 0);
5829 if (rc != 0) {
5830 pr_err("error %d\n", rc);
5831 goto rw_error;
5832 }
5833 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, data: 1, flags: 0);
5834 if (rc != 0) {
5835 pr_err("error %d\n", rc);
5836 goto rw_error;
5837 }
5838
5839 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, data: 1, flags: 0);
5840 if (rc != 0) {
5841 pr_err("error %d\n", rc);
5842 goto rw_error;
5843 }
5844 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, data: 28, flags: 0);
5845 if (rc != 0) {
5846 pr_err("error %d\n", rc);
5847 goto rw_error;
5848 }
5849 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, data: 0, flags: 0);
5850 if (rc != 0) {
5851 pr_err("error %d\n", rc);
5852 goto rw_error;
5853 }
5854 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, data: 0, flags: 0);
5855 if (rc != 0) {
5856 pr_err("error %d\n", rc);
5857 goto rw_error;
5858 }
5859 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, data: 3, flags: 0);
5860 if (rc != 0) {
5861 pr_err("error %d\n", rc);
5862 goto rw_error;
5863 }
5864 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, flags: 0);
5865 if (rc != 0) {
5866 pr_err("error %d\n", rc);
5867 goto rw_error;
5868 }
5869 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, data: 1393, flags: 0);
5870 if (rc != 0) {
5871 pr_err("error %d\n", rc);
5872 goto rw_error;
5873 }
5874 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, data: 0, flags: 0);
5875 if (rc != 0) {
5876 pr_err("error %d\n", rc);
5877 goto rw_error;
5878 }
5879 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, data: 1, flags: 0);
5880 if (rc != 0) {
5881 pr_err("error %d\n", rc);
5882 goto rw_error;
5883 }
5884
5885 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, datasize: sizeof(vsb_taps_re), data: ((u8 *)vsb_taps_re), flags: 0);
5886 if (rc != 0) {
5887 pr_err("error %d\n", rc);
5888 goto rw_error;
5889 }
5890 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, datasize: sizeof(vsb_taps_re), data: ((u8 *)vsb_taps_re), flags: 0);
5891 if (rc != 0) {
5892 pr_err("error %d\n", rc);
5893 goto rw_error;
5894 }
5895
5896 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, data: 330, flags: 0);
5897 if (rc != 0) {
5898 pr_err("error %d\n", rc);
5899 goto rw_error;
5900 } /* set higher threshold */
5901 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, data: 90, flags: 0);
5902 if (rc != 0) {
5903 pr_err("error %d\n", rc);
5904 goto rw_error;
5905 } /* burst detection on */
5906 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, data: 0x0042, flags: 0);
5907 if (rc != 0) {
5908 pr_err("error %d\n", rc);
5909 goto rw_error;
5910 } /* drop thresholds by 1 dB */
5911 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, data: 0x0053, flags: 0);
5912 if (rc != 0) {
5913 pr_err("error %d\n", rc);
5914 goto rw_error;
5915 } /* drop thresholds by 2 dB */
5916 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, data: 0x1, flags: 0);
5917 if (rc != 0) {
5918 pr_err("error %d\n", rc);
5919 goto rw_error;
5920 } /* cma on */
5921 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, data: 0, flags: 0);
5922 if (rc != 0) {
5923 pr_err("error %d\n", rc);
5924 goto rw_error;
5925 } /* GPIO */
5926
5927 /* Initialize the FEC Subsystem */
5928 rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, flags: 0);
5929 if (rc != 0) {
5930 pr_err("error %d\n", rc);
5931 goto rw_error;
5932 }
5933 {
5934 u16 fec_oc_snc_mode = 0;
5935 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, data: &fec_oc_snc_mode, flags: 0);
5936 if (rc != 0) {
5937 pr_err("error %d\n", rc);
5938 goto rw_error;
5939 }
5940 /* output data even when not locked */
5941 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, data: fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, flags: 0);
5942 if (rc != 0) {
5943 pr_err("error %d\n", rc);
5944 goto rw_error;
5945 }
5946 }
5947
5948 /* set clip */
5949 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, data: 0, flags: 0);
5950 if (rc != 0) {
5951 pr_err("error %d\n", rc);
5952 goto rw_error;
5953 }
5954 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, data: 470, flags: 0);
5955 if (rc != 0) {
5956 pr_err("error %d\n", rc);
5957 goto rw_error;
5958 }
5959 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, data: 0, flags: 0);
5960 if (rc != 0) {
5961 pr_err("error %d\n", rc);
5962 goto rw_error;
5963 }
5964 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, data: 0xD4, flags: 0);
5965 if (rc != 0) {
5966 pr_err("error %d\n", rc);
5967 goto rw_error;
5968 }
5969 /* no transparent, no A&C framing; parity is set in mpegoutput */
5970 {
5971 u16 fec_oc_reg_mode = 0;
5972 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, data: &fec_oc_reg_mode, flags: 0);
5973 if (rc != 0) {
5974 pr_err("error %d\n", rc);
5975 goto rw_error;
5976 }
5977 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, data: fec_oc_reg_mode & (~(FEC_OC_MODE_TRANSPARENT__M | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)), flags: 0);
5978 if (rc != 0) {
5979 pr_err("error %d\n", rc);
5980 goto rw_error;
5981 }
5982 }
5983
5984 rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, data: 0, flags: 0);
5985 if (rc != 0) {
5986 pr_err("error %d\n", rc);
5987 goto rw_error;
5988 } /* timeout counter for restarting */
5989 rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, data: 3, flags: 0);
5990 if (rc != 0) {
5991 pr_err("error %d\n", rc);
5992 goto rw_error;
5993 }
5994 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, data: 0, flags: 0);
5995 if (rc != 0) {
5996 pr_err("error %d\n", rc);
5997 goto rw_error;
5998 } /* bypass disabled */
5999 /* initialize RS packet error measurement parameters */
6000 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, flags: 0);
6001 if (rc != 0) {
6002 pr_err("error %d\n", rc);
6003 goto rw_error;
6004 }
6005 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, flags: 0);
6006 if (rc != 0) {
6007 pr_err("error %d\n", rc);
6008 goto rw_error;
6009 }
6010
6011 /* init measurement period of MER/SER */
6012 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, flags: 0);
6013 if (rc != 0) {
6014 pr_err("error %d\n", rc);
6015 goto rw_error;
6016 }
6017 rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, data: 0, flags: 0);
6018 if (rc != 0) {
6019 pr_err("error %d\n", rc);
6020 goto rw_error;
6021 }
6022 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, data: 0, flags: 0);
6023 if (rc != 0) {
6024 pr_err("error %d\n", rc);
6025 goto rw_error;
6026 }
6027 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, data: 0, flags: 0);
6028 if (rc != 0) {
6029 pr_err("error %d\n", rc);
6030 goto rw_error;
6031 }
6032
6033 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, data: 128, flags: 0);
6034 if (rc != 0) {
6035 pr_err("error %d\n", rc);
6036 goto rw_error;
6037 }
6038 /* B-Input to ADC, PGA+filter in standby */
6039 if (!ext_attr->has_lna) {
6040 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, data: 0x02, flags: 0);
6041 if (rc != 0) {
6042 pr_err("error %d\n", rc);
6043 goto rw_error;
6044 }
6045 }
6046
6047 /* turn on IQMAF. It has to be in front of setAgc**() */
6048 rc = set_iqm_af(demod, active: true);
6049 if (rc != 0) {
6050 pr_err("error %d\n", rc);
6051 goto rw_error;
6052 }
6053 rc = adc_synchronization(demod);
6054 if (rc != 0) {
6055 pr_err("error %d\n", rc);
6056 goto rw_error;
6057 }
6058
6059 rc = init_agc(demod);
6060 if (rc != 0) {
6061 pr_err("error %d\n", rc);
6062 goto rw_error;
6063 }
6064 rc = set_agc_if(demod, agc_settings: &(ext_attr->vsb_if_agc_cfg), atomic: false);
6065 if (rc != 0) {
6066 pr_err("error %d\n", rc);
6067 goto rw_error;
6068 }
6069 rc = set_agc_rf(demod, agc_settings: &(ext_attr->vsb_rf_agc_cfg), atomic: false);
6070 if (rc != 0) {
6071 pr_err("error %d\n", rc);
6072 goto rw_error;
6073 }
6074 {
6075 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
6076 of only the gain */
6077 struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
6078
6079 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
6080 rc = ctrl_set_cfg_afe_gain(demod, afe_gain: &vsb_pga_cfg);
6081 if (rc != 0) {
6082 pr_err("error %d\n", rc);
6083 goto rw_error;
6084 }
6085 }
6086 rc = ctrl_set_cfg_pre_saw(demod, pre_saw: &(ext_attr->vsb_pre_saw_cfg));
6087 if (rc != 0) {
6088 pr_err("error %d\n", rc);
6089 goto rw_error;
6090 }
6091
6092 /* Mpeg output has to be in front of FEC active */
6093 rc = set_mpegtei_handling(demod);
6094 if (rc != 0) {
6095 pr_err("error %d\n", rc);
6096 goto rw_error;
6097 }
6098 rc = bit_reverse_mpeg_output(demod);
6099 if (rc != 0) {
6100 pr_err("error %d\n", rc);
6101 goto rw_error;
6102 }
6103 rc = set_mpeg_start_width(demod);
6104 if (rc != 0) {
6105 pr_err("error %d\n", rc);
6106 goto rw_error;
6107 }
6108 {
6109 /* TODO: move to set_standard after hardware reset value problem is solved */
6110 /* Configure initial MPEG output */
6111 struct drx_cfg_mpeg_output cfg_mpeg_output;
6112
6113 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
6114 cfg_mpeg_output.enable_mpeg_output = true;
6115
6116 rc = ctrl_set_cfg_mpeg_output(demod, cfg_data: &cfg_mpeg_output);
6117 if (rc != 0) {
6118 pr_err("error %d\n", rc);
6119 goto rw_error;
6120 }
6121 }
6122
6123 /* TBD: what parameters should be set */
6124 cmd_param = 0x00; /* Default mode AGC on, etc */
6125 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6126 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
6127 cmd_scu.parameter_len = 1;
6128 cmd_scu.result_len = 1;
6129 cmd_scu.parameter = &cmd_param;
6130 cmd_scu.result = &cmd_result;
6131 rc = scu_command(dev_addr, cmd: &cmd_scu);
6132 if (rc != 0) {
6133 pr_err("error %d\n", rc);
6134 goto rw_error;
6135 }
6136
6137 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, data: 0x0004, flags: 0);
6138 if (rc != 0) {
6139 pr_err("error %d\n", rc);
6140 goto rw_error;
6141 }
6142 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, data: 0x00D2, flags: 0);
6143 if (rc != 0) {
6144 pr_err("error %d\n", rc);
6145 goto rw_error;
6146 }
6147 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, flags: 0);
6148 if (rc != 0) {
6149 pr_err("error %d\n", rc);
6150 goto rw_error;
6151 }
6152 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, data: 0x142, flags: 0);
6153 if (rc != 0) {
6154 pr_err("error %d\n", rc);
6155 goto rw_error;
6156 }
6157 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, data: 640, flags: 0);
6158 if (rc != 0) {
6159 pr_err("error %d\n", rc);
6160 goto rw_error;
6161 }
6162 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, data: 4, flags: 0);
6163 if (rc != 0) {
6164 pr_err("error %d\n", rc);
6165 goto rw_error;
6166 }
6167 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, data: 2, flags: 0);
6168 if (rc != 0) {
6169 pr_err("error %d\n", rc);
6170 goto rw_error;
6171 }
6172 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, data: 3, flags: 0);
6173 if (rc != 0) {
6174 pr_err("error %d\n", rc);
6175 goto rw_error;
6176 }
6177
6178 /* start demodulator */
6179 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6180 | SCU_RAM_COMMAND_CMD_DEMOD_START;
6181 cmd_scu.parameter_len = 0;
6182 cmd_scu.result_len = 1;
6183 cmd_scu.parameter = NULL;
6184 cmd_scu.result = &cmd_result;
6185 rc = scu_command(dev_addr, cmd: &cmd_scu);
6186 if (rc != 0) {
6187 pr_err("error %d\n", rc);
6188 goto rw_error;
6189 }
6190
6191 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, flags: 0);
6192 if (rc != 0) {
6193 pr_err("error %d\n", rc);
6194 goto rw_error;
6195 }
6196 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, flags: 0);
6197 if (rc != 0) {
6198 pr_err("error %d\n", rc);
6199 goto rw_error;
6200 }
6201 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, flags: 0);
6202 if (rc != 0) {
6203 pr_err("error %d\n", rc);
6204 goto rw_error;
6205 }
6206
6207 return 0;
6208rw_error:
6209 return rc;
6210}
6211
6212/*
6213* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
6214* \brief Get the values of packet error in 8VSB mode
6215* \return Error code
6216*/
6217static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
6218 u32 *pck_errs, u32 *pck_count)
6219{
6220 int rc;
6221 u16 data = 0;
6222 u16 period = 0;
6223 u16 prescale = 0;
6224 u16 packet_errors_mant = 0;
6225 u16 packet_errors_exp = 0;
6226
6227 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, data: &data, flags: 0);
6228 if (rc != 0) {
6229 pr_err("error %d\n", rc);
6230 goto rw_error;
6231 }
6232 packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
6233 packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
6234 >> FEC_RS_NR_FAILURES_EXP__B;
6235 period = FEC_RS_MEASUREMENT_PERIOD;
6236 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6237 /* packet error rate = (error packet number) per second */
6238 /* 77.3 us is time for per packet */
6239 if (period * prescale == 0) {
6240 pr_err("error: period and/or prescale is zero!\n");
6241 return -EIO;
6242 }
6243 *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
6244 *pck_count = period * prescale * 77;
6245
6246 return 0;
6247rw_error:
6248 return rc;
6249}
6250
6251/*
6252* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
6253* \brief Get the values of ber in VSB mode
6254* \return Error code
6255*/
6256static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
6257 u32 *ber, u32 *cnt)
6258{
6259 int rc;
6260 u16 data = 0;
6261 u16 period = 0;
6262 u16 prescale = 0;
6263 u16 bit_errors_mant = 0;
6264 u16 bit_errors_exp = 0;
6265
6266 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, data: &data, flags: 0);
6267 if (rc != 0) {
6268 pr_err("error %d\n", rc);
6269 goto rw_error;
6270 }
6271 period = FEC_RS_MEASUREMENT_PERIOD;
6272 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6273
6274 bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
6275 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
6276 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
6277
6278 *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
6279
6280 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
6281 *ber = (*cnt) * 26570;
6282 else {
6283 if (period * prescale == 0) {
6284 pr_err("error: period and/or prescale is zero!\n");
6285 return -EIO;
6286 }
6287 *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
6288 (bit_errors_exp - 3) : bit_errors_exp);
6289 }
6290
6291 return 0;
6292rw_error:
6293 return rc;
6294}
6295
6296/*
6297* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
6298* \brief Get the values of ber in VSB mode
6299* \return Error code
6300*/
6301static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
6302 u32 *ber, u32 *cnt)
6303{
6304 u16 data = 0;
6305 int rc;
6306
6307 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, data: &data, flags: 0);
6308 if (rc != 0) {
6309 pr_err("error %d\n", rc);
6310 return -EIO;
6311 }
6312 *ber = data;
6313 *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
6314
6315 return 0;
6316}
6317
6318/*
6319* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6320* \brief Get the values of MER
6321* \return Error code
6322*/
6323static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6324{
6325 int rc;
6326 u16 data_hi = 0;
6327
6328 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, data: &data_hi, flags: 0);
6329 if (rc != 0) {
6330 pr_err("error %d\n", rc);
6331 goto rw_error;
6332 }
6333 *mer =
6334 (u16) (log1_times100(x: 21504) - log1_times100(x: (data_hi << 6) / 52));
6335
6336 return 0;
6337rw_error:
6338 return rc;
6339}
6340
6341
6342/*============================================================================*/
6343/*== END 8VSB DATAPATH FUNCTIONS ==*/
6344/*============================================================================*/
6345
6346/*============================================================================*/
6347/*============================================================================*/
6348/*== QAM DATAPATH FUNCTIONS ==*/
6349/*============================================================================*/
6350/*============================================================================*/
6351
6352/*
6353* \fn int power_down_qam ()
6354* \brief Powr down QAM related blocks.
6355* \param demod instance of demodulator.
6356* \param channel pointer to channel data.
6357* \return int.
6358*/
6359static int power_down_qam(struct drx_demod_instance *demod, bool primary)
6360{
6361 struct drxjscu_cmd cmd_scu = { /* command */ 0,
6362 /* parameter_len */ 0,
6363 /* result_len */ 0,
6364 /* *parameter */ NULL,
6365 /* *result */ NULL
6366 };
6367 int rc;
6368 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6369 struct drx_cfg_mpeg_output cfg_mpeg_output;
6370 struct drx_common_attr *common_attr = demod->my_common_attr;
6371 u16 cmd_result = 0;
6372
6373 /*
6374 STOP demodulator
6375 resets IQM, QAM and FEC HW blocks
6376 */
6377 /* stop all comm_exec */
6378 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, flags: 0);
6379 if (rc != 0) {
6380 pr_err("error %d\n", rc);
6381 goto rw_error;
6382 }
6383 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, flags: 0);
6384 if (rc != 0) {
6385 pr_err("error %d\n", rc);
6386 goto rw_error;
6387 }
6388
6389 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
6390 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6391 cmd_scu.parameter_len = 0;
6392 cmd_scu.result_len = 1;
6393 cmd_scu.parameter = NULL;
6394 cmd_scu.result = &cmd_result;
6395 rc = scu_command(dev_addr, cmd: &cmd_scu);
6396 if (rc != 0) {
6397 pr_err("error %d\n", rc);
6398 goto rw_error;
6399 }
6400
6401 if (primary) {
6402 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, flags: 0);
6403 if (rc != 0) {
6404 pr_err("error %d\n", rc);
6405 goto rw_error;
6406 }
6407 rc = set_iqm_af(demod, active: false);
6408 if (rc != 0) {
6409 pr_err("error %d\n", rc);
6410 goto rw_error;
6411 }
6412 } else {
6413 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, flags: 0);
6414 if (rc != 0) {
6415 pr_err("error %d\n", rc);
6416 goto rw_error;
6417 }
6418 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, flags: 0);
6419 if (rc != 0) {
6420 pr_err("error %d\n", rc);
6421 goto rw_error;
6422 }
6423 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, flags: 0);
6424 if (rc != 0) {
6425 pr_err("error %d\n", rc);
6426 goto rw_error;
6427 }
6428 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, flags: 0);
6429 if (rc != 0) {
6430 pr_err("error %d\n", rc);
6431 goto rw_error;
6432 }
6433 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, flags: 0);
6434 if (rc != 0) {
6435 pr_err("error %d\n", rc);
6436 goto rw_error;
6437 }
6438 }
6439
6440 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
6441 cfg_mpeg_output.enable_mpeg_output = false;
6442
6443 rc = ctrl_set_cfg_mpeg_output(demod, cfg_data: &cfg_mpeg_output);
6444 if (rc != 0) {
6445 pr_err("error %d\n", rc);
6446 goto rw_error;
6447 }
6448
6449 return 0;
6450rw_error:
6451 return rc;
6452}
6453
6454/*============================================================================*/
6455
6456/*
6457* \fn int set_qam_measurement ()
6458* \brief Setup of the QAM Measuremnt intervals for signal quality
6459* \param demod instance of demod.
6460* \param constellation current constellation.
6461* \return int.
6462*
6463* NOTE:
6464* Take into account that for certain settings the errorcounters can overflow.
6465* The implementation does not check this.
6466*
6467* TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
6468* constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
6469* field ?
6470*
6471*/
6472#ifndef DRXJ_VSB_ONLY
6473static int
6474set_qam_measurement(struct drx_demod_instance *demod,
6475 enum drx_modulation constellation, u32 symbol_rate)
6476{
6477 struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */
6478 struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specific data */
6479 int rc;
6480 u32 fec_bits_desired = 0; /* BER accounting period */
6481 u16 fec_rs_plen = 0; /* defines RS BER measurement period */
6482 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
6483 u32 fec_rs_period = 0; /* Value for corresponding I2C register */
6484 u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
6485 u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
6486 u32 qam_vd_period = 0; /* Value for corresponding I2C register */
6487 u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
6488 u16 fec_vd_plen = 0; /* no of trellis symbols: VD SER measur period */
6489 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
6490
6491 dev_addr = demod->my_i2c_dev_addr;
6492 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6493
6494 fec_bits_desired = ext_attr->fec_bits_desired;
6495 fec_rs_prescale = ext_attr->fec_rs_prescale;
6496
6497 switch (constellation) {
6498 case DRX_CONSTELLATION_QAM16:
6499 fec_bits_desired = 4 * symbol_rate;
6500 break;
6501 case DRX_CONSTELLATION_QAM32:
6502 fec_bits_desired = 5 * symbol_rate;
6503 break;
6504 case DRX_CONSTELLATION_QAM64:
6505 fec_bits_desired = 6 * symbol_rate;
6506 break;
6507 case DRX_CONSTELLATION_QAM128:
6508 fec_bits_desired = 7 * symbol_rate;
6509 break;
6510 case DRX_CONSTELLATION_QAM256:
6511 fec_bits_desired = 8 * symbol_rate;
6512 break;
6513 default:
6514 return -EINVAL;
6515 }
6516
6517 /* Parameters for Reed-Solomon Decoder */
6518 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
6519 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
6520 /* result is within 32 bit arithmetic -> */
6521 /* no need for mult or frac functions */
6522
6523 /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
6524 switch (ext_attr->standard) {
6525 case DRX_STANDARD_ITU_A:
6526 case DRX_STANDARD_ITU_C:
6527 fec_rs_plen = 204 * 8;
6528 break;
6529 case DRX_STANDARD_ITU_B:
6530 fec_rs_plen = 128 * 7;
6531 break;
6532 default:
6533 return -EINVAL;
6534 }
6535
6536 ext_attr->fec_rs_plen = fec_rs_plen; /* for getSigQual */
6537 fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage */
6538 if (fec_rs_bit_cnt == 0) {
6539 pr_err("error: fec_rs_bit_cnt is zero!\n");
6540 return -EIO;
6541 }
6542 fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1; /* ceil */
6543 if (ext_attr->standard != DRX_STANDARD_ITU_B)
6544 fec_oc_snc_fail_period = fec_rs_period;
6545
6546 /* limit to max 16 bit value (I2C register width) if needed */
6547 if (fec_rs_period > 0xFFFF)
6548 fec_rs_period = 0xFFFF;
6549
6550 /* write corresponding registers */
6551 switch (ext_attr->standard) {
6552 case DRX_STANDARD_ITU_A:
6553 case DRX_STANDARD_ITU_C:
6554 break;
6555 case DRX_STANDARD_ITU_B:
6556 switch (constellation) {
6557 case DRX_CONSTELLATION_QAM64:
6558 fec_rs_period = 31581;
6559 fec_oc_snc_fail_period = 17932;
6560 break;
6561 case DRX_CONSTELLATION_QAM256:
6562 fec_rs_period = 45446;
6563 fec_oc_snc_fail_period = 25805;
6564 break;
6565 default:
6566 return -EINVAL;
6567 }
6568 break;
6569 default:
6570 return -EINVAL;
6571 }
6572
6573 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, data: (u16)fec_oc_snc_fail_period, flags: 0);
6574 if (rc != 0) {
6575 pr_err("error %d\n", rc);
6576 goto rw_error;
6577 }
6578 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, data: (u16)fec_rs_period, flags: 0);
6579 if (rc != 0) {
6580 pr_err("error %d\n", rc);
6581 goto rw_error;
6582 }
6583 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, data: fec_rs_prescale, flags: 0);
6584 if (rc != 0) {
6585 pr_err("error %d\n", rc);
6586 goto rw_error;
6587 }
6588 ext_attr->fec_rs_period = (u16) fec_rs_period;
6589 ext_attr->fec_rs_prescale = fec_rs_prescale;
6590 rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, data: 0, flags: 0);
6591 if (rc != 0) {
6592 pr_err("error %d\n", rc);
6593 goto rw_error;
6594 }
6595 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, data: 0, flags: 0);
6596 if (rc != 0) {
6597 pr_err("error %d\n", rc);
6598 goto rw_error;
6599 }
6600 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, data: 0, flags: 0);
6601 if (rc != 0) {
6602 pr_err("error %d\n", rc);
6603 goto rw_error;
6604 }
6605
6606 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
6607 /* Parameters for Viterbi Decoder */
6608 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
6609 /* (qamvd_prescale*plen*(qam_constellation+1))) */
6610 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
6611 /* result is within 32 bit arithmetic -> */
6612 /* no need for mult or frac functions */
6613
6614 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
6615 fec_vd_plen = ext_attr->fec_vd_plen;
6616 qam_vd_prescale = ext_attr->qam_vd_prescale;
6617 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
6618
6619 switch (constellation) {
6620 case DRX_CONSTELLATION_QAM64:
6621 /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
6622 qam_vd_period =
6623 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
6624 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
6625 break;
6626 case DRX_CONSTELLATION_QAM256:
6627 /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
6628 qam_vd_period =
6629 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
6630 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
6631 break;
6632 default:
6633 return -EINVAL;
6634 }
6635 if (qam_vd_period == 0) {
6636 pr_err("error: qam_vd_period is zero!\n");
6637 return -EIO;
6638 }
6639 qam_vd_period = fec_bits_desired / qam_vd_period;
6640 /* limit to max 16 bit value (I2C register width) if needed */
6641 if (qam_vd_period > 0xFFFF)
6642 qam_vd_period = 0xFFFF;
6643
6644 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
6645 qam_vd_bit_cnt *= qam_vd_period;
6646
6647 rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, data: (u16)qam_vd_period, flags: 0);
6648 if (rc != 0) {
6649 pr_err("error %d\n", rc);
6650 goto rw_error;
6651 }
6652 rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, data: qam_vd_prescale, flags: 0);
6653 if (rc != 0) {
6654 pr_err("error %d\n", rc);
6655 goto rw_error;
6656 }
6657 ext_attr->qam_vd_period = (u16) qam_vd_period;
6658 ext_attr->qam_vd_prescale = qam_vd_prescale;
6659 }
6660
6661 return 0;
6662rw_error:
6663 return rc;
6664}
6665
6666/*============================================================================*/
6667
6668/*
6669* \fn int set_qam16 ()
6670* \brief QAM16 specific setup
6671* \param demod instance of demod.
6672* \return int.
6673*/
6674static int set_qam16(struct drx_demod_instance *demod)
6675{
6676 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6677 int rc;
6678 static const u8 qam_dq_qual_fun[] = {
6679 DRXJ_16TO8(2), /* fun0 */
6680 DRXJ_16TO8(2), /* fun1 */
6681 DRXJ_16TO8(2), /* fun2 */
6682 DRXJ_16TO8(2), /* fun3 */
6683 DRXJ_16TO8(3), /* fun4 */
6684 DRXJ_16TO8(3), /* fun5 */
6685 };
6686 static const u8 qam_eq_cma_rad[] = {
6687 DRXJ_16TO8(13517), /* RAD0 */
6688 DRXJ_16TO8(13517), /* RAD1 */
6689 DRXJ_16TO8(13517), /* RAD2 */
6690 DRXJ_16TO8(13517), /* RAD3 */
6691 DRXJ_16TO8(13517), /* RAD4 */
6692 DRXJ_16TO8(13517), /* RAD5 */
6693 };
6694
6695 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, datasize: sizeof(qam_dq_qual_fun), data: ((u8 *)qam_dq_qual_fun), flags: 0);
6696 if (rc != 0) {
6697 pr_err("error %d\n", rc);
6698 goto rw_error;
6699 }
6700 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, datasize: sizeof(qam_eq_cma_rad), data: ((u8 *)qam_eq_cma_rad), flags: 0);
6701 if (rc != 0) {
6702 pr_err("error %d\n", rc);
6703 goto rw_error;
6704 }
6705
6706 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, data: 140, flags: 0);
6707 if (rc != 0) {
6708 pr_err("error %d\n", rc);
6709 goto rw_error;
6710 }
6711 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, data: 50, flags: 0);
6712 if (rc != 0) {
6713 pr_err("error %d\n", rc);
6714 goto rw_error;
6715 }
6716 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, data: 120, flags: 0);
6717 if (rc != 0) {
6718 pr_err("error %d\n", rc);
6719 goto rw_error;
6720 }
6721 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, data: 230, flags: 0);
6722 if (rc != 0) {
6723 pr_err("error %d\n", rc);
6724 goto rw_error;
6725 }
6726 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, data: 95, flags: 0);
6727 if (rc != 0) {
6728 pr_err("error %d\n", rc);
6729 goto rw_error;
6730 }
6731 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, data: 105, flags: 0);
6732 if (rc != 0) {
6733 pr_err("error %d\n", rc);
6734 goto rw_error;
6735 }
6736
6737 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, data: 40, flags: 0);
6738 if (rc != 0) {
6739 pr_err("error %d\n", rc);
6740 goto rw_error;
6741 }
6742 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, data: 56, flags: 0);
6743 if (rc != 0) {
6744 pr_err("error %d\n", rc);
6745 goto rw_error;
6746 }
6747 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, data: 3, flags: 0);
6748 if (rc != 0) {
6749 pr_err("error %d\n", rc);
6750 goto rw_error;
6751 }
6752
6753 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, data: 16, flags: 0);
6754 if (rc != 0) {
6755 pr_err("error %d\n", rc);
6756 goto rw_error;
6757 }
6758 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, data: 220, flags: 0);
6759 if (rc != 0) {
6760 pr_err("error %d\n", rc);
6761 goto rw_error;
6762 }
6763 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, data: 25, flags: 0);
6764 if (rc != 0) {
6765 pr_err("error %d\n", rc);
6766 goto rw_error;
6767 }
6768 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, data: 6, flags: 0);
6769 if (rc != 0) {
6770 pr_err("error %d\n", rc);
6771 goto rw_error;
6772 }
6773 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, data: (u16)(-24), flags: 0);
6774 if (rc != 0) {
6775 pr_err("error %d\n", rc);
6776 goto rw_error;
6777 }
6778 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, data: (u16)(-65), flags: 0);
6779 if (rc != 0) {
6780 pr_err("error %d\n", rc);
6781 goto rw_error;
6782 }
6783 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, data: (u16)(-127), flags: 0);
6784 if (rc != 0) {
6785 pr_err("error %d\n", rc);
6786 goto rw_error;
6787 }
6788
6789 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, data: 15, flags: 0);
6790 if (rc != 0) {
6791 pr_err("error %d\n", rc);
6792 goto rw_error;
6793 }
6794 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, data: 40, flags: 0);
6795 if (rc != 0) {
6796 pr_err("error %d\n", rc);
6797 goto rw_error;
6798 }
6799 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, data: 2, flags: 0);
6800 if (rc != 0) {
6801 pr_err("error %d\n", rc);
6802 goto rw_error;
6803 }
6804 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, data: 20, flags: 0);
6805 if (rc != 0) {
6806 pr_err("error %d\n", rc);
6807 goto rw_error;
6808 }
6809 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, data: 255, flags: 0);
6810 if (rc != 0) {
6811 pr_err("error %d\n", rc);
6812 goto rw_error;
6813 }
6814 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, data: 2, flags: 0);
6815 if (rc != 0) {
6816 pr_err("error %d\n", rc);
6817 goto rw_error;
6818 }
6819 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, data: 10, flags: 0);
6820 if (rc != 0) {
6821 pr_err("error %d\n", rc);
6822 goto rw_error;
6823 }
6824 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, data: 50, flags: 0);
6825 if (rc != 0) {
6826 pr_err("error %d\n", rc);
6827 goto rw_error;
6828 }
6829 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, data: 12, flags: 0);
6830 if (rc != 0) {
6831 pr_err("error %d\n", rc);
6832 goto rw_error;
6833 }
6834 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, data: 24, flags: 0);
6835 if (rc != 0) {
6836 pr_err("error %d\n", rc);
6837 goto rw_error;
6838 }
6839 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, data: 24, flags: 0);
6840 if (rc != 0) {
6841 pr_err("error %d\n", rc);
6842 goto rw_error;
6843 }
6844 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, data: 12, flags: 0);
6845 if (rc != 0) {
6846 pr_err("error %d\n", rc);
6847 goto rw_error;
6848 }
6849 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, data: 16, flags: 0);
6850 if (rc != 0) {
6851 pr_err("error %d\n", rc);
6852 goto rw_error;
6853 }
6854 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, data: 16, flags: 0);
6855 if (rc != 0) {
6856 pr_err("error %d\n", rc);
6857 goto rw_error;
6858 }
6859 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, data: 16, flags: 0);
6860 if (rc != 0) {
6861 pr_err("error %d\n", rc);
6862 goto rw_error;
6863 }
6864 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, data: 32, flags: 0);
6865 if (rc != 0) {
6866 pr_err("error %d\n", rc);
6867 goto rw_error;
6868 }
6869 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, data: 240, flags: 0);
6870 if (rc != 0) {
6871 pr_err("error %d\n", rc);
6872 goto rw_error;
6873 }
6874 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, data: 5, flags: 0);
6875 if (rc != 0) {
6876 pr_err("error %d\n", rc);
6877 goto rw_error;
6878 }
6879 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, data: 15, flags: 0);
6880 if (rc != 0) {
6881 pr_err("error %d\n", rc);
6882 goto rw_error;
6883 }
6884 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, data: 32, flags: 0);
6885 if (rc != 0) {
6886 pr_err("error %d\n", rc);
6887 goto rw_error;
6888 }
6889
6890 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, data: 40960, flags: 0);
6891 if (rc != 0) {
6892 pr_err("error %d\n", rc);
6893 goto rw_error;
6894 }
6895
6896 return 0;
6897rw_error:
6898 return rc;
6899}
6900
6901/*============================================================================*/
6902
6903/*
6904* \fn int set_qam32 ()
6905* \brief QAM32 specific setup
6906* \param demod instance of demod.
6907* \return int.
6908*/
6909static int set_qam32(struct drx_demod_instance *demod)
6910{
6911 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6912 int rc;
6913 static const u8 qam_dq_qual_fun[] = {
6914 DRXJ_16TO8(3), /* fun0 */
6915 DRXJ_16TO8(3), /* fun1 */
6916 DRXJ_16TO8(3), /* fun2 */
6917 DRXJ_16TO8(3), /* fun3 */
6918 DRXJ_16TO8(4), /* fun4 */
6919 DRXJ_16TO8(4), /* fun5 */
6920 };
6921 static const u8 qam_eq_cma_rad[] = {
6922 DRXJ_16TO8(6707), /* RAD0 */
6923 DRXJ_16TO8(6707), /* RAD1 */
6924 DRXJ_16TO8(6707), /* RAD2 */
6925 DRXJ_16TO8(6707), /* RAD3 */
6926 DRXJ_16TO8(6707), /* RAD4 */
6927 DRXJ_16TO8(6707), /* RAD5 */
6928 };
6929
6930 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, datasize: sizeof(qam_dq_qual_fun), data: ((u8 *)qam_dq_qual_fun), flags: 0);
6931 if (rc != 0) {
6932 pr_err("error %d\n", rc);
6933 goto rw_error;
6934 }
6935 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, datasize: sizeof(qam_eq_cma_rad), data: ((u8 *)qam_eq_cma_rad), flags: 0);
6936 if (rc != 0) {
6937 pr_err("error %d\n", rc);
6938 goto rw_error;
6939 }
6940
6941 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, data: 90, flags: 0);
6942 if (rc != 0) {
6943 pr_err("error %d\n", rc);
6944 goto rw_error;
6945 }
6946 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, data: 50, flags: 0);
6947 if (rc != 0) {
6948 pr_err("error %d\n", rc);
6949 goto rw_error;
6950 }
6951 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, data: 100, flags: 0);
6952 if (rc != 0) {
6953 pr_err("error %d\n", rc);
6954 goto rw_error;
6955 }
6956 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, data: 170, flags: 0);
6957 if (rc != 0) {
6958 pr_err("error %d\n", rc);
6959 goto rw_error;
6960 }
6961 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, data: 80, flags: 0);
6962 if (rc != 0) {
6963 pr_err("error %d\n", rc);
6964 goto rw_error;
6965 }
6966 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, data: 100, flags: 0);
6967 if (rc != 0) {
6968 pr_err("error %d\n", rc);
6969 goto rw_error;
6970 }
6971
6972 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, data: 40, flags: 0);
6973 if (rc != 0) {
6974 pr_err("error %d\n", rc);
6975 goto rw_error;
6976 }
6977 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, data: 56, flags: 0);
6978 if (rc != 0) {
6979 pr_err("error %d\n", rc);
6980 goto rw_error;
6981 }
6982 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, data: 3, flags: 0);
6983 if (rc != 0) {
6984 pr_err("error %d\n", rc);
6985 goto rw_error;
6986 }
6987
6988 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, data: 12, flags: 0);
6989 if (rc != 0) {
6990 pr_err("error %d\n", rc);
6991 goto rw_error;
6992 }
6993 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, data: 140, flags: 0);
6994 if (rc != 0) {
6995 pr_err("error %d\n", rc);
6996 goto rw_error;
6997 }
6998 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, data: (u16)(-8), flags: 0);
6999 if (rc != 0) {
7000 pr_err("error %d\n", rc);
7001 goto rw_error;
7002 }
7003 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, data: (u16)(-16), flags: 0);
7004 if (rc != 0) {
7005 pr_err("error %d\n", rc);
7006 goto rw_error;
7007 }
7008 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, data: (u16)(-26), flags: 0);
7009 if (rc != 0) {
7010 pr_err("error %d\n", rc);
7011 goto rw_error;
7012 }
7013 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, data: (u16)(-56), flags: 0);
7014 if (rc != 0) {
7015 pr_err("error %d\n", rc);
7016 goto rw_error;
7017 }
7018 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, data: (u16)(-86), flags: 0);
7019 if (rc != 0) {
7020 pr_err("error %d\n", rc);
7021 goto rw_error;
7022 }
7023
7024 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, data: 15, flags: 0);
7025 if (rc != 0) {
7026 pr_err("error %d\n", rc);
7027 goto rw_error;
7028 }
7029 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, data: 40, flags: 0);
7030 if (rc != 0) {
7031 pr_err("error %d\n", rc);
7032 goto rw_error;
7033 }
7034 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, data: 2, flags: 0);
7035 if (rc != 0) {
7036 pr_err("error %d\n", rc);
7037 goto rw_error;
7038 }
7039 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, data: 20, flags: 0);
7040 if (rc != 0) {
7041 pr_err("error %d\n", rc);
7042 goto rw_error;
7043 }
7044 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, data: 255, flags: 0);
7045 if (rc != 0) {
7046 pr_err("error %d\n", rc);
7047 goto rw_error;
7048 }
7049 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, data: 2, flags: 0);
7050 if (rc != 0) {
7051 pr_err("error %d\n", rc);
7052 goto rw_error;
7053 }
7054 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, data: 10, flags: 0);
7055 if (rc != 0) {
7056 pr_err("error %d\n", rc);
7057 goto rw_error;
7058 }
7059 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, data: 50, flags: 0);
7060 if (rc != 0) {
7061 pr_err("error %d\n", rc);
7062 goto rw_error;
7063 }
7064 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, data: 12, flags: 0);
7065 if (rc != 0) {
7066 pr_err("error %d\n", rc);
7067 goto rw_error;
7068 }
7069 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, data: 24, flags: 0);
7070 if (rc != 0) {
7071 pr_err("error %d\n", rc);
7072 goto rw_error;
7073 }
7074 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, data: 24, flags: 0);
7075 if (rc != 0) {
7076 pr_err("error %d\n", rc);
7077 goto rw_error;
7078 }
7079 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, data: 12, flags: 0);
7080 if (rc != 0) {
7081 pr_err("error %d\n", rc);
7082 goto rw_error;
7083 }
7084 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, data: 16, flags: 0);
7085 if (rc != 0) {
7086 pr_err("error %d\n", rc);
7087 goto rw_error;
7088 }
7089 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, data: 16, flags: 0);
7090 if (rc != 0) {
7091 pr_err("error %d\n", rc);
7092 goto rw_error;
7093 }
7094 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, data: 16, flags: 0);
7095 if (rc != 0) {
7096 pr_err("error %d\n", rc);
7097 goto rw_error;
7098 }
7099 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, data: 32, flags: 0);
7100 if (rc != 0) {
7101 pr_err("error %d\n", rc);
7102 goto rw_error;
7103 }
7104 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, data: 176, flags: 0);
7105 if (rc != 0) {
7106 pr_err("error %d\n", rc);
7107 goto rw_error;
7108 }
7109 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, data: 5, flags: 0);
7110 if (rc != 0) {
7111 pr_err("error %d\n", rc);
7112 goto rw_error;
7113 }
7114 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, data: 15, flags: 0);
7115 if (rc != 0) {
7116 pr_err("error %d\n", rc);
7117 goto rw_error;
7118 }
7119 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, data: 8, flags: 0);
7120 if (rc != 0) {
7121 pr_err("error %d\n", rc);
7122 goto rw_error;
7123 }
7124
7125 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, data: 20480, flags: 0);
7126 if (rc != 0) {
7127 pr_err("error %d\n", rc);
7128 goto rw_error;
7129 }
7130
7131 return 0;
7132rw_error:
7133 return rc;
7134}
7135
7136/*============================================================================*/
7137
7138/*
7139* \fn int set_qam64 ()
7140* \brief QAM64 specific setup
7141* \param demod instance of demod.
7142* \return int.
7143*/
7144static int set_qam64(struct drx_demod_instance *demod)
7145{
7146 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7147 int rc;
7148 static const u8 qam_dq_qual_fun[] = {
7149 /* this is hw reset value. no necessary to re-write */
7150 DRXJ_16TO8(4), /* fun0 */
7151 DRXJ_16TO8(4), /* fun1 */
7152 DRXJ_16TO8(4), /* fun2 */
7153 DRXJ_16TO8(4), /* fun3 */
7154 DRXJ_16TO8(6), /* fun4 */
7155 DRXJ_16TO8(6), /* fun5 */
7156 };
7157 static const u8 qam_eq_cma_rad[] = {
7158 DRXJ_16TO8(13336), /* RAD0 */
7159 DRXJ_16TO8(12618), /* RAD1 */
7160 DRXJ_16TO8(11988), /* RAD2 */
7161 DRXJ_16TO8(13809), /* RAD3 */
7162 DRXJ_16TO8(13809), /* RAD4 */
7163 DRXJ_16TO8(15609), /* RAD5 */
7164 };
7165
7166 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, datasize: sizeof(qam_dq_qual_fun), data: ((u8 *)qam_dq_qual_fun), flags: 0);
7167 if (rc != 0) {
7168 pr_err("error %d\n", rc);
7169 goto rw_error;
7170 }
7171 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, datasize: sizeof(qam_eq_cma_rad), data: ((u8 *)qam_eq_cma_rad), flags: 0);
7172 if (rc != 0) {
7173 pr_err("error %d\n", rc);
7174 goto rw_error;
7175 }
7176
7177 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, data: 105, flags: 0);
7178 if (rc != 0) {
7179 pr_err("error %d\n", rc);
7180 goto rw_error;
7181 }
7182 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, data: 60, flags: 0);
7183 if (rc != 0) {
7184 pr_err("error %d\n", rc);
7185 goto rw_error;
7186 }
7187 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, data: 100, flags: 0);
7188 if (rc != 0) {
7189 pr_err("error %d\n", rc);
7190 goto rw_error;
7191 }
7192 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, data: 195, flags: 0);
7193 if (rc != 0) {
7194 pr_err("error %d\n", rc);
7195 goto rw_error;
7196 }
7197 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, data: 80, flags: 0);
7198 if (rc != 0) {
7199 pr_err("error %d\n", rc);
7200 goto rw_error;
7201 }
7202 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, data: 84, flags: 0);
7203 if (rc != 0) {
7204 pr_err("error %d\n", rc);
7205 goto rw_error;
7206 }
7207
7208 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, data: 40, flags: 0);
7209 if (rc != 0) {
7210 pr_err("error %d\n", rc);
7211 goto rw_error;
7212 }
7213 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, data: 32, flags: 0);
7214 if (rc != 0) {
7215 pr_err("error %d\n", rc);
7216 goto rw_error;
7217 }
7218 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, data: 3, flags: 0);
7219 if (rc != 0) {
7220 pr_err("error %d\n", rc);
7221 goto rw_error;
7222 }
7223
7224 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, data: 12, flags: 0);
7225 if (rc != 0) {
7226 pr_err("error %d\n", rc);
7227 goto rw_error;
7228 }
7229 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, data: 141, flags: 0);
7230 if (rc != 0) {
7231 pr_err("error %d\n", rc);
7232 goto rw_error;
7233 }
7234 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, data: 7, flags: 0);
7235 if (rc != 0) {
7236 pr_err("error %d\n", rc);
7237 goto rw_error;
7238 }
7239 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, data: 0, flags: 0);
7240 if (rc != 0) {
7241 pr_err("error %d\n", rc);
7242 goto rw_error;
7243 }
7244 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, data: (u16)(-15), flags: 0);
7245 if (rc != 0) {
7246 pr_err("error %d\n", rc);
7247 goto rw_error;
7248 }
7249 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, data: (u16)(-45), flags: 0);
7250 if (rc != 0) {
7251 pr_err("error %d\n", rc);
7252 goto rw_error;
7253 }
7254 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, data: (u16)(-80), flags: 0);
7255 if (rc != 0) {
7256 pr_err("error %d\n", rc);
7257 goto rw_error;
7258 }
7259
7260 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, data: 15, flags: 0);
7261 if (rc != 0) {
7262 pr_err("error %d\n", rc);
7263 goto rw_error;
7264 }
7265 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, data: 40, flags: 0);
7266 if (rc != 0) {
7267 pr_err("error %d\n", rc);
7268 goto rw_error;
7269 }
7270 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, data: 2, flags: 0);
7271 if (rc != 0) {
7272 pr_err("error %d\n", rc);
7273 goto rw_error;
7274 }
7275 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, data: 30, flags: 0);
7276 if (rc != 0) {
7277 pr_err("error %d\n", rc);
7278 goto rw_error;
7279 }
7280 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, data: 255, flags: 0);
7281 if (rc != 0) {
7282 pr_err("error %d\n", rc);
7283 goto rw_error;
7284 }
7285 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, data: 2, flags: 0);
7286 if (rc != 0) {
7287 pr_err("error %d\n", rc);
7288 goto rw_error;
7289 }
7290 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, data: 15, flags: 0);
7291 if (rc != 0) {
7292 pr_err("error %d\n", rc);
7293 goto rw_error;
7294 }
7295 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, data: 80, flags: 0);
7296 if (rc != 0) {
7297 pr_err("error %d\n", rc);
7298 goto rw_error;
7299 }
7300 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, data: 12, flags: 0);
7301 if (rc != 0) {
7302 pr_err("error %d\n", rc);
7303 goto rw_error;
7304 }
7305 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, data: 24, flags: 0);
7306 if (rc != 0) {
7307 pr_err("error %d\n", rc);
7308 goto rw_error;
7309 }
7310 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, data: 24, flags: 0);
7311 if (rc != 0) {
7312 pr_err("error %d\n", rc);
7313 goto rw_error;
7314 }
7315 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, data: 12, flags: 0);
7316 if (rc != 0) {
7317 pr_err("error %d\n", rc);
7318 goto rw_error;
7319 }
7320 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, data: 16, flags: 0);
7321 if (rc != 0) {
7322 pr_err("error %d\n", rc);
7323 goto rw_error;
7324 }
7325 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, data: 16, flags: 0);
7326 if (rc != 0) {
7327 pr_err("error %d\n", rc);
7328 goto rw_error;
7329 }
7330 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, data: 16, flags: 0);
7331 if (rc != 0) {
7332 pr_err("error %d\n", rc);
7333 goto rw_error;
7334 }
7335 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, data: 48, flags: 0);
7336 if (rc != 0) {
7337 pr_err("error %d\n", rc);
7338 goto rw_error;
7339 }
7340 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, data: 160, flags: 0);
7341 if (rc != 0) {
7342 pr_err("error %d\n", rc);
7343 goto rw_error;
7344 }
7345 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, data: 5, flags: 0);
7346 if (rc != 0) {
7347 pr_err("error %d\n", rc);
7348 goto rw_error;
7349 }
7350 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, data: 15, flags: 0);
7351 if (rc != 0) {
7352 pr_err("error %d\n", rc);
7353 goto rw_error;
7354 }
7355 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, data: 32, flags: 0);
7356 if (rc != 0) {
7357 pr_err("error %d\n", rc);
7358 goto rw_error;
7359 }
7360
7361 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, data: 43008, flags: 0);
7362 if (rc != 0) {
7363 pr_err("error %d\n", rc);
7364 goto rw_error;
7365 }
7366
7367 return 0;
7368rw_error:
7369 return rc;
7370}
7371
7372/*============================================================================*/
7373
7374/*
7375* \fn int set_qam128 ()
7376* \brief QAM128 specific setup
7377* \param demod: instance of demod.
7378* \return int.
7379*/
7380static int set_qam128(struct drx_demod_instance *demod)
7381{
7382 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7383 int rc;
7384 static const u8 qam_dq_qual_fun[] = {
7385 DRXJ_16TO8(6), /* fun0 */
7386 DRXJ_16TO8(6), /* fun1 */
7387 DRXJ_16TO8(6), /* fun2 */
7388 DRXJ_16TO8(6), /* fun3 */
7389 DRXJ_16TO8(9), /* fun4 */
7390 DRXJ_16TO8(9), /* fun5 */
7391 };
7392 static const u8 qam_eq_cma_rad[] = {
7393 DRXJ_16TO8(6164), /* RAD0 */
7394 DRXJ_16TO8(6598), /* RAD1 */
7395 DRXJ_16TO8(6394), /* RAD2 */
7396 DRXJ_16TO8(6409), /* RAD3 */
7397 DRXJ_16TO8(6656), /* RAD4 */
7398 DRXJ_16TO8(7238), /* RAD5 */
7399 };
7400
7401 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, datasize: sizeof(qam_dq_qual_fun), data: ((u8 *)qam_dq_qual_fun), flags: 0);
7402 if (rc != 0) {
7403 pr_err("error %d\n", rc);
7404 goto rw_error;
7405 }
7406 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, datasize: sizeof(qam_eq_cma_rad), data: ((u8 *)qam_eq_cma_rad), flags: 0);
7407 if (rc != 0) {
7408 pr_err("error %d\n", rc);
7409 goto rw_error;
7410 }
7411
7412 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, data: 50, flags: 0);
7413 if (rc != 0) {
7414 pr_err("error %d\n", rc);
7415 goto rw_error;
7416 }
7417 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, data: 60, flags: 0);
7418 if (rc != 0) {
7419 pr_err("error %d\n", rc);
7420 goto rw_error;
7421 }
7422 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, data: 100, flags: 0);
7423 if (rc != 0) {
7424 pr_err("error %d\n", rc);
7425 goto rw_error;
7426 }
7427 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, data: 140, flags: 0);
7428 if (rc != 0) {
7429 pr_err("error %d\n", rc);
7430 goto rw_error;
7431 }
7432 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, data: 80, flags: 0);
7433 if (rc != 0) {
7434 pr_err("error %d\n", rc);
7435 goto rw_error;
7436 }
7437 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, data: 100, flags: 0);
7438 if (rc != 0) {
7439 pr_err("error %d\n", rc);
7440 goto rw_error;
7441 }
7442
7443 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, data: 40, flags: 0);
7444 if (rc != 0) {
7445 pr_err("error %d\n", rc);
7446 goto rw_error;
7447 }
7448 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, data: 32, flags: 0);
7449 if (rc != 0) {
7450 pr_err("error %d\n", rc);
7451 goto rw_error;
7452 }
7453 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, data: 3, flags: 0);
7454 if (rc != 0) {
7455 pr_err("error %d\n", rc);
7456 goto rw_error;
7457 }
7458
7459 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, data: 8, flags: 0);
7460 if (rc != 0) {
7461 pr_err("error %d\n", rc);
7462 goto rw_error;
7463 }
7464 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, data: 65, flags: 0);
7465 if (rc != 0) {
7466 pr_err("error %d\n", rc);
7467 goto rw_error;
7468 }
7469 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, data: 5, flags: 0);
7470 if (rc != 0) {
7471 pr_err("error %d\n", rc);
7472 goto rw_error;
7473 }
7474 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, data: 3, flags: 0);
7475 if (rc != 0) {
7476 pr_err("error %d\n", rc);
7477 goto rw_error;
7478 }
7479 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, data: (u16)(-1), flags: 0);
7480 if (rc != 0) {
7481 pr_err("error %d\n", rc);
7482 goto rw_error;
7483 }
7484 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, data: 12, flags: 0);
7485 if (rc != 0) {
7486 pr_err("error %d\n", rc);
7487 goto rw_error;
7488 }
7489 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, data: (u16)(-23), flags: 0);
7490 if (rc != 0) {
7491 pr_err("error %d\n", rc);
7492 goto rw_error;
7493 }
7494
7495 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, data: 15, flags: 0);
7496 if (rc != 0) {
7497 pr_err("error %d\n", rc);
7498 goto rw_error;
7499 }
7500 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, data: 40, flags: 0);
7501 if (rc != 0) {
7502 pr_err("error %d\n", rc);
7503 goto rw_error;
7504 }
7505 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, data: 2, flags: 0);
7506 if (rc != 0) {
7507 pr_err("error %d\n", rc);
7508 goto rw_error;
7509 }
7510 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, data: 40, flags: 0);
7511 if (rc != 0) {
7512 pr_err("error %d\n", rc);
7513 goto rw_error;
7514 }
7515 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, data: 255, flags: 0);
7516 if (rc != 0) {
7517 pr_err("error %d\n", rc);
7518 goto rw_error;
7519 }
7520 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, data: 2, flags: 0);
7521 if (rc != 0) {
7522 pr_err("error %d\n", rc);
7523 goto rw_error;
7524 }
7525 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, data: 20, flags: 0);
7526 if (rc != 0) {
7527 pr_err("error %d\n", rc);
7528 goto rw_error;
7529 }
7530 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, data: 80, flags: 0);
7531 if (rc != 0) {
7532 pr_err("error %d\n", rc);
7533 goto rw_error;
7534 }
7535 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, data: 12, flags: 0);
7536 if (rc != 0) {
7537 pr_err("error %d\n", rc);
7538 goto rw_error;
7539 }
7540 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, data: 24, flags: 0);
7541 if (rc != 0) {
7542 pr_err("error %d\n", rc);
7543 goto rw_error;
7544 }
7545 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, data: 24, flags: 0);
7546 if (rc != 0) {
7547 pr_err("error %d\n", rc);
7548 goto rw_error;
7549 }
7550 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, data: 12, flags: 0);
7551 if (rc != 0) {
7552 pr_err("error %d\n", rc);
7553 goto rw_error;
7554 }
7555 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, data: 16, flags: 0);
7556 if (rc != 0) {
7557 pr_err("error %d\n", rc);
7558 goto rw_error;
7559 }
7560 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, data: 16, flags: 0);
7561 if (rc != 0) {
7562 pr_err("error %d\n", rc);
7563 goto rw_error;
7564 }
7565 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, data: 16, flags: 0);
7566 if (rc != 0) {
7567 pr_err("error %d\n", rc);
7568 goto rw_error;
7569 }
7570 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, data: 32, flags: 0);
7571 if (rc != 0) {
7572 pr_err("error %d\n", rc);
7573 goto rw_error;
7574 }
7575 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, data: 144, flags: 0);
7576 if (rc != 0) {
7577 pr_err("error %d\n", rc);
7578 goto rw_error;
7579 }
7580 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, data: 5, flags: 0);
7581 if (rc != 0) {
7582 pr_err("error %d\n", rc);
7583 goto rw_error;
7584 }
7585 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, data: 15, flags: 0);
7586 if (rc != 0) {
7587 pr_err("error %d\n", rc);
7588 goto rw_error;
7589 }
7590 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, data: 16, flags: 0);
7591 if (rc != 0) {
7592 pr_err("error %d\n", rc);
7593 goto rw_error;
7594 }
7595
7596 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, data: 20992, flags: 0);
7597 if (rc != 0) {
7598 pr_err("error %d\n", rc);
7599 goto rw_error;
7600 }
7601
7602 return 0;
7603rw_error:
7604 return rc;
7605}
7606
7607/*============================================================================*/
7608
7609/*
7610* \fn int set_qam256 ()
7611* \brief QAM256 specific setup
7612* \param demod: instance of demod.
7613* \return int.
7614*/
7615static int set_qam256(struct drx_demod_instance *demod)
7616{
7617 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7618 int rc;
7619 static const u8 qam_dq_qual_fun[] = {
7620 DRXJ_16TO8(8), /* fun0 */
7621 DRXJ_16TO8(8), /* fun1 */
7622 DRXJ_16TO8(8), /* fun2 */
7623 DRXJ_16TO8(8), /* fun3 */
7624 DRXJ_16TO8(12), /* fun4 */
7625 DRXJ_16TO8(12), /* fun5 */
7626 };
7627 static const u8 qam_eq_cma_rad[] = {
7628 DRXJ_16TO8(12345), /* RAD0 */
7629 DRXJ_16TO8(12345), /* RAD1 */
7630 DRXJ_16TO8(13626), /* RAD2 */
7631 DRXJ_16TO8(12931), /* RAD3 */
7632 DRXJ_16TO8(14719), /* RAD4 */
7633 DRXJ_16TO8(15356), /* RAD5 */
7634 };
7635
7636 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, datasize: sizeof(qam_dq_qual_fun), data: ((u8 *)qam_dq_qual_fun), flags: 0);
7637 if (rc != 0) {
7638 pr_err("error %d\n", rc);
7639 goto rw_error;
7640 }
7641 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, datasize: sizeof(qam_eq_cma_rad), data: ((u8 *)qam_eq_cma_rad), flags: 0);
7642 if (rc != 0) {
7643 pr_err("error %d\n", rc);
7644 goto rw_error;
7645 }
7646
7647 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, data: 50, flags: 0);
7648 if (rc != 0) {
7649 pr_err("error %d\n", rc);
7650 goto rw_error;
7651 }
7652 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, data: 60, flags: 0);
7653 if (rc != 0) {
7654 pr_err("error %d\n", rc);
7655 goto rw_error;
7656 }
7657 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, data: 100, flags: 0);
7658 if (rc != 0) {
7659 pr_err("error %d\n", rc);
7660 goto rw_error;
7661 }
7662 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, data: 150, flags: 0);
7663 if (rc != 0) {
7664 pr_err("error %d\n", rc);
7665 goto rw_error;
7666 }
7667 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, data: 80, flags: 0);
7668 if (rc != 0) {
7669 pr_err("error %d\n", rc);
7670 goto rw_error;
7671 }
7672 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, data: 110, flags: 0);
7673 if (rc != 0) {
7674 pr_err("error %d\n", rc);
7675 goto rw_error;
7676 }
7677
7678 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, data: 40, flags: 0);
7679 if (rc != 0) {
7680 pr_err("error %d\n", rc);
7681 goto rw_error;
7682 }
7683 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, data: 16, flags: 0);
7684 if (rc != 0) {
7685 pr_err("error %d\n", rc);
7686 goto rw_error;
7687 }
7688 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, data: 3, flags: 0);
7689 if (rc != 0) {
7690 pr_err("error %d\n", rc);
7691 goto rw_error;
7692 }
7693
7694 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, data: 8, flags: 0);
7695 if (rc != 0) {
7696 pr_err("error %d\n", rc);
7697 goto rw_error;
7698 }
7699 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, data: 74, flags: 0);
7700 if (rc != 0) {
7701 pr_err("error %d\n", rc);
7702 goto rw_error;
7703 }
7704 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, data: 18, flags: 0);
7705 if (rc != 0) {
7706 pr_err("error %d\n", rc);
7707 goto rw_error;
7708 }
7709 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, data: 13, flags: 0);
7710 if (rc != 0) {
7711 pr_err("error %d\n", rc);
7712 goto rw_error;
7713 }
7714 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, data: 7, flags: 0);
7715 if (rc != 0) {
7716 pr_err("error %d\n", rc);
7717 goto rw_error;
7718 }
7719 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, data: 0, flags: 0);
7720 if (rc != 0) {
7721 pr_err("error %d\n", rc);
7722 goto rw_error;
7723 }
7724 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, data: (u16)(-8), flags: 0);
7725 if (rc != 0) {
7726 pr_err("error %d\n", rc);
7727 goto rw_error;
7728 }
7729
7730 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, data: 15, flags: 0);
7731 if (rc != 0) {
7732 pr_err("error %d\n", rc);
7733 goto rw_error;
7734 }
7735 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, data: 40, flags: 0);
7736 if (rc != 0) {
7737 pr_err("error %d\n", rc);
7738 goto rw_error;
7739 }
7740 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, data: 2, flags: 0);
7741 if (rc != 0) {
7742 pr_err("error %d\n", rc);
7743 goto rw_error;
7744 }
7745 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, data: 50, flags: 0);
7746 if (rc != 0) {
7747 pr_err("error %d\n", rc);
7748 goto rw_error;
7749 }
7750 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, data: 255, flags: 0);
7751 if (rc != 0) {
7752 pr_err("error %d\n", rc);
7753 goto rw_error;
7754 }
7755 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, data: 2, flags: 0);
7756 if (rc != 0) {
7757 pr_err("error %d\n", rc);
7758 goto rw_error;
7759 }
7760 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, data: 25, flags: 0);
7761 if (rc != 0) {
7762 pr_err("error %d\n", rc);
7763 goto rw_error;
7764 }
7765 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, data: 80, flags: 0);
7766 if (rc != 0) {
7767 pr_err("error %d\n", rc);
7768 goto rw_error;
7769 }
7770 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, data: 12, flags: 0);
7771 if (rc != 0) {
7772 pr_err("error %d\n", rc);
7773 goto rw_error;
7774 }
7775 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, data: 24, flags: 0);
7776 if (rc != 0) {
7777 pr_err("error %d\n", rc);
7778 goto rw_error;
7779 }
7780 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, data: 24, flags: 0);
7781 if (rc != 0) {
7782 pr_err("error %d\n", rc);
7783 goto rw_error;
7784 }
7785 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, data: 12, flags: 0);
7786 if (rc != 0) {
7787 pr_err("error %d\n", rc);
7788 goto rw_error;
7789 }
7790 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, data: 16, flags: 0);
7791 if (rc != 0) {
7792 pr_err("error %d\n", rc);
7793 goto rw_error;
7794 }
7795 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, data: 16, flags: 0);
7796 if (rc != 0) {
7797 pr_err("error %d\n", rc);
7798 goto rw_error;
7799 }
7800 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, data: 16, flags: 0);
7801 if (rc != 0) {
7802 pr_err("error %d\n", rc);
7803 goto rw_error;
7804 }
7805 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, data: 48, flags: 0);
7806 if (rc != 0) {
7807 pr_err("error %d\n", rc);
7808 goto rw_error;
7809 }
7810 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, data: 80, flags: 0);
7811 if (rc != 0) {
7812 pr_err("error %d\n", rc);
7813 goto rw_error;
7814 }
7815 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, data: 5, flags: 0);
7816 if (rc != 0) {
7817 pr_err("error %d\n", rc);
7818 goto rw_error;
7819 }
7820 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, data: 15, flags: 0);
7821 if (rc != 0) {
7822 pr_err("error %d\n", rc);
7823 goto rw_error;
7824 }
7825 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, data: 16, flags: 0);
7826 if (rc != 0) {
7827 pr_err("error %d\n", rc);
7828 goto rw_error;
7829 }
7830
7831 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, data: 43520, flags: 0);
7832 if (rc != 0) {
7833 pr_err("error %d\n", rc);
7834 goto rw_error;
7835 }
7836
7837 return 0;
7838rw_error:
7839 return rc;
7840}
7841
7842/*============================================================================*/
7843#define QAM_SET_OP_ALL 0x1
7844#define QAM_SET_OP_CONSTELLATION 0x2
7845#define QAM_SET_OP_SPECTRUM 0X4
7846
7847/*
7848* \fn int set_qam ()
7849* \brief Set QAM demod.
7850* \param demod: instance of demod.
7851* \param channel: pointer to channel data.
7852* \return int.
7853*/
7854static int
7855set_qam(struct drx_demod_instance *demod,
7856 struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
7857{
7858 struct i2c_device_addr *dev_addr = NULL;
7859 struct drxj_data *ext_attr = NULL;
7860 struct drx_common_attr *common_attr = NULL;
7861 int rc;
7862 u32 adc_frequency = 0;
7863 u32 iqm_rc_rate = 0;
7864 u16 cmd_result = 0;
7865 u16 lc_symbol_freq = 0;
7866 u16 iqm_rc_stretch = 0;
7867 u16 set_env_parameters = 0;
7868 u16 set_param_parameters[2] = { 0 };
7869 struct drxjscu_cmd cmd_scu = { /* command */ 0,
7870 /* parameter_len */ 0,
7871 /* result_len */ 0,
7872 /* parameter */ NULL,
7873 /* result */ NULL
7874 };
7875 static const u8 qam_a_taps[] = {
7876 DRXJ_16TO8(-1), /* re0 */
7877 DRXJ_16TO8(1), /* re1 */
7878 DRXJ_16TO8(1), /* re2 */
7879 DRXJ_16TO8(-1), /* re3 */
7880 DRXJ_16TO8(-1), /* re4 */
7881 DRXJ_16TO8(2), /* re5 */
7882 DRXJ_16TO8(1), /* re6 */
7883 DRXJ_16TO8(-2), /* re7 */
7884 DRXJ_16TO8(0), /* re8 */
7885 DRXJ_16TO8(3), /* re9 */
7886 DRXJ_16TO8(-1), /* re10 */
7887 DRXJ_16TO8(-3), /* re11 */
7888 DRXJ_16TO8(4), /* re12 */
7889 DRXJ_16TO8(1), /* re13 */
7890 DRXJ_16TO8(-8), /* re14 */
7891 DRXJ_16TO8(4), /* re15 */
7892 DRXJ_16TO8(13), /* re16 */
7893 DRXJ_16TO8(-13), /* re17 */
7894 DRXJ_16TO8(-19), /* re18 */
7895 DRXJ_16TO8(28), /* re19 */
7896 DRXJ_16TO8(25), /* re20 */
7897 DRXJ_16TO8(-53), /* re21 */
7898 DRXJ_16TO8(-31), /* re22 */
7899 DRXJ_16TO8(96), /* re23 */
7900 DRXJ_16TO8(37), /* re24 */
7901 DRXJ_16TO8(-190), /* re25 */
7902 DRXJ_16TO8(-40), /* re26 */
7903 DRXJ_16TO8(619) /* re27 */
7904 };
7905 static const u8 qam_b64_taps[] = {
7906 DRXJ_16TO8(0), /* re0 */
7907 DRXJ_16TO8(-2), /* re1 */
7908 DRXJ_16TO8(1), /* re2 */
7909 DRXJ_16TO8(2), /* re3 */
7910 DRXJ_16TO8(-2), /* re4 */
7911 DRXJ_16TO8(0), /* re5 */
7912 DRXJ_16TO8(4), /* re6 */
7913 DRXJ_16TO8(-2), /* re7 */
7914 DRXJ_16TO8(-4), /* re8 */
7915 DRXJ_16TO8(4), /* re9 */
7916 DRXJ_16TO8(3), /* re10 */
7917 DRXJ_16TO8(-6), /* re11 */
7918 DRXJ_16TO8(0), /* re12 */
7919 DRXJ_16TO8(6), /* re13 */
7920 DRXJ_16TO8(-5), /* re14 */
7921 DRXJ_16TO8(-3), /* re15 */
7922 DRXJ_16TO8(11), /* re16 */
7923 DRXJ_16TO8(-4), /* re17 */
7924 DRXJ_16TO8(-19), /* re18 */
7925 DRXJ_16TO8(19), /* re19 */
7926 DRXJ_16TO8(28), /* re20 */
7927 DRXJ_16TO8(-45), /* re21 */
7928 DRXJ_16TO8(-36), /* re22 */
7929 DRXJ_16TO8(90), /* re23 */
7930 DRXJ_16TO8(42), /* re24 */
7931 DRXJ_16TO8(-185), /* re25 */
7932 DRXJ_16TO8(-46), /* re26 */
7933 DRXJ_16TO8(614) /* re27 */
7934 };
7935 static const u8 qam_b256_taps[] = {
7936 DRXJ_16TO8(-2), /* re0 */
7937 DRXJ_16TO8(4), /* re1 */
7938 DRXJ_16TO8(1), /* re2 */
7939 DRXJ_16TO8(-4), /* re3 */
7940 DRXJ_16TO8(0), /* re4 */
7941 DRXJ_16TO8(4), /* re5 */
7942 DRXJ_16TO8(-2), /* re6 */
7943 DRXJ_16TO8(-4), /* re7 */
7944 DRXJ_16TO8(5), /* re8 */
7945 DRXJ_16TO8(2), /* re9 */
7946 DRXJ_16TO8(-8), /* re10 */
7947 DRXJ_16TO8(2), /* re11 */
7948 DRXJ_16TO8(11), /* re12 */
7949 DRXJ_16TO8(-8), /* re13 */
7950 DRXJ_16TO8(-15), /* re14 */
7951 DRXJ_16TO8(16), /* re15 */
7952 DRXJ_16TO8(19), /* re16 */
7953 DRXJ_16TO8(-27), /* re17 */
7954 DRXJ_16TO8(-22), /* re18 */
7955 DRXJ_16TO8(44), /* re19 */
7956 DRXJ_16TO8(26), /* re20 */
7957 DRXJ_16TO8(-69), /* re21 */
7958 DRXJ_16TO8(-28), /* re22 */
7959 DRXJ_16TO8(110), /* re23 */
7960 DRXJ_16TO8(31), /* re24 */
7961 DRXJ_16TO8(-201), /* re25 */
7962 DRXJ_16TO8(-32), /* re26 */
7963 DRXJ_16TO8(628) /* re27 */
7964 };
7965 static const u8 qam_c_taps[] = {
7966 DRXJ_16TO8(-3), /* re0 */
7967 DRXJ_16TO8(3), /* re1 */
7968 DRXJ_16TO8(2), /* re2 */
7969 DRXJ_16TO8(-4), /* re3 */
7970 DRXJ_16TO8(0), /* re4 */
7971 DRXJ_16TO8(4), /* re5 */
7972 DRXJ_16TO8(-1), /* re6 */
7973 DRXJ_16TO8(-4), /* re7 */
7974 DRXJ_16TO8(3), /* re8 */
7975 DRXJ_16TO8(3), /* re9 */
7976 DRXJ_16TO8(-5), /* re10 */
7977 DRXJ_16TO8(0), /* re11 */
7978 DRXJ_16TO8(9), /* re12 */
7979 DRXJ_16TO8(-4), /* re13 */
7980 DRXJ_16TO8(-12), /* re14 */
7981 DRXJ_16TO8(10), /* re15 */
7982 DRXJ_16TO8(16), /* re16 */
7983 DRXJ_16TO8(-21), /* re17 */
7984 DRXJ_16TO8(-20), /* re18 */
7985 DRXJ_16TO8(37), /* re19 */
7986 DRXJ_16TO8(25), /* re20 */
7987 DRXJ_16TO8(-62), /* re21 */
7988 DRXJ_16TO8(-28), /* re22 */
7989 DRXJ_16TO8(105), /* re23 */
7990 DRXJ_16TO8(31), /* re24 */
7991 DRXJ_16TO8(-197), /* re25 */
7992 DRXJ_16TO8(-33), /* re26 */
7993 DRXJ_16TO8(626) /* re27 */
7994 };
7995
7996 dev_addr = demod->my_i2c_dev_addr;
7997 ext_attr = (struct drxj_data *) demod->my_ext_attr;
7998 common_attr = (struct drx_common_attr *) demod->my_common_attr;
7999
8000 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8001 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8002 switch (channel->constellation) {
8003 case DRX_CONSTELLATION_QAM256:
8004 iqm_rc_rate = 0x00AE3562;
8005 lc_symbol_freq =
8006 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
8007 channel->symbolrate = 5360537;
8008 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
8009 break;
8010 case DRX_CONSTELLATION_QAM64:
8011 iqm_rc_rate = 0x00C05A0E;
8012 lc_symbol_freq = 409;
8013 channel->symbolrate = 5056941;
8014 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
8015 break;
8016 default:
8017 return -EINVAL;
8018 }
8019 } else {
8020 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
8021 if (channel->symbolrate == 0) {
8022 pr_err("error: channel symbolrate is zero!\n");
8023 return -EIO;
8024 }
8025 iqm_rc_rate =
8026 (adc_frequency / channel->symbolrate) * (1 << 21) +
8027 (frac28
8028 (N: (adc_frequency % channel->symbolrate),
8029 D: channel->symbolrate) >> 7) - (1 << 23);
8030 lc_symbol_freq =
8031 (u16) (frac28
8032 (N: channel->symbolrate +
8033 (adc_frequency >> 13),
8034 D: adc_frequency) >> 16);
8035 if (lc_symbol_freq > 511)
8036 lc_symbol_freq = 511;
8037
8038 iqm_rc_stretch = 21;
8039 }
8040
8041 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8042 set_env_parameters = QAM_TOP_ANNEX_A; /* annex */
8043 set_param_parameters[0] = channel->constellation; /* constellation */
8044 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
8045 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8046 set_env_parameters = QAM_TOP_ANNEX_B; /* annex */
8047 set_param_parameters[0] = channel->constellation; /* constellation */
8048 set_param_parameters[1] = channel->interleavemode; /* interleave mode */
8049 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8050 set_env_parameters = QAM_TOP_ANNEX_C; /* annex */
8051 set_param_parameters[0] = channel->constellation; /* constellation */
8052 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
8053 } else {
8054 return -EINVAL;
8055 }
8056 }
8057
8058 if (op & QAM_SET_OP_ALL) {
8059 /*
8060 STEP 1: reset demodulator
8061 resets IQM, QAM and FEC HW blocks
8062 resets SCU variables
8063 */
8064 /* stop all comm_exec */
8065 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, flags: 0);
8066 if (rc != 0) {
8067 pr_err("error %d\n", rc);
8068 goto rw_error;
8069 }
8070 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, flags: 0);
8071 if (rc != 0) {
8072 pr_err("error %d\n", rc);
8073 goto rw_error;
8074 }
8075 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, flags: 0);
8076 if (rc != 0) {
8077 pr_err("error %d\n", rc);
8078 goto rw_error;
8079 }
8080 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, flags: 0);
8081 if (rc != 0) {
8082 pr_err("error %d\n", rc);
8083 goto rw_error;
8084 }
8085 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, flags: 0);
8086 if (rc != 0) {
8087 pr_err("error %d\n", rc);
8088 goto rw_error;
8089 }
8090 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, flags: 0);
8091 if (rc != 0) {
8092 pr_err("error %d\n", rc);
8093 goto rw_error;
8094 }
8095 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, flags: 0);
8096 if (rc != 0) {
8097 pr_err("error %d\n", rc);
8098 goto rw_error;
8099 }
8100
8101 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8102 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
8103 cmd_scu.parameter_len = 0;
8104 cmd_scu.result_len = 1;
8105 cmd_scu.parameter = NULL;
8106 cmd_scu.result = &cmd_result;
8107 rc = scu_command(dev_addr, cmd: &cmd_scu);
8108 if (rc != 0) {
8109 pr_err("error %d\n", rc);
8110 goto rw_error;
8111 }
8112 }
8113
8114 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8115 /*
8116 STEP 2: configure demodulator
8117 -set env
8118 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
8119 */
8120 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8121 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
8122 cmd_scu.parameter_len = 1;
8123 cmd_scu.result_len = 1;
8124 cmd_scu.parameter = &set_env_parameters;
8125 cmd_scu.result = &cmd_result;
8126 rc = scu_command(dev_addr, cmd: &cmd_scu);
8127 if (rc != 0) {
8128 pr_err("error %d\n", rc);
8129 goto rw_error;
8130 }
8131
8132 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8133 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
8134 cmd_scu.parameter_len = 2;
8135 cmd_scu.result_len = 1;
8136 cmd_scu.parameter = set_param_parameters;
8137 cmd_scu.result = &cmd_result;
8138 rc = scu_command(dev_addr, cmd: &cmd_scu);
8139 if (rc != 0) {
8140 pr_err("error %d\n", rc);
8141 goto rw_error;
8142 }
8143 /* set symbol rate */
8144 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, data: iqm_rc_rate, flags: 0);
8145 if (rc != 0) {
8146 pr_err("error %d\n", rc);
8147 goto rw_error;
8148 }
8149 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
8150 rc = set_qam_measurement(demod, constellation: channel->constellation, symbol_rate: channel->symbolrate);
8151 if (rc != 0) {
8152 pr_err("error %d\n", rc);
8153 goto rw_error;
8154 }
8155 }
8156 /* STEP 3: enable the system in a mode where the ADC provides valid signal
8157 setup constellation independent registers */
8158 /* from qam_cmd.py script (qam_driver_b) */
8159 /* TODO: remove re-writes of HW reset values */
8160 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
8161 rc = set_frequency(demod, channel, tuner_freq_offset);
8162 if (rc != 0) {
8163 pr_err("error %d\n", rc);
8164 goto rw_error;
8165 }
8166 }
8167
8168 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8169
8170 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, data: lc_symbol_freq, flags: 0);
8171 if (rc != 0) {
8172 pr_err("error %d\n", rc);
8173 goto rw_error;
8174 }
8175 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, data: iqm_rc_stretch, flags: 0);
8176 if (rc != 0) {
8177 pr_err("error %d\n", rc);
8178 goto rw_error;
8179 }
8180 }
8181
8182 if (op & QAM_SET_OP_ALL) {
8183 if (!ext_attr->has_lna) {
8184 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, data: 0x02, flags: 0);
8185 if (rc != 0) {
8186 pr_err("error %d\n", rc);
8187 goto rw_error;
8188 }
8189 }
8190 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, data: 0, flags: 0);
8191 if (rc != 0) {
8192 pr_err("error %d\n", rc);
8193 goto rw_error;
8194 }
8195 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, data: 3, flags: 0);
8196 if (rc != 0) {
8197 pr_err("error %d\n", rc);
8198 goto rw_error;
8199 }
8200 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, flags: 0);
8201 if (rc != 0) {
8202 pr_err("error %d\n", rc);
8203 goto rw_error;
8204 }
8205
8206 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, data: 0x5f, flags: 0);
8207 if (rc != 0) {
8208 pr_err("error %d\n", rc);
8209 goto rw_error;
8210 } /* scu temporary shut down agc */
8211
8212 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, data: 3, flags: 0);
8213 if (rc != 0) {
8214 pr_err("error %d\n", rc);
8215 goto rw_error;
8216 }
8217 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, data: 0, flags: 0);
8218 if (rc != 0) {
8219 pr_err("error %d\n", rc);
8220 goto rw_error;
8221 }
8222 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, data: 448, flags: 0);
8223 if (rc != 0) {
8224 pr_err("error %d\n", rc);
8225 goto rw_error;
8226 }
8227 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, data: 0, flags: 0);
8228 if (rc != 0) {
8229 pr_err("error %d\n", rc);
8230 goto rw_error;
8231 }
8232 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, data: 4, flags: 0);
8233 if (rc != 0) {
8234 pr_err("error %d\n", rc);
8235 goto rw_error;
8236 }
8237 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data: 0x10, flags: 0);
8238 if (rc != 0) {
8239 pr_err("error %d\n", rc);
8240 goto rw_error;
8241 }
8242 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, data: 11, flags: 0);
8243 if (rc != 0) {
8244 pr_err("error %d\n", rc);
8245 goto rw_error;
8246 }
8247
8248 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, data: 1, flags: 0);
8249 if (rc != 0) {
8250 pr_err("error %d\n", rc);
8251 goto rw_error;
8252 }
8253 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, flags: 0);
8254 if (rc != 0) {
8255 pr_err("error %d\n", rc);
8256 goto rw_error;
8257 } /*! reset default val ! */
8258
8259 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, flags: 0);
8260 if (rc != 0) {
8261 pr_err("error %d\n", rc);
8262 goto rw_error;
8263 } /*! reset default val ! */
8264 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8265 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, flags: 0);
8266 if (rc != 0) {
8267 pr_err("error %d\n", rc);
8268 goto rw_error;
8269 } /*! reset default val ! */
8270 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, flags: 0);
8271 if (rc != 0) {
8272 pr_err("error %d\n", rc);
8273 goto rw_error;
8274 } /*! reset default val ! */
8275 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, flags: 0);
8276 if (rc != 0) {
8277 pr_err("error %d\n", rc);
8278 goto rw_error;
8279 } /*! reset default val ! */
8280 } else {
8281 switch (channel->constellation) {
8282 case DRX_CONSTELLATION_QAM16:
8283 case DRX_CONSTELLATION_QAM64:
8284 case DRX_CONSTELLATION_QAM256:
8285 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, data: 0x03, flags: 0);
8286 if (rc != 0) {
8287 pr_err("error %d\n", rc);
8288 goto rw_error;
8289 }
8290 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, data: 0x04, flags: 0);
8291 if (rc != 0) {
8292 pr_err("error %d\n", rc);
8293 goto rw_error;
8294 }
8295 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, flags: 0);
8296 if (rc != 0) {
8297 pr_err("error %d\n", rc);
8298 goto rw_error;
8299 } /*! reset default val ! */
8300 break;
8301 case DRX_CONSTELLATION_QAM32:
8302 case DRX_CONSTELLATION_QAM128:
8303 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, data: 0x03, flags: 0);
8304 if (rc != 0) {
8305 pr_err("error %d\n", rc);
8306 goto rw_error;
8307 }
8308 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, data: 0x05, flags: 0);
8309 if (rc != 0) {
8310 pr_err("error %d\n", rc);
8311 goto rw_error;
8312 }
8313 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, data: 0x06, flags: 0);
8314 if (rc != 0) {
8315 pr_err("error %d\n", rc);
8316 goto rw_error;
8317 }
8318 break;
8319 default:
8320 return -EIO;
8321 } /* switch */
8322 }
8323
8324 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, flags: 0);
8325 if (rc != 0) {
8326 pr_err("error %d\n", rc);
8327 goto rw_error;
8328 } /*! reset default val ! */
8329 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, data: 3, flags: 0);
8330 if (rc != 0) {
8331 pr_err("error %d\n", rc);
8332 goto rw_error;
8333 }
8334 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, data: 4, flags: 0);
8335 if (rc != 0) {
8336 pr_err("error %d\n", rc);
8337 goto rw_error;
8338 }
8339 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, data: 4, flags: 0);
8340 if (rc != 0) {
8341 pr_err("error %d\n", rc);
8342 goto rw_error;
8343 }
8344 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, data: 7, flags: 0);
8345 if (rc != 0) {
8346 pr_err("error %d\n", rc);
8347 goto rw_error;
8348 }
8349 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, data: 1, flags: 0);
8350 if (rc != 0) {
8351 pr_err("error %d\n", rc);
8352 goto rw_error;
8353 }
8354 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, data: 1, flags: 0);
8355 if (rc != 0) {
8356 pr_err("error %d\n", rc);
8357 goto rw_error;
8358 }
8359 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, data: 1, flags: 0);
8360 if (rc != 0) {
8361 pr_err("error %d\n", rc);
8362 goto rw_error;
8363 }
8364 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, data: 1, flags: 0);
8365 if (rc != 0) {
8366 pr_err("error %d\n", rc);
8367 goto rw_error;
8368 }
8369 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, data: 2, flags: 0);
8370 if (rc != 0) {
8371 pr_err("error %d\n", rc);
8372 goto rw_error;
8373 }
8374 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, data: 2, flags: 0);
8375 if (rc != 0) {
8376 pr_err("error %d\n", rc);
8377 goto rw_error;
8378 }
8379 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, data: 2, flags: 0);
8380 if (rc != 0) {
8381 pr_err("error %d\n", rc);
8382 goto rw_error;
8383 }
8384 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, data: 2, flags: 0);
8385 if (rc != 0) {
8386 pr_err("error %d\n", rc);
8387 goto rw_error;
8388 }
8389 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, data: 2, flags: 0);
8390 if (rc != 0) {
8391 pr_err("error %d\n", rc);
8392 goto rw_error;
8393 }
8394 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, data: 2, flags: 0);
8395 if (rc != 0) {
8396 pr_err("error %d\n", rc);
8397 goto rw_error;
8398 }
8399 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, data: 2, flags: 0);
8400 if (rc != 0) {
8401 pr_err("error %d\n", rc);
8402 goto rw_error;
8403 }
8404 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, data: 3, flags: 0);
8405 if (rc != 0) {
8406 pr_err("error %d\n", rc);
8407 goto rw_error;
8408 }
8409 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, data: 3, flags: 0);
8410 if (rc != 0) {
8411 pr_err("error %d\n", rc);
8412 goto rw_error;
8413 }
8414 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, data: 4, flags: 0);
8415 if (rc != 0) {
8416 pr_err("error %d\n", rc);
8417 goto rw_error;
8418 }
8419 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, data: 4, flags: 0);
8420 if (rc != 0) {
8421 pr_err("error %d\n", rc);
8422 goto rw_error;
8423 }
8424
8425 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, data: 1, flags: 0);
8426 if (rc != 0) {
8427 pr_err("error %d\n", rc);
8428 goto rw_error;
8429 }
8430 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, data: 1, flags: 0);
8431 if (rc != 0) {
8432 pr_err("error %d\n", rc);
8433 goto rw_error;
8434 }
8435 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, data: 1, flags: 0);
8436 if (rc != 0) {
8437 pr_err("error %d\n", rc);
8438 goto rw_error;
8439 }
8440 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, data: 0, flags: 0);
8441 if (rc != 0) {
8442 pr_err("error %d\n", rc);
8443 goto rw_error;
8444 }
8445 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, data: 0, flags: 0);
8446 if (rc != 0) {
8447 pr_err("error %d\n", rc);
8448 goto rw_error;
8449 }
8450
8451 /* No more resets of the IQM, current standard correctly set =>
8452 now AGCs can be configured. */
8453 /* turn on IQMAF. It has to be in front of setAgc**() */
8454 rc = set_iqm_af(demod, active: true);
8455 if (rc != 0) {
8456 pr_err("error %d\n", rc);
8457 goto rw_error;
8458 }
8459 rc = adc_synchronization(demod);
8460 if (rc != 0) {
8461 pr_err("error %d\n", rc);
8462 goto rw_error;
8463 }
8464
8465 rc = init_agc(demod);
8466 if (rc != 0) {
8467 pr_err("error %d\n", rc);
8468 goto rw_error;
8469 }
8470 rc = set_agc_if(demod, agc_settings: &(ext_attr->qam_if_agc_cfg), atomic: false);
8471 if (rc != 0) {
8472 pr_err("error %d\n", rc);
8473 goto rw_error;
8474 }
8475 rc = set_agc_rf(demod, agc_settings: &(ext_attr->qam_rf_agc_cfg), atomic: false);
8476 if (rc != 0) {
8477 pr_err("error %d\n", rc);
8478 goto rw_error;
8479 }
8480 {
8481 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
8482 of only the gain */
8483 struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
8484
8485 qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
8486 rc = ctrl_set_cfg_afe_gain(demod, afe_gain: &qam_pga_cfg);
8487 if (rc != 0) {
8488 pr_err("error %d\n", rc);
8489 goto rw_error;
8490 }
8491 }
8492 rc = ctrl_set_cfg_pre_saw(demod, pre_saw: &(ext_attr->qam_pre_saw_cfg));
8493 if (rc != 0) {
8494 pr_err("error %d\n", rc);
8495 goto rw_error;
8496 }
8497 }
8498
8499 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8500 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8501 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, datasize: sizeof(qam_a_taps), data: ((u8 *)qam_a_taps), flags: 0);
8502 if (rc != 0) {
8503 pr_err("error %d\n", rc);
8504 goto rw_error;
8505 }
8506 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, datasize: sizeof(qam_a_taps), data: ((u8 *)qam_a_taps), flags: 0);
8507 if (rc != 0) {
8508 pr_err("error %d\n", rc);
8509 goto rw_error;
8510 }
8511 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8512 switch (channel->constellation) {
8513 case DRX_CONSTELLATION_QAM64:
8514 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, datasize: sizeof(qam_b64_taps), data: ((u8 *)qam_b64_taps), flags: 0);
8515 if (rc != 0) {
8516 pr_err("error %d\n", rc);
8517 goto rw_error;
8518 }
8519 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, datasize: sizeof(qam_b64_taps), data: ((u8 *)qam_b64_taps), flags: 0);
8520 if (rc != 0) {
8521 pr_err("error %d\n", rc);
8522 goto rw_error;
8523 }
8524 break;
8525 case DRX_CONSTELLATION_QAM256:
8526 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, datasize: sizeof(qam_b256_taps), data: ((u8 *)qam_b256_taps), flags: 0);
8527 if (rc != 0) {
8528 pr_err("error %d\n", rc);
8529 goto rw_error;
8530 }
8531 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, datasize: sizeof(qam_b256_taps), data: ((u8 *)qam_b256_taps), flags: 0);
8532 if (rc != 0) {
8533 pr_err("error %d\n", rc);
8534 goto rw_error;
8535 }
8536 break;
8537 default:
8538 return -EIO;
8539 }
8540 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8541 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, datasize: sizeof(qam_c_taps), data: ((u8 *)qam_c_taps), flags: 0);
8542 if (rc != 0) {
8543 pr_err("error %d\n", rc);
8544 goto rw_error;
8545 }
8546 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, datasize: sizeof(qam_c_taps), data: ((u8 *)qam_c_taps), flags: 0);
8547 if (rc != 0) {
8548 pr_err("error %d\n", rc);
8549 goto rw_error;
8550 }
8551 }
8552
8553 /* SETP 4: constellation specific setup */
8554 switch (channel->constellation) {
8555 case DRX_CONSTELLATION_QAM16:
8556 rc = set_qam16(demod);
8557 if (rc != 0) {
8558 pr_err("error %d\n", rc);
8559 goto rw_error;
8560 }
8561 break;
8562 case DRX_CONSTELLATION_QAM32:
8563 rc = set_qam32(demod);
8564 if (rc != 0) {
8565 pr_err("error %d\n", rc);
8566 goto rw_error;
8567 }
8568 break;
8569 case DRX_CONSTELLATION_QAM64:
8570 rc = set_qam64(demod);
8571 if (rc != 0) {
8572 pr_err("error %d\n", rc);
8573 goto rw_error;
8574 }
8575 break;
8576 case DRX_CONSTELLATION_QAM128:
8577 rc = set_qam128(demod);
8578 if (rc != 0) {
8579 pr_err("error %d\n", rc);
8580 goto rw_error;
8581 }
8582 break;
8583 case DRX_CONSTELLATION_QAM256:
8584 rc = set_qam256(demod);
8585 if (rc != 0) {
8586 pr_err("error %d\n", rc);
8587 goto rw_error;
8588 }
8589 break;
8590 default:
8591 return -EIO;
8592 } /* switch */
8593 }
8594
8595 if ((op & QAM_SET_OP_ALL)) {
8596 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, data: 0, flags: 0);
8597 if (rc != 0) {
8598 pr_err("error %d\n", rc);
8599 goto rw_error;
8600 }
8601
8602 /* Mpeg output has to be in front of FEC active */
8603 rc = set_mpegtei_handling(demod);
8604 if (rc != 0) {
8605 pr_err("error %d\n", rc);
8606 goto rw_error;
8607 }
8608 rc = bit_reverse_mpeg_output(demod);
8609 if (rc != 0) {
8610 pr_err("error %d\n", rc);
8611 goto rw_error;
8612 }
8613 rc = set_mpeg_start_width(demod);
8614 if (rc != 0) {
8615 pr_err("error %d\n", rc);
8616 goto rw_error;
8617 }
8618 {
8619 /* TODO: move to set_standard after hardware reset value problem is solved */
8620 /* Configure initial MPEG output */
8621 struct drx_cfg_mpeg_output cfg_mpeg_output;
8622
8623 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
8624 cfg_mpeg_output.enable_mpeg_output = true;
8625
8626 rc = ctrl_set_cfg_mpeg_output(demod, cfg_data: &cfg_mpeg_output);
8627 if (rc != 0) {
8628 pr_err("error %d\n", rc);
8629 goto rw_error;
8630 }
8631 }
8632 }
8633
8634 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8635
8636 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
8637 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8638 SCU_RAM_COMMAND_CMD_DEMOD_START;
8639 cmd_scu.parameter_len = 0;
8640 cmd_scu.result_len = 1;
8641 cmd_scu.parameter = NULL;
8642 cmd_scu.result = &cmd_result;
8643 rc = scu_command(dev_addr, cmd: &cmd_scu);
8644 if (rc != 0) {
8645 pr_err("error %d\n", rc);
8646 goto rw_error;
8647 }
8648 }
8649
8650 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, flags: 0);
8651 if (rc != 0) {
8652 pr_err("error %d\n", rc);
8653 goto rw_error;
8654 }
8655 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, flags: 0);
8656 if (rc != 0) {
8657 pr_err("error %d\n", rc);
8658 goto rw_error;
8659 }
8660 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, flags: 0);
8661 if (rc != 0) {
8662 pr_err("error %d\n", rc);
8663 goto rw_error;
8664 }
8665
8666 return 0;
8667rw_error:
8668 return rc;
8669}
8670
8671/*============================================================================*/
8672static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
8673
8674static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
8675{
8676 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8677 struct drxj_data *ext_attr = demod->my_ext_attr;
8678 int rc;
8679 u32 iqm_fs_rate_ofs = 0;
8680 u32 iqm_fs_rate_lo = 0;
8681 u16 qam_ctl_ena = 0;
8682 u16 data = 0;
8683 u16 equ_mode = 0;
8684 u16 fsm_state = 0;
8685 int i = 0;
8686 int ofsofs = 0;
8687
8688 /* Silence the controlling of lc, equ, and the acquisition state machine */
8689 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, data: &qam_ctl_ena, flags: 0);
8690 if (rc != 0) {
8691 pr_err("error %d\n", rc);
8692 goto rw_error;
8693 }
8694 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, data: qam_ctl_ena & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M), flags: 0);
8695 if (rc != 0) {
8696 pr_err("error %d\n", rc);
8697 goto rw_error;
8698 }
8699
8700 /* freeze the frequency control loop */
8701 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, data: 0, flags: 0);
8702 if (rc != 0) {
8703 pr_err("error %d\n", rc);
8704 goto rw_error;
8705 }
8706 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, data: 0, flags: 0);
8707 if (rc != 0) {
8708 pr_err("error %d\n", rc);
8709 goto rw_error;
8710 }
8711
8712 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, data: &iqm_fs_rate_ofs, flags: 0);
8713 if (rc != 0) {
8714 pr_err("error %d\n", rc);
8715 goto rw_error;
8716 }
8717 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, data: &iqm_fs_rate_lo, flags: 0);
8718 if (rc != 0) {
8719 pr_err("error %d\n", rc);
8720 goto rw_error;
8721 }
8722 ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
8723 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
8724 iqm_fs_rate_ofs -= 2 * ofsofs;
8725
8726 /* freeze dq/fq updating */
8727 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, data: &data, flags: 0);
8728 if (rc != 0) {
8729 pr_err("error %d\n", rc);
8730 goto rw_error;
8731 }
8732 data = (data & 0xfff9);
8733 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, flags: 0);
8734 if (rc != 0) {
8735 pr_err("error %d\n", rc);
8736 goto rw_error;
8737 }
8738 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, flags: 0);
8739 if (rc != 0) {
8740 pr_err("error %d\n", rc);
8741 goto rw_error;
8742 }
8743
8744 /* lc_cp / _ci / _ca */
8745 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, data: 0, flags: 0);
8746 if (rc != 0) {
8747 pr_err("error %d\n", rc);
8748 goto rw_error;
8749 }
8750 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, data: 0, flags: 0);
8751 if (rc != 0) {
8752 pr_err("error %d\n", rc);
8753 goto rw_error;
8754 }
8755 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, data: 0, flags: 0);
8756 if (rc != 0) {
8757 pr_err("error %d\n", rc);
8758 goto rw_error;
8759 }
8760
8761 /* flip the spec */
8762 rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, data: iqm_fs_rate_ofs, flags: 0);
8763 if (rc != 0) {
8764 pr_err("error %d\n", rc);
8765 goto rw_error;
8766 }
8767 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
8768 ext_attr->pos_image = !ext_attr->pos_image;
8769
8770 /* freeze dq/fq updating */
8771 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, data: &data, flags: 0);
8772 if (rc != 0) {
8773 pr_err("error %d\n", rc);
8774 goto rw_error;
8775 }
8776 equ_mode = data;
8777 data = (data & 0xfff9);
8778 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, flags: 0);
8779 if (rc != 0) {
8780 pr_err("error %d\n", rc);
8781 goto rw_error;
8782 }
8783 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, flags: 0);
8784 if (rc != 0) {
8785 pr_err("error %d\n", rc);
8786 goto rw_error;
8787 }
8788
8789 for (i = 0; i < 28; i++) {
8790 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), data: &data, flags: 0);
8791 if (rc != 0) {
8792 pr_err("error %d\n", rc);
8793 goto rw_error;
8794 }
8795 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), data: -data, flags: 0);
8796 if (rc != 0) {
8797 pr_err("error %d\n", rc);
8798 goto rw_error;
8799 }
8800 }
8801
8802 for (i = 0; i < 24; i++) {
8803 rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), data: &data, flags: 0);
8804 if (rc != 0) {
8805 pr_err("error %d\n", rc);
8806 goto rw_error;
8807 }
8808 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), data: -data, flags: 0);
8809 if (rc != 0) {
8810 pr_err("error %d\n", rc);
8811 goto rw_error;
8812 }
8813 }
8814
8815 data = equ_mode;
8816 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, flags: 0);
8817 if (rc != 0) {
8818 pr_err("error %d\n", rc);
8819 goto rw_error;
8820 }
8821 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, flags: 0);
8822 if (rc != 0) {
8823 pr_err("error %d\n", rc);
8824 goto rw_error;
8825 }
8826
8827 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, data: 4, flags: 0);
8828 if (rc != 0) {
8829 pr_err("error %d\n", rc);
8830 goto rw_error;
8831 }
8832
8833 i = 0;
8834 while ((fsm_state != 4) && (i++ < 100)) {
8835 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, data: &fsm_state, flags: 0);
8836 if (rc != 0) {
8837 pr_err("error %d\n", rc);
8838 goto rw_error;
8839 }
8840 }
8841 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, data: (qam_ctl_ena | 0x0016), flags: 0);
8842 if (rc != 0) {
8843 pr_err("error %d\n", rc);
8844 goto rw_error;
8845 }
8846
8847 return 0;
8848rw_error:
8849 return rc;
8850
8851}
8852
8853#define NO_LOCK 0x0
8854#define DEMOD_LOCKED 0x1
8855#define SYNC_FLIPPED 0x2
8856#define SPEC_MIRRORED 0x4
8857/*
8858* \fn int qam64auto ()
8859* \brief auto do sync pattern switching and mirroring.
8860* \param demod: instance of demod.
8861* \param channel: pointer to channel data.
8862* \param tuner_freq_offset: tuner frequency offset.
8863* \param lock_status: pointer to lock status.
8864* \return int.
8865*/
8866static int
8867qam64auto(struct drx_demod_instance *demod,
8868 struct drx_channel *channel,
8869 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
8870{
8871 struct drxj_data *ext_attr = demod->my_ext_attr;
8872 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8873 struct drx39xxj_state *state = dev_addr->user_data;
8874 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
8875 int rc;
8876 u32 lck_state = NO_LOCK;
8877 u32 start_time = 0;
8878 u32 d_locked_time = 0;
8879 u32 timeout_ofs = 0;
8880 u16 data = 0;
8881
8882 /* external attributes for storing acquired channel constellation */
8883 *lock_status = DRX_NOT_LOCKED;
8884 start_time = jiffies_to_msecs(j: jiffies);
8885 lck_state = NO_LOCK;
8886 do {
8887 rc = ctrl_lock_status(demod, lock_stat: lock_status);
8888 if (rc != 0) {
8889 pr_err("error %d\n", rc);
8890 goto rw_error;
8891 }
8892
8893 switch (lck_state) {
8894 case NO_LOCK:
8895 if (*lock_status == DRXJ_DEMOD_LOCK) {
8896 rc = ctrl_get_qam_sig_quality(demod);
8897 if (rc != 0) {
8898 pr_err("error %d\n", rc);
8899 goto rw_error;
8900 }
8901 if (p->cnr.stat[0].svalue > 20800) {
8902 lck_state = DEMOD_LOCKED;
8903 /* some delay to see if fec_lock possible TODO find the right value */
8904 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
8905 d_locked_time = jiffies_to_msecs(j: jiffies);
8906 }
8907 }
8908 break;
8909 case DEMOD_LOCKED:
8910 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
8911 ((jiffies_to_msecs(j: jiffies) - d_locked_time) >
8912 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8913 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data: &data, flags: 0);
8914 if (rc != 0) {
8915 pr_err("error %d\n", rc);
8916 goto rw_error;
8917 }
8918 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data: data | 0x1, flags: 0);
8919 if (rc != 0) {
8920 pr_err("error %d\n", rc);
8921 goto rw_error;
8922 }
8923 lck_state = SYNC_FLIPPED;
8924 msleep(msecs: 10);
8925 }
8926 break;
8927 case SYNC_FLIPPED:
8928 if (*lock_status == DRXJ_DEMOD_LOCK) {
8929 if (channel->mirror == DRX_MIRROR_AUTO) {
8930 /* flip sync pattern back */
8931 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data: &data, flags: 0);
8932 if (rc != 0) {
8933 pr_err("error %d\n", rc);
8934 goto rw_error;
8935 }
8936 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data: data & 0xFFFE, flags: 0);
8937 if (rc != 0) {
8938 pr_err("error %d\n", rc);
8939 goto rw_error;
8940 }
8941 /* flip spectrum */
8942 ext_attr->mirror = DRX_MIRROR_YES;
8943 rc = qam_flip_spec(demod, channel);
8944 if (rc != 0) {
8945 pr_err("error %d\n", rc);
8946 goto rw_error;
8947 }
8948 lck_state = SPEC_MIRRORED;
8949 /* reset timer TODO: still need 500ms? */
8950 start_time = d_locked_time =
8951 jiffies_to_msecs(j: jiffies);
8952 timeout_ofs = 0;
8953 } else { /* no need to wait lock */
8954
8955 start_time =
8956 jiffies_to_msecs(j: jiffies) -
8957 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
8958 }
8959 }
8960 break;
8961 case SPEC_MIRRORED:
8962 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
8963 ((jiffies_to_msecs(j: jiffies) - d_locked_time) >
8964 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8965 rc = ctrl_get_qam_sig_quality(demod);
8966 if (rc != 0) {
8967 pr_err("error %d\n", rc);
8968 goto rw_error;
8969 }
8970 if (p->cnr.stat[0].svalue > 20800) {
8971 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data: &data, flags: 0);
8972 if (rc != 0) {
8973 pr_err("error %d\n", rc);
8974 goto rw_error;
8975 }
8976 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data: data | 0x1, flags: 0);
8977 if (rc != 0) {
8978 pr_err("error %d\n", rc);
8979 goto rw_error;
8980 }
8981 /* no need to wait lock */
8982 start_time =
8983 jiffies_to_msecs(j: jiffies) -
8984 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
8985 }
8986 }
8987 break;
8988 default:
8989 break;
8990 }
8991 msleep(msecs: 10);
8992 } while
8993 ((*lock_status != DRX_LOCKED) &&
8994 (*lock_status != DRX_NEVER_LOCK) &&
8995 ((jiffies_to_msecs(j: jiffies) - start_time) <
8996 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
8997 );
8998 /* Returning control to application ... */
8999
9000 return 0;
9001rw_error:
9002 return rc;
9003}
9004
9005/*
9006* \fn int qam256auto ()
9007* \brief auto do sync pattern switching and mirroring.
9008* \param demod: instance of demod.
9009* \param channel: pointer to channel data.
9010* \param tuner_freq_offset: tuner frequency offset.
9011* \param lock_status: pointer to lock status.
9012* \return int.
9013*/
9014static int
9015qam256auto(struct drx_demod_instance *demod,
9016 struct drx_channel *channel,
9017 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
9018{
9019 struct drxj_data *ext_attr = demod->my_ext_attr;
9020 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9021 struct drx39xxj_state *state = dev_addr->user_data;
9022 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9023 int rc;
9024 u32 lck_state = NO_LOCK;
9025 u32 start_time = 0;
9026 u32 d_locked_time = 0;
9027 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
9028
9029 /* external attributes for storing acquired channel constellation */
9030 *lock_status = DRX_NOT_LOCKED;
9031 start_time = jiffies_to_msecs(j: jiffies);
9032 lck_state = NO_LOCK;
9033 do {
9034 rc = ctrl_lock_status(demod, lock_stat: lock_status);
9035 if (rc != 0) {
9036 pr_err("error %d\n", rc);
9037 goto rw_error;
9038 }
9039 switch (lck_state) {
9040 case NO_LOCK:
9041 if (*lock_status == DRXJ_DEMOD_LOCK) {
9042 rc = ctrl_get_qam_sig_quality(demod);
9043 if (rc != 0) {
9044 pr_err("error %d\n", rc);
9045 goto rw_error;
9046 }
9047 if (p->cnr.stat[0].svalue > 26800) {
9048 lck_state = DEMOD_LOCKED;
9049 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
9050 d_locked_time = jiffies_to_msecs(j: jiffies);
9051 }
9052 }
9053 break;
9054 case DEMOD_LOCKED:
9055 if (*lock_status == DRXJ_DEMOD_LOCK) {
9056 if ((channel->mirror == DRX_MIRROR_AUTO) &&
9057 ((jiffies_to_msecs(j: jiffies) - d_locked_time) >
9058 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
9059 ext_attr->mirror = DRX_MIRROR_YES;
9060 rc = qam_flip_spec(demod, channel);
9061 if (rc != 0) {
9062 pr_err("error %d\n", rc);
9063 goto rw_error;
9064 }
9065 lck_state = SPEC_MIRRORED;
9066 /* reset timer TODO: still need 300ms? */
9067 start_time = jiffies_to_msecs(j: jiffies);
9068 timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
9069 }
9070 }
9071 break;
9072 case SPEC_MIRRORED:
9073 break;
9074 default:
9075 break;
9076 }
9077 msleep(msecs: 10);
9078 } while
9079 ((*lock_status < DRX_LOCKED) &&
9080 (*lock_status != DRX_NEVER_LOCK) &&
9081 ((jiffies_to_msecs(j: jiffies) - start_time) <
9082 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
9083
9084 return 0;
9085rw_error:
9086 return rc;
9087}
9088
9089/*
9090* \fn int set_qam_channel ()
9091* \brief Set QAM channel according to the requested constellation.
9092* \param demod: instance of demod.
9093* \param channel: pointer to channel data.
9094* \return int.
9095*/
9096static int
9097set_qam_channel(struct drx_demod_instance *demod,
9098 struct drx_channel *channel, s32 tuner_freq_offset)
9099{
9100 struct drxj_data *ext_attr = NULL;
9101 int rc;
9102 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
9103 bool auto_flag = false;
9104
9105 /* external attributes for storing acquired channel constellation */
9106 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9107
9108 /* set QAM channel constellation */
9109 switch (channel->constellation) {
9110 case DRX_CONSTELLATION_QAM16:
9111 case DRX_CONSTELLATION_QAM32:
9112 case DRX_CONSTELLATION_QAM128:
9113 return -EINVAL;
9114 case DRX_CONSTELLATION_QAM64:
9115 case DRX_CONSTELLATION_QAM256:
9116 if (ext_attr->standard != DRX_STANDARD_ITU_B)
9117 return -EINVAL;
9118
9119 ext_attr->constellation = channel->constellation;
9120 if (channel->mirror == DRX_MIRROR_AUTO)
9121 ext_attr->mirror = DRX_MIRROR_NO;
9122 else
9123 ext_attr->mirror = channel->mirror;
9124
9125 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
9126 if (rc != 0) {
9127 pr_err("error %d\n", rc);
9128 goto rw_error;
9129 }
9130
9131 if (channel->constellation == DRX_CONSTELLATION_QAM64)
9132 rc = qam64auto(demod, channel, tuner_freq_offset,
9133 lock_status: &lock_status);
9134 else
9135 rc = qam256auto(demod, channel, tuner_freq_offset,
9136 lock_status: &lock_status);
9137 if (rc != 0) {
9138 pr_err("error %d\n", rc);
9139 goto rw_error;
9140 }
9141 break;
9142 case DRX_CONSTELLATION_AUTO: /* for channel scan */
9143 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9144 u16 qam_ctl_ena = 0;
9145
9146 auto_flag = true;
9147
9148 /* try to lock default QAM constellation: QAM256 */
9149 channel->constellation = DRX_CONSTELLATION_QAM256;
9150 ext_attr->constellation = DRX_CONSTELLATION_QAM256;
9151 if (channel->mirror == DRX_MIRROR_AUTO)
9152 ext_attr->mirror = DRX_MIRROR_NO;
9153 else
9154 ext_attr->mirror = channel->mirror;
9155 rc = set_qam(demod, channel, tuner_freq_offset,
9156 QAM_SET_OP_ALL);
9157 if (rc != 0) {
9158 pr_err("error %d\n", rc);
9159 goto rw_error;
9160 }
9161 rc = qam256auto(demod, channel, tuner_freq_offset,
9162 lock_status: &lock_status);
9163 if (rc != 0) {
9164 pr_err("error %d\n", rc);
9165 goto rw_error;
9166 }
9167
9168 if (lock_status >= DRX_LOCKED) {
9169 channel->constellation = DRX_CONSTELLATION_AUTO;
9170 break;
9171 }
9172
9173 /* QAM254 not locked. Try QAM64 constellation */
9174 channel->constellation = DRX_CONSTELLATION_QAM64;
9175 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9176 if (channel->mirror == DRX_MIRROR_AUTO)
9177 ext_attr->mirror = DRX_MIRROR_NO;
9178 else
9179 ext_attr->mirror = channel->mirror;
9180
9181 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr,
9182 SCU_RAM_QAM_CTL_ENA__A,
9183 data: &qam_ctl_ena, flags: 0);
9184 if (rc != 0) {
9185 pr_err("error %d\n", rc);
9186 goto rw_error;
9187 }
9188 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr,
9189 SCU_RAM_QAM_CTL_ENA__A,
9190 data: qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, flags: 0);
9191 if (rc != 0) {
9192 pr_err("error %d\n", rc);
9193 goto rw_error;
9194 }
9195 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr,
9196 SCU_RAM_QAM_FSM_STATE_TGT__A,
9197 data: 0x2, flags: 0);
9198 if (rc != 0) {
9199 pr_err("error %d\n", rc);
9200 goto rw_error;
9201 } /* force to rate hunting */
9202
9203 rc = set_qam(demod, channel, tuner_freq_offset,
9204 QAM_SET_OP_CONSTELLATION);
9205 if (rc != 0) {
9206 pr_err("error %d\n", rc);
9207 goto rw_error;
9208 }
9209 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr,
9210 SCU_RAM_QAM_CTL_ENA__A,
9211 data: qam_ctl_ena, flags: 0);
9212 if (rc != 0) {
9213 pr_err("error %d\n", rc);
9214 goto rw_error;
9215 }
9216
9217 rc = qam64auto(demod, channel, tuner_freq_offset,
9218 lock_status: &lock_status);
9219 if (rc != 0) {
9220 pr_err("error %d\n", rc);
9221 goto rw_error;
9222 }
9223
9224 channel->constellation = DRX_CONSTELLATION_AUTO;
9225 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9226 u16 qam_ctl_ena = 0;
9227
9228 channel->constellation = DRX_CONSTELLATION_QAM64;
9229 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9230 auto_flag = true;
9231
9232 if (channel->mirror == DRX_MIRROR_AUTO)
9233 ext_attr->mirror = DRX_MIRROR_NO;
9234 else
9235 ext_attr->mirror = channel->mirror;
9236 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr,
9237 SCU_RAM_QAM_CTL_ENA__A,
9238 data: &qam_ctl_ena, flags: 0);
9239 if (rc != 0) {
9240 pr_err("error %d\n", rc);
9241 goto rw_error;
9242 }
9243 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr,
9244 SCU_RAM_QAM_CTL_ENA__A,
9245 data: qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, flags: 0);
9246 if (rc != 0) {
9247 pr_err("error %d\n", rc);
9248 goto rw_error;
9249 }
9250 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr,
9251 SCU_RAM_QAM_FSM_STATE_TGT__A,
9252 data: 0x2, flags: 0);
9253 if (rc != 0) {
9254 pr_err("error %d\n", rc);
9255 goto rw_error;
9256 } /* force to rate hunting */
9257
9258 rc = set_qam(demod, channel, tuner_freq_offset,
9259 QAM_SET_OP_CONSTELLATION);
9260 if (rc != 0) {
9261 pr_err("error %d\n", rc);
9262 goto rw_error;
9263 }
9264 rc = drxj_dap_write_reg16(dev_addr: demod->my_i2c_dev_addr,
9265 SCU_RAM_QAM_CTL_ENA__A,
9266 data: qam_ctl_ena, flags: 0);
9267 if (rc != 0) {
9268 pr_err("error %d\n", rc);
9269 goto rw_error;
9270 }
9271 rc = qam64auto(demod, channel, tuner_freq_offset,
9272 lock_status: &lock_status);
9273 if (rc != 0) {
9274 pr_err("error %d\n", rc);
9275 goto rw_error;
9276 }
9277 channel->constellation = DRX_CONSTELLATION_AUTO;
9278 } else {
9279 return -EINVAL;
9280 }
9281 break;
9282 default:
9283 return -EINVAL;
9284 }
9285
9286 return 0;
9287rw_error:
9288 /* restore starting value */
9289 if (auto_flag)
9290 channel->constellation = DRX_CONSTELLATION_AUTO;
9291 return rc;
9292}
9293
9294/*============================================================================*/
9295
9296/*
9297* \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
9298* \brief Get RS error count in QAM mode (used for post RS BER calculation)
9299* \return Error code
9300*
9301* precondition: measurement period & measurement prescale must be set
9302*
9303*/
9304static int
9305get_qamrs_err_count(struct i2c_device_addr *dev_addr,
9306 struct drxjrs_errors *rs_errors)
9307{
9308 int rc;
9309 u16 nr_bit_errors = 0,
9310 nr_symbol_errors = 0,
9311 nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
9312
9313 /* check arguments */
9314 if (dev_addr == NULL)
9315 return -EINVAL;
9316
9317 /* all reported errors are received in the */
9318 /* most recently finished measurement period */
9319 /* no of pre RS bit errors */
9320 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, data: &nr_bit_errors, flags: 0);
9321 if (rc != 0) {
9322 pr_err("error %d\n", rc);
9323 goto rw_error;
9324 }
9325 /* no of symbol errors */
9326 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, data: &nr_symbol_errors, flags: 0);
9327 if (rc != 0) {
9328 pr_err("error %d\n", rc);
9329 goto rw_error;
9330 }
9331 /* no of packet errors */
9332 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, data: &nr_packet_errors, flags: 0);
9333 if (rc != 0) {
9334 pr_err("error %d\n", rc);
9335 goto rw_error;
9336 }
9337 /* no of failures to decode */
9338 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, data: &nr_failures, flags: 0);
9339 if (rc != 0) {
9340 pr_err("error %d\n", rc);
9341 goto rw_error;
9342 }
9343 /* no of post RS bit erros */
9344 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, data: &nr_snc_par_fail_count, flags: 0);
9345 if (rc != 0) {
9346 pr_err("error %d\n", rc);
9347 goto rw_error;
9348 }
9349 /* TODO: NOTE */
9350 /* These register values are fetched in non-atomic fashion */
9351 /* It is possible that the read values contain unrelated information */
9352
9353 rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
9354 rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
9355 rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
9356 rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
9357 rs_errors->nr_snc_par_fail_count =
9358 nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
9359
9360 return 0;
9361rw_error:
9362 return rc;
9363}
9364
9365/*============================================================================*/
9366
9367/*
9368 * \fn int get_sig_strength()
9369 * \brief Retrieve signal strength for VSB and QAM.
9370 * \param demod Pointer to demod instance
9371 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
9372 * \return int.
9373 * \retval 0 sig_strength contains valid data.
9374 * \retval -EINVAL sig_strength is NULL.
9375 * \retval -EIO Erroneous data, sig_strength contains invalid data.
9376 */
9377#define DRXJ_AGC_TOP 0x2800
9378#define DRXJ_AGC_SNS 0x1600
9379#define DRXJ_RFAGC_MAX 0x3fff
9380#define DRXJ_RFAGC_MIN 0x800
9381
9382static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
9383{
9384 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9385 int rc;
9386 u16 rf_gain = 0;
9387 u16 if_gain = 0;
9388 u16 if_agc_sns = 0;
9389 u16 if_agc_top = 0;
9390 u16 rf_agc_max = 0;
9391 u16 rf_agc_min = 0;
9392
9393 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, data: &if_gain, flags: 0);
9394 if (rc != 0) {
9395 pr_err("error %d\n", rc);
9396 goto rw_error;
9397 }
9398 if_gain &= IQM_AF_AGC_IF__M;
9399 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, data: &rf_gain, flags: 0);
9400 if (rc != 0) {
9401 pr_err("error %d\n", rc);
9402 goto rw_error;
9403 }
9404 rf_gain &= IQM_AF_AGC_RF__M;
9405
9406 if_agc_sns = DRXJ_AGC_SNS;
9407 if_agc_top = DRXJ_AGC_TOP;
9408 rf_agc_max = DRXJ_RFAGC_MAX;
9409 rf_agc_min = DRXJ_RFAGC_MIN;
9410
9411 if (if_gain > if_agc_top) {
9412 if (rf_gain > rf_agc_max)
9413 *sig_strength = 100;
9414 else if (rf_gain > rf_agc_min) {
9415 if (rf_agc_max == rf_agc_min) {
9416 pr_err("error: rf_agc_max == rf_agc_min\n");
9417 return -EIO;
9418 }
9419 *sig_strength =
9420 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
9421 rf_agc_min);
9422 } else
9423 *sig_strength = 75;
9424 } else if (if_gain > if_agc_sns) {
9425 if (if_agc_top == if_agc_sns) {
9426 pr_err("error: if_agc_top == if_agc_sns\n");
9427 return -EIO;
9428 }
9429 *sig_strength =
9430 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
9431 } else {
9432 if (!if_agc_sns) {
9433 pr_err("error: if_agc_sns is zero!\n");
9434 return -EIO;
9435 }
9436 *sig_strength = (20 * if_gain / if_agc_sns);
9437 }
9438
9439 if (*sig_strength <= 7)
9440 *sig_strength = 0;
9441
9442 return 0;
9443rw_error:
9444 return rc;
9445}
9446
9447/*
9448* \fn int ctrl_get_qam_sig_quality()
9449* \brief Retrieve QAM signal quality from device.
9450* \param devmod Pointer to demodulator instance.
9451* \param sig_quality Pointer to signal quality data.
9452* \return int.
9453* \retval 0 sig_quality contains valid data.
9454* \retval -EINVAL sig_quality is NULL.
9455* \retval -EIO Erroneous data, sig_quality contains invalid data.
9456
9457* Pre-condition: Device must be started and in lock.
9458*/
9459static int
9460ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9461{
9462 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9463 struct drxj_data *ext_attr = demod->my_ext_attr;
9464 struct drx39xxj_state *state = dev_addr->user_data;
9465 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9466 struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
9467 enum drx_modulation constellation = ext_attr->constellation;
9468 int rc;
9469
9470 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
9471 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
9472 u32 pkt_errs = 0; /* no of packet errors in RS */
9473 u16 qam_sl_err_power = 0; /* accumulated error between raw and sliced symbols */
9474 u16 qsym_err_vd = 0; /* quadrature symbol errors in QAM_VD */
9475 u16 fec_oc_period = 0; /* SNC sync failure measurement period */
9476 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
9477 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
9478 /* calculation constants */
9479 u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
9480 u32 qam_sl_sig_power = 0; /* used for MER, depends of QAM constellation */
9481 /* intermediate results */
9482 u32 e = 0; /* exponent value used for QAM BER/SER */
9483 u32 m = 0; /* mantisa value used for QAM BER/SER */
9484 u32 ber_cnt = 0; /* BER count */
9485 /* signal quality info */
9486 u32 qam_sl_mer = 0; /* QAM MER */
9487 u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
9488 u32 qam_post_rs_ber = 0; /* Post RedSolomon BER */
9489 u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
9490 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
9491 u16 qam_vd_period = 0; /* Viterbi Measurement period */
9492 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
9493
9494 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9495
9496 /* read the physical registers */
9497 /* Get the RS error data */
9498 rc = get_qamrs_err_count(dev_addr, rs_errors: &measuredrs_errors);
9499 if (rc != 0) {
9500 pr_err("error %d\n", rc);
9501 goto rw_error;
9502 }
9503 /* get the register value needed for MER */
9504 rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, data: &qam_sl_err_power, flags: 0);
9505 if (rc != 0) {
9506 pr_err("error %d\n", rc);
9507 goto rw_error;
9508 }
9509 /* get the register value needed for post RS BER */
9510 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, data: &fec_oc_period, flags: 0);
9511 if (rc != 0) {
9512 pr_err("error %d\n", rc);
9513 goto rw_error;
9514 }
9515
9516 /* get constants needed for signal quality calculation */
9517 fec_rs_period = ext_attr->fec_rs_period;
9518 fec_rs_prescale = ext_attr->fec_rs_prescale;
9519 rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
9520 qam_vd_period = ext_attr->qam_vd_period;
9521 qam_vd_prescale = ext_attr->qam_vd_prescale;
9522 vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
9523
9524 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
9525 switch (constellation) {
9526 case DRX_CONSTELLATION_QAM16:
9527 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
9528 break;
9529 case DRX_CONSTELLATION_QAM32:
9530 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
9531 break;
9532 case DRX_CONSTELLATION_QAM64:
9533 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
9534 break;
9535 case DRX_CONSTELLATION_QAM128:
9536 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
9537 break;
9538 case DRX_CONSTELLATION_QAM256:
9539 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
9540 break;
9541 default:
9542 rc = -EIO;
9543 goto rw_error;
9544 }
9545
9546 /* ------------------------------ */
9547 /* MER Calculation */
9548 /* ------------------------------ */
9549 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
9550
9551 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
9552 if (qam_sl_err_power == 0)
9553 qam_sl_mer = 0;
9554 else
9555 qam_sl_mer = log1_times100(x: qam_sl_sig_power) - log1_times100(x: (u32)qam_sl_err_power);
9556
9557 /* ----------------------------------------- */
9558 /* Pre Viterbi Symbol Error Rate Calculation */
9559 /* ----------------------------------------- */
9560 /* pre viterbi SER is good if it is below 0.025 */
9561
9562 /* get the register value */
9563 /* no of quadrature symbol errors */
9564 rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, data: &qsym_err_vd, flags: 0);
9565 if (rc != 0) {
9566 pr_err("error %d\n", rc);
9567 goto rw_error;
9568 }
9569 /* Extract the Exponent and the Mantisa */
9570 /* of number of quadrature symbol errors */
9571 e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
9572 QAM_VD_NR_QSYM_ERRORS_EXP__B;
9573 m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
9574 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
9575
9576 if ((m << e) >> 3 > 549752)
9577 qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9578 else
9579 qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
9580
9581 /* --------------------------------------- */
9582 /* pre and post RedSolomon BER Calculation */
9583 /* --------------------------------------- */
9584 /* pre RS BER is good if it is below 3.5e-4 */
9585
9586 /* get the register values */
9587 pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
9588 pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
9589
9590 /* Extract the Exponent and the Mantisa of the */
9591 /* pre Reed-Solomon bit error count */
9592 e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
9593 FEC_RS_NR_BIT_ERRORS_EXP__B;
9594 m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
9595 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
9596
9597 ber_cnt = m << e;
9598
9599 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
9600 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
9601 qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
9602 else
9603 qam_pre_rs_ber = ber_cnt;
9604
9605 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
9606 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
9607 /*
9608 => c = (1000000*100*11.17)/1504 =
9609 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
9610 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
9611 *100 and /100 is for more precision.
9612 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
9613
9614 Precision errors still possible.
9615 */
9616 if (!fec_oc_period) {
9617 qam_post_rs_ber = 0xFFFFFFFF;
9618 } else {
9619 e = post_bit_err_rs * 742686;
9620 m = fec_oc_period * 100;
9621 qam_post_rs_ber = e / m;
9622 }
9623
9624 /* fill signal quality data structure */
9625 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9626 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9627 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9628 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9629 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
9630 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
9631
9632 p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
9633 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9634 p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
9635 p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9636 } else {
9637 p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
9638 p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9639 }
9640
9641 p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;
9642 p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9643
9644 p->block_error.stat[0].uvalue += pkt_errs;
9645
9646#ifdef DRXJ_SIGNAL_ACCUM_ERR
9647 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
9648 if (rc != 0) {
9649 pr_err("error %d\n", rc);
9650 goto rw_error;
9651 }
9652#endif
9653
9654 return 0;
9655rw_error:
9656 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9657 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9658 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9659 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9660 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9661 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9662
9663 return rc;
9664}
9665
9666#endif /* #ifndef DRXJ_VSB_ONLY */
9667
9668/*============================================================================*/
9669/*== END QAM DATAPATH FUNCTIONS ==*/
9670/*============================================================================*/
9671
9672/*============================================================================*/
9673/*============================================================================*/
9674/*== ATV DATAPATH FUNCTIONS ==*/
9675/*============================================================================*/
9676/*============================================================================*/
9677
9678/*
9679 Implementation notes.
9680
9681 NTSC/FM AGCs
9682
9683 Four AGCs are used for NTSC:
9684 (1) RF (used to attenuate the input signal in case of to much power)
9685 (2) IF (used to attenuate the input signal in case of to much power)
9686 (3) Video AGC (used to amplify the output signal in case input to low)
9687 (4) SIF AGC (used to amplify the output signal in case input to low)
9688
9689 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
9690 that the coupling between Video AGC and the RF and IF AGCs also works in
9691 favor of the SIF AGC.
9692
9693 Three AGCs are used for FM:
9694 (1) RF (used to attenuate the input signal in case of to much power)
9695 (2) IF (used to attenuate the input signal in case of to much power)
9696 (3) SIF AGC (used to amplify the output signal in case input to low)
9697
9698 The SIF AGC is now coupled to the RF/IF AGCs.
9699 The SIF AGC is needed for both SIF output and the internal SIF signal to
9700 the AUD block.
9701
9702 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
9703 the ATV block. The AGC control algorithms are all implemented in
9704 microcode.
9705
9706 ATV SETTINGS
9707
9708 (Shadow settings will not be used for now, they will be implemented
9709 later on because of the schedule)
9710
9711 Several HW/SCU "settings" can be used for ATV. The standard selection
9712 will reset most of these settings. To avoid that the end user application
9713 has to perform these settings each time the ATV or FM standards is
9714 selected the driver will shadow these settings. This enables the end user
9715 to perform the settings only once after a drx_open(). The driver must
9716 write the shadow settings to HW/SCU in case:
9717 ( setstandard FM/ATV) ||
9718 ( settings have changed && FM/ATV standard is active)
9719 The shadow settings will be stored in the device specific data container.
9720 A set of flags will be defined to flag changes in shadow settings.
9721 A routine will be implemented to write all changed shadow settings to
9722 HW/SCU.
9723
9724 The "settings" will consist of: AGC settings, filter settings etc.
9725
9726 Disadvantage of use of shadow settings:
9727 Direct changes in HW/SCU registers will not be reflected in the
9728 shadow settings and these changes will be overwritten during a next
9729 update. This can happen during evaluation. This will not be a problem
9730 for normal customer usage.
9731*/
9732/* -------------------------------------------------------------------------- */
9733
9734/*
9735* \fn int power_down_atv ()
9736* \brief Power down ATV.
9737* \param demod instance of demodulator
9738* \param standard either NTSC or FM (sub strandard for ATV )
9739* \return int.
9740*
9741* Stops and thus resets ATV and IQM block
9742* SIF and CVBS ADC are powered down
9743* Calls audio power down
9744*/
9745static int
9746power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
9747{
9748 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9749 struct drxjscu_cmd cmd_scu = { /* command */ 0,
9750 /* parameter_len */ 0,
9751 /* result_len */ 0,
9752 /* *parameter */ NULL,
9753 /* *result */ NULL
9754 };
9755 int rc;
9756 u16 cmd_result = 0;
9757
9758 /* ATV NTSC */
9759
9760 /* Stop ATV SCU (will reset ATV and IQM hardware */
9761 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
9762 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9763 cmd_scu.parameter_len = 0;
9764 cmd_scu.result_len = 1;
9765 cmd_scu.parameter = NULL;
9766 cmd_scu.result = &cmd_result;
9767 rc = scu_command(dev_addr, cmd: &cmd_scu);
9768 if (rc != 0) {
9769 pr_err("error %d\n", rc);
9770 goto rw_error;
9771 }
9772 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
9773 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, data: (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), flags: 0);
9774 if (rc != 0) {
9775 pr_err("error %d\n", rc);
9776 goto rw_error;
9777 }
9778
9779 rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, flags: 0);
9780 if (rc != 0) {
9781 pr_err("error %d\n", rc);
9782 goto rw_error;
9783 }
9784 if (primary) {
9785 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, flags: 0);
9786 if (rc != 0) {
9787 pr_err("error %d\n", rc);
9788 goto rw_error;
9789 }
9790 rc = set_iqm_af(demod, active: false);
9791 if (rc != 0) {
9792 pr_err("error %d\n", rc);
9793 goto rw_error;
9794 }
9795 } else {
9796 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, flags: 0);
9797 if (rc != 0) {
9798 pr_err("error %d\n", rc);
9799 goto rw_error;
9800 }
9801 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, flags: 0);
9802 if (rc != 0) {
9803 pr_err("error %d\n", rc);
9804 goto rw_error;
9805 }
9806 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, flags: 0);
9807 if (rc != 0) {
9808 pr_err("error %d\n", rc);
9809 goto rw_error;
9810 }
9811 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, flags: 0);
9812 if (rc != 0) {
9813 pr_err("error %d\n", rc);
9814 goto rw_error;
9815 }
9816 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, flags: 0);
9817 if (rc != 0) {
9818 pr_err("error %d\n", rc);
9819 goto rw_error;
9820 }
9821 }
9822 rc = power_down_aud(demod);
9823 if (rc != 0) {
9824 pr_err("error %d\n", rc);
9825 goto rw_error;
9826 }
9827
9828 return 0;
9829rw_error:
9830 return rc;
9831}
9832
9833/*============================================================================*/
9834
9835/*
9836* \brief Power up AUD.
9837* \param demod instance of demodulator
9838* \return int.
9839*
9840*/
9841static int power_down_aud(struct drx_demod_instance *demod)
9842{
9843 struct i2c_device_addr *dev_addr = NULL;
9844 struct drxj_data *ext_attr = NULL;
9845 int rc;
9846
9847 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
9848 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9849
9850 rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, flags: 0);
9851 if (rc != 0) {
9852 pr_err("error %d\n", rc);
9853 goto rw_error;
9854 }
9855
9856 ext_attr->aud_data.audio_is_active = false;
9857
9858 return 0;
9859rw_error:
9860 return rc;
9861}
9862
9863/*
9864* \fn int set_orx_nsu_aox()
9865* \brief Configure OrxNsuAox for OOB
9866* \param demod instance of demodulator.
9867* \param active
9868* \return int.
9869*/
9870static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
9871{
9872 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9873 int rc;
9874 u16 data = 0;
9875
9876 /* Configure NSU_AOX */
9877 rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data: &data, flags: 0);
9878 if (rc != 0) {
9879 pr_err("error %d\n", rc);
9880 goto rw_error;
9881 }
9882 if (!active)
9883 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));
9884 else
9885 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);
9886 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, flags: 0);
9887 if (rc != 0) {
9888 pr_err("error %d\n", rc);
9889 goto rw_error;
9890 }
9891
9892 return 0;
9893rw_error:
9894 return rc;
9895}
9896
9897/*
9898* \fn int ctrl_set_oob()
9899* \brief Set OOB channel to be used.
9900* \param demod instance of demodulator
9901* \param oob_param OOB parameters for channel setting.
9902* \frequency should be in KHz
9903* \return int.
9904*
9905* Accepts only. Returns error otherwise.
9906* Demapper value is written after scu_command START
9907* because START command causes COMM_EXEC transition
9908* from 0 to 1 which causes all registers to be
9909* overwritten with initial value
9910*
9911*/
9912
9913/* Nyquist filter impulse response */
9914#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 */
9915#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 */
9916#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) */
9917
9918/* Coefficients for the nyquist filter (total: 27 taps) */
9919#define NYQFILTERLEN 27
9920
9921static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
9922{
9923 int rc;
9924 s32 freq = 0; /* KHz */
9925 struct i2c_device_addr *dev_addr = NULL;
9926 struct drxj_data *ext_attr = NULL;
9927 u16 i = 0;
9928 bool mirror_freq_spect_oob = false;
9929 u16 trk_filter_value = 0;
9930 struct drxjscu_cmd scu_cmd;
9931 u16 set_param_parameters[3];
9932 u16 cmd_result[2] = { 0, 0 };
9933 s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
9934 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
9935 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
9936 IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
9937 IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
9938 };
9939 u8 mode_val[4] = { 2, 2, 0, 1 };
9940 u8 pfi_coeffs[4][6] = {
9941 {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) */
9942 {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) */
9943 {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) */
9944 {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) */
9945 };
9946 u16 mode_index;
9947
9948 dev_addr = demod->my_i2c_dev_addr;
9949 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9950 mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
9951
9952 /* Check parameters */
9953 if (oob_param == NULL) {
9954 /* power off oob module */
9955 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
9956 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9957 scu_cmd.parameter_len = 0;
9958 scu_cmd.result_len = 1;
9959 scu_cmd.result = cmd_result;
9960 rc = scu_command(dev_addr, cmd: &scu_cmd);
9961 if (rc != 0) {
9962 pr_err("error %d\n", rc);
9963 goto rw_error;
9964 }
9965 rc = set_orx_nsu_aox(demod, active: false);
9966 if (rc != 0) {
9967 pr_err("error %d\n", rc);
9968 goto rw_error;
9969 }
9970 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, flags: 0);
9971 if (rc != 0) {
9972 pr_err("error %d\n", rc);
9973 goto rw_error;
9974 }
9975
9976 ext_attr->oob_power_on = false;
9977 return 0;
9978 }
9979
9980 freq = oob_param->frequency;
9981 if ((freq < 70000) || (freq > 130000))
9982 return -EIO;
9983 freq = (freq - 50000) / 50;
9984
9985 {
9986 u16 index = 0;
9987 u16 remainder = 0;
9988 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
9989
9990 index = (u16) ((freq - 400) / 200);
9991 remainder = (u16) ((freq - 400) % 200);
9992 trk_filter_value =
9993 trk_filtercfg[index] - (trk_filtercfg[index] -
9994 trk_filtercfg[index +
9995 1]) / 10 * remainder /
9996 20;
9997 }
9998
9999 /********/
10000 /* Stop */
10001 /********/
10002 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, flags: 0);
10003 if (rc != 0) {
10004 pr_err("error %d\n", rc);
10005 goto rw_error;
10006 }
10007 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10008 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
10009 scu_cmd.parameter_len = 0;
10010 scu_cmd.result_len = 1;
10011 scu_cmd.result = cmd_result;
10012 rc = scu_command(dev_addr, cmd: &scu_cmd);
10013 if (rc != 0) {
10014 pr_err("error %d\n", rc);
10015 goto rw_error;
10016 }
10017 /********/
10018 /* Reset */
10019 /********/
10020 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10021 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
10022 scu_cmd.parameter_len = 0;
10023 scu_cmd.result_len = 1;
10024 scu_cmd.result = cmd_result;
10025 rc = scu_command(dev_addr, cmd: &scu_cmd);
10026 if (rc != 0) {
10027 pr_err("error %d\n", rc);
10028 goto rw_error;
10029 }
10030 /**********/
10031 /* SET_ENV */
10032 /**********/
10033 /* set frequency, spectrum inversion and data rate */
10034 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10035 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
10036 scu_cmd.parameter_len = 3;
10037 /* 1-data rate;2-frequency */
10038 switch (oob_param->standard) {
10039 case DRX_OOB_MODE_A:
10040 if (
10041 /* signal is transmitted inverted */
10042 ((oob_param->spectrum_inverted == true) &&
10043 /* and tuner is not mirroring the signal */
10044 (!mirror_freq_spect_oob)) |
10045 /* or */
10046 /* signal is transmitted noninverted */
10047 ((oob_param->spectrum_inverted == false) &&
10048 /* and tuner is mirroring the signal */
10049 (mirror_freq_spect_oob))
10050 )
10051 set_param_parameters[0] =
10052 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
10053 else
10054 set_param_parameters[0] =
10055 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
10056 break;
10057 case DRX_OOB_MODE_B_GRADE_A:
10058 if (
10059 /* signal is transmitted inverted */
10060 ((oob_param->spectrum_inverted == true) &&
10061 /* and tuner is not mirroring the signal */
10062 (!mirror_freq_spect_oob)) |
10063 /* or */
10064 /* signal is transmitted noninverted */
10065 ((oob_param->spectrum_inverted == false) &&
10066 /* and tuner is mirroring the signal */
10067 (mirror_freq_spect_oob))
10068 )
10069 set_param_parameters[0] =
10070 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
10071 else
10072 set_param_parameters[0] =
10073 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
10074 break;
10075 case DRX_OOB_MODE_B_GRADE_B:
10076 default:
10077 if (
10078 /* signal is transmitted inverted */
10079 ((oob_param->spectrum_inverted == true) &&
10080 /* and tuner is not mirroring the signal */
10081 (!mirror_freq_spect_oob)) |
10082 /* or */
10083 /* signal is transmitted noninverted */
10084 ((oob_param->spectrum_inverted == false) &&
10085 /* and tuner is mirroring the signal */
10086 (mirror_freq_spect_oob))
10087 )
10088 set_param_parameters[0] =
10089 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
10090 else
10091 set_param_parameters[0] =
10092 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
10093 break;
10094 }
10095 set_param_parameters[1] = (u16) (freq & 0xFFFF);
10096 set_param_parameters[2] = trk_filter_value;
10097 scu_cmd.parameter = set_param_parameters;
10098 scu_cmd.result_len = 1;
10099 scu_cmd.result = cmd_result;
10100 mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
10101 rc = scu_command(dev_addr, cmd: &scu_cmd);
10102 if (rc != 0) {
10103 pr_err("error %d\n", rc);
10104 goto rw_error;
10105 }
10106
10107 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, data: 0xFABA, flags: 0);
10108 if (rc != 0) {
10109 pr_err("error %d\n", rc);
10110 goto rw_error;
10111 } /* Write magic word to enable pdr reg write */
10112 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, flags: 0);
10113 if (rc != 0) {
10114 pr_err("error %d\n", rc);
10115 goto rw_error;
10116 }
10117 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, flags: 0);
10118 if (rc != 0) {
10119 pr_err("error %d\n", rc);
10120 goto rw_error;
10121 }
10122 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, data: 0x0000, flags: 0);
10123 if (rc != 0) {
10124 pr_err("error %d\n", rc);
10125 goto rw_error;
10126 } /* Write magic word to disable pdr reg write */
10127
10128 rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, data: 0, flags: 0);
10129 if (rc != 0) {
10130 pr_err("error %d\n", rc);
10131 goto rw_error;
10132 }
10133 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, data: 16000, flags: 0);
10134 if (rc != 0) {
10135 pr_err("error %d\n", rc);
10136 goto rw_error;
10137 }
10138 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, data: 40, flags: 0);
10139 if (rc != 0) {
10140 pr_err("error %d\n", rc);
10141 goto rw_error;
10142 }
10143
10144 /* ddc */
10145 rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, flags: 0);
10146 if (rc != 0) {
10147 pr_err("error %d\n", rc);
10148 goto rw_error;
10149 }
10150
10151 /* nsu */
10152 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, data: ext_attr->oob_lo_pow, flags: 0);
10153 if (rc != 0) {
10154 pr_err("error %d\n", rc);
10155 goto rw_error;
10156 }
10157
10158 /* initialization for target mode */
10159 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, flags: 0);
10160 if (rc != 0) {
10161 pr_err("error %d\n", rc);
10162 goto rw_error;
10163 }
10164 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, flags: 0);
10165 if (rc != 0) {
10166 pr_err("error %d\n", rc);
10167 goto rw_error;
10168 }
10169
10170 /* Reset bits for timing and freq. recovery */
10171 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, data: 0x0001, flags: 0);
10172 if (rc != 0) {
10173 pr_err("error %d\n", rc);
10174 goto rw_error;
10175 }
10176 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, data: 0x0002, flags: 0);
10177 if (rc != 0) {
10178 pr_err("error %d\n", rc);
10179 goto rw_error;
10180 }
10181 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, data: 0x0004, flags: 0);
10182 if (rc != 0) {
10183 pr_err("error %d\n", rc);
10184 goto rw_error;
10185 }
10186 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, data: 0x0008, flags: 0);
10187 if (rc != 0) {
10188 pr_err("error %d\n", rc);
10189 goto rw_error;
10190 }
10191
10192 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
10193 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, data: 2048 >> 3, flags: 0);
10194 if (rc != 0) {
10195 pr_err("error %d\n", rc);
10196 goto rw_error;
10197 }
10198 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, data: (u16)(-2048), flags: 0);
10199 if (rc != 0) {
10200 pr_err("error %d\n", rc);
10201 goto rw_error;
10202 }
10203 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, data: 8, flags: 0);
10204 if (rc != 0) {
10205 pr_err("error %d\n", rc);
10206 goto rw_error;
10207 }
10208 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, data: (u16)(-8), flags: 0);
10209 if (rc != 0) {
10210 pr_err("error %d\n", rc);
10211 goto rw_error;
10212 }
10213 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, data: 1, flags: 0);
10214 if (rc != 0) {
10215 pr_err("error %d\n", rc);
10216 goto rw_error;
10217 }
10218
10219 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
10220 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, data: 10, flags: 0);
10221 if (rc != 0) {
10222 pr_err("error %d\n", rc);
10223 goto rw_error;
10224 }
10225 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, data: (u16)(-2048), flags: 0);
10226 if (rc != 0) {
10227 pr_err("error %d\n", rc);
10228 goto rw_error;
10229 }
10230 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, data: 8, flags: 0);
10231 if (rc != 0) {
10232 pr_err("error %d\n", rc);
10233 goto rw_error;
10234 }
10235 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, data: (u16)(-8), flags: 0);
10236 if (rc != 0) {
10237 pr_err("error %d\n", rc);
10238 goto rw_error;
10239 }
10240 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, data: 1 << 1, flags: 0);
10241 if (rc != 0) {
10242 pr_err("error %d\n", rc);
10243 goto rw_error;
10244 }
10245
10246 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
10247 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, data: 17, flags: 0);
10248 if (rc != 0) {
10249 pr_err("error %d\n", rc);
10250 goto rw_error;
10251 }
10252 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, data: (u16)(-2048), flags: 0);
10253 if (rc != 0) {
10254 pr_err("error %d\n", rc);
10255 goto rw_error;
10256 }
10257 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, data: 8, flags: 0);
10258 if (rc != 0) {
10259 pr_err("error %d\n", rc);
10260 goto rw_error;
10261 }
10262 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, data: (u16)(-8), flags: 0);
10263 if (rc != 0) {
10264 pr_err("error %d\n", rc);
10265 goto rw_error;
10266 }
10267 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, data: 1 << 2, flags: 0);
10268 if (rc != 0) {
10269 pr_err("error %d\n", rc);
10270 goto rw_error;
10271 }
10272
10273 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
10274 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, data: 3000, flags: 0);
10275 if (rc != 0) {
10276 pr_err("error %d\n", rc);
10277 goto rw_error;
10278 }
10279 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, data: (u16)(-2048), flags: 0);
10280 if (rc != 0) {
10281 pr_err("error %d\n", rc);
10282 goto rw_error;
10283 }
10284 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, data: 8, flags: 0);
10285 if (rc != 0) {
10286 pr_err("error %d\n", rc);
10287 goto rw_error;
10288 }
10289 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, data: (u16)(-8), flags: 0);
10290 if (rc != 0) {
10291 pr_err("error %d\n", rc);
10292 goto rw_error;
10293 }
10294 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, data: 1 << 3, flags: 0);
10295 if (rc != 0) {
10296 pr_err("error %d\n", rc);
10297 goto rw_error;
10298 }
10299
10300 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
10301 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, data: 400, flags: 0);
10302 if (rc != 0) {
10303 pr_err("error %d\n", rc);
10304 goto rw_error;
10305 }
10306 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, data: (u16)(-2048), flags: 0);
10307 if (rc != 0) {
10308 pr_err("error %d\n", rc);
10309 goto rw_error;
10310 }
10311 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, data: 8, flags: 0);
10312 if (rc != 0) {
10313 pr_err("error %d\n", rc);
10314 goto rw_error;
10315 }
10316 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, data: (u16)(-8), flags: 0);
10317 if (rc != 0) {
10318 pr_err("error %d\n", rc);
10319 goto rw_error;
10320 }
10321 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, data: 1 << 4, flags: 0);
10322 if (rc != 0) {
10323 pr_err("error %d\n", rc);
10324 goto rw_error;
10325 }
10326
10327 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
10328 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, data: 20, flags: 0);
10329 if (rc != 0) {
10330 pr_err("error %d\n", rc);
10331 goto rw_error;
10332 }
10333 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, data: (u16)(-2048), flags: 0);
10334 if (rc != 0) {
10335 pr_err("error %d\n", rc);
10336 goto rw_error;
10337 }
10338 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, data: 4, flags: 0);
10339 if (rc != 0) {
10340 pr_err("error %d\n", rc);
10341 goto rw_error;
10342 }
10343 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, data: (u16)(-4), flags: 0);
10344 if (rc != 0) {
10345 pr_err("error %d\n", rc);
10346 goto rw_error;
10347 }
10348 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, data: 1 << 5, flags: 0);
10349 if (rc != 0) {
10350 pr_err("error %d\n", rc);
10351 goto rw_error;
10352 }
10353
10354 /* PRE-Filter coefficients (PFI) */
10355 rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, datasize: sizeof(pfi_coeffs[mode_index]), data: ((u8 *)pfi_coeffs[mode_index]), flags: 0);
10356 if (rc != 0) {
10357 pr_err("error %d\n", rc);
10358 goto rw_error;
10359 }
10360 rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, data: mode_index, flags: 0);
10361 if (rc != 0) {
10362 pr_err("error %d\n", rc);
10363 goto rw_error;
10364 }
10365
10366 /* NYQUIST-Filter coefficients (NYQ) */
10367 for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
10368 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, data: i, flags: 0);
10369 if (rc != 0) {
10370 pr_err("error %d\n", rc);
10371 goto rw_error;
10372 }
10373 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, data: nyquist_coeffs[mode_index][i], flags: 0);
10374 if (rc != 0) {
10375 pr_err("error %d\n", rc);
10376 goto rw_error;
10377 }
10378 }
10379 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, data: 31, flags: 0);
10380 if (rc != 0) {
10381 pr_err("error %d\n", rc);
10382 goto rw_error;
10383 }
10384 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, flags: 0);
10385 if (rc != 0) {
10386 pr_err("error %d\n", rc);
10387 goto rw_error;
10388 }
10389 /********/
10390 /* Start */
10391 /********/
10392 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10393 | SCU_RAM_COMMAND_CMD_DEMOD_START;
10394 scu_cmd.parameter_len = 0;
10395 scu_cmd.result_len = 1;
10396 scu_cmd.result = cmd_result;
10397 rc = scu_command(dev_addr, cmd: &scu_cmd);
10398 if (rc != 0) {
10399 pr_err("error %d\n", rc);
10400 goto rw_error;
10401 }
10402
10403 rc = set_orx_nsu_aox(demod, active: true);
10404 if (rc != 0) {
10405 pr_err("error %d\n", rc);
10406 goto rw_error;
10407 }
10408 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, data: ext_attr->oob_pre_saw, flags: 0);
10409 if (rc != 0) {
10410 pr_err("error %d\n", rc);
10411 goto rw_error;
10412 }
10413
10414 ext_attr->oob_power_on = true;
10415
10416 return 0;
10417rw_error:
10418 return rc;
10419}
10420
10421/*============================================================================*/
10422/*== END OOB DATAPATH FUNCTIONS ==*/
10423/*============================================================================*/
10424
10425/*=============================================================================
10426 ===== MC command related functions ==========================================
10427 ===========================================================================*/
10428
10429/*=============================================================================
10430 ===== ctrl_set_channel() ==========================================================
10431 ===========================================================================*/
10432/*
10433* \fn int ctrl_set_channel()
10434* \brief Select a new transmission channel.
10435* \param demod instance of demod.
10436* \param channel Pointer to channel data.
10437* \return int.
10438*
10439* In case the tuner module is not used and in case of NTSC/FM the pogrammer
10440* must tune the tuner to the centre frequency of the NTSC/FM channel.
10441*
10442*/
10443static int
10444ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
10445{
10446 int rc;
10447 s32 tuner_freq_offset = 0;
10448 struct drxj_data *ext_attr = NULL;
10449 struct i2c_device_addr *dev_addr = NULL;
10450 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10451#ifndef DRXJ_VSB_ONLY
10452 u32 min_symbol_rate = 0;
10453 u32 max_symbol_rate = 0;
10454 int bandwidth_temp = 0;
10455 int bandwidth = 0;
10456#endif
10457 /*== check arguments ======================================================*/
10458 if ((demod == NULL) || (channel == NULL))
10459 return -EINVAL;
10460
10461 dev_addr = demod->my_i2c_dev_addr;
10462 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10463 standard = ext_attr->standard;
10464
10465 /* check valid standards */
10466 switch (standard) {
10467 case DRX_STANDARD_8VSB:
10468#ifndef DRXJ_VSB_ONLY
10469 case DRX_STANDARD_ITU_A:
10470 case DRX_STANDARD_ITU_B:
10471 case DRX_STANDARD_ITU_C:
10472#endif /* DRXJ_VSB_ONLY */
10473 break;
10474 case DRX_STANDARD_UNKNOWN:
10475 default:
10476 return -EINVAL;
10477 }
10478
10479 /* check bandwidth QAM annex B, NTSC and 8VSB */
10480 if ((standard == DRX_STANDARD_ITU_B) ||
10481 (standard == DRX_STANDARD_8VSB) ||
10482 (standard == DRX_STANDARD_NTSC)) {
10483 switch (channel->bandwidth) {
10484 case DRX_BANDWIDTH_6MHZ:
10485 case DRX_BANDWIDTH_UNKNOWN:
10486 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10487 break;
10488 case DRX_BANDWIDTH_8MHZ:
10489 case DRX_BANDWIDTH_7MHZ:
10490 default:
10491 return -EINVAL;
10492 }
10493 }
10494
10495 /* For QAM annex A and annex C:
10496 -check symbolrate and constellation
10497 -derive bandwidth from symbolrate (input bandwidth is ignored)
10498 */
10499#ifndef DRXJ_VSB_ONLY
10500 if ((standard == DRX_STANDARD_ITU_A) ||
10501 (standard == DRX_STANDARD_ITU_C)) {
10502 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
10503 int bw_rolloff_factor = 0;
10504
10505 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
10506 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
10507 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
10508 /* config SMA_TX pin to SAW switch mode */
10509 rc = ctrl_set_uio_cfg(demod, uio_cfg: &uio_cfg);
10510 if (rc != 0) {
10511 pr_err("error %d\n", rc);
10512 goto rw_error;
10513 }
10514
10515 if (channel->symbolrate < min_symbol_rate ||
10516 channel->symbolrate > max_symbol_rate) {
10517 return -EINVAL;
10518 }
10519
10520 switch (channel->constellation) {
10521 case DRX_CONSTELLATION_QAM16:
10522 case DRX_CONSTELLATION_QAM32:
10523 case DRX_CONSTELLATION_QAM64:
10524 case DRX_CONSTELLATION_QAM128:
10525 case DRX_CONSTELLATION_QAM256:
10526 bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
10527 bandwidth = bandwidth_temp / 100;
10528
10529 if ((bandwidth_temp % 100) >= 50)
10530 bandwidth++;
10531
10532 if (bandwidth <= 6100000) {
10533 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10534 } else if ((bandwidth > 6100000)
10535 && (bandwidth <= 7100000)) {
10536 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
10537 } else if (bandwidth > 7100000) {
10538 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
10539 }
10540 break;
10541 default:
10542 return -EINVAL;
10543 }
10544 }
10545
10546 /* For QAM annex B:
10547 -check constellation
10548 */
10549 if (standard == DRX_STANDARD_ITU_B) {
10550 switch (channel->constellation) {
10551 case DRX_CONSTELLATION_AUTO:
10552 case DRX_CONSTELLATION_QAM256:
10553 case DRX_CONSTELLATION_QAM64:
10554 break;
10555 default:
10556 return -EINVAL;
10557 }
10558
10559 switch (channel->interleavemode) {
10560 case DRX_INTERLEAVEMODE_I128_J1:
10561 case DRX_INTERLEAVEMODE_I128_J1_V2:
10562 case DRX_INTERLEAVEMODE_I128_J2:
10563 case DRX_INTERLEAVEMODE_I64_J2:
10564 case DRX_INTERLEAVEMODE_I128_J3:
10565 case DRX_INTERLEAVEMODE_I32_J4:
10566 case DRX_INTERLEAVEMODE_I128_J4:
10567 case DRX_INTERLEAVEMODE_I16_J8:
10568 case DRX_INTERLEAVEMODE_I128_J5:
10569 case DRX_INTERLEAVEMODE_I8_J16:
10570 case DRX_INTERLEAVEMODE_I128_J6:
10571 case DRX_INTERLEAVEMODE_I128_J7:
10572 case DRX_INTERLEAVEMODE_I128_J8:
10573 case DRX_INTERLEAVEMODE_I12_J17:
10574 case DRX_INTERLEAVEMODE_I5_J4:
10575 case DRX_INTERLEAVEMODE_B52_M240:
10576 case DRX_INTERLEAVEMODE_B52_M720:
10577 case DRX_INTERLEAVEMODE_UNKNOWN:
10578 case DRX_INTERLEAVEMODE_AUTO:
10579 break;
10580 default:
10581 return -EINVAL;
10582 }
10583 }
10584
10585 if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
10586 /* SAW SW, user UIO is used for switchable SAW */
10587 struct drxuio_data uio1 = { DRX_UIO1, false };
10588
10589 switch (channel->bandwidth) {
10590 case DRX_BANDWIDTH_8MHZ:
10591 uio1.value = true;
10592 break;
10593 case DRX_BANDWIDTH_7MHZ:
10594 uio1.value = false;
10595 break;
10596 case DRX_BANDWIDTH_6MHZ:
10597 uio1.value = false;
10598 break;
10599 case DRX_BANDWIDTH_UNKNOWN:
10600 default:
10601 return -EINVAL;
10602 }
10603
10604 rc = ctrl_uio_write(demod, uio_data: &uio1);
10605 if (rc != 0) {
10606 pr_err("error %d\n", rc);
10607 goto rw_error;
10608 }
10609 }
10610#endif /* DRXJ_VSB_ONLY */
10611 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, flags: 0);
10612 if (rc != 0) {
10613 pr_err("error %d\n", rc);
10614 goto rw_error;
10615 }
10616
10617 tuner_freq_offset = 0;
10618
10619 /*== Setup demod for specific standard ====================================*/
10620 switch (standard) {
10621 case DRX_STANDARD_8VSB:
10622 if (channel->mirror == DRX_MIRROR_AUTO)
10623 ext_attr->mirror = DRX_MIRROR_NO;
10624 else
10625 ext_attr->mirror = channel->mirror;
10626 rc = set_vsb(demod);
10627 if (rc != 0) {
10628 pr_err("error %d\n", rc);
10629 goto rw_error;
10630 }
10631 rc = set_frequency(demod, channel, tuner_freq_offset);
10632 if (rc != 0) {
10633 pr_err("error %d\n", rc);
10634 goto rw_error;
10635 }
10636 break;
10637#ifndef DRXJ_VSB_ONLY
10638 case DRX_STANDARD_ITU_A:
10639 case DRX_STANDARD_ITU_B:
10640 case DRX_STANDARD_ITU_C:
10641 rc = set_qam_channel(demod, channel, tuner_freq_offset);
10642 if (rc != 0) {
10643 pr_err("error %d\n", rc);
10644 goto rw_error;
10645 }
10646 break;
10647#endif
10648 case DRX_STANDARD_UNKNOWN:
10649 default:
10650 return -EIO;
10651 }
10652
10653 /* flag the packet error counter reset */
10654 ext_attr->reset_pkt_err_acc = true;
10655
10656 return 0;
10657rw_error:
10658 return rc;
10659}
10660
10661/*=============================================================================
10662 ===== SigQuality() ==========================================================
10663 ===========================================================================*/
10664
10665/*
10666* \fn int ctrl_sig_quality()
10667* \brief Retrieve signal quality form device.
10668* \param devmod Pointer to demodulator instance.
10669* \param sig_quality Pointer to signal quality data.
10670* \return int.
10671* \retval 0 sig_quality contains valid data.
10672* \retval -EINVAL sig_quality is NULL.
10673* \retval -EIO Erroneous data, sig_quality contains invalid data.
10674
10675*/
10676static int
10677ctrl_sig_quality(struct drx_demod_instance *demod,
10678 enum drx_lock_status lock_status)
10679{
10680 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
10681 struct drxj_data *ext_attr = demod->my_ext_attr;
10682 struct drx39xxj_state *state = dev_addr->user_data;
10683 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
10684 enum drx_standard standard = ext_attr->standard;
10685 int rc;
10686 u32 ber, cnt, err, pkt;
10687 u16 mer, strength = 0;
10688
10689 rc = get_sig_strength(demod, sig_strength: &strength);
10690 if (rc < 0) {
10691 pr_err("error getting signal strength %d\n", rc);
10692 p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10693 } else {
10694 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
10695 p->strength.stat[0].uvalue = 65535UL * strength/ 100;
10696 }
10697
10698 switch (standard) {
10699 case DRX_STANDARD_8VSB:
10700#ifdef DRXJ_SIGNAL_ACCUM_ERR
10701 rc = get_acc_pkt_err(demod, &pkt);
10702 if (rc != 0) {
10703 pr_err("error %d\n", rc);
10704 goto rw_error;
10705 }
10706#endif
10707 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
10708 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10709 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10710 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10711 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10712 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10713 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10714 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10715 } else {
10716 rc = get_vsb_post_rs_pck_err(dev_addr, pck_errs: &err, pck_count: &pkt);
10717 if (rc != 0) {
10718 pr_err("error %d getting UCB\n", rc);
10719 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10720 } else {
10721 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
10722 p->block_error.stat[0].uvalue += err;
10723 p->block_count.stat[0].scale = FE_SCALE_COUNTER;
10724 p->block_count.stat[0].uvalue += pkt;
10725 }
10726
10727 /* PostViterbi is compute in steps of 10^(-6) */
10728 rc = get_vs_bpre_viterbi_ber(dev_addr, ber: &ber, cnt: &cnt);
10729 if (rc != 0) {
10730 pr_err("error %d getting pre-ber\n", rc);
10731 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10732 } else {
10733 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10734 p->pre_bit_error.stat[0].uvalue += ber;
10735 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10736 p->pre_bit_count.stat[0].uvalue += cnt;
10737 }
10738
10739 rc = get_vs_bpost_viterbi_ber(dev_addr, ber: &ber, cnt: &cnt);
10740 if (rc != 0) {
10741 pr_err("error %d getting post-ber\n", rc);
10742 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10743 } else {
10744 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10745 p->post_bit_error.stat[0].uvalue += ber;
10746 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10747 p->post_bit_count.stat[0].uvalue += cnt;
10748 }
10749 rc = get_vsbmer(dev_addr, mer: &mer);
10750 if (rc != 0) {
10751 pr_err("error %d getting MER\n", rc);
10752 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10753 } else {
10754 p->cnr.stat[0].svalue = mer * 100;
10755 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
10756 }
10757 }
10758 break;
10759#ifndef DRXJ_VSB_ONLY
10760 case DRX_STANDARD_ITU_A:
10761 case DRX_STANDARD_ITU_B:
10762 case DRX_STANDARD_ITU_C:
10763 rc = ctrl_get_qam_sig_quality(demod);
10764 if (rc != 0) {
10765 pr_err("error %d\n", rc);
10766 goto rw_error;
10767 }
10768 break;
10769#endif
10770 default:
10771 return -EIO;
10772 }
10773
10774 return 0;
10775rw_error:
10776 return rc;
10777}
10778
10779/*============================================================================*/
10780
10781/*
10782* \fn int ctrl_lock_status()
10783* \brief Retrieve lock status .
10784* \param dev_addr Pointer to demodulator device address.
10785* \param lock_stat Pointer to lock status structure.
10786* \return int.
10787*
10788*/
10789static int
10790ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
10791{
10792 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10793 struct drxj_data *ext_attr = NULL;
10794 struct i2c_device_addr *dev_addr = NULL;
10795 struct drxjscu_cmd cmd_scu = { /* command */ 0,
10796 /* parameter_len */ 0,
10797 /* result_len */ 0,
10798 /* *parameter */ NULL,
10799 /* *result */ NULL
10800 };
10801 int rc;
10802 u16 cmd_result[2] = { 0, 0 };
10803 u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
10804
10805 /* check arguments */
10806 if ((demod == NULL) || (lock_stat == NULL))
10807 return -EINVAL;
10808
10809 dev_addr = demod->my_i2c_dev_addr;
10810 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10811 standard = ext_attr->standard;
10812
10813 *lock_stat = DRX_NOT_LOCKED;
10814
10815 /* define the SCU command code */
10816 switch (standard) {
10817 case DRX_STANDARD_8VSB:
10818 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
10819 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10820 demod_lock |= 0x6;
10821 break;
10822#ifndef DRXJ_VSB_ONLY
10823 case DRX_STANDARD_ITU_A:
10824 case DRX_STANDARD_ITU_B:
10825 case DRX_STANDARD_ITU_C:
10826 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10827 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10828 break;
10829#endif
10830 case DRX_STANDARD_UNKNOWN:
10831 default:
10832 return -EIO;
10833 }
10834
10835 /* define the SCU command parameters and execute the command */
10836 cmd_scu.parameter_len = 0;
10837 cmd_scu.result_len = 2;
10838 cmd_scu.parameter = NULL;
10839 cmd_scu.result = cmd_result;
10840 rc = scu_command(dev_addr, cmd: &cmd_scu);
10841 if (rc != 0) {
10842 pr_err("error %d\n", rc);
10843 goto rw_error;
10844 }
10845
10846 /* set the lock status */
10847 if (cmd_scu.result[1] < demod_lock) {
10848 /* 0x0000 NOT LOCKED */
10849 *lock_stat = DRX_NOT_LOCKED;
10850 } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
10851 *lock_stat = DRXJ_DEMOD_LOCK;
10852 } else if (cmd_scu.result[1] <
10853 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
10854 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
10855 *lock_stat = DRX_LOCKED;
10856 } else {
10857 /* 0xC000 NEVER LOCKED */
10858 /* (system will never be able to lock to the signal) */
10859 *lock_stat = DRX_NEVER_LOCK;
10860 }
10861
10862 return 0;
10863rw_error:
10864 return rc;
10865}
10866
10867/*============================================================================*/
10868
10869/*
10870* \fn int ctrl_set_standard()
10871* \brief Set modulation standard to be used.
10872* \param standard Modulation standard.
10873* \return int.
10874*
10875* Setup stuff for the desired demodulation standard.
10876* Disable and power down the previous selected demodulation standard
10877*
10878*/
10879static int
10880ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
10881{
10882 struct drxj_data *ext_attr = NULL;
10883 int rc;
10884 enum drx_standard prev_standard;
10885
10886 /* check arguments */
10887 if ((standard == NULL) || (demod == NULL))
10888 return -EINVAL;
10889
10890 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10891 prev_standard = ext_attr->standard;
10892
10893 /*
10894 Stop and power down previous standard
10895 */
10896 switch (prev_standard) {
10897#ifndef DRXJ_VSB_ONLY
10898 case DRX_STANDARD_ITU_A:
10899 case DRX_STANDARD_ITU_B:
10900 case DRX_STANDARD_ITU_C:
10901 rc = power_down_qam(demod, primary: false);
10902 if (rc != 0) {
10903 pr_err("error %d\n", rc);
10904 goto rw_error;
10905 }
10906 break;
10907#endif
10908 case DRX_STANDARD_8VSB:
10909 rc = power_down_vsb(demod, primary: false);
10910 if (rc != 0) {
10911 pr_err("error %d\n", rc);
10912 goto rw_error;
10913 }
10914 break;
10915 case DRX_STANDARD_UNKNOWN:
10916 /* Do nothing */
10917 break;
10918 case DRX_STANDARD_AUTO:
10919 default:
10920 rc = -EINVAL;
10921 goto rw_error;
10922 }
10923
10924 /*
10925 Initialize channel independent registers
10926 Power up new standard
10927 */
10928 ext_attr->standard = *standard;
10929
10930 switch (*standard) {
10931#ifndef DRXJ_VSB_ONLY
10932 case DRX_STANDARD_ITU_A:
10933 case DRX_STANDARD_ITU_B:
10934 case DRX_STANDARD_ITU_C:
10935 do {
10936 u16 dummy;
10937 rc = drxj_dap_read_reg16(dev_addr: demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, data: &dummy, flags: 0);
10938 if (rc != 0) {
10939 pr_err("error %d\n", rc);
10940 goto rw_error;
10941 }
10942 } while (0);
10943 break;
10944#endif
10945 case DRX_STANDARD_8VSB:
10946 rc = set_vsb_leak_n_gain(demod);
10947 if (rc != 0) {
10948 pr_err("error %d\n", rc);
10949 goto rw_error;
10950 }
10951 break;
10952 default:
10953 ext_attr->standard = DRX_STANDARD_UNKNOWN;
10954 return -EINVAL;
10955 }
10956
10957 return 0;
10958rw_error:
10959 /* Don't know what the standard is now ... try again */
10960 ext_attr->standard = DRX_STANDARD_UNKNOWN;
10961 return rc;
10962}
10963
10964/*============================================================================*/
10965
10966static void drxj_reset_mode(struct drxj_data *ext_attr)
10967{
10968 /* Initialize default AFE configuration for QAM */
10969 if (ext_attr->has_lna) {
10970 /* IF AGC off, PGA active */
10971#ifndef DRXJ_VSB_ONLY
10972 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10973 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10974 ext_attr->qam_pga_cfg = 140 + (11 * 13);
10975#endif
10976 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10977 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10978 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
10979 } else {
10980 /* IF AGC on, PGA not active */
10981#ifndef DRXJ_VSB_ONLY
10982 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10983 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10984 ext_attr->qam_if_agc_cfg.min_output_level = 0;
10985 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
10986 ext_attr->qam_if_agc_cfg.speed = 3;
10987 ext_attr->qam_if_agc_cfg.top = 1297;
10988 ext_attr->qam_pga_cfg = 140;
10989#endif
10990 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10991 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10992 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
10993 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
10994 ext_attr->vsb_if_agc_cfg.speed = 3;
10995 ext_attr->vsb_if_agc_cfg.top = 1024;
10996 ext_attr->vsb_pga_cfg = 140;
10997 }
10998 /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
10999 /* mc has not used them */
11000#ifndef DRXJ_VSB_ONLY
11001 ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
11002 ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11003 ext_attr->qam_rf_agc_cfg.min_output_level = 0;
11004 ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
11005 ext_attr->qam_rf_agc_cfg.speed = 3;
11006 ext_attr->qam_rf_agc_cfg.top = 9500;
11007 ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
11008 ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
11009 ext_attr->qam_pre_saw_cfg.reference = 0x07;
11010 ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
11011#endif
11012 /* Initialize default AFE configuration for VSB */
11013 ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
11014 ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11015 ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
11016 ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
11017 ext_attr->vsb_rf_agc_cfg.speed = 3;
11018 ext_attr->vsb_rf_agc_cfg.top = 9500;
11019 ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
11020 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
11021 ext_attr->vsb_pre_saw_cfg.reference = 0x07;
11022 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
11023}
11024
11025/*
11026* \fn int ctrl_power_mode()
11027* \brief Set the power mode of the device to the specified power mode
11028* \param demod Pointer to demodulator instance.
11029* \param mode Pointer to new power mode.
11030* \return int.
11031* \retval 0 Success
11032* \retval -EIO I2C error or other failure
11033* \retval -EINVAL Invalid mode argument.
11034*
11035*
11036*/
11037static int
11038ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
11039{
11040 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
11041 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
11042 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
11043 int rc;
11044 u16 sio_cc_pwd_mode = 0;
11045
11046 common_attr = (struct drx_common_attr *) demod->my_common_attr;
11047 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11048 dev_addr = demod->my_i2c_dev_addr;
11049
11050 /* Check arguments */
11051 if (mode == NULL)
11052 return -EINVAL;
11053
11054 /* If already in requested power mode, do nothing */
11055 if (common_attr->current_power_mode == *mode)
11056 return 0;
11057
11058 switch (*mode) {
11059 case DRX_POWER_UP:
11060 case DRXJ_POWER_DOWN_MAIN_PATH:
11061 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
11062 break;
11063 case DRXJ_POWER_DOWN_CORE:
11064 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
11065 break;
11066 case DRXJ_POWER_DOWN_PLL:
11067 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
11068 break;
11069 case DRX_POWER_DOWN:
11070 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
11071 break;
11072 default:
11073 /* Unknown sleep mode */
11074 return -EINVAL;
11075 }
11076
11077 /* Check if device needs to be powered up */
11078 if ((common_attr->current_power_mode != DRX_POWER_UP)) {
11079 rc = power_up_device(demod);
11080 if (rc != 0) {
11081 pr_err("error %d\n", rc);
11082 goto rw_error;
11083 }
11084 }
11085
11086 if (*mode == DRX_POWER_UP) {
11087 /* Restore analog & pin configuration */
11088
11089 /* Initialize default AFE configuration for VSB */
11090 drxj_reset_mode(ext_attr);
11091 } else {
11092 /* Power down to requested mode */
11093 /* Backup some register settings */
11094 /* Set pins with possible pull-ups connected to them in input mode */
11095 /* Analog power down */
11096 /* ADC power down */
11097 /* Power down device */
11098 /* stop all comm_exec */
11099 /*
11100 Stop and power down previous standard
11101 */
11102
11103 switch (ext_attr->standard) {
11104 case DRX_STANDARD_ITU_A:
11105 case DRX_STANDARD_ITU_B:
11106 case DRX_STANDARD_ITU_C:
11107 rc = power_down_qam(demod, primary: true);
11108 if (rc != 0) {
11109 pr_err("error %d\n", rc);
11110 goto rw_error;
11111 }
11112 break;
11113 case DRX_STANDARD_8VSB:
11114 rc = power_down_vsb(demod, primary: true);
11115 if (rc != 0) {
11116 pr_err("error %d\n", rc);
11117 goto rw_error;
11118 }
11119 break;
11120 case DRX_STANDARD_PAL_SECAM_BG:
11121 case DRX_STANDARD_PAL_SECAM_DK:
11122 case DRX_STANDARD_PAL_SECAM_I:
11123 case DRX_STANDARD_PAL_SECAM_L:
11124 case DRX_STANDARD_PAL_SECAM_LP:
11125 case DRX_STANDARD_NTSC:
11126 case DRX_STANDARD_FM:
11127 rc = power_down_atv(demod, standard: ext_attr->standard, primary: true);
11128 if (rc != 0) {
11129 pr_err("error %d\n", rc);
11130 goto rw_error;
11131 }
11132 break;
11133 case DRX_STANDARD_UNKNOWN:
11134 /* Do nothing */
11135 break;
11136 case DRX_STANDARD_AUTO:
11137 default:
11138 return -EIO;
11139 }
11140 ext_attr->standard = DRX_STANDARD_UNKNOWN;
11141 }
11142
11143 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
11144 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, data: sio_cc_pwd_mode, flags: 0);
11145 if (rc != 0) {
11146 pr_err("error %d\n", rc);
11147 goto rw_error;
11148 }
11149 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, flags: 0);
11150 if (rc != 0) {
11151 pr_err("error %d\n", rc);
11152 goto rw_error;
11153 }
11154
11155 if ((*mode != DRX_POWER_UP)) {
11156 /* Initialize HI, wakeup key especially before put IC to sleep */
11157 rc = init_hi(demod);
11158 if (rc != 0) {
11159 pr_err("error %d\n", rc);
11160 goto rw_error;
11161 }
11162
11163 ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
11164 rc = hi_cfg_command(demod);
11165 if (rc != 0) {
11166 pr_err("error %d\n", rc);
11167 goto rw_error;
11168 }
11169 }
11170 }
11171
11172 common_attr->current_power_mode = *mode;
11173
11174 return 0;
11175rw_error:
11176 return rc;
11177}
11178
11179/*============================================================================*/
11180/*== CTRL Set/Get Config related functions ===================================*/
11181/*============================================================================*/
11182
11183/*
11184* \fn int ctrl_set_cfg_pre_saw()
11185* \brief Set Pre-saw reference.
11186* \param demod demod instance
11187* \param u16 *
11188* \return int.
11189*
11190* Check arguments
11191* Dispatch handling to standard specific function.
11192*
11193*/
11194static int
11195ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
11196{
11197 struct i2c_device_addr *dev_addr = NULL;
11198 struct drxj_data *ext_attr = NULL;
11199 int rc;
11200
11201 dev_addr = demod->my_i2c_dev_addr;
11202 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11203
11204 /* check arguments */
11205 if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
11206 ) {
11207 return -EINVAL;
11208 }
11209
11210 /* Only if standard is currently active */
11211 if ((ext_attr->standard == pre_saw->standard) ||
11212 (DRXJ_ISQAMSTD(ext_attr->standard) &&
11213 DRXJ_ISQAMSTD(pre_saw->standard)) ||
11214 (DRXJ_ISATVSTD(ext_attr->standard) &&
11215 DRXJ_ISATVSTD(pre_saw->standard))) {
11216 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, data: pre_saw->reference, flags: 0);
11217 if (rc != 0) {
11218 pr_err("error %d\n", rc);
11219 goto rw_error;
11220 }
11221 }
11222
11223 /* Store pre-saw settings */
11224 switch (pre_saw->standard) {
11225 case DRX_STANDARD_8VSB:
11226 ext_attr->vsb_pre_saw_cfg = *pre_saw;
11227 break;
11228#ifndef DRXJ_VSB_ONLY
11229 case DRX_STANDARD_ITU_A:
11230 case DRX_STANDARD_ITU_B:
11231 case DRX_STANDARD_ITU_C:
11232 ext_attr->qam_pre_saw_cfg = *pre_saw;
11233 break;
11234#endif
11235 default:
11236 return -EINVAL;
11237 }
11238
11239 return 0;
11240rw_error:
11241 return rc;
11242}
11243
11244/*============================================================================*/
11245
11246/*
11247* \fn int ctrl_set_cfg_afe_gain()
11248* \brief Set AFE Gain.
11249* \param demod demod instance
11250* \param u16 *
11251* \return int.
11252*
11253* Check arguments
11254* Dispatch handling to standard specific function.
11255*
11256*/
11257static int
11258ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
11259{
11260 struct i2c_device_addr *dev_addr = NULL;
11261 struct drxj_data *ext_attr = NULL;
11262 int rc;
11263 u8 gain = 0;
11264
11265 /* check arguments */
11266 if (afe_gain == NULL)
11267 return -EINVAL;
11268
11269 dev_addr = demod->my_i2c_dev_addr;
11270 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11271
11272 switch (afe_gain->standard) {
11273 case DRX_STANDARD_8VSB: fallthrough;
11274#ifndef DRXJ_VSB_ONLY
11275 case DRX_STANDARD_ITU_A:
11276 case DRX_STANDARD_ITU_B:
11277 case DRX_STANDARD_ITU_C:
11278#endif
11279 /* Do nothing */
11280 break;
11281 default:
11282 return -EINVAL;
11283 }
11284
11285 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
11286 So I (PJ) think interface requires choice between auto, user mode */
11287
11288 if (afe_gain->gain >= 329)
11289 gain = 15;
11290 else if (afe_gain->gain <= 147)
11291 gain = 0;
11292 else
11293 gain = (afe_gain->gain - 140 + 6) / 13;
11294
11295 /* Only if standard is currently active */
11296 if (ext_attr->standard == afe_gain->standard) {
11297 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, data: gain, flags: 0);
11298 if (rc != 0) {
11299 pr_err("error %d\n", rc);
11300 goto rw_error;
11301 }
11302 }
11303
11304 /* Store AFE Gain settings */
11305 switch (afe_gain->standard) {
11306 case DRX_STANDARD_8VSB:
11307 ext_attr->vsb_pga_cfg = gain * 13 + 140;
11308 break;
11309#ifndef DRXJ_VSB_ONLY
11310 case DRX_STANDARD_ITU_A:
11311 case DRX_STANDARD_ITU_B:
11312 case DRX_STANDARD_ITU_C:
11313 ext_attr->qam_pga_cfg = gain * 13 + 140;
11314 break;
11315#endif
11316 default:
11317 return -EIO;
11318 }
11319
11320 return 0;
11321rw_error:
11322 return rc;
11323}
11324
11325/*============================================================================*/
11326
11327
11328/*=============================================================================
11329===== EXPORTED FUNCTIONS ====================================================*/
11330
11331static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11332 struct drxu_code_info *mc_info,
11333 enum drxu_code_action action);
11334static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
11335
11336/*
11337* \fn drxj_open()
11338* \brief Open the demod instance, configure device, configure drxdriver
11339* \return Status_t Return status.
11340*
11341* drxj_open() can be called with a NULL ucode image => no ucode upload.
11342* This means that drxj_open() must NOT contain SCU commands or, in general,
11343* rely on SCU or AUD ucode to be present.
11344*
11345*/
11346
11347static int drxj_open(struct drx_demod_instance *demod)
11348{
11349 struct i2c_device_addr *dev_addr = NULL;
11350 struct drxj_data *ext_attr = NULL;
11351 struct drx_common_attr *common_attr = NULL;
11352 u32 driver_version = 0;
11353 struct drxu_code_info ucode_info;
11354 struct drx_cfg_mpeg_output cfg_mpeg_output;
11355 int rc;
11356 enum drx_power_mode power_mode = DRX_POWER_UP;
11357
11358 if ((demod == NULL) ||
11359 (demod->my_common_attr == NULL) ||
11360 (demod->my_ext_attr == NULL) ||
11361 (demod->my_i2c_dev_addr == NULL) ||
11362 (demod->my_common_attr->is_opened)) {
11363 return -EINVAL;
11364 }
11365
11366 /* Check arguments */
11367 if (demod->my_ext_attr == NULL)
11368 return -EINVAL;
11369
11370 dev_addr = demod->my_i2c_dev_addr;
11371 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11372 common_attr = (struct drx_common_attr *) demod->my_common_attr;
11373
11374 rc = ctrl_power_mode(demod, mode: &power_mode);
11375 if (rc != 0) {
11376 pr_err("error %d\n", rc);
11377 goto rw_error;
11378 }
11379 if (power_mode != DRX_POWER_UP) {
11380 rc = -EINVAL;
11381 pr_err("failed to powerup device\n");
11382 goto rw_error;
11383 }
11384
11385 /* has to be in front of setIqmAf and setOrxNsuAox */
11386 rc = get_device_capabilities(demod);
11387 if (rc != 0) {
11388 pr_err("error %d\n", rc);
11389 goto rw_error;
11390 }
11391
11392 /*
11393 * Soft reset of sys- and osc-clockdomain
11394 *
11395 * HACK: On windows, it writes a 0x07 here, instead of just 0x03.
11396 * As we didn't load the firmware here yet, we should do the same.
11397 * Btw, this is coherent with DRX-K, where we send reset codes
11398 * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.
11399 */
11400 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_SOFT_RST__A, data: (0x04 | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), flags: 0);
11401 if (rc != 0) {
11402 pr_err("error %d\n", rc);
11403 goto rw_error;
11404 }
11405 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, flags: 0);
11406 if (rc != 0) {
11407 pr_err("error %d\n", rc);
11408 goto rw_error;
11409 }
11410 msleep(msecs: 1);
11411
11412 /* TODO first make sure that everything keeps working before enabling this */
11413 /* PowerDownAnalogBlocks() */
11414 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, data: (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, flags: 0);
11415 if (rc != 0) {
11416 pr_err("error %d\n", rc);
11417 goto rw_error;
11418 }
11419
11420 rc = set_iqm_af(demod, active: false);
11421 if (rc != 0) {
11422 pr_err("error %d\n", rc);
11423 goto rw_error;
11424 }
11425 rc = set_orx_nsu_aox(demod, active: false);
11426 if (rc != 0) {
11427 pr_err("error %d\n", rc);
11428 goto rw_error;
11429 }
11430
11431 rc = init_hi(demod);
11432 if (rc != 0) {
11433 pr_err("error %d\n", rc);
11434 goto rw_error;
11435 }
11436
11437 /* disable mpegoutput pins */
11438 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
11439 cfg_mpeg_output.enable_mpeg_output = false;
11440
11441 rc = ctrl_set_cfg_mpeg_output(demod, cfg_data: &cfg_mpeg_output);
11442 if (rc != 0) {
11443 pr_err("error %d\n", rc);
11444 goto rw_error;
11445 }
11446 /* Stop AUD Inform SetAudio it will need to do all setting */
11447 rc = power_down_aud(demod);
11448 if (rc != 0) {
11449 pr_err("error %d\n", rc);
11450 goto rw_error;
11451 }
11452 /* Stop SCU */
11453 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, flags: 0);
11454 if (rc != 0) {
11455 pr_err("error %d\n", rc);
11456 goto rw_error;
11457 }
11458
11459 /* Upload microcode */
11460 if (common_attr->microcode_file != NULL) {
11461 /* Dirty trick to use common ucode upload & verify,
11462 pretend device is already open */
11463 common_attr->is_opened = true;
11464 ucode_info.mc_file = common_attr->microcode_file;
11465
11466 if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
11467 pr_err("Should powerup before loading the firmware.");
11468 rc = -EINVAL;
11469 goto rw_error;
11470 }
11471
11472 rc = drx_ctrl_u_code(demod, mc_info: &ucode_info, action: UCODE_UPLOAD);
11473 if (rc != 0) {
11474 pr_err("error %d while uploading the firmware\n", rc);
11475 goto rw_error;
11476 }
11477 if (common_attr->verify_microcode == true) {
11478 rc = drx_ctrl_u_code(demod, mc_info: &ucode_info, action: UCODE_VERIFY);
11479 if (rc != 0) {
11480 pr_err("error %d while verifying the firmware\n",
11481 rc);
11482 goto rw_error;
11483 }
11484 }
11485 common_attr->is_opened = false;
11486 }
11487
11488 /* Run SCU for a little while to initialize microcode version numbers */
11489 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, flags: 0);
11490 if (rc != 0) {
11491 pr_err("error %d\n", rc);
11492 goto rw_error;
11493 }
11494
11495 /* Initialize scan timeout */
11496 common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
11497 common_attr->scan_desired_lock = DRX_LOCKED;
11498
11499 drxj_reset_mode(ext_attr);
11500 ext_attr->standard = DRX_STANDARD_UNKNOWN;
11501
11502 rc = smart_ant_init(demod);
11503 if (rc != 0) {
11504 pr_err("error %d\n", rc);
11505 goto rw_error;
11506 }
11507
11508 /* Stamp driver version number in SCU data RAM in BCD code
11509 Done to enable field application engineers to retrieve drxdriver version
11510 via I2C from SCU RAM
11511 */
11512 driver_version = (VERSION_MAJOR / 100) % 10;
11513 driver_version <<= 4;
11514 driver_version += (VERSION_MAJOR / 10) % 10;
11515 driver_version <<= 4;
11516 driver_version += (VERSION_MAJOR % 10);
11517 driver_version <<= 4;
11518 driver_version += (VERSION_MINOR % 10);
11519 driver_version <<= 4;
11520 driver_version += (VERSION_PATCH / 1000) % 10;
11521 driver_version <<= 4;
11522 driver_version += (VERSION_PATCH / 100) % 10;
11523 driver_version <<= 4;
11524 driver_version += (VERSION_PATCH / 10) % 10;
11525 driver_version <<= 4;
11526 driver_version += (VERSION_PATCH % 10);
11527 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, data: (u16)(driver_version >> 16), flags: 0);
11528 if (rc != 0) {
11529 pr_err("error %d\n", rc);
11530 goto rw_error;
11531 }
11532 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, data: (u16)(driver_version & 0xFFFF), flags: 0);
11533 if (rc != 0) {
11534 pr_err("error %d\n", rc);
11535 goto rw_error;
11536 }
11537
11538 rc = ctrl_set_oob(demod, NULL);
11539 if (rc != 0) {
11540 pr_err("error %d\n", rc);
11541 goto rw_error;
11542 }
11543
11544 /* refresh the audio data structure with default */
11545 ext_attr->aud_data = drxj_default_aud_data_g;
11546
11547 demod->my_common_attr->is_opened = true;
11548 drxj_set_lna_state(demod, state: false);
11549 return 0;
11550rw_error:
11551 common_attr->is_opened = false;
11552 return rc;
11553}
11554
11555/*============================================================================*/
11556/*
11557* \fn drxj_close()
11558* \brief Close the demod instance, power down the device
11559* \return Status_t Return status.
11560*
11561*/
11562static int drxj_close(struct drx_demod_instance *demod)
11563{
11564 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11565 int rc;
11566 enum drx_power_mode power_mode = DRX_POWER_UP;
11567
11568 if ((demod->my_common_attr == NULL) ||
11569 (demod->my_ext_attr == NULL) ||
11570 (demod->my_i2c_dev_addr == NULL) ||
11571 (!demod->my_common_attr->is_opened)) {
11572 return -EINVAL;
11573 }
11574
11575 /* power up */
11576 rc = ctrl_power_mode(demod, mode: &power_mode);
11577 if (rc != 0) {
11578 pr_err("error %d\n", rc);
11579 goto rw_error;
11580 }
11581
11582 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, flags: 0);
11583 if (rc != 0) {
11584 pr_err("error %d\n", rc);
11585 goto rw_error;
11586 }
11587 power_mode = DRX_POWER_DOWN;
11588 rc = ctrl_power_mode(demod, mode: &power_mode);
11589 if (rc != 0) {
11590 pr_err("error %d\n", rc);
11591 goto rw_error;
11592 }
11593
11594 DRX_ATTR_ISOPENED(demod) = false;
11595
11596 return 0;
11597rw_error:
11598 DRX_ATTR_ISOPENED(demod) = false;
11599
11600 return rc;
11601}
11602
11603/*
11604 * Microcode related functions
11605 */
11606
11607/*
11608 * drx_u_code_compute_crc - Compute CRC of block of microcode data.
11609 * @block_data: Pointer to microcode data.
11610 * @nr_words: Size of microcode block (number of 16 bits words).
11611 *
11612 * returns The computed CRC residue.
11613 */
11614static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
11615{
11616 u16 i = 0;
11617 u16 j = 0;
11618 u32 crc_word = 0;
11619 u32 carry = 0;
11620
11621 while (i < nr_words) {
11622 crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
11623 for (j = 0; j < 16; j++) {
11624 crc_word <<= 1;
11625 if (carry != 0)
11626 crc_word ^= 0x80050000UL;
11627 carry = crc_word & 0x80000000UL;
11628 }
11629 i++;
11630 block_data += (sizeof(u16));
11631 }
11632 return (u16)(crc_word >> 16);
11633}
11634
11635/*
11636 * drx_check_firmware - checks if the loaded firmware is valid
11637 *
11638 * @demod: demod structure
11639 * @mc_data: pointer to the start of the firmware
11640 * @size: firmware size
11641 */
11642static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
11643 unsigned size)
11644{
11645 struct drxu_code_block_hdr block_hdr;
11646 int i;
11647 unsigned count = 2 * sizeof(u16);
11648 u32 mc_dev_type, mc_version, mc_base_version;
11649 u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
11650
11651 /*
11652 * Scan microcode blocks first for version info
11653 * and firmware check
11654 */
11655
11656 /* Clear version block */
11657 DRX_ATTR_MCRECORD(demod).aux_type = 0;
11658 DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
11659 DRX_ATTR_MCRECORD(demod).mc_version = 0;
11660 DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
11661
11662 for (i = 0; i < mc_nr_of_blks; i++) {
11663 if (count + 3 * sizeof(u16) + sizeof(u32) > size)
11664 goto eof;
11665
11666 /* Process block header */
11667 block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
11668 count += sizeof(u32);
11669 block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
11670 count += sizeof(u16);
11671 block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
11672 count += sizeof(u16);
11673 block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
11674 count += sizeof(u16);
11675
11676 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11677 count, block_hdr.addr, block_hdr.size, block_hdr.flags,
11678 block_hdr.CRC);
11679
11680 if (block_hdr.flags & 0x8) {
11681 u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
11682 u16 auxtype;
11683
11684 if (block_hdr.addr + sizeof(u16) > size)
11685 goto eof;
11686
11687 auxtype = be16_to_cpu(*(__be16 *)(auxblk));
11688
11689 /* Aux block. Check type */
11690 if (DRX_ISMCVERTYPE(auxtype)) {
11691 if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
11692 goto eof;
11693
11694 auxblk += sizeof(u16);
11695 mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
11696 auxblk += sizeof(u32);
11697 mc_version = be32_to_cpu(*(__be32 *)(auxblk));
11698 auxblk += sizeof(u32);
11699 mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
11700
11701 DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
11702 DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
11703 DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
11704 DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
11705
11706 pr_info("Firmware dev %x, ver %x, base ver %x\n",
11707 mc_dev_type, mc_version, mc_base_version);
11708
11709 }
11710 } else if (count + block_hdr.size * sizeof(u16) > size)
11711 goto eof;
11712
11713 count += block_hdr.size * sizeof(u16);
11714 }
11715 return 0;
11716eof:
11717 pr_err("Firmware is truncated at pos %u/%u\n", count, size);
11718 return -EINVAL;
11719}
11720
11721/*
11722 * drx_ctrl_u_code - Handle microcode upload or verify.
11723 * @dev_addr: Address of device.
11724 * @mc_info: Pointer to information about microcode data.
11725 * @action: Either UCODE_UPLOAD or UCODE_VERIFY
11726 *
11727 * This function returns:
11728 * 0:
11729 * - In case of UCODE_UPLOAD: code is successfully uploaded.
11730 * - In case of UCODE_VERIFY: image on device is equal to
11731 * image provided to this control function.
11732 * -EIO:
11733 * - In case of UCODE_UPLOAD: I2C error.
11734 * - In case of UCODE_VERIFY: I2C error or image on device
11735 * is not equal to image provided to this control function.
11736 * -EINVAL:
11737 * - Invalid arguments.
11738 * - Provided image is corrupt
11739 */
11740static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11741 struct drxu_code_info *mc_info,
11742 enum drxu_code_action action)
11743{
11744 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11745 int rc;
11746 u16 i = 0;
11747 u16 mc_nr_of_blks = 0;
11748 u16 mc_magic_word = 0;
11749 const u8 *mc_data_init = NULL;
11750 u8 *mc_data = NULL;
11751 unsigned size;
11752 char *mc_file;
11753
11754 /* Check arguments */
11755 if (!mc_info || !mc_info->mc_file)
11756 return -EINVAL;
11757
11758 mc_file = mc_info->mc_file;
11759
11760 if (!demod->firmware) {
11761 const struct firmware *fw = NULL;
11762
11763 rc = request_firmware(fw: &fw, name: mc_file, device: demod->i2c->dev.parent);
11764 if (rc < 0) {
11765 pr_err("Couldn't read firmware %s\n", mc_file);
11766 return rc;
11767 }
11768 demod->firmware = fw;
11769
11770 if (demod->firmware->size < 2 * sizeof(u16)) {
11771 rc = -EINVAL;
11772 pr_err("Firmware is too short!\n");
11773 goto release;
11774 }
11775
11776 pr_info("Firmware %s, size %zu\n",
11777 mc_file, demod->firmware->size);
11778 }
11779
11780 mc_data_init = demod->firmware->data;
11781 size = demod->firmware->size;
11782
11783 mc_data = (void *)mc_data_init;
11784 /* Check data */
11785 mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
11786 mc_data += sizeof(u16);
11787 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
11788 mc_data += sizeof(u16);
11789
11790 if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
11791 rc = -EINVAL;
11792 pr_err("Firmware magic word doesn't match\n");
11793 goto release;
11794 }
11795
11796 if (action == UCODE_UPLOAD) {
11797 rc = drx_check_firmware(demod, mc_data: (u8 *)mc_data_init, size);
11798 if (rc)
11799 goto release;
11800 pr_info("Uploading firmware %s\n", mc_file);
11801 } else {
11802 pr_info("Verifying if firmware upload was ok.\n");
11803 }
11804
11805 /* Process microcode blocks */
11806 for (i = 0; i < mc_nr_of_blks; i++) {
11807 struct drxu_code_block_hdr block_hdr;
11808 u16 mc_block_nr_bytes = 0;
11809
11810 /* Process block header */
11811 block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
11812 mc_data += sizeof(u32);
11813 block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
11814 mc_data += sizeof(u16);
11815 block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
11816 mc_data += sizeof(u16);
11817 block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
11818 mc_data += sizeof(u16);
11819
11820 pr_debug("%zd: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11821 (mc_data - mc_data_init), block_hdr.addr,
11822 block_hdr.size, block_hdr.flags, block_hdr.CRC);
11823
11824 /* Check block header on:
11825 - data larger than 64Kb
11826 - if CRC enabled check CRC
11827 */
11828 if ((block_hdr.size > 0x7FFF) ||
11829 (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
11830 (block_hdr.CRC != drx_u_code_compute_crc(block_data: mc_data, nr_words: block_hdr.size)))
11831 ) {
11832 /* Wrong data ! */
11833 rc = -EINVAL;
11834 pr_err("firmware CRC is wrong\n");
11835 goto release;
11836 }
11837
11838 if (!block_hdr.size)
11839 continue;
11840
11841 mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
11842
11843 /* Perform the desired action */
11844 switch (action) {
11845 case UCODE_UPLOAD: /* Upload microcode */
11846 if (drxdap_fasi_write_block(dev_addr,
11847 addr: block_hdr.addr,
11848 datasize: mc_block_nr_bytes,
11849 data: mc_data, flags: 0x0000)) {
11850 rc = -EIO;
11851 pr_err("error writing firmware at pos %zd\n",
11852 mc_data - mc_data_init);
11853 goto release;
11854 }
11855 break;
11856 case UCODE_VERIFY: { /* Verify uploaded microcode */
11857 int result = 0;
11858 u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
11859 u32 bytes_to_comp = 0;
11860 u32 bytes_left = mc_block_nr_bytes;
11861 u32 curr_addr = block_hdr.addr;
11862 u8 *curr_ptr = mc_data;
11863
11864 while (bytes_left != 0) {
11865 if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
11866 bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
11867 else
11868 bytes_to_comp = bytes_left;
11869
11870 if (drxdap_fasi_read_block(dev_addr,
11871 addr: curr_addr,
11872 datasize: (u16)bytes_to_comp,
11873 data: (u8 *)mc_data_buffer,
11874 flags: 0x0000)) {
11875 pr_err("error reading firmware at pos %zd\n",
11876 mc_data - mc_data_init);
11877 return -EIO;
11878 }
11879
11880 result = memcmp(p: curr_ptr, q: mc_data_buffer,
11881 size: bytes_to_comp);
11882
11883 if (result) {
11884 pr_err("error verifying firmware at pos %zd\n",
11885 mc_data - mc_data_init);
11886 return -EIO;
11887 }
11888
11889 curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
11890 curr_ptr =&(curr_ptr[bytes_to_comp]);
11891 bytes_left -=((u32) bytes_to_comp);
11892 }
11893 break;
11894 }
11895 default:
11896 return -EINVAL;
11897
11898 }
11899 mc_data += mc_block_nr_bytes;
11900 }
11901
11902 return 0;
11903
11904release:
11905 release_firmware(fw: demod->firmware);
11906 demod->firmware = NULL;
11907
11908 return rc;
11909}
11910
11911/* caller is expected to check if lna is supported before enabling */
11912static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
11913{
11914 struct drxuio_cfg uio_cfg;
11915 struct drxuio_data uio_data;
11916 int result;
11917
11918 uio_cfg.uio = DRX_UIO1;
11919 uio_cfg.mode = DRX_UIO_MODE_READWRITE;
11920 /* Configure user-I/O #3: enable read/write */
11921 result = ctrl_set_uio_cfg(demod, uio_cfg: &uio_cfg);
11922 if (result) {
11923 pr_err("Failed to setup LNA GPIO!\n");
11924 return result;
11925 }
11926
11927 uio_data.uio = DRX_UIO1;
11928 uio_data.value = state;
11929 result = ctrl_uio_write(demod, uio_data: &uio_data);
11930 if (result != 0) {
11931 pr_err("Failed to %sable LNA!\n",
11932 state ? "en" : "dis");
11933 return result;
11934 }
11935 return 0;
11936}
11937
11938/*
11939 * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
11940 *
11941 * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
11942 */
11943
11944static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
11945{
11946 struct drx39xxj_state *state = fe->demodulator_priv;
11947 struct drx_demod_instance *demod = state->demod;
11948 int result;
11949 enum drx_power_mode power_mode;
11950
11951 if (enable)
11952 power_mode = DRX_POWER_UP;
11953 else
11954 power_mode = DRX_POWER_DOWN;
11955
11956 result = ctrl_power_mode(demod, mode: &power_mode);
11957 if (result != 0) {
11958 pr_err("Power state change failed\n");
11959 return 0;
11960 }
11961
11962 return 0;
11963}
11964
11965static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)
11966{
11967 struct drx39xxj_state *state = fe->demodulator_priv;
11968 struct drx_demod_instance *demod = state->demod;
11969 int result;
11970 enum drx_lock_status lock_status;
11971
11972 *status = 0;
11973
11974 result = ctrl_lock_status(demod, lock_stat: &lock_status);
11975 if (result != 0) {
11976 pr_err("drx39xxj: could not get lock status!\n");
11977 *status = 0;
11978 }
11979
11980 switch (lock_status) {
11981 case DRX_NEVER_LOCK:
11982 *status = 0;
11983 pr_err("drx says NEVER_LOCK\n");
11984 break;
11985 case DRX_NOT_LOCKED:
11986 *status = 0;
11987 break;
11988 case DRX_LOCK_STATE_1:
11989 case DRX_LOCK_STATE_2:
11990 case DRX_LOCK_STATE_3:
11991 case DRX_LOCK_STATE_4:
11992 case DRX_LOCK_STATE_5:
11993 case DRX_LOCK_STATE_6:
11994 case DRX_LOCK_STATE_7:
11995 case DRX_LOCK_STATE_8:
11996 case DRX_LOCK_STATE_9:
11997 *status = FE_HAS_SIGNAL
11998 | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
11999 break;
12000 case DRX_LOCKED:
12001 *status = FE_HAS_SIGNAL
12002 | FE_HAS_CARRIER
12003 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
12004 break;
12005 default:
12006 pr_err("Lock state unknown %d\n", lock_status);
12007 }
12008 ctrl_sig_quality(demod, lock_status);
12009
12010 return 0;
12011}
12012
12013static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
12014{
12015 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12016
12017 if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12018 *ber = 0;
12019 return 0;
12020 }
12021
12022 if (!p->pre_bit_count.stat[0].uvalue) {
12023 if (!p->pre_bit_error.stat[0].uvalue)
12024 *ber = 0;
12025 else
12026 *ber = 1000000;
12027 } else {
12028 *ber = frac_times1e6(N: p->pre_bit_error.stat[0].uvalue,
12029 D: p->pre_bit_count.stat[0].uvalue);
12030 }
12031 return 0;
12032}
12033
12034static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
12035 u16 *strength)
12036{
12037 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12038
12039 if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12040 *strength = 0;
12041 return 0;
12042 }
12043
12044 *strength = p->strength.stat[0].uvalue;
12045 return 0;
12046}
12047
12048static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
12049{
12050 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12051 u64 tmp64;
12052
12053 if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12054 *snr = 0;
12055 return 0;
12056 }
12057
12058 tmp64 = p->cnr.stat[0].svalue;
12059 do_div(tmp64, 10);
12060 *snr = tmp64;
12061 return 0;
12062}
12063
12064static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
12065{
12066 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12067
12068 if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12069 *ucb = 0;
12070 return 0;
12071 }
12072
12073 *ucb = p->block_error.stat[0].uvalue;
12074 return 0;
12075}
12076
12077static int drx39xxj_set_frontend(struct dvb_frontend *fe)
12078{
12079#ifdef DJH_DEBUG
12080 int i;
12081#endif
12082 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12083 struct drx39xxj_state *state = fe->demodulator_priv;
12084 struct drx_demod_instance *demod = state->demod;
12085 enum drx_standard standard = DRX_STANDARD_8VSB;
12086 struct drx_channel channel;
12087 int result;
12088 static const struct drx_channel def_channel = {
12089 /* frequency */ 0,
12090 /* bandwidth */ DRX_BANDWIDTH_6MHZ,
12091 /* mirror */ DRX_MIRROR_NO,
12092 /* constellation */ DRX_CONSTELLATION_AUTO,
12093 /* hierarchy */ DRX_HIERARCHY_UNKNOWN,
12094 /* priority */ DRX_PRIORITY_UNKNOWN,
12095 /* coderate */ DRX_CODERATE_UNKNOWN,
12096 /* guard */ DRX_GUARD_UNKNOWN,
12097 /* fftmode */ DRX_FFTMODE_UNKNOWN,
12098 /* classification */ DRX_CLASSIFICATION_AUTO,
12099 /* symbolrate */ 5057000,
12100 /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,
12101 /* ldpc */ DRX_LDPC_UNKNOWN,
12102 /* carrier */ DRX_CARRIER_UNKNOWN,
12103 /* frame mode */ DRX_FRAMEMODE_UNKNOWN
12104 };
12105 u32 constellation = DRX_CONSTELLATION_AUTO;
12106
12107 /* Bring the demod out of sleep */
12108 drx39xxj_set_powerstate(fe, enable: 1);
12109
12110 if (fe->ops.tuner_ops.set_params) {
12111 u32 int_freq;
12112
12113 if (fe->ops.i2c_gate_ctrl)
12114 fe->ops.i2c_gate_ctrl(fe, 1);
12115
12116 /* Set tuner to desired frequency and standard */
12117 fe->ops.tuner_ops.set_params(fe);
12118
12119 /* Use the tuner's IF */
12120 if (fe->ops.tuner_ops.get_if_frequency) {
12121 fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);
12122 demod->my_common_attr->intermediate_freq = int_freq / 1000;
12123 }
12124
12125 if (fe->ops.i2c_gate_ctrl)
12126 fe->ops.i2c_gate_ctrl(fe, 0);
12127 }
12128
12129 switch (p->delivery_system) {
12130 case SYS_ATSC:
12131 standard = DRX_STANDARD_8VSB;
12132 break;
12133 case SYS_DVBC_ANNEX_B:
12134 standard = DRX_STANDARD_ITU_B;
12135
12136 switch (p->modulation) {
12137 case QAM_64:
12138 constellation = DRX_CONSTELLATION_QAM64;
12139 break;
12140 case QAM_256:
12141 constellation = DRX_CONSTELLATION_QAM256;
12142 break;
12143 default:
12144 constellation = DRX_CONSTELLATION_AUTO;
12145 break;
12146 }
12147 break;
12148 default:
12149 return -EINVAL;
12150 }
12151 /* Set the standard (will be powered up if necessary */
12152 result = ctrl_set_standard(demod, standard: &standard);
12153 if (result != 0) {
12154 pr_err("Failed to set standard! result=%02x\n",
12155 result);
12156 return -EINVAL;
12157 }
12158
12159 /* set channel parameters */
12160 channel = def_channel;
12161 channel.frequency = p->frequency / 1000;
12162 channel.bandwidth = DRX_BANDWIDTH_6MHZ;
12163 channel.constellation = constellation;
12164
12165 /* program channel */
12166 result = ctrl_set_channel(demod, channel: &channel);
12167 if (result != 0) {
12168 pr_err("Failed to set channel!\n");
12169 return -EINVAL;
12170 }
12171 /* Just for giggles, let's shut off the LNA again.... */
12172 drxj_set_lna_state(demod, state: false);
12173
12174 /* After set_frontend, except for strength, stats aren't available */
12175 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12176
12177 return 0;
12178}
12179
12180static int drx39xxj_sleep(struct dvb_frontend *fe)
12181{
12182 /* power-down the demodulator */
12183 return drx39xxj_set_powerstate(fe, enable: 0);
12184}
12185
12186static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
12187{
12188 struct drx39xxj_state *state = fe->demodulator_priv;
12189 struct drx_demod_instance *demod = state->demod;
12190 bool i2c_gate_state;
12191 int result;
12192
12193#ifdef DJH_DEBUG
12194 pr_debug("i2c gate call: enable=%d state=%d\n", enable,
12195 state->i2c_gate_open);
12196#endif
12197
12198 if (enable)
12199 i2c_gate_state = true;
12200 else
12201 i2c_gate_state = false;
12202
12203 if (state->i2c_gate_open == enable) {
12204 /* We're already in the desired state */
12205 return 0;
12206 }
12207
12208 result = ctrl_i2c_bridge(demod, bridge_closed: &i2c_gate_state);
12209 if (result != 0) {
12210 pr_err("drx39xxj: could not open i2c gate [%d]\n",
12211 result);
12212 dump_stack();
12213 } else {
12214 state->i2c_gate_open = enable;
12215 }
12216 return 0;
12217}
12218
12219static int drx39xxj_init(struct dvb_frontend *fe)
12220{
12221 struct drx39xxj_state *state = fe->demodulator_priv;
12222 struct drx_demod_instance *demod = state->demod;
12223 int rc = 0;
12224
12225 if (fe->exit == DVB_FE_DEVICE_RESUME) {
12226 /* so drxj_open() does what it needs to do */
12227 demod->my_common_attr->is_opened = false;
12228 rc = drxj_open(demod);
12229 if (rc != 0)
12230 pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
12231 } else
12232 drx39xxj_set_powerstate(fe, enable: 1);
12233
12234 return rc;
12235}
12236
12237static int drx39xxj_set_lna(struct dvb_frontend *fe)
12238{
12239 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
12240 struct drx39xxj_state *state = fe->demodulator_priv;
12241 struct drx_demod_instance *demod = state->demod;
12242 struct drxj_data *ext_attr = demod->my_ext_attr;
12243
12244 if (c->lna) {
12245 if (!ext_attr->has_lna) {
12246 pr_err("LNA is not supported on this device!\n");
12247 return -EINVAL;
12248
12249 }
12250 }
12251
12252 return drxj_set_lna_state(demod, state: c->lna);
12253}
12254
12255static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
12256 struct dvb_frontend_tune_settings *tune)
12257{
12258 tune->min_delay_ms = 1000;
12259 return 0;
12260}
12261
12262static void drx39xxj_release(struct dvb_frontend *fe)
12263{
12264 struct drx39xxj_state *state = fe->demodulator_priv;
12265 struct drx_demod_instance *demod = state->demod;
12266
12267 /* if device is removed don't access it */
12268 if (fe->exit != DVB_FE_DEVICE_REMOVED)
12269 drxj_close(demod);
12270
12271 kfree(objp: demod->my_ext_attr);
12272 kfree(objp: demod->my_common_attr);
12273 kfree(objp: demod->my_i2c_dev_addr);
12274 release_firmware(fw: demod->firmware);
12275 kfree(objp: demod);
12276 kfree(objp: state);
12277}
12278
12279static const struct dvb_frontend_ops drx39xxj_ops;
12280
12281struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
12282{
12283 struct drx39xxj_state *state = NULL;
12284 struct i2c_device_addr *demod_addr = NULL;
12285 struct drx_common_attr *demod_comm_attr = NULL;
12286 struct drxj_data *demod_ext_attr = NULL;
12287 struct drx_demod_instance *demod = NULL;
12288 struct dtv_frontend_properties *p;
12289 int result;
12290
12291 /* allocate memory for the internal state */
12292 state = kzalloc(size: sizeof(struct drx39xxj_state), GFP_KERNEL);
12293 if (state == NULL)
12294 goto error;
12295
12296 demod = kmemdup(p: &drxj_default_demod_g,
12297 size: sizeof(struct drx_demod_instance), GFP_KERNEL);
12298 if (demod == NULL)
12299 goto error;
12300
12301 demod_addr = kmemdup(p: &drxj_default_addr_g,
12302 size: sizeof(struct i2c_device_addr), GFP_KERNEL);
12303 if (demod_addr == NULL)
12304 goto error;
12305
12306 demod_comm_attr = kmemdup(p: &drxj_default_comm_attr_g,
12307 size: sizeof(struct drx_common_attr), GFP_KERNEL);
12308 if (demod_comm_attr == NULL)
12309 goto error;
12310
12311 demod_ext_attr = kmemdup(p: &drxj_data_g, size: sizeof(struct drxj_data),
12312 GFP_KERNEL);
12313 if (demod_ext_attr == NULL)
12314 goto error;
12315
12316 /* setup the state */
12317 state->i2c = i2c;
12318 state->demod = demod;
12319
12320 /* setup the demod data */
12321 demod->my_i2c_dev_addr = demod_addr;
12322 demod->my_common_attr = demod_comm_attr;
12323 demod->my_i2c_dev_addr->user_data = state;
12324 demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;
12325 demod->my_common_attr->verify_microcode = true;
12326 demod->my_common_attr->intermediate_freq = 5000;
12327 demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;
12328 demod->my_ext_attr = demod_ext_attr;
12329 ((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;
12330 demod->i2c = i2c;
12331
12332 result = drxj_open(demod);
12333 if (result != 0) {
12334 pr_err("DRX open failed! Aborting\n");
12335 goto error;
12336 }
12337
12338 /* create dvb_frontend */
12339 memcpy(&state->frontend.ops, &drx39xxj_ops,
12340 sizeof(struct dvb_frontend_ops));
12341
12342 state->frontend.demodulator_priv = state;
12343
12344 /* Initialize stats - needed for DVBv5 stats to work */
12345 p = &state->frontend.dtv_property_cache;
12346 p->strength.len = 1;
12347 p->pre_bit_count.len = 1;
12348 p->pre_bit_error.len = 1;
12349 p->post_bit_count.len = 1;
12350 p->post_bit_error.len = 1;
12351 p->block_count.len = 1;
12352 p->block_error.len = 1;
12353 p->cnr.len = 1;
12354
12355 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12356 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12357 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12358 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12359 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12360 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12361 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12362 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12363
12364 return &state->frontend;
12365
12366error:
12367 kfree(objp: demod_ext_attr);
12368 kfree(objp: demod_comm_attr);
12369 kfree(objp: demod_addr);
12370 kfree(objp: demod);
12371 kfree(objp: state);
12372
12373 return NULL;
12374}
12375EXPORT_SYMBOL_GPL(drx39xxj_attach);
12376
12377static const struct dvb_frontend_ops drx39xxj_ops = {
12378 .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
12379 .info = {
12380 .name = "Micronas DRX39xxj family Frontend",
12381 .frequency_min_hz = 51 * MHz,
12382 .frequency_max_hz = 858 * MHz,
12383 .frequency_stepsize_hz = 62500,
12384 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
12385 },
12386
12387 .init = drx39xxj_init,
12388 .i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,
12389 .sleep = drx39xxj_sleep,
12390 .set_frontend = drx39xxj_set_frontend,
12391 .get_tune_settings = drx39xxj_get_tune_settings,
12392 .read_status = drx39xxj_read_status,
12393 .read_ber = drx39xxj_read_ber,
12394 .read_signal_strength = drx39xxj_read_signal_strength,
12395 .read_snr = drx39xxj_read_snr,
12396 .read_ucblocks = drx39xxj_read_ucblocks,
12397 .release = drx39xxj_release,
12398 .set_lna = drx39xxj_set_lna,
12399};
12400
12401MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
12402MODULE_AUTHOR("Devin Heitmueller");
12403MODULE_LICENSE("GPL");
12404MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);
12405

source code of linux/drivers/media/dvb-frontends/drx39xyj/drxj.c