blob: 3a63520b745c97ace2e39de00914788ec6174243 [file] [log] [blame]
Devin Heitmuellerca3355a2010-07-04 18:42:11 -03001/*
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
Devin Heitmueller38b2df92012-08-13 21:18:02 -030031/**
32* \file $Id: drxj.c,v 1.637 2010/01/18 17:21:10 dingtao Exp $
33*
34* \brief DRXJ specific implementation of DRX driver
35*
36* \author Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
37*/
38
Devin Heitmueller38b2df92012-08-13 21:18:02 -030039/*-----------------------------------------------------------------------------
40INCLUDE FILES
41----------------------------------------------------------------------------*/
42
43#include "drxj.h"
44#include "drxj_map.h"
45
46#ifdef DRXJ_OPTIONS_H
47#include "drxj_options.h"
48#endif
49
Devin Heitmueller38b2df92012-08-13 21:18:02 -030050/*============================================================================*/
51/*=== DEFINES ================================================================*/
52/*============================================================================*/
53
54/**
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030055* \brief Maximum u32 value.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030056*/
57#ifndef MAX_U32
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030058#define MAX_U32 ((u32) (0xFFFFFFFFL))
Devin Heitmueller38b2df92012-08-13 21:18:02 -030059#endif
60
61/* Customer configurable hardware settings, etc */
62#ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
63#define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
64#endif
65
66#ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
67#define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
68#endif
69
70#ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
71#define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
72#endif
73
74#ifndef OOB_CRX_DRIVE_STRENGTH
75#define OOB_CRX_DRIVE_STRENGTH 0x02
76#endif
77
78#ifndef OOB_DRX_DRIVE_STRENGTH
79#define OOB_DRX_DRIVE_STRENGTH 0x02
80#endif
81/**** START DJCOMBO patches to DRXJ registermap constants *********************/
82/**** registermap 200706071303 from drxj **************************************/
83#define ATV_TOP_CR_AMP_TH_FM 0x0
84#define ATV_TOP_CR_AMP_TH_L 0xA
85#define ATV_TOP_CR_AMP_TH_LP 0xA
86#define ATV_TOP_CR_AMP_TH_BG 0x8
87#define ATV_TOP_CR_AMP_TH_DK 0x8
88#define ATV_TOP_CR_AMP_TH_I 0x8
89#define ATV_TOP_CR_CONT_CR_D_MN 0x18
90#define ATV_TOP_CR_CONT_CR_D_FM 0x0
91#define ATV_TOP_CR_CONT_CR_D_L 0x20
92#define ATV_TOP_CR_CONT_CR_D_LP 0x20
93#define ATV_TOP_CR_CONT_CR_D_BG 0x18
94#define ATV_TOP_CR_CONT_CR_D_DK 0x18
95#define ATV_TOP_CR_CONT_CR_D_I 0x18
96#define ATV_TOP_CR_CONT_CR_I_MN 0x80
97#define ATV_TOP_CR_CONT_CR_I_FM 0x0
98#define ATV_TOP_CR_CONT_CR_I_L 0x80
99#define ATV_TOP_CR_CONT_CR_I_LP 0x80
100#define ATV_TOP_CR_CONT_CR_I_BG 0x80
101#define ATV_TOP_CR_CONT_CR_I_DK 0x80
102#define ATV_TOP_CR_CONT_CR_I_I 0x80
103#define ATV_TOP_CR_CONT_CR_P_MN 0x4
104#define ATV_TOP_CR_CONT_CR_P_FM 0x0
105#define ATV_TOP_CR_CONT_CR_P_L 0x4
106#define ATV_TOP_CR_CONT_CR_P_LP 0x4
107#define ATV_TOP_CR_CONT_CR_P_BG 0x4
108#define ATV_TOP_CR_CONT_CR_P_DK 0x4
109#define ATV_TOP_CR_CONT_CR_P_I 0x4
110#define ATV_TOP_CR_OVM_TH_MN 0xA0
111#define ATV_TOP_CR_OVM_TH_FM 0x0
112#define ATV_TOP_CR_OVM_TH_L 0xA0
113#define ATV_TOP_CR_OVM_TH_LP 0xA0
114#define ATV_TOP_CR_OVM_TH_BG 0xA0
115#define ATV_TOP_CR_OVM_TH_DK 0xA0
116#define ATV_TOP_CR_OVM_TH_I 0xA0
117#define ATV_TOP_EQU0_EQU_C0_FM 0x0
118#define ATV_TOP_EQU0_EQU_C0_L 0x3
119#define ATV_TOP_EQU0_EQU_C0_LP 0x3
120#define ATV_TOP_EQU0_EQU_C0_BG 0x7
121#define ATV_TOP_EQU0_EQU_C0_DK 0x0
122#define ATV_TOP_EQU0_EQU_C0_I 0x3
123#define ATV_TOP_EQU1_EQU_C1_FM 0x0
124#define ATV_TOP_EQU1_EQU_C1_L 0x1F6
125#define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
126#define ATV_TOP_EQU1_EQU_C1_BG 0x197
127#define ATV_TOP_EQU1_EQU_C1_DK 0x198
128#define ATV_TOP_EQU1_EQU_C1_I 0x1F6
129#define ATV_TOP_EQU2_EQU_C2_FM 0x0
130#define ATV_TOP_EQU2_EQU_C2_L 0x28
131#define ATV_TOP_EQU2_EQU_C2_LP 0x28
132#define ATV_TOP_EQU2_EQU_C2_BG 0xC5
133#define ATV_TOP_EQU2_EQU_C2_DK 0xB0
134#define ATV_TOP_EQU2_EQU_C2_I 0x28
135#define ATV_TOP_EQU3_EQU_C3_FM 0x0
136#define ATV_TOP_EQU3_EQU_C3_L 0x192
137#define ATV_TOP_EQU3_EQU_C3_LP 0x192
138#define ATV_TOP_EQU3_EQU_C3_BG 0x12E
139#define ATV_TOP_EQU3_EQU_C3_DK 0x18E
140#define ATV_TOP_EQU3_EQU_C3_I 0x192
141#define ATV_TOP_STD_MODE_MN 0x0
142#define ATV_TOP_STD_MODE_FM 0x1
143#define ATV_TOP_STD_MODE_L 0x0
144#define ATV_TOP_STD_MODE_LP 0x0
145#define ATV_TOP_STD_MODE_BG 0x0
146#define ATV_TOP_STD_MODE_DK 0x0
147#define ATV_TOP_STD_MODE_I 0x0
148#define ATV_TOP_STD_VID_POL_MN 0x0
149#define ATV_TOP_STD_VID_POL_FM 0x0
150#define ATV_TOP_STD_VID_POL_L 0x2
151#define ATV_TOP_STD_VID_POL_LP 0x2
152#define ATV_TOP_STD_VID_POL_BG 0x0
153#define ATV_TOP_STD_VID_POL_DK 0x0
154#define ATV_TOP_STD_VID_POL_I 0x0
155#define ATV_TOP_VID_AMP_MN 0x380
156#define ATV_TOP_VID_AMP_FM 0x0
157#define ATV_TOP_VID_AMP_L 0xF50
158#define ATV_TOP_VID_AMP_LP 0xF50
159#define ATV_TOP_VID_AMP_BG 0x380
160#define ATV_TOP_VID_AMP_DK 0x394
161#define ATV_TOP_VID_AMP_I 0x3D8
162#define IQM_CF_OUT_ENA_OFDM__M 0x4
163#define IQM_FS_ADJ_SEL_B_QAM 0x1
164#define IQM_FS_ADJ_SEL_B_OFF 0x0
165#define IQM_FS_ADJ_SEL_B_VSB 0x2
166#define IQM_RC_ADJ_SEL_B_OFF 0x0
167#define IQM_RC_ADJ_SEL_B_QAM 0x1
168#define IQM_RC_ADJ_SEL_B_VSB 0x2
169/**** END DJCOMBO patches to DRXJ registermap *********************************/
170
171#include "drx_driver_version.h"
172
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300173/* #define DRX_DEBUG */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300174#ifdef DRX_DEBUG
175#include <stdio.h>
176#endif
177
178/*-----------------------------------------------------------------------------
179ENUMS
180----------------------------------------------------------------------------*/
181
182/*-----------------------------------------------------------------------------
183DEFINES
184----------------------------------------------------------------------------*/
185#ifndef DRXJ_WAKE_UP_KEY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300186#define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300187#endif
188
189/**
190* \def DRXJ_DEF_I2C_ADDR
191* \brief Default I2C addres of a demodulator instance.
192*/
193#define DRXJ_DEF_I2C_ADDR (0x52)
194
195/**
196* \def DRXJ_DEF_DEMOD_DEV_ID
197* \brief Default device identifier of a demodultor instance.
198*/
199#define DRXJ_DEF_DEMOD_DEV_ID (1)
200
201/**
202* \def DRXJ_SCAN_TIMEOUT
203* \brief Timeout value for waiting on demod lock during channel scan (millisec).
204*/
205#define DRXJ_SCAN_TIMEOUT 1000
206
207/**
208* \def DRXJ_DAP
209* \brief Name of structure containing all data access protocol functions.
210*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300211#define DRXJ_DAP drx_dap_drxj_funct_g
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300212
213/**
214* \def HI_I2C_DELAY
215* \brief HI timing delay for I2C timing (in nano seconds)
216*
217* Used to compute HI_CFG_DIV
218*/
219#define HI_I2C_DELAY 42
220
221/**
222* \def HI_I2C_BRIDGE_DELAY
223* \brief HI timing delay for I2C timing (in nano seconds)
224*
225* Used to compute HI_CFG_BDL
226*/
227#define HI_I2C_BRIDGE_DELAY 750
228
229/**
230* \brief Time Window for MER and SER Measurement in Units of Segment duration.
231*/
232#define VSB_TOP_MEASUREMENT_PERIOD 64
233#define SYMBOLS_PER_SEGMENT 832
234
235/**
236* \brief bit rate and segment rate constants used for SER and BER.
237*/
238/* values taken from the QAM microcode */
239#define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
240#define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
241#define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
242#define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
243#define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
244#define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
245#define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
246#define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
247/**
248* \brief Min supported symbolrates.
249*/
250#ifndef DRXJ_QAM_SYMBOLRATE_MIN
251#define DRXJ_QAM_SYMBOLRATE_MIN (520000)
252#endif
253
254/**
255* \brief Max supported symbolrates.
256*/
257#ifndef DRXJ_QAM_SYMBOLRATE_MAX
258#define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
259#endif
260
261/**
262* \def DRXJ_QAM_MAX_WAITTIME
263* \brief Maximal wait time for QAM auto constellation in ms
264*/
265#ifndef DRXJ_QAM_MAX_WAITTIME
266#define DRXJ_QAM_MAX_WAITTIME 900
267#endif
268
269#ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
270#define DRXJ_QAM_FEC_LOCK_WAITTIME 150
271#endif
272
273#ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
274#define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
275#endif
276
277/**
278* \def SCU status and results
279* \brief SCU
280*/
281#define DRX_SCU_READY 0
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300282#define DRXJ_MAX_WAITTIME 100 /* ms */
283#define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
284#define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300285
286/**
287* \def DRX_AUD_MAX_DEVIATION
288* \brief Needed for calculation of prescale feature in AUD
289*/
290#ifndef DRXJ_AUD_MAX_FM_DEVIATION
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300291#define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300292#endif
293
294/**
295* \brief Needed for calculation of NICAM prescale feature in AUD
296*/
297#ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300298#define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300299#endif
300
301/**
302* \brief Needed for calculation of NICAM prescale feature in AUD
303*/
304#ifndef DRXJ_AUD_MAX_WAITTIME
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300305#define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300306#endif
307
308/* ATV config changed flags */
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300309#define DRXJ_ATV_CHANGED_COEF (0x00000001UL)
310#define DRXJ_ATV_CHANGED_PEAK_FLT (0x00000008UL)
311#define DRXJ_ATV_CHANGED_NOISE_FLT (0x00000010UL)
312#define DRXJ_ATV_CHANGED_OUTPUT (0x00000020UL)
313#define DRXJ_ATV_CHANGED_SIF_ATT (0x00000040UL)
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300314
315/* UIO define */
316#define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
317#define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
318
319#ifdef DRXJ_SPLIT_UCODE_UPLOAD
320/*============================================================================*/
321/*=== MICROCODE RELATED DEFINES ==============================================*/
322/*============================================================================*/
323
324/**
325* \def DRXJ_UCODE_MAGIC_WORD
326* \brief Magic word for checking correct Endianess of microcode data.
327*
328*/
329
330#ifndef DRXJ_UCODE_MAGIC_WORD
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300331#define DRXJ_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L'))
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300332#endif
333
334/**
335* \def DRXJ_UCODE_CRC_FLAG
336* \brief CRC flag in ucode header, flags field.
337*
338*/
339
340#ifndef DRXJ_UCODE_CRC_FLAG
341#define DRXJ_UCODE_CRC_FLAG (0x0001)
342#endif
343
344/**
345* \def DRXJ_UCODE_COMPRESSION_FLAG
346* \brief Compression flag in ucode header, flags field.
347*
348*/
349
350#ifndef DRXJ_UCODE_COMPRESSION_FLAG
351#define DRXJ_UCODE_COMPRESSION_FLAG (0x0002)
352#endif
353
354/**
355* \def DRXJ_UCODE_MAX_BUF_SIZE
356* \brief Maximum size of buffer used to verify the microcode.Must be an even number.
357*
358*/
359
360#ifndef DRXJ_UCODE_MAX_BUF_SIZE
361#define DRXJ_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
362#endif
363#if DRXJ_UCODE_MAX_BUF_SIZE & 1
364#error DRXJ_UCODE_MAX_BUF_SIZE must be an even number
365#endif
366
367#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
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 adresses directly. This must be READ ONLY to avoid problems. */
385/* Writing to the interface adresses is more than only writing the RAM */
386/* locations */
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*/
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300427#ifdef AUD_DEM_WR_FM_MATRIX__A
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300428#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
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300450#define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300451#endif
452
453/**
454* \brief Needed for calculation of NICAM prescale feature in AUD
455*/
456#ifndef DRX_AUD_MAX_NICAM_PRESCALE
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300457#define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300458#endif
459
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300460/*============================================================================*/
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#ifdef DRXJDRIVER_DEBUG
482#include <stdio.h>
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300483#define CHK_ERROR(s) \
484 do { \
485 if ((s) != DRX_STS_OK) \
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300486 { \
487 fprintf(stderr, \
488 "ERROR[\n file : %s\n line : %d\n]\n", \
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300489 __FILE__, __LINE__); \
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300490 goto rw_error; }; \
491 } \
492 while (0 != 0)
493#else
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300494#define CHK_ERROR(s) \
495 do { \
496 if ((s) != DRX_STS_OK) { goto rw_error; } \
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300497 } while (0 != 0)
498#endif
499
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300500#define CHK_ZERO(s) \
501 do { \
502 if ((s) == 0) return DRX_STS_ERROR; \
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300503 } while (0)
504
505#define DUMMY_READ() \
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300506 do { \
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300507 u16 dummy; \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300508 RR16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy); \
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300509 } while (0)
510
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300511#define WR16(dev, addr, val) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300512 CHK_ERROR(DRXJ_DAP.write_reg16func( (dev), (addr), (val), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300513
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300514#define RR16(dev, addr, val) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300515 CHK_ERROR(DRXJ_DAP.read_reg16func( (dev), (addr), (val), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300516
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300517#define WR32(dev, addr, val) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300518 CHK_ERROR(DRXJ_DAP.write_reg32func( (dev), (addr), (val), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300519
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300520#define RR32(dev, addr, val) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300521 CHK_ERROR(DRXJ_DAP.read_reg32func( (dev), (addr), (val), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300522
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300523#define WRB(dev, addr, len, block) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300524 CHK_ERROR(DRXJ_DAP.write_block_func( (dev), (addr), (len), (block), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300525
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300526#define RRB(dev, addr, len, block) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300527 CHK_ERROR(DRXJ_DAP.read_block_func( (dev), (addr), (len), (block), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300528
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300529#define BCWR16(dev, addr, val) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300530 CHK_ERROR(DRXJ_DAP.write_reg16func( (dev), (addr), (val), DRXDAP_FASI_BROADCAST) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300531
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300532#define ARR32(dev, addr, val) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300533 CHK_ERROR(drxj_dap_atomic_read_reg32( (dev), (addr), (val), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300534
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300535#define SARR16(dev, addr, val) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300536 CHK_ERROR(drxj_dap_scu_atomic_read_reg16( (dev), (addr), (val), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300537
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300538#define SAWR16(dev, addr, val) \
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300539 CHK_ERROR(drxj_dap_scu_atomic_write_reg16( (dev), (addr), (val), 0) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300540
541/**
542* This macro is used to create byte arrays for block writes.
543* Block writes speed up I2C traffic between host and demod.
544* The macro takes care of the required byte order in a 16 bits word.
545* x -> lowbyte(x), highbyte(x)
546*/
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300547#define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300548 ((u8)((((u16)x)>>8)&0xFF))
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300549/**
550* This macro is used to convert byte array to 16 bit register value for block read.
551* Block read speed up I2C traffic between host and demod.
552* The macro takes care of the required byte order in a 16 bits word.
553*/
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300554#define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300555
556/*============================================================================*/
557/*=== MISC DEFINES ===========================================================*/
558/*============================================================================*/
559
560/*============================================================================*/
561/*=== HI COMMAND RELATED DEFINES =============================================*/
562/*============================================================================*/
563
564/**
565* \brief General maximum number of retries for ucode command interfaces
566*/
567#define DRXJ_MAX_RETRIES (100)
568
569/*============================================================================*/
570/*=== STANDARD RELATED MACROS ================================================*/
571/*============================================================================*/
572
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300573#define DRXJ_ISATVSTD(std) ( ( std == DRX_STANDARD_PAL_SECAM_BG ) || \
574 (std == DRX_STANDARD_PAL_SECAM_DK) || \
575 (std == DRX_STANDARD_PAL_SECAM_I) || \
576 (std == DRX_STANDARD_PAL_SECAM_L) || \
577 (std == DRX_STANDARD_PAL_SECAM_LP) || \
578 (std == DRX_STANDARD_NTSC) || \
579 (std == DRX_STANDARD_FM) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300580
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -0300581#define DRXJ_ISQAMSTD(std) ( ( std == DRX_STANDARD_ITU_A ) || \
582 (std == DRX_STANDARD_ITU_B) || \
583 (std == DRX_STANDARD_ITU_C) || \
584 (std == DRX_STANDARD_ITU_D))
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300585
586/*-----------------------------------------------------------------------------
587STATIC VARIABLES
588----------------------------------------------------------------------------*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300589int drxj_open(pdrx_demod_instance_t demod);
590int drxj_close(pdrx_demod_instance_t demod);
591int drxj_ctrl(pdrx_demod_instance_t demod,
592 u32 ctrl, void *ctrl_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300593
594/*-----------------------------------------------------------------------------
595GLOBAL VARIABLES
596----------------------------------------------------------------------------*/
597/*
598 * DRXJ DAP structures
599 */
600
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300601static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
602 dr_xaddr_t addr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300603 u16 datasize,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300604 u8 *data, dr_xflags_t flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300605
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300606static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
607 dr_xaddr_t waddr,
608 dr_xaddr_t raddr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300609 u8 wdata, u8 *rdata);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300610
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300611static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
612 dr_xaddr_t waddr,
613 dr_xaddr_t raddr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300614 u16 wdata, u16 *rdata);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300615
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300616static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
617 dr_xaddr_t waddr,
618 dr_xaddr_t raddr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300619 u32 wdata, u32 *rdata);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300620
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300621static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
622 dr_xaddr_t addr,
623 u8 *data, dr_xflags_t flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300624
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300625static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
626 dr_xaddr_t addr,
627 u16 *data, dr_xflags_t flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300628
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300629static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
630 dr_xaddr_t addr,
631 u32 *data, dr_xflags_t flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300632
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300633static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
634 dr_xaddr_t addr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300635 u16 datasize,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300636 u8 *data, dr_xflags_t flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300637
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300638static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
639 dr_xaddr_t addr,
640 u8 data, dr_xflags_t flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300641
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300642static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
643 dr_xaddr_t addr,
644 u16 data, dr_xflags_t flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300645
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300646static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
647 dr_xaddr_t addr,
648 u32 data, dr_xflags_t flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300649
650/* The version structure of this protocol implementation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300651char drx_dap_drxj_module_name[] = "DRXJ Data Access Protocol";
652char drx_dap_drxj_version_text[] = "0.0.0";
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300653
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300654drx_version_t drx_dap_drxj_version = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300655 DRX_MODULE_DAP, /**< type identifier of the module */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300656 drx_dap_drxj_module_name, /**< name or description of module */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300657
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300658 0, /**< major version number */
659 0, /**< minor version number */
660 0, /**< patch version number */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300661 drx_dap_drxj_version_text /**< version as text string */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300662};
663
664/* The structure containing the protocol interface */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300665drx_access_func_t drx_dap_drxj_funct_g = {
666 &drx_dap_drxj_version,
667 drxj_dap_write_block, /* Supported */
668 drxj_dap_read_block, /* Supported */
669 drxj_dap_write_reg8, /* Not supported */
670 drxj_dap_read_reg8, /* Not supported */
671 drxj_dap_read_modify_write_reg8, /* Not supported */
672 drxj_dap_write_reg16, /* Supported */
673 drxj_dap_read_reg16, /* Supported */
674 drxj_dap_read_modify_write_reg16, /* Supported */
675 drxj_dap_write_reg32, /* Supported */
676 drxj_dap_read_reg32, /* Supported */
677 drxj_dap_read_modify_write_reg32, /* Not supported */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300678};
679
680/**
681* /var DRXJ_Func_g
682* /brief The driver functions of the drxj
683*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300684drx_demod_func_t drxj_functions_g = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300685 DRXJ_TYPE_ID,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300686 drxj_open,
687 drxj_close,
688 drxj_ctrl
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300689};
690
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300691drxj_data_t drxj_data_g = {
692 false, /* has_lna : true if LNA (aka PGA) present */
693 false, /* has_oob : true if OOB supported */
694 false, /* has_ntsc: true if NTSC supported */
695 false, /* has_btsc: true if BTSC supported */
696 false, /* has_smatx: true if SMA_TX pin is available */
697 false, /* has_smarx: true if SMA_RX pin is available */
698 false, /* has_gpio : true if GPIO pin is available */
699 false, /* has_irqn : true if IRQN pin is available */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300700 0, /* mfx A1/A2/A... */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300701
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300702 /* tuner settings */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300703 false, /* tuner mirrors RF signal */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300704 /* standard/channel settings */
705 DRX_STANDARD_UNKNOWN, /* current standard */
706 DRX_CONSTELLATION_AUTO, /* constellation */
707 0, /* frequency in KHz */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300708 DRX_BANDWIDTH_UNKNOWN, /* curr_bandwidth */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300709 DRX_MIRROR_NO, /* mirror */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300710
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300711 /* signal quality information: */
712 /* default values taken from the QAM Programming guide */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300713 /* fec_bits_desired should not be less than 4000000 */
714 4000000, /* fec_bits_desired */
715 5, /* fec_vd_plen */
716 4, /* qam_vd_prescale */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300717 0xFFFF, /* qamVDPeriod */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300718 204 * 8, /* fec_rs_plen annex A */
719 1, /* fec_rs_prescale */
720 FEC_RS_MEASUREMENT_PERIOD, /* fec_rs_period */
721 true, /* reset_pkt_err_acc */
722 0, /* pkt_errAccStart */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300723
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300724 /* HI configuration */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300725 0, /* hi_cfg_timing_div */
726 0, /* hi_cfg_bridge_delay */
727 0, /* hi_cfg_wake_up_key */
728 0, /* hi_cfg_ctrl */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300729 0, /* HICfgTimeout */
730 /* UIO configuartion */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300731 DRX_UIO_MODE_DISABLE, /* uio_sma_rx_mode */
732 DRX_UIO_MODE_DISABLE, /* uio_sma_tx_mode */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300733 DRX_UIO_MODE_DISABLE, /* uioASELMode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300734 DRX_UIO_MODE_DISABLE, /* uio_irqn_mode */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300735 /* FS setting */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300736 0UL, /* iqm_fs_rate_ofs */
737 false, /* pos_image */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300738 /* RC setting */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300739 0UL, /* iqm_rc_rate_ofs */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300740 /* AUD information */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300741/* false, * flagSetAUDdone */
742/* false, * detectedRDS */
743/* true, * flagASDRequest */
744/* false, * flagHDevClear */
745/* false, * flagHDevSet */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300746/* (u16) 0xFFF, * rdsLastCount */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300747
748/*#ifdef DRXJ_SPLIT_UCODE_UPLOAD
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300749 false, * flag_aud_mc_uploaded */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300750/*#endif * DRXJ_SPLIT_UCODE_UPLOAD */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300751 /* ATV configuartion */
752 0UL, /* flags cfg changes */
753 /* shadow of ATV_TOP_EQU0__A */
754 {-5,
755 ATV_TOP_EQU0_EQU_C0_FM,
756 ATV_TOP_EQU0_EQU_C0_L,
757 ATV_TOP_EQU0_EQU_C0_LP,
758 ATV_TOP_EQU0_EQU_C0_BG,
759 ATV_TOP_EQU0_EQU_C0_DK,
760 ATV_TOP_EQU0_EQU_C0_I},
761 /* shadow of ATV_TOP_EQU1__A */
762 {-50,
763 ATV_TOP_EQU1_EQU_C1_FM,
764 ATV_TOP_EQU1_EQU_C1_L,
765 ATV_TOP_EQU1_EQU_C1_LP,
766 ATV_TOP_EQU1_EQU_C1_BG,
767 ATV_TOP_EQU1_EQU_C1_DK,
768 ATV_TOP_EQU1_EQU_C1_I},
769 /* shadow of ATV_TOP_EQU2__A */
770 {210,
771 ATV_TOP_EQU2_EQU_C2_FM,
772 ATV_TOP_EQU2_EQU_C2_L,
773 ATV_TOP_EQU2_EQU_C2_LP,
774 ATV_TOP_EQU2_EQU_C2_BG,
775 ATV_TOP_EQU2_EQU_C2_DK,
776 ATV_TOP_EQU2_EQU_C2_I},
777 /* shadow of ATV_TOP_EQU3__A */
778 {-160,
779 ATV_TOP_EQU3_EQU_C3_FM,
780 ATV_TOP_EQU3_EQU_C3_L,
781 ATV_TOP_EQU3_EQU_C3_LP,
782 ATV_TOP_EQU3_EQU_C3_BG,
783 ATV_TOP_EQU3_EQU_C3_DK,
784 ATV_TOP_EQU3_EQU_C3_I},
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300785 false, /* flag: true=bypass */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300786 ATV_TOP_VID_PEAK__PRE, /* shadow of ATV_TOP_VID_PEAK__A */
787 ATV_TOP_NOISE_TH__PRE, /* shadow of ATV_TOP_NOISE_TH__A */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300788 true, /* flag CVBS ouput enable */
789 false, /* flag SIF ouput enable */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300790 DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300791 { /* qam_rf_agc_cfg */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300792 DRX_STANDARD_ITU_B, /* standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300793 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
794 0, /* output_level */
795 0, /* min_output_level */
796 0xFFFF, /* max_output_level */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300797 0x0000, /* speed */
798 0x0000, /* top */
799 0x0000 /* c.o.c. */
800 },
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300801 { /* qam_if_agc_cfg */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300802 DRX_STANDARD_ITU_B, /* standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300803 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
804 0, /* output_level */
805 0, /* min_output_level */
806 0xFFFF, /* max_output_level */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300807 0x0000, /* speed */
808 0x0000, /* top (don't care) */
809 0x0000 /* c.o.c. (don't care) */
810 },
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300811 { /* vsb_rf_agc_cfg */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300812 DRX_STANDARD_8VSB, /* standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300813 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
814 0, /* output_level */
815 0, /* min_output_level */
816 0xFFFF, /* max_output_level */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300817 0x0000, /* speed */
818 0x0000, /* top (don't care) */
819 0x0000 /* c.o.c. (don't care) */
820 },
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300821 { /* vsb_if_agc_cfg */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300822 DRX_STANDARD_8VSB, /* standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300823 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
824 0, /* output_level */
825 0, /* min_output_level */
826 0xFFFF, /* max_output_level */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300827 0x0000, /* speed */
828 0x0000, /* top (don't care) */
829 0x0000 /* c.o.c. (don't care) */
830 },
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300831 0, /* qam_pga_cfg */
832 0, /* vsb_pga_cfg */
833 { /* qam_pre_saw_cfg */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300834 DRX_STANDARD_ITU_B, /* standard */
835 0, /* reference */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300836 false /* use_pre_saw */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300837 },
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300838 { /* vsb_pre_saw_cfg */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300839 DRX_STANDARD_8VSB, /* standard */
840 0, /* reference */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300841 false /* use_pre_saw */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300842 },
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300843
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300844 /* Version information */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300845#ifndef _CH_
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300846 {
847 "01234567890", /* human readable version microcode */
848 "01234567890" /* human readable version device specific code */
849 },
850 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300851 { /* drx_version_t for microcode */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300852 DRX_MODULE_UNKNOWN,
853 (char *)(NULL),
854 0,
855 0,
856 0,
857 (char *)(NULL)
858 },
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300859 { /* drx_version_t for device specific code */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300860 DRX_MODULE_UNKNOWN,
861 (char *)(NULL),
862 0,
863 0,
864 0,
865 (char *)(NULL)
866 }
867 },
868 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300869 { /* drx_version_list_t for microcode */
870 (pdrx_version_t) (NULL),
871 (p_drx_version_list_t) (NULL)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300872 },
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300873 { /* drx_version_list_t for device specific code */
874 (pdrx_version_t) (NULL),
875 (p_drx_version_list_t) (NULL)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300876 }
877 },
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300878#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300879 false, /* smart_ant_inverted */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300880 /* Tracking filter setting for OOB */
881 {
882 12000,
883 9300,
884 6600,
885 5280,
886 3700,
887 3000,
888 2000,
889 0},
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300890 false, /* oob_power_on */
891 0, /* mpeg_ts_static_bitrate */
892 false, /* disable_te_ihandling */
893 false, /* bit_reverse_mpeg_outout */
894 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO, /* mpeg_output_clock_rate */
895 DRXJ_MPEG_START_WIDTH_1CLKCYC, /* mpeg_start_width */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300896
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300897 /* Pre SAW & Agc configuration for ATV */
898 {
899 DRX_STANDARD_NTSC, /* standard */
900 7, /* reference */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300901 true /* use_pre_saw */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300902 },
903 { /* ATV RF-AGC */
904 DRX_STANDARD_NTSC, /* standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300905 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
906 0, /* output_level */
907 0, /* min_output_level (d.c.) */
908 0, /* max_output_level (d.c.) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300909 3, /* speed */
910 9500, /* top */
911 4000 /* cut-off current */
912 },
913 { /* ATV IF-AGC */
914 DRX_STANDARD_NTSC, /* standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300915 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
916 0, /* output_level */
917 0, /* min_output_level (d.c.) */
918 0, /* max_output_level (d.c.) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300919 3, /* speed */
920 2400, /* top */
921 0 /* c.o.c. (d.c.) */
922 },
923 140, /* ATV PGA config */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300924 0, /* curr_symbol_rate */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300925
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300926 false, /* pdr_safe_mode */
927 SIO_PDR_GPIO_CFG__PRE, /* pdr_safe_restore_val_gpio */
928 SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
929 SIO_PDR_SMA_RX_CFG__PRE, /* pdr_safe_restore_val_sma_rx */
930 SIO_PDR_SMA_TX_CFG__PRE, /* pdr_safe_restore_val_sma_tx */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300931
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300932 4, /* oob_pre_saw */
933 DRXJ_OOB_LO_POW_MINUS10DB, /* oob_lo_pow */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300934 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300935 false /* aud_data, only first member */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300936 },
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300937};
938
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300939/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300940* \var drxj_default_addr_g
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300941* \brief Default I2C address and device identifier.
942*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300943struct i2c_device_addr drxj_default_addr_g = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300944 DRXJ_DEF_I2C_ADDR, /* i2c address */
945 DRXJ_DEF_DEMOD_DEV_ID /* device id */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300946};
947
948/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300949* \var drxj_default_comm_attr_g
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300950* \brief Default common attributes of a drxj demodulator instance.
951*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300952drx_common_attr_t drxj_default_comm_attr_g = {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -0300953 (u8 *) NULL, /* ucode ptr */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300954 0, /* ucode size */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300955 true, /* ucode verify switch */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300956 {0}, /* version record */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300957
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300958 44000, /* IF in kHz in case no tuner instance is used */
959 (151875 - 0), /* system clock frequency in kHz */
960 0, /* oscillator frequency kHz */
961 0, /* oscillator deviation in ppm, signed */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300962 false, /* If true mirror frequency spectrum */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300963 {
964 /* MPEG output configuration */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300965 true, /* If true, enable MPEG ouput */
966 false, /* If true, insert RS byte */
967 true, /* If true, parallel out otherwise serial */
968 false, /* If true, invert DATA signals */
969 false, /* If true, invert ERR signal */
970 false, /* If true, invert STR signals */
971 false, /* If true, invert VAL signals */
972 false, /* If true, invert CLK signals */
973 true, /* If true, static MPEG clockrate will
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300974 be used, otherwise clockrate will
975 adapt to the bitrate of the TS */
976 19392658UL, /* Maximum bitrate in b/s in case
977 static clockrate is selected */
978 DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
979 },
980 /* Initilisations below can be ommited, they require no user input and
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300981 are initialy 0, NULL or false. The compiler will initialize them to these
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300982 values when ommited. */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -0300983 false, /* is_opened */
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300984
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300985 /* SCAN */
986 NULL, /* no scan params yet */
987 0, /* current scan index */
988 0, /* next scan frequency */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300989 false, /* scan ready flag */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300990 0, /* max channels to scan */
991 0, /* nr of channels scanned */
992 NULL, /* default scan function */
993 NULL, /* default context pointer */
994 0, /* millisec to wait for demod lock */
995 DRXJ_DEMOD_LOCK, /* desired lock */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -0300996 false,
Devin Heitmueller38b2df92012-08-13 21:18:02 -0300997
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -0300998 /* Power management */
999 DRX_POWER_UP,
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001000
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001001 /* Tuner */
1002 1, /* nr of I2C port to wich tuner is */
1003 0L, /* minimum RF input frequency, in kHz */
1004 0L, /* maximum RF input frequency, in kHz */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03001005 false, /* Rf Agc Polarity */
1006 false, /* If Agc Polarity */
1007 false, /* tuner slow mode */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001008
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001009 { /* current channel (all 0) */
1010 0UL /* channel.frequency */
1011 },
1012 DRX_STANDARD_UNKNOWN, /* current standard */
1013 DRX_STANDARD_UNKNOWN, /* previous standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001014 DRX_STANDARD_UNKNOWN, /* di_cache_standard */
1015 false, /* use_bootloader */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001016 0UL, /* capabilities */
1017 0 /* mfx */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001018};
1019
1020/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001021* \var drxj_default_demod_g
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001022* \brief Default drxj demodulator instance.
1023*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001024drx_demod_instance_t drxj_default_demod_g = {
1025 &drxj_functions_g, /* demod functions */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001026 &DRXJ_DAP, /* data access protocol functions */
1027 NULL, /* tuner instance */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001028 &drxj_default_addr_g, /* i2c address & device id */
1029 &drxj_default_comm_attr_g, /* demod common attributes */
1030 &drxj_data_g /* demod device specific attributes */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001031};
1032
1033/**
1034* \brief Default audio data structure for DRK demodulator instance.
1035*
1036* This structure is DRXK specific.
1037*
1038*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001039drx_aud_data_t drxj_default_aud_data_g = {
1040 false, /* audio_is_active */
1041 DRX_AUD_STANDARD_AUTO, /* audio_standard */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001042
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001043 /* i2sdata */
1044 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001045 false, /* output_enable */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001046 48000, /* frequency */
1047 DRX_I2S_MODE_MASTER, /* mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001048 DRX_I2S_WORDLENGTH_32, /* word_length */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001049 DRX_I2S_POLARITY_RIGHT, /* polarity */
1050 DRX_I2S_FORMAT_WS_WITH_DATA /* format */
1051 },
1052 /* volume */
1053 {
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03001054 true, /* mute; */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001055 0, /* volume */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001056 DRX_AUD_AVC_OFF, /* avc_mode */
1057 0, /* avc_ref_level */
1058 DRX_AUD_AVC_MAX_GAIN_12DB, /* avc_max_gain */
1059 DRX_AUD_AVC_MAX_ATTEN_24DB, /* avc_max_atten */
1060 0, /* strength_left */
1061 0 /* strength_right */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001062 },
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001063 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
1064 /* ass_thresholds */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001065 {
1066 440, /* A2 */
1067 12, /* BTSC */
1068 700, /* NICAM */
1069 },
1070 /* carrier */
1071 {
1072 /* a */
1073 {
1074 42, /* thres */
1075 DRX_NO_CARRIER_NOISE, /* opt */
1076 0, /* shift */
1077 0 /* dco */
1078 },
1079 /* b */
1080 {
1081 42, /* thres */
1082 DRX_NO_CARRIER_MUTE, /* opt */
1083 0, /* shift */
1084 0 /* dco */
1085 },
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001086
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001087 },
1088 /* mixer */
1089 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001090 DRX_AUD_SRC_STEREO_OR_A, /* source_i2s */
1091 DRX_AUD_I2S_MATRIX_STEREO, /* matrix_i2s */
1092 DRX_AUD_FM_MATRIX_SOUND_A /* matrix_fm */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001093 },
1094 DRX_AUD_DEVIATION_NORMAL, /* deviation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001095 DRX_AUD_AVSYNC_OFF, /* av_sync */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001096
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001097 /* prescale */
1098 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001099 DRX_AUD_MAX_FM_DEVIATION, /* fm_deviation */
1100 DRX_AUD_MAX_NICAM_PRESCALE /* nicam_gain */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001101 },
1102 DRX_AUD_FM_DEEMPH_75US, /* deemph */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001103 DRX_BTSC_STEREO, /* btsc_detect */
1104 0, /* rds_data_counter */
1105 false /* rds_data_present */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001106};
1107
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001108/*-----------------------------------------------------------------------------
1109STRUCTURES
1110----------------------------------------------------------------------------*/
1111typedef struct {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001112 u16 eq_mse;
1113 u8 eq_mode;
1114 u8 eq_ctrl;
1115 u8 eq_stat;
1116} drxjeq_stat_t, *pdrxjeq_stat_t;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001117
1118/* HI command */
1119typedef struct {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001120 u16 cmd;
1121 u16 param1;
1122 u16 param2;
1123 u16 param3;
1124 u16 param4;
1125 u16 param5;
1126 u16 param6;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001127} drxj_hi_cmd_t, *pdrxj_hi_cmd_t;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001128
1129#ifdef DRXJ_SPLIT_UCODE_UPLOAD
1130/*============================================================================*/
1131/*=== MICROCODE RELATED STRUCTURES ===========================================*/
1132/*============================================================================*/
1133
1134typedef struct {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001135 u32 addr;
1136 u16 size;
1137 u16 flags; /* bit[15..2]=reserved,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001138 bit[1]= compression on/off
1139 bit[0]= CRC on/off */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001140 u16 CRC;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001141} drxu_code_block_hdr_t, *pdrxu_code_block_hdr_t;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001142#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1143
1144/*-----------------------------------------------------------------------------
1145FUNCTIONS
1146----------------------------------------------------------------------------*/
1147/* Some prototypes */
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001148static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001149hi_command(struct i2c_device_addr *dev_addr,
1150 const pdrxj_hi_cmd_t cmd, u16 *result);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001151
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001152static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001153ctrl_lock_status(pdrx_demod_instance_t demod, pdrx_lock_status_t lock_stat);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001154
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001155static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001156ctrl_power_mode(pdrx_demod_instance_t demod, pdrx_power_mode_t mode);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001157
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001158static int power_down_aud(pdrx_demod_instance_t demod);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001159
1160#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001161static int power_up_aud(pdrx_demod_instance_t demod, bool set_standard);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001162#endif
1163
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001164static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001165aud_ctrl_set_standard(pdrx_demod_instance_t demod, pdrx_aud_standard_t standard);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001166
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001167static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001168ctrl_set_cfg_pre_saw(pdrx_demod_instance_t demod, p_drxj_cfg_pre_saw_t pre_saw);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001169
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001170static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001171ctrl_set_cfg_afe_gain(pdrx_demod_instance_t demod, p_drxj_cfg_afe_gain_t afe_gain);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001172
1173#ifdef DRXJ_SPLIT_UCODE_UPLOAD
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001174static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001175ctrl_u_codeUpload(pdrx_demod_instance_t demod,
1176 p_drxu_code_info_t mc_info,
1177 drxu_code_action_t action, bool audio_mc_upload);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001178#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1179
1180/*============================================================================*/
1181/*============================================================================*/
1182/*== HELPER FUNCTIONS ==*/
1183/*============================================================================*/
1184/*============================================================================*/
1185
1186/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001187* \fn void mult32(u32 a, u32 b, u32 *h, u32 *l)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001188* \brief 32bitsx32bits signed multiplication
1189* \param a 32 bits multiplicant, typecast from signed to unisgned
1190* \param b 32 bits multiplier, typecast from signed to unisgned
1191* \param h pointer to high part 64 bits result, typecast from signed to unisgned
1192* \param l pointer to low part 64 bits result
1193*
1194* For the 2n+n addition a + b:
1195* if a >= 0, then h += 0 (sign extension = 0)
1196* but if a < 0, then h += 2^n-1 ==> h -= 1.
1197*
1198* Also, if a + b < 2^n, then a + b >= a && a + b >= b
1199* but if a + b >= 2^n, then R = a + b - 2^n,
1200* and because a < 2^n && b < 2*n ==> R < a && R < b.
1201* Therefore, to detect overflow, simply compare the addition result with
1202* one of the operands; if the result is smaller, overflow has occurred and
1203* h must be incremented.
1204*
1205* Booth multiplication uses additions and subtractions to reduce the number
1206* of iterations. This is done by taking three subsequent bits abc and calculating
1207* the following multiplication factor: -2a + b + c. This factor is multiplied
1208* by the second operand and added to the result. Next, the first operand is
1209* shifted two bits (hence one of the three bits is reused) and the process
1210* repeated. The last iteration has only two bits left, but we simply add
1211* a zero to the end.
1212*
1213* Hence: (n=4)
1214* 1 * a = 0 * 4a + 1 * a
1215* 2 * a = 1 * 4a - 2 * a
1216* 3 * a = 1 * 4a - 1 * a
1217* -1 * a = 0 * 4a - 1 * a
1218* -5 * a = -1 * 4a - 1 * a
1219*
1220* etc.
1221*
1222* Note that the function is type size independent. Any unsigned integer type
1223* can be substituted for booth_t.
1224*
1225*/
1226
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -03001227#define DRX_IS_BOOTH_NEGATIVE(__a) (((__a) & (1 << (sizeof(u32) * 8 - 1))) != 0)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001228
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001229static void mult32(u32 a, u32 b, u32 *h, u32 *l)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001230{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001231 unsigned int i;
1232 *h = *l = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001233
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001234 /* n/2 iterations; shift operand a left two bits after each iteration. */
1235 /* This automatically appends a zero to the operand for the last iteration. */
1236 for (i = 0; i < sizeof(a) * 8; i += 2, a = a << 2) {
1237 /* Shift result left two bits */
1238 *h = (*h << 2) + (*l >> (sizeof(*l) * 8 - 2));
1239 *l = (*l << 2);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001240
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001241 /* Take the first three bits of operand a for the Booth conversion: */
1242 /* 0, 7: do nothing */
1243 /* 1, 2: add b */
1244 /* 3 : add 2b */
1245 /* 4 : subtract 2b */
1246 /* 5, 6: subtract b */
1247 switch (a >> (sizeof(a) * 8 - 3)) {
1248 case 3:
1249 *l += b;
1250 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1251 case 1:
1252 case 2:
1253 *l += b;
1254 *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1255 break;
1256 case 4:
1257 *l -= b;
1258 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001259 ((u32)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001260 (-
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001261 ((s32)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001262 b))));
1263 case 5:
1264 case 6:
1265 *l -= b;
1266 *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001267 ((u32)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001268 (-
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001269 ((s32)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001270 b))));
1271 break;
1272 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001273 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001274}
1275
1276/*============================================================================*/
1277
1278/*
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001279* \fn u32 frac28(u32 N, u32 D)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001280* \brief Compute: (1<<28)*N/D
1281* \param N 32 bits
1282* \param D 32 bits
1283* \return (1<<28)*N/D
1284* This function is used to avoid floating-point calculations as they may
1285* not be present on the target platform.
1286
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001287* frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001288* fraction used for setting the Frequency Shifter registers.
1289* N and D can hold numbers up to width: 28-bits.
1290* The 4 bits integer part and the 28 bits fractional part are calculated.
1291
1292* Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1293
1294* N: 0...(1<<28)-1 = 268435454
1295* D: 0...(1<<28)-1
1296* Q: 0...(1<<32)-1
1297*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001298static u32 frac28(u32 N, u32 D)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001299{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001300 int i = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001301 u32 Q1 = 0;
1302 u32 R0 = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001303
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001304 R0 = (N % D) << 4; /* 32-28 == 4 shifts possible at max */
1305 Q1 = N / D; /* integer part, only the 4 least significant bits
1306 will be visible in the result */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001307
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001308 /* division using radix 16, 7 nibbles in the result */
1309 for (i = 0; i < 7; i++) {
1310 Q1 = (Q1 << 4) | R0 / D;
1311 R0 = (R0 % D) << 4;
1312 }
1313 /* rounding */
1314 if ((R0 >> 3) >= D)
1315 Q1++;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001316
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001317 return Q1;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001318}
1319
1320/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001321* \fn u32 log1_times100( u32 x)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001322* \brief Compute: 100*log10(x)
1323* \param x 32 bits
1324* \return 100*log10(x)
1325*
1326* 100*log10(x)
1327* = 100*(log2(x)/log2(10)))
1328* = (100*(2^15)*log2(x))/((2^15)*log2(10))
1329* = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1330* = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1331* = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1332*
1333* where y = 2^k and 1<= (x/y) < 2
1334*/
1335
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001336static u32 log1_times100(u32 x)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001337{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001338 static const u8 scale = 15;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001339 static const u8 index_width = 5;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001340 /*
1341 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1342 0 <= n < ((1<<INDEXWIDTH)+1)
1343 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001344
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001345 static const u32 log2lut[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001346 0, /* 0.000000 */
1347 290941, /* 290941.300628 */
1348 573196, /* 573196.476418 */
1349 847269, /* 847269.179851 */
1350 1113620, /* 1113620.489452 */
1351 1372674, /* 1372673.576986 */
1352 1624818, /* 1624817.752104 */
1353 1870412, /* 1870411.981536 */
1354 2109788, /* 2109787.962654 */
1355 2343253, /* 2343252.817465 */
1356 2571091, /* 2571091.461923 */
1357 2793569, /* 2793568.696416 */
1358 3010931, /* 3010931.055901 */
1359 3223408, /* 3223408.452106 */
1360 3431216, /* 3431215.635215 */
1361 3634553, /* 3634553.498355 */
1362 3833610, /* 3833610.244726 */
1363 4028562, /* 4028562.434393 */
1364 4219576, /* 4219575.925308 */
1365 4406807, /* 4406806.721144 */
1366 4590402, /* 4590401.736809 */
1367 4770499, /* 4770499.491025 */
1368 4947231, /* 4947230.734179 */
1369 5120719, /* 5120719.018555 */
1370 5291081, /* 5291081.217197 */
1371 5458428, /* 5458427.996830 */
1372 5622864, /* 5622864.249668 */
1373 5784489, /* 5784489.488298 */
1374 5943398, /* 5943398.207380 */
1375 6099680, /* 6099680.215452 */
1376 6253421, /* 6253420.939751 */
1377 6404702, /* 6404701.706649 */
1378 6553600, /* 6553600.000000 */
1379 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001380
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001381 u8 i = 0;
1382 u32 y = 0;
1383 u32 d = 0;
1384 u32 k = 0;
1385 u32 r = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001386
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001387 if (x == 0)
1388 return (0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001389
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001390 /* Scale x (normalize) */
1391 /* computing y in log(x/y) = log(x) - log(y) */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001392 if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001393 for (k = scale; k > 0; k--) {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001394 if (x & (((u32) 1) << scale))
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001395 break;
1396 x <<= 1;
1397 }
1398 } else {
1399 for (k = scale; k < 31; k++) {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001400 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001401 break;
1402 x >>= 1;
1403 }
1404 }
1405 /*
1406 Now x has binary point between bit[scale] and bit[scale-1]
1407 and 1.0 <= x < 2.0 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001408
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001409 /* correction for divison: log(x) = log(x/y)+log(y) */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001410 y = k * ((((u32) 1) << scale) * 200);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001411
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001412 /* remove integer part */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001413 x &= ((((u32) 1) << scale) - 1);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001414 /* get index */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001415 i = (u8) (x >> (scale - index_width));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001416 /* compute delta (x-a) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001417 d = x & ((((u32) 1) << (scale - index_width)) - 1);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001418 /* compute log, multiplication ( d* (.. )) must be within range ! */
1419 y += log2lut[i] +
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001420 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001421 /* Conver to log10() */
1422 y /= 108853; /* (log2(10) << scale) */
1423 r = (y >> 1);
1424 /* rounding */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001425 if (y & ((u32) 1))
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001426 r++;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001427
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001428 return (r);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001429
1430}
1431
1432/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001433* \fn u32 frac_times1e6( u16 N, u32 D)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001434* \brief Compute: (N/D) * 1000000.
1435* \param N nominator 16-bits.
1436* \param D denominator 32-bits.
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001437* \return u32
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001438* \retval ((N/D) * 1000000), 32 bits
1439*
1440* No check on D=0!
1441*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001442static u32 frac_times1e6(u32 N, u32 D)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001443{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001444 u32 remainder = 0;
1445 u32 frac = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001446
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001447 /*
1448 frac = (N * 1000000) / D
1449 To let it fit in a 32 bits computation:
1450 frac = (N * (1000000 >> 4)) / (D >> 4)
1451 This would result in a problem in case D < 16 (div by 0).
1452 So we do it more elaborate as shown below.
1453 */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001454 frac = (((u32) N) * (1000000 >> 4)) / D;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001455 frac <<= 4;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001456 remainder = (((u32) N) * (1000000 >> 4)) % D;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001457 remainder <<= 4;
1458 frac += remainder / D;
1459 remainder = remainder % D;
1460 if ((remainder * 2) > D) {
1461 frac++;
1462 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001463
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001464 return (frac);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001465}
1466
1467/*============================================================================*/
1468
1469/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001470* \brief Compute: 100 * 10^( gd_b / 200 ).
1471* \param u32 gd_b Gain in 0.1dB
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001472* \return u32 Gainfactor in 0.01 resolution
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001473*
1474*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001475static u32 d_b2lin_times100(u32 gd_b)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001476{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001477 u32 result = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001478 u32 nr6d_b_steps = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001479 u32 remainder = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001480 u32 remainder_fac = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001481
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001482 /* start with factors 2 (6.02dB) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001483 nr6d_b_steps = gd_b * 1000UL / 60206UL;
1484 if (nr6d_b_steps > 17) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001485 /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
1486 return MAX_U32;
1487 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001488 result = (1 << nr6d_b_steps);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001489
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001490 /* calculate remaining factor,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001491 poly approximation of 10^(gd_b/200):
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001492
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001493 y = 1E-04x2 + 0.0106x + 1.0026
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001494
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001495 max deviation < 0.005 for range x = [0 ... 60]
1496 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001497 remainder = ((gd_b * 1000UL) % 60206UL) / 1000UL;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001498 /* using 1e-4 for poly calculation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001499 remainder_fac = 1 * remainder * remainder;
1500 remainder_fac += 106 * remainder;
1501 remainder_fac += 10026;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001502
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001503 /* multiply by remaining factor */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001504 result *= remainder_fac;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001505
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001506 /* conversion from 1e-4 to 1e-2 */
1507 return ((result + 50) / 100);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001508}
1509
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001510#ifndef DRXJ_DIGITAL_ONLY
1511#define FRAC_FLOOR 0
1512#define FRAC_CEIL 1
1513#define FRAC_ROUND 2
1514/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001515* \fn u32 frac( u32 N, u32 D, u16 RC )
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001516* \brief Compute: N/D.
1517* \param N nominator 32-bits.
1518* \param D denominator 32-bits.
1519* \param RC-result correction: 0-floor; 1-ceil; 2-round
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001520* \return u32
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001521* \retval N/D, 32 bits
1522*
1523* If D=0 returns 0
1524*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001525static u32 frac(u32 N, u32 D, u16 RC)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001526{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001527 u32 remainder = 0;
1528 u32 frac = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001529 u16 bit_cnt = 32;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001530
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001531 if (D == 0) {
1532 frac = 0;
1533 remainder = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001534
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001535 return (frac);
1536 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001537
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001538 if (D > N) {
1539 frac = 0;
1540 remainder = N;
1541 } else {
1542 remainder = 0;
1543 frac = N;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001544 while (bit_cnt-- > 0) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001545 remainder <<= 1;
1546 remainder |= ((frac & 0x80000000) >> 31);
1547 frac <<= 1;
1548 if (remainder < D) {
1549 frac &= 0xFFFFFFFE;
1550 } else {
1551 remainder -= D;
1552 frac |= 0x1;
1553 }
1554 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001555
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001556 /* result correction if needed */
1557 if ((RC == FRAC_CEIL) && (remainder != 0)) {
1558 /* ceil the result */
1559 /*(remainder is not zero -> value behind decimal point exists) */
1560 frac++;
1561 }
1562 if ((RC == FRAC_ROUND) && (remainder >= D >> 1)) {
1563 /* remainder is bigger from D/2 -> round the result */
1564 frac++;
1565 }
1566 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001567
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001568 return (frac);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001569}
1570#endif
1571
1572#ifdef DRXJ_SPLIT_UCODE_UPLOAD
1573/*============================================================================*/
1574
1575/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001576* \fn u16 u_code_read16( u8 *addr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001577* \brief Read a 16 bits word, expect big endian data.
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001578* \return u16 The data read.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001579*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001580static u16 u_code_read16(u8 *addr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001581{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001582 /* Works fo any host processor */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001583
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001584 u16 word = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001585
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001586 word = ((u16) addr[0]);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001587 word <<= 8;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001588 word |= ((u16) addr[1]);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001589
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001590 return (word);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001591}
1592
1593/*============================================================================*/
1594
1595/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001596* \fn u32 u_code_read32( u8 *addr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001597* \brief Read a 32 bits word, expect big endian data.
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001598* \return u32 The data read.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001599*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001600static u32 u_code_read32(u8 *addr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001601{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001602 /* Works fo any host processor */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001603
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001604 u32 word = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001605
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001606 word = ((u16) addr[0]);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001607 word <<= 8;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001608 word |= ((u16) addr[1]);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001609 word <<= 8;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001610 word |= ((u16) addr[2]);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001611 word <<= 8;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001612 word |= ((u16) addr[3]);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001613
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001614 return (word);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001615}
1616
1617/*============================================================================*/
1618
1619/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001620* \fn u16 u_code_compute_crc (u8 *block_data, u16 nr_words)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001621* \brief Compute CRC of block of microcode data.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001622* \param block_data Pointer to microcode data.
1623* \param nr_words Size of microcode block (number of 16 bits words).
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001624* \return u16 The computed CRC residu.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001625*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001626static u16 u_code_compute_crc(u8 *block_data, u16 nr_words)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001627{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001628 u16 i = 0;
1629 u16 j = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001630 u32 crc_word = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001631 u32 carry = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001632
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001633 while (i < nr_words) {
1634 crc_word |= (u32) u_code_read16(block_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001635 for (j = 0; j < 16; j++) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001636 crc_word <<= 1;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001637 if (carry != 0)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001638 crc_word ^= 0x80050000UL;
1639 carry = crc_word & 0x80000000UL;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001640 }
1641 i++;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001642 block_data += (sizeof(u16));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001643 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001644 return ((u16) (crc_word >> 16));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001645}
1646#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1647
1648/**
1649* \brief Values for NICAM prescaler gain. Computed from dB to integer
1650* and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1651*
1652*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001653static const u16 nicam_presc_table_val[43] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001654 { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1655 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1656 18, 20, 23, 25, 28, 32, 36, 40, 45,
1657 51, 57, 64, 71, 80, 90, 101, 113, 127
1658};
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001659
1660/*============================================================================*/
1661/*== END HELPER FUNCTIONS ==*/
1662/*============================================================================*/
1663
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001664/*============================================================================*/
1665/*============================================================================*/
1666/*== DRXJ DAP FUNCTIONS ==*/
1667/*============================================================================*/
1668/*============================================================================*/
1669
1670/*
1671 This layer takes care of some device specific register access protocols:
1672 -conversion to short address format
1673 -access to audio block
1674 This layer is placed between the drx_dap_fasi and the rest of the drxj
1675 specific implementation. This layer can use address map knowledge whereas
1676 dap_fasi may not use memory map knowledge.
1677
1678 * For audio currently only 16 bits read and write register access is
1679 supported. More is not needed. RMW and 32 or 8 bit access on audio
1680 registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1681 single/multi master) will be ignored.
1682
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001683 TODO: check ignoring single/multimaster is ok for AUD access ?
1684*/
1685
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -03001686#define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1)?true:false)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001687#define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001688/*============================================================================*/
1689
1690/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001691* \fn bool is_handled_by_aud_tr_if( dr_xaddr_t addr )
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001692* \brief Check if this address is handled by the audio token ring interface.
1693* \param addr
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03001694* \return bool
1695* \retval true Yes, handled by audio token ring interface
1696* \retval false No, not handled by audio token ring interface
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001697*
1698*/
1699static
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001700bool is_handled_by_aud_tr_if(dr_xaddr_t addr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001701{
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03001702 bool retval = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001703
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001704 if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1705 (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1706 (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03001707 retval = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001708 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001709
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001710 return (retval);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001711}
1712
1713/*============================================================================*/
1714
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001715static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
1716 dr_xaddr_t addr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001717 u16 datasize,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001718 u8 *data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001719{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001720 return drx_dap_fasi_funct_g.read_block_func(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001721 addr, datasize, data, flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001722}
1723
1724/*============================================================================*/
1725
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001726static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
1727 dr_xaddr_t waddr,
1728 dr_xaddr_t raddr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001729 u8 wdata, u8 *rdata)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001730{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001731 return drx_dap_fasi_funct_g.read_modify_write_reg8func(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001732 waddr,
1733 raddr, wdata, rdata);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001734}
1735
1736/*============================================================================*/
1737
1738/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001739* \fn int drxj_dap_rm_write_reg16short
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001740* \brief Read modify write 16 bits audio register using short format only.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001741* \param dev_addr
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001742* \param waddr Address to write to
1743* \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1744* \param wdata Data to write
1745* \param rdata Buffer for data to read
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001746* \return int
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001747* \retval DRX_STS_OK Succes
1748* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
1749*
1750* 16 bits register read modify write access using short addressing format only.
1751* Requires knowledge of the registermap, thus device dependent.
1752* Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1753*
1754*/
1755
1756/* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001757 See comments drxj_dap_read_modify_write_reg16 */
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -03001758#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001759static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1760 dr_xaddr_t waddr,
1761 dr_xaddr_t raddr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001762 u16 wdata, u16 *rdata)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001763{
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001764 int rc;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001765
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001766 if (rdata == NULL) {
1767 return DRX_STS_INVALID_ARG;
1768 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001769
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001770 /* Set RMW flag */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001771 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001772 SIO_HI_RA_RAM_S0_FLG_ACC__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001773 SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001774 0x0000);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001775 if (rc == DRX_STS_OK) {
1776 /* Write new data: triggers RMW */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001777 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr, waddr, wdata,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001778 0x0000);
1779 }
1780 if (rc == DRX_STS_OK) {
1781 /* Read old data */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001782 rc = drx_dap_fasi_funct_g.read_reg16func(dev_addr, raddr, rdata,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001783 0x0000);
1784 }
1785 if (rc == DRX_STS_OK) {
1786 /* Reset RMW flag */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001787 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001788 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1789 0, 0x0000);
1790 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001791
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001792 return rc;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001793}
1794#endif
1795
1796/*============================================================================*/
1797
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001798static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1799 dr_xaddr_t waddr,
1800 dr_xaddr_t raddr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001801 u16 wdata, u16 *rdata)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001802{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001803 /* TODO: correct short/long addressing format decision,
1804 now long format has higher prio then short because short also
1805 needs virt bnks (not impl yet) for certain audio registers */
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -03001806#if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001807 return drx_dap_fasi_funct_g.read_modify_write_reg16func(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001808 waddr,
1809 raddr, wdata, rdata);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001810#else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001811 return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001812#endif
1813}
1814
1815/*============================================================================*/
1816
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001817static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
1818 dr_xaddr_t waddr,
1819 dr_xaddr_t raddr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001820 u32 wdata, u32 *rdata)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001821{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001822 return drx_dap_fasi_funct_g.read_modify_write_reg32func(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001823 waddr,
1824 raddr, wdata, rdata);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001825}
1826
1827/*============================================================================*/
1828
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001829static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
1830 dr_xaddr_t addr,
1831 u8 *data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001832{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001833 return drx_dap_fasi_funct_g.read_reg8func(dev_addr, addr, data, flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001834}
1835
1836/*============================================================================*/
1837
1838/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001839* \fn int drxj_dap_read_aud_reg16
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001840* \brief Read 16 bits audio register
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001841* \param dev_addr
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001842* \param addr
1843* \param data
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001844* \return int
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001845* \retval DRX_STS_OK Succes
1846* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
1847*
1848* 16 bits register read access via audio token ring interface.
1849*
1850*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001851static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1852 dr_xaddr_t addr, u16 *data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001853{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001854 u32 start_timer = 0;
1855 u32 current_timer = 0;
1856 u32 delta_timer = 0;
1857 u16 tr_status = 0;
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001858 int stat = DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001859
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001860 /* No read possible for bank 3, return with error */
1861 if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1862 stat = DRX_STS_INVALID_ARG;
1863 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001864 const dr_xaddr_t write_bit = ((dr_xaddr_t) 1) << 16;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001865
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001866 /* Force reset write bit */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001867 addr &= (~write_bit);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001868
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001869 /* Set up read */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001870 start_timer = drxbsp_hst_clock();
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001871 do {
1872 /* RMW to aud TR IF until request is granted or timeout */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001873 stat = drxj_dap_read_modify_write_reg16(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001874 addr,
1875 SIO_HI_RA_RAM_S0_RMWBUF__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001876 0x0000, &tr_status);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001877
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001878 if (stat != DRX_STS_OK) {
1879 break;
1880 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001881
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001882 current_timer = drxbsp_hst_clock();
1883 delta_timer = current_timer - start_timer;
1884 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001885 stat = DRX_STS_ERROR;
1886 break;
1887 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001888
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001889 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001890 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001891 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001892 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1893 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001894
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001895 /* Wait for read ready status or timeout */
1896 if (stat == DRX_STS_OK) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001897 start_timer = drxbsp_hst_clock();
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001898
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001899 while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001900 AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001901 stat = drxj_dap_read_reg16(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001902 AUD_TOP_TR_CTR__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001903 &tr_status, 0x0000);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001904 if (stat != DRX_STS_OK) {
1905 break;
1906 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001907
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001908 current_timer = drxbsp_hst_clock();
1909 delta_timer = current_timer - start_timer;
1910 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001911 stat = DRX_STS_ERROR;
1912 break;
1913 };
1914 } /* while ( ... ) */
1915 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001916
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001917 /* if { stat == DRX_STS_OK ) */
1918 /* Read value */
1919 if (stat == DRX_STS_OK) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001920 stat = drxj_dap_read_modify_write_reg16(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001921 AUD_TOP_TR_RD_REG__A,
1922 SIO_HI_RA_RAM_S0_RMWBUF__A,
1923 0x0000, data);
1924 }
1925 /* if { stat == DRX_STS_OK ) */
1926 return stat;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001927}
1928
1929/*============================================================================*/
1930
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001931static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1932 dr_xaddr_t addr,
1933 u16 *data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001934{
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001935 int stat = DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001936
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001937 /* Check param */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001938 if ((dev_addr == NULL) || (data == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001939 return DRX_STS_INVALID_ARG;
1940 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001941
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001942 if (is_handled_by_aud_tr_if(addr)) {
1943 stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001944 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001945 stat = drx_dap_fasi_funct_g.read_reg16func(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001946 addr, data, flags);
1947 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001948
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001949 return stat;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001950}
1951
1952/*============================================================================*/
1953
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001954static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
1955 dr_xaddr_t addr,
1956 u32 *data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001957{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001958 return drx_dap_fasi_funct_g.read_reg32func(dev_addr, addr, data, flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001959}
1960
1961/*============================================================================*/
1962
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001963static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
1964 dr_xaddr_t addr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03001965 u16 datasize,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001966 u8 *data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001967{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001968 return drx_dap_fasi_funct_g.write_block_func(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03001969 addr, datasize, data, flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001970}
1971
1972/*============================================================================*/
1973
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001974static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
1975 dr_xaddr_t addr,
1976 u8 data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001977{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001978 return drx_dap_fasi_funct_g.write_reg8func(dev_addr, addr, data, flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001979}
1980
1981/*============================================================================*/
1982
1983/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001984* \fn int drxj_dap_write_aud_reg16
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001985* \brief Write 16 bits audio register
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001986* \param dev_addr
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001987* \param addr
1988* \param data
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001989* \return int
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001990* \retval DRX_STS_OK Succes
1991* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
1992*
1993* 16 bits register write access via audio token ring interface.
1994*
1995*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03001996static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
1997 dr_xaddr_t addr, u16 data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03001998{
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03001999 int stat = DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002000
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002001 /* No write possible for bank 2, return with error */
2002 if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
2003 stat = DRX_STS_INVALID_ARG;
2004 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002005 u32 start_timer = 0;
2006 u32 current_timer = 0;
2007 u32 delta_timer = 0;
2008 u16 tr_status = 0;
2009 const dr_xaddr_t write_bit = ((dr_xaddr_t) 1) << 16;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002010
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002011 /* Force write bit */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002012 addr |= write_bit;
2013 start_timer = drxbsp_hst_clock();
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002014 do {
2015 /* RMW to aud TR IF until request is granted or timeout */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002016 stat = drxj_dap_read_modify_write_reg16(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002017 addr,
2018 SIO_HI_RA_RAM_S0_RMWBUF__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002019 data, &tr_status);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002020 if (stat != DRX_STS_OK) {
2021 break;
2022 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002023
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002024 current_timer = drxbsp_hst_clock();
2025 delta_timer = current_timer - start_timer;
2026 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002027 stat = DRX_STS_ERROR;
2028 break;
2029 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002030
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002031 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002032 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002033 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002034 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002035
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002036 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002037
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002038 return stat;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002039}
2040
2041/*============================================================================*/
2042
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002043static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
2044 dr_xaddr_t addr,
2045 u16 data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002046{
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002047 int stat = DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002048
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002049 /* Check param */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002050 if (dev_addr == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002051 return DRX_STS_INVALID_ARG;
2052 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002053
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002054 if (is_handled_by_aud_tr_if(addr)) {
2055 stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002056 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002057 stat = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002058 addr, data, flags);
2059 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002060
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002061 return stat;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002062}
2063
2064/*============================================================================*/
2065
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002066static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
2067 dr_xaddr_t addr,
2068 u32 data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002069{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002070 return drx_dap_fasi_funct_g.write_reg32func(dev_addr, addr, data, flags);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002071}
2072
2073/*============================================================================*/
2074
2075/* Free data ram in SIO HI */
2076#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2077#define SIO_HI_RA_RAM_USR_END__A 0x420060
2078
2079#define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2080#define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2081#define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2082#define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2083
2084/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002085* \fn int drxj_dap_atomic_read_write_block()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002086* \brief Basic access routine for atomic read or write access
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002087* \param dev_addr pointer to i2c dev address
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002088* \param addr destination/source address
2089* \param datasize size of data buffer in bytes
2090* \param data pointer to data buffer
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002091* \return int
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002092* \retval DRX_STS_OK Succes
2093* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
2094*
2095*/
2096static
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002097int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2098 dr_xaddr_t addr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002099 u16 datasize,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002100 u8 *data, bool read_flag)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002101{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002102 drxj_hi_cmd_t hi_cmd;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002103
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002104 u16 word;
2105 u16 dummy = 0;
2106 u16 i = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002107
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002108 /* Parameter check */
2109 if ((data == NULL) ||
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002110 (dev_addr == NULL) || ((datasize % 2) != 0) || ((datasize / 2) > 8)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002111 ) {
2112 return (DRX_STS_INVALID_ARG);
2113 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002114
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002115 /* Set up HI parameters to read or write n bytes */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002116 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2117 hi_cmd.param1 =
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002118 (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002119 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002120 hi_cmd.param2 =
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002121 (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002122 hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2123 if (read_flag == false) {
2124 hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002125 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002126 hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002127 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002128 hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002129 DRXDAP_FASI_ADDR2BANK(addr));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002130 hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002131
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002132 if (read_flag == false) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002133 /* write data to buffer */
2134 for (i = 0; i < (datasize / 2); i++) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002135
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002136 word = ((u16) data[2 * i]);
2137 word += (((u16) data[(2 * i) + 1]) << 8);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002138 drxj_dap_write_reg16(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002139 (DRXJ_HI_ATOMIC_BUF_START + i),
2140 word, 0);
2141 }
2142 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002143
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002144 CHK_ERROR(hi_command(dev_addr, &hi_cmd, &dummy));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002145
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002146 if (read_flag == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002147 /* read data from buffer */
2148 for (i = 0; i < (datasize / 2); i++) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002149 drxj_dap_read_reg16(dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002150 (DRXJ_HI_ATOMIC_BUF_START + i),
2151 &word, 0);
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002152 data[2 * i] = (u8) (word & 0xFF);
2153 data[(2 * i) + 1] = (u8) (word >> 8);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002154 }
2155 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002156
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002157 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002158
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002159rw_error:
2160 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002161
2162}
2163
2164/*============================================================================*/
2165
2166/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002167* \fn int drxj_dap_atomic_read_reg32()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002168* \brief Atomic read of 32 bits words
2169*/
2170static
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002171int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2172 dr_xaddr_t addr,
2173 u32 *data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002174{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002175 u8 buf[sizeof(*data)];
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002176 int rc = DRX_STS_ERROR;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002177 u32 word = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002178
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002179 if (!data) {
2180 return DRX_STS_INVALID_ARG;
2181 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002182
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002183 rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03002184 sizeof(*data), buf, true);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002185
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002186 word = (u32) buf[3];
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002187 word <<= 8;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002188 word |= (u32) buf[2];
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002189 word <<= 8;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002190 word |= (u32) buf[1];
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002191 word <<= 8;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002192 word |= (u32) buf[0];
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002193
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002194 *data = word;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002195
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002196 return rc;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002197}
2198
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002199/*============================================================================*/
2200
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002201/*============================================================================*/
2202/*== END DRXJ DAP FUNCTIONS ==*/
2203/*============================================================================*/
2204
2205/*============================================================================*/
2206/*============================================================================*/
2207/*== HOST INTERFACE FUNCTIONS ==*/
2208/*============================================================================*/
2209/*============================================================================*/
2210
2211/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002212* \fn int hi_cfg_command()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002213* \brief Configure HI with settings stored in the demod structure.
2214* \param demod Demodulator.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002215* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002216*
2217* This routine was created because to much orthogonal settings have
2218* been put into one HI API function (configure). Especially the I2C bridge
2219* enable/disable should not need re-configuration of the HI.
2220*
2221*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002222static int hi_cfg_command(const pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002223{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002224 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
2225 drxj_hi_cmd_t hi_cmd;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002226 u16 result = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002227
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002228 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002229
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002230 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2231 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2232 hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2233 hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2234 hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2235 hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2236 hi_cmd.param6 = ext_attr->hi_cfg_transmit;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002237
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002238 CHK_ERROR(hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002239
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002240 /* Reset power down flag (set one call only) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002241 ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002242
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002243 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002244
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002245rw_error:
2246 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002247}
2248
2249/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002250* \fn int hi_command()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002251* \brief Configure HI with settings stored in the demod structure.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002252* \param dev_addr I2C address.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002253* \param cmd HI command.
2254* \param result HI command result.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002255* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002256*
2257* Sends command to HI
2258*
2259*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002260static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002261hi_command(struct i2c_device_addr *dev_addr, const pdrxj_hi_cmd_t cmd, u16 *result)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002262{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002263 u16 wait_cmd = 0;
2264 u16 nr_retries = 0;
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03002265 bool powerdown_cmd = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002266
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002267 /* Write parameters */
2268 switch (cmd->cmd) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002269
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002270 case SIO_HI_RA_RAM_CMD_CONFIG:
2271 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002272 WR16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6);
2273 WR16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5);
2274 WR16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4);
2275 WR16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002276 /* fallthrough */
2277 case SIO_HI_RA_RAM_CMD_BRDCTRL:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002278 WR16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2);
2279 WR16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002280 /* fallthrough */
2281 case SIO_HI_RA_RAM_CMD_NULL:
2282 /* No parameters */
2283 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002284
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002285 default:
2286 return (DRX_STS_INVALID_ARG);
2287 break;
2288 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002289
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002290 /* Write command */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002291 WR16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002292
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002293 if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET) {
2294 /* Allow for HI to reset */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002295 drxbsp_hst_sleep(1);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002296 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002297
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002298 /* Detect power down to ommit reading result */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03002299 powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002300 (((cmd->
2301 param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2302 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03002303 if (powerdown_cmd == false) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002304 /* Wait until command rdy */
2305 do {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002306 nr_retries++;
2307 if (nr_retries > DRXJ_MAX_RETRIES) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002308 goto rw_error;
2309 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002310
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002311 RR16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd);
2312 } while (wait_cmd != 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002313
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002314 /* Read result */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002315 RR16(dev_addr, SIO_HI_RA_RAM_RES__A, result);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002316
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002317 }
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03002318 /* if ( powerdown_cmd == true ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002319 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002320rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002321 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002322}
2323
2324/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002325* \fn int init_hi( const pdrx_demod_instance_t demod )
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002326* \brief Initialise and configurate HI.
2327* \param demod pointer to demod data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002328* \return int Return status.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002329* \retval DRX_STS_OK Success.
2330* \retval DRX_STS_ERROR Failure.
2331*
2332* Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2333* Need to store configuration in driver because of the way I2C
2334* bridging is controlled.
2335*
2336*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002337static int init_hi(const pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002338{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002339 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
2340 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) (NULL);
2341 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002342
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002343 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
2344 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
2345 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002346
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002347 /* PATCH for bug 5003, HI ucode v3.1.0 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002348 WR16(dev_addr, 0x4301D7, 0x801);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002349
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002350 /* Timing div, 250ns/Psys */
2351 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002352 ext_attr->hi_cfg_timing_div =
2353 (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002354 /* Clipping */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002355 if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M) {
2356 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002357 }
2358 /* Bridge delay, uses oscilator clock */
2359 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2360 /* SDA brdige delay */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002361 ext_attr->hi_cfg_bridge_delay =
2362 (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002363 1000;
2364 /* Clipping */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002365 if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
2366 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002367 }
2368 /* SCL bridge delay, same as SDA for now */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002369 ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002370 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2371 /* Wakeup key, setting the read flag (as suggest in the documentation) does
2372 not always result into a working solution (barebones worked VI2C failed).
2373 Not setting the bit works in all cases . */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002374 ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002375 /* port/bridge/power down ctrl */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002376 ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002377 /* transit mode time out delay and watch dog divider */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002378 ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002379
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002380 CHK_ERROR(hi_cfg_command(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002381
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002382 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002383
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002384rw_error:
2385 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002386}
2387
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002388/*============================================================================*/
2389/*== END HOST INTERFACE FUNCTIONS ==*/
2390/*============================================================================*/
2391
2392/*============================================================================*/
2393/*============================================================================*/
2394/*== AUXILIARY FUNCTIONS ==*/
2395/*============================================================================*/
2396/*============================================================================*/
2397
2398/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002399* \fn int get_device_capabilities()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002400* \brief Get and store device capabilities.
2401* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002402* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002403* \return DRX_STS_OK Success
2404* \retval DRX_STS_ERROR Failure
2405*
2406* Depending on pulldowns on MDx pins the following internals are set:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002407* * common_attr->osc_clock_freq
2408* * ext_attr->has_lna
2409* * ext_attr->has_ntsc
2410* * ext_attr->has_btsc
2411* * ext_attr->has_oob
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002412*
2413*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002414static int get_device_capabilities(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002415{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002416 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) (NULL);
2417 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
2418 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
2419 u16 sio_pdr_ohw_cfg = 0;
2420 u32 sio_top_jtagid_lo = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002421 u16 bid = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002422
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002423 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
2424 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
2425 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002426
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002427 WR16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
2428 RR16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
2429 WR16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002430
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002431 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002432 case 0:
2433 /* ignore (bypass ?) */
2434 break;
2435 case 1:
2436 /* 27 MHz */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002437 common_attr->osc_clock_freq = 27000;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002438 break;
2439 case 2:
2440 /* 20.25 MHz */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002441 common_attr->osc_clock_freq = 20250;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002442 break;
2443 case 3:
2444 /* 4 MHz */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002445 common_attr->osc_clock_freq = 4000;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002446 break;
2447 default:
2448 return (DRX_STS_ERROR);
2449 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002450
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002451 /*
2452 Determine device capabilities
2453 Based on pinning v47
2454 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002455 RR32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
2456 ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002457
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002458 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002459 case 0x31:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002460 WR16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
2461 RR16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002462 bid = (bid >> 10) & 0xf;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002463 WR16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002464
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002465 ext_attr->has_lna = true;
2466 ext_attr->has_ntsc = false;
2467 ext_attr->has_btsc = false;
2468 ext_attr->has_oob = false;
2469 ext_attr->has_smatx = true;
2470 ext_attr->has_smarx = false;
2471 ext_attr->has_gpio = false;
2472 ext_attr->has_irqn = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002473 break;
2474 case 0x33:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002475 ext_attr->has_lna = false;
2476 ext_attr->has_ntsc = false;
2477 ext_attr->has_btsc = false;
2478 ext_attr->has_oob = false;
2479 ext_attr->has_smatx = true;
2480 ext_attr->has_smarx = false;
2481 ext_attr->has_gpio = false;
2482 ext_attr->has_irqn = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002483 break;
2484 case 0x45:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002485 ext_attr->has_lna = true;
2486 ext_attr->has_ntsc = true;
2487 ext_attr->has_btsc = false;
2488 ext_attr->has_oob = false;
2489 ext_attr->has_smatx = true;
2490 ext_attr->has_smarx = true;
2491 ext_attr->has_gpio = true;
2492 ext_attr->has_irqn = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002493 break;
2494 case 0x46:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002495 ext_attr->has_lna = false;
2496 ext_attr->has_ntsc = true;
2497 ext_attr->has_btsc = false;
2498 ext_attr->has_oob = false;
2499 ext_attr->has_smatx = true;
2500 ext_attr->has_smarx = true;
2501 ext_attr->has_gpio = true;
2502 ext_attr->has_irqn = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002503 break;
2504 case 0x41:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002505 ext_attr->has_lna = true;
2506 ext_attr->has_ntsc = true;
2507 ext_attr->has_btsc = true;
2508 ext_attr->has_oob = false;
2509 ext_attr->has_smatx = true;
2510 ext_attr->has_smarx = true;
2511 ext_attr->has_gpio = true;
2512 ext_attr->has_irqn = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002513 break;
2514 case 0x43:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002515 ext_attr->has_lna = false;
2516 ext_attr->has_ntsc = true;
2517 ext_attr->has_btsc = true;
2518 ext_attr->has_oob = false;
2519 ext_attr->has_smatx = true;
2520 ext_attr->has_smarx = true;
2521 ext_attr->has_gpio = true;
2522 ext_attr->has_irqn = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002523 break;
2524 case 0x32:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002525 ext_attr->has_lna = true;
2526 ext_attr->has_ntsc = false;
2527 ext_attr->has_btsc = false;
2528 ext_attr->has_oob = true;
2529 ext_attr->has_smatx = true;
2530 ext_attr->has_smarx = true;
2531 ext_attr->has_gpio = true;
2532 ext_attr->has_irqn = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002533 break;
2534 case 0x34:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002535 ext_attr->has_lna = false;
2536 ext_attr->has_ntsc = true;
2537 ext_attr->has_btsc = true;
2538 ext_attr->has_oob = true;
2539 ext_attr->has_smatx = true;
2540 ext_attr->has_smarx = true;
2541 ext_attr->has_gpio = true;
2542 ext_attr->has_irqn = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002543 break;
2544 case 0x42:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002545 ext_attr->has_lna = true;
2546 ext_attr->has_ntsc = true;
2547 ext_attr->has_btsc = true;
2548 ext_attr->has_oob = true;
2549 ext_attr->has_smatx = true;
2550 ext_attr->has_smarx = true;
2551 ext_attr->has_gpio = true;
2552 ext_attr->has_irqn = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002553 break;
2554 case 0x44:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002555 ext_attr->has_lna = false;
2556 ext_attr->has_ntsc = true;
2557 ext_attr->has_btsc = true;
2558 ext_attr->has_oob = true;
2559 ext_attr->has_smatx = true;
2560 ext_attr->has_smarx = true;
2561 ext_attr->has_gpio = true;
2562 ext_attr->has_irqn = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002563 break;
2564 default:
2565 /* Unknown device variant */
2566 return (DRX_STS_ERROR);
2567 break;
2568 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002569
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002570 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002571rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002572 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002573}
2574
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002575/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002576* \fn int power_up_device()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002577* \brief Power up device.
2578* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002579* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002580* \return DRX_STS_OK Success
2581* \retval DRX_STS_ERROR Failure, I2C or max retries reached
2582*
2583*/
2584
2585#ifndef DRXJ_MAX_RETRIES_POWERUP
2586#define DRXJ_MAX_RETRIES_POWERUP 10
2587#endif
2588
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002589static int power_up_device(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002590{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002591 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002592 u8 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002593 u16 retry_count = 0;
2594 struct i2c_device_addr wake_up_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002595
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002596 dev_addr = demod->my_i2c_dev_addr;
2597 wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2598 wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2599 wake_up_addr.user_data = dev_addr->user_data;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002600 /* CHK_ERROR macro not used, I2C access may fail in this case: no ack
2601 dummy write must be used to wake uop device, dummy read must be used to
2602 reset HI state machine (avoiding actual writes) */
2603 do {
2604 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002605 drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
Mauro Carvalho Chehab5b223b32012-03-20 00:33:46 -03002606 (struct i2c_device_addr *) (NULL), 0,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03002607 (u8 *) (NULL));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002608 drxbsp_hst_sleep(10);
2609 retry_count++;
2610 } while ((drxbsp_i2c_write_read
2611 ((struct i2c_device_addr *) (NULL), 0, (u8 *) (NULL), dev_addr, 1,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002612 &data)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002613 != DRX_STS_OK) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002614
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002615 /* Need some recovery time .... */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002616 drxbsp_hst_sleep(10);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002617
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002618 if (retry_count == DRXJ_MAX_RETRIES_POWERUP) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002619 return (DRX_STS_ERROR);
2620 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002621
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002622 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002623}
2624
2625/*----------------------------------------------------------------------------*/
2626/* MPEG Output Configuration Functions - begin */
2627/*----------------------------------------------------------------------------*/
2628/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002629* \fn int ctrl_set_cfg_mpeg_output()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002630* \brief Set MPEG output configuration of the device.
2631* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002632* \param cfg_data Pointer to mpeg output configuaration.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002633* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002634*
2635* Configure MPEG output parameters.
2636*
2637*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03002638static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002639ctrl_set_cfg_mpeg_output(pdrx_demod_instance_t demod, pdrx_cfg_mpeg_output_t cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002640{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002641 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
2642 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
2643 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) (NULL);
2644 u16 fec_oc_reg_mode = 0;
2645 u16 fec_oc_reg_ipr_mode = 0;
2646 u16 fec_oc_reg_ipr_invert = 0;
2647 u32 max_bit_rate = 0;
2648 u32 rcn_rate = 0;
2649 u32 nr_bits = 0;
2650 u16 sio_pdr_md_cfg = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002651 /* data mask for the output data byte */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002652 u16 invert_data_mask =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002653 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2654 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2655 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2656 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2657 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002658 if ((demod == NULL) || (cfg_data == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002659 return (DRX_STS_INVALID_ARG);
2660 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002661
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002662 dev_addr = demod->my_i2c_dev_addr;
2663 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
2664 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002665
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002666 if (cfg_data->enable_mpeg_output == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002667 /* quick and dirty patch to set MPEG incase current std is not
2668 producing MPEG */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002669 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002670 case DRX_STANDARD_8VSB:
2671 case DRX_STANDARD_ITU_A:
2672 case DRX_STANDARD_ITU_B:
2673 case DRX_STANDARD_ITU_C:
2674 break;
2675 default:
2676 /* not an MPEG producing std, just store MPEG cfg */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002677 common_attr->mpeg_cfg.enable_mpeg_output =
2678 cfg_data->enable_mpeg_output;
2679 common_attr->mpeg_cfg.insert_rs_byte =
2680 cfg_data->insert_rs_byte;
2681 common_attr->mpeg_cfg.enable_parallel =
2682 cfg_data->enable_parallel;
2683 common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
2684 common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
2685 common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
2686 common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
2687 common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
2688 common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
2689 common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002690 return (DRX_STS_OK);
2691 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002692
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002693 WR16(dev_addr, FEC_OC_OCR_INVERT__A, 0);
2694 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002695 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002696 WR16(dev_addr, FEC_OC_FCT_USAGE__A, 7); /* 2048 bytes fifo ram */
2697 WR16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10);
2698 WR16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10);
2699 WR16(dev_addr, FEC_OC_AVR_PARM_A__A, 5);
2700 WR16(dev_addr, FEC_OC_AVR_PARM_B__A, 7);
2701 WR16(dev_addr, FEC_OC_RCN_GAIN__A, 10);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002702 /* Low Water Mark for synchronization */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002703 WR16(dev_addr, FEC_OC_SNC_LWM__A, 3);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002704 /* High Water Mark for synchronization */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002705 WR16(dev_addr, FEC_OC_SNC_HWM__A, 5);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002706 break;
2707 case DRX_STANDARD_ITU_A:
2708 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002709 switch (ext_attr->constellation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002710 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002711 nr_bits = 8;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002712 break;
2713 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002714 nr_bits = 7;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002715 break;
2716 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002717 nr_bits = 6;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002718 break;
2719 case DRX_CONSTELLATION_QAM32:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002720 nr_bits = 5;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002721 break;
2722 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002723 nr_bits = 4;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002724 break;
2725 default:
2726 return (DRX_STS_ERROR);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002727 } /* ext_attr->constellation */
2728 /* max_bit_rate = symbol_rate * nr_bits * coef */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002729 /* coef = 188/204 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002730 max_bit_rate =
2731 (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002732 /* pass through b/c Annex A/c need following settings */
2733 case DRX_STANDARD_ITU_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002734 WR16(dev_addr, FEC_OC_FCT_USAGE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002735 FEC_OC_FCT_USAGE__PRE);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002736 WR16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002737 FEC_OC_TMD_CTL_UPD_RATE__PRE);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002738 WR16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5);
2739 WR16(dev_addr, FEC_OC_AVR_PARM_A__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002740 FEC_OC_AVR_PARM_A__PRE);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002741 WR16(dev_addr, FEC_OC_AVR_PARM_B__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002742 FEC_OC_AVR_PARM_B__PRE);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002743 if (cfg_data->static_clk == true) {
2744 WR16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002745 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002746 WR16(dev_addr, FEC_OC_RCN_GAIN__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002747 FEC_OC_RCN_GAIN__PRE);
2748 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002749 WR16(dev_addr, FEC_OC_SNC_LWM__A, 2);
2750 WR16(dev_addr, FEC_OC_SNC_HWM__A, 12);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002751 break;
2752 default:
2753 break;
2754 } /* swtich (standard) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002755
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002756 /* Check insertion of the Reed-Solomon parity bytes */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002757 RR16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode);
2758 RR16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
2759 if (cfg_data->insert_rs_byte == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002760 /* enable parity symbol forward */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002761 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002762 /* MVAL disable during parity bytes */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002763 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2764 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002765 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002766 rcn_rate = 0x004854D3;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002767 break;
2768 case DRX_STANDARD_ITU_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002769 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2770 switch (ext_attr->constellation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002771 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002772 rcn_rate = 0x008945E7;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002773 break;
2774 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002775 rcn_rate = 0x005F64D4;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002776 break;
2777 default:
2778 return (DRX_STS_ERROR);
2779 }
2780 break;
2781 case DRX_STANDARD_ITU_A:
2782 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002783 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2784 rcn_rate =
2785 (frac28
2786 (max_bit_rate,
2787 (u32) (common_attr->sys_clock_freq / 8))) /
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002788 188;
2789 break;
2790 default:
2791 return (DRX_STS_ERROR);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002792 } /* ext_attr->standard */
2793 } else { /* insert_rs_byte == false */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002794
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002795 /* disable parity symbol forward */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002796 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002797 /* MVAL enable during parity bytes */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002798 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2799 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002800 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002801 rcn_rate = 0x0041605C;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002802 break;
2803 case DRX_STANDARD_ITU_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002804 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2805 switch (ext_attr->constellation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002806 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002807 rcn_rate = 0x0082D6A0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002808 break;
2809 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002810 rcn_rate = 0x005AEC1A;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002811 break;
2812 default:
2813 return (DRX_STS_ERROR);
2814 }
2815 break;
2816 case DRX_STANDARD_ITU_A:
2817 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002818 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2819 rcn_rate =
2820 (frac28
2821 (max_bit_rate,
2822 (u32) (common_attr->sys_clock_freq / 8))) /
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002823 204;
2824 break;
2825 default:
2826 return (DRX_STS_ERROR);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002827 } /* ext_attr->standard */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002828 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002829
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002830 if (cfg_data->enable_parallel == true) { /* MPEG data output is paralel -> clear ipr_mode[0] */
2831 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002832 } else { /* MPEG data output is serial -> set ipr_mode[0] */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002833 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002834 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002835
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002836 /* Control slective inversion of output bits */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002837 if (cfg_data->invert_data == true) {
2838 fec_oc_reg_ipr_invert |= invert_data_mask;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002839 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002840 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002841 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002842
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002843 if (cfg_data->invert_err == true) {
2844 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002845 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002846 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002847 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002848
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002849 if (cfg_data->invert_str == true) {
2850 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002851 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002852 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002853 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002854
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002855 if (cfg_data->invert_val == true) {
2856 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002857 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002858 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002859 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002860
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002861 if (cfg_data->invert_clk == true) {
2862 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002863 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002864 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002865 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002866
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002867 if (cfg_data->static_clk == true) { /* Static mode */
2868 u32 dto_rate = 0;
2869 u32 bit_rate = 0;
2870 u16 fec_oc_dto_burst_len = 0;
2871 u16 fec_oc_dto_period = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002872
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002873 fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002874
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002875 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002876 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002877 fec_oc_dto_period = 4;
2878 if (cfg_data->insert_rs_byte == true) {
2879 fec_oc_dto_burst_len = 208;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002880 }
2881 break;
2882 case DRX_STANDARD_ITU_A:
2883 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002884 u32 symbol_rate_th = 6400000;
2885 if (cfg_data->insert_rs_byte == true) {
2886 fec_oc_dto_burst_len = 204;
2887 symbol_rate_th = 5900000;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002888 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002889 if (ext_attr->curr_symbol_rate >=
2890 symbol_rate_th) {
2891 fec_oc_dto_period = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002892 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002893 fec_oc_dto_period = 1;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002894 }
2895 }
2896 break;
2897 case DRX_STANDARD_ITU_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002898 fec_oc_dto_period = 1;
2899 if (cfg_data->insert_rs_byte == true) {
2900 fec_oc_dto_burst_len = 128;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002901 }
2902 break;
2903 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002904 fec_oc_dto_period = 1;
2905 if (cfg_data->insert_rs_byte == true) {
2906 fec_oc_dto_burst_len = 204;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002907 }
2908 break;
2909 default:
2910 return (DRX_STS_ERROR);
2911 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002912 bit_rate =
2913 common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002914 2);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002915 dto_rate =
2916 frac28(bit_rate, common_attr->sys_clock_freq * 1000);
2917 dto_rate >>= 3;
2918 WR16(dev_addr, FEC_OC_DTO_RATE_HI__A,
2919 (u16) ((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M));
2920 WR16(dev_addr, FEC_OC_DTO_RATE_LO__A,
2921 (u16) (dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M));
2922 WR16(dev_addr, FEC_OC_DTO_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002923 FEC_OC_DTO_MODE_DYNAMIC__M |
2924 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002925 WR16(dev_addr, FEC_OC_FCT_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002926 FEC_OC_FCT_MODE_RAT_ENA__M |
2927 FEC_OC_FCT_MODE_VIRT_ENA__M);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002928 WR16(dev_addr, FEC_OC_DTO_BURST_LEN__A,
2929 fec_oc_dto_burst_len);
2930 if (ext_attr->mpeg_output_clock_rate !=
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002931 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002932 fec_oc_dto_period =
2933 ext_attr->mpeg_output_clock_rate - 1;
2934 WR16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002935 } else { /* Dynamic mode */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002936
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002937 WR16(dev_addr, FEC_OC_DTO_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002938 FEC_OC_DTO_MODE_DYNAMIC__M);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002939 WR16(dev_addr, FEC_OC_FCT_MODE__A, 0);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002940 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002941
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002942 WR32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002943
2944 /* Write appropriate registers with requested configuration */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002945 WR16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode);
2946 WR16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
2947 WR16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002948
2949 /* enabling for both parallel and serial now */
2950 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002951 WR16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002952 /* Set MPEG TS pads to outputmode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002953 WR16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013);
2954 WR16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013);
2955 WR16(dev_addr, SIO_PDR_MCLK_CFG__A,
Devin Heitmueller38b2df92012-08-13 21:18:02 -03002956 MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002957 | 0x03 << SIO_PDR_MCLK_CFG_MODE__B);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002958 WR16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013);
2959 sio_pdr_md_cfg =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002960 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
2961 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002962 WR16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg);
2963 if (cfg_data->enable_parallel == true) { /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
2964 sio_pdr_md_cfg =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002965 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
2966 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
2967 SIO_PDR_MD0_CFG_MODE__B;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002968 WR16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg);
2969 WR16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg);
2970 WR16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg);
2971 WR16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg);
2972 WR16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg);
2973 WR16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg);
2974 WR16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg);
2975 WR16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002976 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002977 WR16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000);
2978 WR16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000);
2979 WR16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000);
2980 WR16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000);
2981 WR16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000);
2982 WR16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000);
2983 WR16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002984 }
2985 /* Enable Monitor Bus output over MPEG pads and ctl input */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002986 WR16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002987 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002988 WR16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002989 } else {
2990 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002991 WR16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03002992 /* Set MPEG TS pads to inputmode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03002993 WR16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000);
2994 WR16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000);
2995 WR16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000);
2996 WR16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000);
2997 WR16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000);
2998 WR16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000);
2999 WR16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000);
3000 WR16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000);
3001 WR16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000);
3002 WR16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000);
3003 WR16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000);
3004 WR16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003005 /* Enable Monitor Bus output over MPEG pads and ctl input */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003006 WR16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003007 /* Write nomagic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003008 WR16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003009 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003010
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003011 /* save values for restore after re-acquire */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003012 common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3013 common_attr->mpeg_cfg.insert_rs_byte = cfg_data->insert_rs_byte;
3014 common_attr->mpeg_cfg.enable_parallel = cfg_data->enable_parallel;
3015 common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
3016 common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
3017 common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
3018 common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
3019 common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
3020 common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
3021 common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003022
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003023 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003024rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003025 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003026}
3027
3028/*----------------------------------------------------------------------------*/
3029
3030/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003031* \fn int ctrl_get_cfg_mpeg_output()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003032* \brief Get MPEG output configuration of the device.
3033* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003034* \param cfg_data Pointer to MPEG output configuaration struct.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003035* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003036*
3037* Retrieve MPEG output configuartion.
3038*
3039*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003040static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003041ctrl_get_cfg_mpeg_output(pdrx_demod_instance_t demod, pdrx_cfg_mpeg_output_t cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003042{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003043 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
3044 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) (NULL);
3045 drx_lock_status_t lock_status = DRX_NOT_LOCKED;
3046 u32 rate_reg = 0;
3047 u32 data64hi = 0;
3048 u32 data64lo = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003049
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003050 if (cfg_data == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003051 return (DRX_STS_INVALID_ARG);
3052 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003053 dev_addr = demod->my_i2c_dev_addr;
3054 common_attr = demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003055
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003056 cfg_data->enable_mpeg_output = common_attr->mpeg_cfg.enable_mpeg_output;
3057 cfg_data->insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
3058 cfg_data->enable_parallel = common_attr->mpeg_cfg.enable_parallel;
3059 cfg_data->invert_data = common_attr->mpeg_cfg.invert_data;
3060 cfg_data->invert_err = common_attr->mpeg_cfg.invert_err;
3061 cfg_data->invert_str = common_attr->mpeg_cfg.invert_str;
3062 cfg_data->invert_val = common_attr->mpeg_cfg.invert_val;
3063 cfg_data->invert_clk = common_attr->mpeg_cfg.invert_clk;
3064 cfg_data->static_clk = common_attr->mpeg_cfg.static_clk;
3065 cfg_data->bitrate = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003066
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003067 CHK_ERROR(ctrl_lock_status(demod, &lock_status));
3068 if ((lock_status == DRX_LOCKED)) {
3069 RR32(dev_addr, FEC_OC_RCN_DYN_RATE_LO__A, &rate_reg);
3070 /* Frcn_rate = rate_reg * Fsys / 2 ^ 25 */
3071 mult32(rate_reg, common_attr->sys_clock_freq * 1000, &data64hi,
3072 &data64lo);
3073 cfg_data->bitrate = (data64hi << 7) | (data64lo >> 25);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003074 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003075
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003076 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003077rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003078 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003079}
3080
3081/*----------------------------------------------------------------------------*/
3082/* MPEG Output Configuration Functions - end */
3083/*----------------------------------------------------------------------------*/
3084
3085/*----------------------------------------------------------------------------*/
3086/* miscellaneous configuartions - begin */
3087/*----------------------------------------------------------------------------*/
3088
3089/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003090* \fn int set_mpegtei_handling()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003091* \brief Activate MPEG TEI handling settings.
3092* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003093* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003094*
3095* This routine should be called during a set channel of QAM/VSB
3096*
3097*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003098static int set_mpegtei_handling(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003099{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003100 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
3101 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
3102 u16 fec_oc_dpr_mode = 0;
3103 u16 fec_oc_snc_mode = 0;
3104 u16 fec_oc_ems_mode = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003105
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003106 dev_addr = demod->my_i2c_dev_addr;
3107 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003108
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003109 RR16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode);
3110 RR16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
3111 RR16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003112
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003113 /* reset to default, allow TEI bit to be changed */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003114 fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3115 fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003116 FEC_OC_SNC_MODE_CORR_DISABLE__M));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003117 fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003118
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003119 if (ext_attr->disable_te_ihandling == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003120 /* do not change TEI bit */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003121 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3122 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003123 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003124 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003125 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003126
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003127 WR16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode);
3128 WR16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
3129 WR16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003130
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003131 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003132rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003133 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003134}
3135
3136/*----------------------------------------------------------------------------*/
3137/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003138* \fn int bit_reverse_mpeg_output()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003139* \brief Set MPEG output bit-endian settings.
3140* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003141* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003142*
3143* This routine should be called during a set channel of QAM/VSB
3144*
3145*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003146static int bit_reverse_mpeg_output(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003147{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003148 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
3149 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
3150 u16 fec_oc_ipr_mode = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003151
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003152 dev_addr = demod->my_i2c_dev_addr;
3153 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003154
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003155 RR16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003156
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003157 /* reset to default (normal bit order) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003158 fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003159
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003160 if (ext_attr->bit_reverse_mpeg_outout == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003161 /* reverse bit order */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003162 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003163 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003164
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003165 WR16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003166
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003167 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003168rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003169 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003170}
3171
3172/*----------------------------------------------------------------------------*/
3173/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003174* \fn int set_mpeg_output_clock_rate()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003175* \brief Set MPEG output clock rate.
3176* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003177* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003178*
3179* This routine should be called during a set channel of QAM/VSB
3180*
3181*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003182static int set_mpeg_output_clock_rate(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003183{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003184 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
3185 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003186
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003187 dev_addr = demod->my_i2c_dev_addr;
3188 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003189
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003190 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3191 WR16(dev_addr, FEC_OC_DTO_PERIOD__A,
3192 ext_attr->mpeg_output_clock_rate - 1);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003193 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003194
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003195 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003196rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003197 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003198}
3199
3200/*----------------------------------------------------------------------------*/
3201/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003202* \fn int set_mpeg_start_width()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003203* \brief Set MPEG start width.
3204* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003205* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003206*
3207* This routine should be called during a set channel of QAM/VSB
3208*
3209*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003210static int set_mpeg_start_width(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003211{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003212 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
3213 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
3214 u16 fec_oc_comm_mb = 0;
3215 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003216
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003217 dev_addr = demod->my_i2c_dev_addr;
3218 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
3219 common_attr = demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003220
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003221 if ((common_attr->mpeg_cfg.static_clk == true)
3222 && (common_attr->mpeg_cfg.enable_parallel == false)) {
3223 RR16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb);
3224 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3225 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC) {
3226 fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003227 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003228 WR16(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003229 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003230
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003231 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003232rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003233 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003234}
3235
3236/*----------------------------------------------------------------------------*/
3237/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003238* \fn int ctrl_set_cfg_mpeg_output_misc()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003239* \brief Set miscellaneous configuartions
3240* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003241* \param cfg_data pDRXJCfgMisc_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003242* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003243*
3244* This routine can be used to set configuartion options that are DRXJ
3245* specific and/or added to the requirements at a late stage.
3246*
3247*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003248static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003249ctrl_set_cfg_mpeg_output_misc(pdrx_demod_instance_t demod,
3250 p_drxj_cfg_mpeg_output_misc_t cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003251{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003252 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003253
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003254 if (cfg_data == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003255 return (DRX_STS_INVALID_ARG);
3256 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003257
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003258 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003259
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003260 /*
3261 Set disable TEI bit handling flag.
3262 TEI must be left untouched by device in case of BER measurements using
3263 external equipment that is unable to ignore the TEI bit in the TS.
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03003264 Default will false (enable TEI bit handling).
3265 Reverse output bit order. Default is false (msb on MD7 (parallel) or out first (serial)).
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003266 Set clock rate. Default is auto that is derived from symbol rate.
3267 The flags and values will also be used to set registers during a set channel.
3268 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003269 ext_attr->disable_te_ihandling = cfg_data->disable_tei_handling;
3270 ext_attr->bit_reverse_mpeg_outout = cfg_data->bit_reverse_mpeg_outout;
3271 ext_attr->mpeg_output_clock_rate = cfg_data->mpeg_output_clock_rate;
3272 ext_attr->mpeg_start_width = cfg_data->mpeg_start_width;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003273 /* Don't care what the active standard is, activate setting immediatly */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003274 CHK_ERROR(set_mpegtei_handling(demod));
3275 CHK_ERROR(bit_reverse_mpeg_output(demod));
3276 CHK_ERROR(set_mpeg_output_clock_rate(demod));
3277 CHK_ERROR(set_mpeg_start_width(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003278
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003279 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003280rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003281 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003282}
3283
3284/*----------------------------------------------------------------------------*/
3285
3286/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003287* \fn int ctrl_get_cfg_mpeg_output_misc()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003288* \brief Get miscellaneous configuartions.
3289* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003290* \param cfg_data Pointer to DRXJCfgMisc_t.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003291* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003292*
3293* This routine can be used to retreive the current setting of the configuartion
3294* options that are DRXJ specific and/or added to the requirements at a
3295* late stage.
3296*
3297*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003298static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003299ctrl_get_cfg_mpeg_output_misc(pdrx_demod_instance_t demod,
3300 p_drxj_cfg_mpeg_output_misc_t cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003301{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003302 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03003303 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003304
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003305 if (cfg_data == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003306 return (DRX_STS_INVALID_ARG);
3307 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003308
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003309 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
3310 cfg_data->disable_tei_handling = ext_attr->disable_te_ihandling;
3311 cfg_data->bit_reverse_mpeg_outout = ext_attr->bit_reverse_mpeg_outout;
3312 cfg_data->mpeg_start_width = ext_attr->mpeg_start_width;
3313 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3314 cfg_data->mpeg_output_clock_rate = ext_attr->mpeg_output_clock_rate;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003315 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003316 RR16(demod->my_i2c_dev_addr, FEC_OC_DTO_PERIOD__A, &data);
3317 cfg_data->mpeg_output_clock_rate =
3318 (drxj_mpeg_output_clock_rate_t) (data + 1);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003319 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003320
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003321 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003322rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003323 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003324}
3325
3326/*----------------------------------------------------------------------------*/
3327
3328/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003329* \fn int ctrl_get_cfg_hw_cfg()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003330* \brief Get HW configuartions.
3331* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003332* \param cfg_data Pointer to Bool.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003333* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003334*
3335* This routine can be used to retreive the current setting of the configuartion
3336* options that are DRXJ specific and/or added to the requirements at a
3337* late stage.
3338*
3339*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003340static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003341ctrl_get_cfg_hw_cfg(pdrx_demod_instance_t demod, p_drxj_cfg_hw_cfg_t cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003342{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03003343 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003344 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003345
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003346 if (cfg_data == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003347 return (DRX_STS_INVALID_ARG);
3348 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003349
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003350 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
3351 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA);
3352 RR16(demod->my_i2c_dev_addr, SIO_PDR_OHW_CFG__A, &data);
3353 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003354
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003355 cfg_data->i2c_speed = (drxji2c_speed_t) ((data >> 6) & 0x1);
3356 cfg_data->xtal_freq = (drxj_xtal_freq_t) (data & 0x3);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003357
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003358 return (DRX_STS_OK);
3359rw_error:
3360 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003361}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003362
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003363/*----------------------------------------------------------------------------*/
3364/* miscellaneous configuartions - end */
3365/*----------------------------------------------------------------------------*/
3366
3367/*----------------------------------------------------------------------------*/
3368/* UIO Configuration Functions - begin */
3369/*----------------------------------------------------------------------------*/
3370/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003371* \fn int ctrl_set_uio_cfg()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003372* \brief Configure modus oprandi UIO.
3373* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003374* \param uio_cfg Pointer to a configuration setting for a certain UIO.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003375* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003376*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003377static int ctrl_set_uio_cfg(pdrx_demod_instance_t demod, pdrxuio_cfg_t uio_cfg)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003378{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003379 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003380
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003381 if ((uio_cfg == NULL) || (demod == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003382 return DRX_STS_INVALID_ARG;
3383 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003384 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003385
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003386 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003387 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
3388 switch (uio_cfg->uio) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003389 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003390 case DRX_UIO1:
3391 /* DRX_UIO1: SMA_TX UIO-1 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003392 if (ext_attr->has_smatx != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003393 return DRX_STS_ERROR;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003394 switch (uio_cfg->mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003395 case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
3396 case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
3397 case DRX_UIO_MODE_READWRITE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003398 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003399 break;
3400 case DRX_UIO_MODE_DISABLE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003401 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003402 /* pad configuration register is set 0 - input mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003403 WR16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003404 break;
3405 default:
3406 return DRX_STS_INVALID_ARG;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003407 } /* switch ( uio_cfg->mode ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003408 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003409 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003410 case DRX_UIO2:
3411 /* DRX_UIO2: SMA_RX UIO-2 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003412 if (ext_attr->has_smarx != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003413 return DRX_STS_ERROR;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003414 switch (uio_cfg->mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003415 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3416 case DRX_UIO_MODE_READWRITE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003417 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003418 break;
3419 case DRX_UIO_MODE_DISABLE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003420 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003421 /* pad configuration register is set 0 - input mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003422 WR16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003423 break;
3424 default:
3425 return DRX_STS_INVALID_ARG;
3426 break;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003427 } /* switch ( uio_cfg->mode ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003428 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003429 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003430 case DRX_UIO3:
3431 /* DRX_UIO3: GPIO UIO-3 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003432 if (ext_attr->has_gpio != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003433 return DRX_STS_ERROR;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003434 switch (uio_cfg->mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003435 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3436 case DRX_UIO_MODE_READWRITE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003437 ext_attr->uio_gpio_mode = uio_cfg->mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003438 break;
3439 case DRX_UIO_MODE_DISABLE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003440 ext_attr->uio_gpio_mode = uio_cfg->mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003441 /* pad configuration register is set 0 - input mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003442 WR16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003443 break;
3444 default:
3445 return DRX_STS_INVALID_ARG;
3446 break;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003447 } /* switch ( uio_cfg->mode ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003448 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003449 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003450 case DRX_UIO4:
3451 /* DRX_UIO4: IRQN UIO-4 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003452 if (ext_attr->has_irqn != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003453 return DRX_STS_ERROR;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003454 switch (uio_cfg->mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003455 case DRX_UIO_MODE_READWRITE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003456 ext_attr->uio_irqn_mode = uio_cfg->mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003457 break;
3458 case DRX_UIO_MODE_DISABLE:
3459 /* pad configuration register is set 0 - input mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003460 WR16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0);
3461 ext_attr->uio_irqn_mode = uio_cfg->mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003462 break;
3463 case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
3464 default:
3465 return DRX_STS_INVALID_ARG;
3466 break;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003467 } /* switch ( uio_cfg->mode ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003468 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003469 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003470 default:
3471 return DRX_STS_INVALID_ARG;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003472 } /* switch ( uio_cfg->uio ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003473
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003474 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003475 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003476
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003477 return (DRX_STS_OK);
3478rw_error:
3479 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003480}
3481
3482/*============================================================================*/
3483/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003484* \fn int CtrlGetuio_cfg()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003485* \brief Get modus oprandi UIO.
3486* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003487* \param uio_cfg Pointer to a configuration setting for a certain UIO.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003488* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003489*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003490static int CtrlGetuio_cfg(pdrx_demod_instance_t demod, pdrxuio_cfg_t uio_cfg)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003491{
3492
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003493 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
3494 pdrxuio_mode_t uio_mode[4] = { NULL };
3495 bool *uio_available[4] = { NULL };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003496
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003497 ext_attr = demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003498
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003499 uio_mode[DRX_UIO1] = &ext_attr->uio_sma_tx_mode;
3500 uio_mode[DRX_UIO2] = &ext_attr->uio_sma_rx_mode;
3501 uio_mode[DRX_UIO3] = &ext_attr->uio_gpio_mode;
3502 uio_mode[DRX_UIO4] = &ext_attr->uio_irqn_mode;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003503
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003504 uio_available[DRX_UIO1] = &ext_attr->has_smatx;
3505 uio_available[DRX_UIO2] = &ext_attr->has_smarx;
3506 uio_available[DRX_UIO3] = &ext_attr->has_gpio;
3507 uio_available[DRX_UIO4] = &ext_attr->has_irqn;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003508
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003509 if (uio_cfg == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003510 return DRX_STS_INVALID_ARG;
3511 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003512
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003513 if ((uio_cfg->uio > DRX_UIO4) || (uio_cfg->uio < DRX_UIO1)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003514 return DRX_STS_INVALID_ARG;
3515 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003516
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003517 if (*uio_available[uio_cfg->uio] == false) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003518 return DRX_STS_ERROR;
3519 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003520
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003521 uio_cfg->mode = *uio_mode[uio_cfg->uio];
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003522
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003523 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003524}
3525
3526/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003527* \fn int ctrl_uio_write()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003528* \brief Write to a UIO.
3529* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003530* \param uio_data Pointer to data container for a certain UIO.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003531* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003532*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003533static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003534ctrl_uio_write(pdrx_demod_instance_t demod, pdrxuio_data_t uio_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003535{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003536 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
3537 u16 pin_cfg_value = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03003538 u16 value = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003539
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003540 if ((uio_data == NULL) || (demod == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003541 return DRX_STS_INVALID_ARG;
3542 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003543
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003544 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003545
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003546 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003547 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
3548 switch (uio_data->uio) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003549 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003550 case DRX_UIO1:
3551 /* DRX_UIO1: SMA_TX UIO-1 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003552 if (ext_attr->has_smatx != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003553 return DRX_STS_ERROR;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003554 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3555 && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003556 return DRX_STS_ERROR;
3557 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003558 pin_cfg_value = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003559 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003560 pin_cfg_value |= 0x0113;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003561 /* io_pad_cfg_mode output mode is drive always */
3562 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003563
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003564 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003565 WR16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003566
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003567 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003568 RR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value);
3569 if (uio_data->value == false) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003570 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
3571 } else {
3572 value |= 0x8000; /* write one to 15th bit - 1st UIO */
3573 }
3574 /* write back to io data output register */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003575 WR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003576 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003577 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003578 case DRX_UIO2:
3579 /* DRX_UIO2: SMA_RX UIO-2 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003580 if (ext_attr->has_smarx != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003581 return DRX_STS_ERROR;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003582 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003583 return DRX_STS_ERROR;
3584 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003585 pin_cfg_value = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003586 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003587 pin_cfg_value |= 0x0113;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003588 /* io_pad_cfg_mode output mode is drive always */
3589 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003590
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003591 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003592 WR16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003593
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003594 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003595 RR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value);
3596 if (uio_data->value == false) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003597 value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
3598 } else {
3599 value |= 0x4000; /* write one to 14th bit - 2nd UIO */
3600 }
3601 /* write back to io data output register */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003602 WR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003603 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003604 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003605 case DRX_UIO3:
3606 /* DRX_UIO3: ASEL UIO-3 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003607 if (ext_attr->has_gpio != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003608 return DRX_STS_ERROR;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003609 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003610 return DRX_STS_ERROR;
3611 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003612 pin_cfg_value = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003613 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003614 pin_cfg_value |= 0x0113;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003615 /* io_pad_cfg_mode output mode is drive always */
3616 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003617
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003618 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003619 WR16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003620
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003621 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003622 RR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value);
3623 if (uio_data->value == false) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003624 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
3625 } else {
3626 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
3627 }
3628 /* write back to io data output register */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003629 WR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003630 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003631 /*=====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003632 case DRX_UIO4:
3633 /* DRX_UIO4: IRQN UIO-4 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003634 if (ext_attr->has_irqn != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003635 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003636
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003637 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003638 return DRX_STS_ERROR;
3639 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003640 pin_cfg_value = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003641 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003642 pin_cfg_value |= 0x0113;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003643 /* io_pad_cfg_mode output mode is drive always */
3644 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003645
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003646 /* write to io pad configuration register - output mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003647 WR16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003648
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003649 /* use corresponding bit in io data output registar */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003650 RR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value);
3651 if (uio_data->value == false) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003652 value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
3653 } else {
3654 value |= 0x1000; /* write one to 12th bit - 4th UIO */
3655 }
3656 /* write back to io data output register */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003657 WR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003658 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003659 /*=====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003660 default:
3661 return DRX_STS_INVALID_ARG;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003662 } /* switch ( uio_data->uio ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003663
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003664 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003665 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003666
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003667 return (DRX_STS_OK);
3668rw_error:
3669 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003670}
3671
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003672/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003673*\fn int ctrl_uio_read
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003674*\brief Read from a UIO.
3675* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003676* \param uio_data Pointer to data container for a certain UIO.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003677* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003678*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003679static int ctrl_uio_read(pdrx_demod_instance_t demod, pdrxuio_data_t uio_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003680{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003681 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
3682 u16 pin_cfg_value = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03003683 u16 value = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003684
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003685 if ((uio_data == NULL) || (demod == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003686 return DRX_STS_INVALID_ARG;
3687 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003688
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003689 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003690
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003691 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003692 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
3693 switch (uio_data->uio) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003694 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003695 case DRX_UIO1:
3696 /* DRX_UIO1: SMA_TX UIO-1 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003697 if (ext_attr->has_smatx != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003698 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003699
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003700 if (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003701 return DRX_STS_ERROR;
3702 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003703 pin_cfg_value = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003704 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003705 pin_cfg_value |= 0x0110;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003706 /* io_pad_cfg_mode output mode is drive always */
3707 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003708
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003709 /* write to io pad configuration register - input mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003710 WR16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003711
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003712 RR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003713 if ((value & 0x8000) != 0) { /* check 15th bit - 1st UIO */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003714 uio_data->value = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003715 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003716 uio_data->value = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003717 }
3718 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003719 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003720 case DRX_UIO2:
3721 /* DRX_UIO2: SMA_RX UIO-2 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003722 if (ext_attr->has_smarx != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003723 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003724
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003725 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003726 return DRX_STS_ERROR;
3727 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003728 pin_cfg_value = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003729 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003730 pin_cfg_value |= 0x0110;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003731 /* io_pad_cfg_mode output mode is drive always */
3732 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003733
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003734 /* write to io pad configuration register - input mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003735 WR16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003736
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003737 RR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003738
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003739 if ((value & 0x4000) != 0) { /* check 14th bit - 2nd UIO */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003740 uio_data->value = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003741 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003742 uio_data->value = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003743 }
3744 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003745 /*=====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003746 case DRX_UIO3:
3747 /* DRX_UIO3: GPIO UIO-3 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003748 if (ext_attr->has_gpio != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003749 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003750
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003751 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003752 return DRX_STS_ERROR;
3753 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003754 pin_cfg_value = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003755 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003756 pin_cfg_value |= 0x0110;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003757 /* io_pad_cfg_mode output mode is drive always */
3758 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003759
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003760 /* write to io pad configuration register - input mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003761 WR16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003762
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003763 /* read io input data registar */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003764 RR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_HI__A, &value);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003765 if ((value & 0x0004) != 0) { /* check 2nd bit - 3rd UIO */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003766 uio_data->value = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003767 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003768 uio_data->value = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003769 }
3770 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003771 /*=====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003772 case DRX_UIO4:
3773 /* DRX_UIO4: IRQN UIO-4 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003774 if (ext_attr->has_irqn != true)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003775 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003776
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003777 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003778 return DRX_STS_ERROR;
3779 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003780 pin_cfg_value = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003781 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003782 pin_cfg_value |= 0x0110;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003783 /* io_pad_cfg_mode output mode is drive always */
3784 /* io_pad_cfg_drive is set to power 2 (23 mA) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003785
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003786 /* write to io pad configuration register - input mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003787 WR16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003788
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003789 /* read io input data registar */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003790 RR16(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003791 if ((value & 0x1000) != 0) { /* check 12th bit - 4th UIO */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003792 uio_data->value = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003793 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003794 uio_data->value = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003795 }
3796 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003797 /*====================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003798 default:
3799 return DRX_STS_INVALID_ARG;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003800 } /* switch ( uio_data->uio ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003801
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003802 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003803 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003804
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003805 return (DRX_STS_OK);
3806rw_error:
3807 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003808}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003809
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003810/*---------------------------------------------------------------------------*/
3811/* UIO Configuration Functions - end */
3812/*---------------------------------------------------------------------------*/
3813
3814/*----------------------------------------------------------------------------*/
3815/* I2C Bridge Functions - begin */
3816/*----------------------------------------------------------------------------*/
3817/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003818* \fn int ctrl_i2c_bridge()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003819* \brief Open or close the I2C switch to tuner.
3820* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003821* \param bridge_closed Pointer to bool indication if bridge is closed not.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003822* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003823
3824*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003825static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003826ctrl_i2c_bridge(pdrx_demod_instance_t demod, bool *bridge_closed)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003827{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003828 drxj_hi_cmd_t hi_cmd;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03003829 u16 result = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003830
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003831 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003832 if (bridge_closed == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003833 return (DRX_STS_INVALID_ARG);
3834 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003835
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003836 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
3837 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
3838 if (*bridge_closed == true) {
3839 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003840 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003841 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003842 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003843
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003844 return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003845}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003846
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003847/*----------------------------------------------------------------------------*/
3848/* I2C Bridge Functions - end */
3849/*----------------------------------------------------------------------------*/
3850
3851/*----------------------------------------------------------------------------*/
3852/* Smart antenna Functions - begin */
3853/*----------------------------------------------------------------------------*/
3854/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003855* \fn int smart_ant_init()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003856* \brief Initialize Smart Antenna.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003857* \param pointer to drx_demod_instance_t.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003858* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003859*
3860*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003861static int smart_ant_init(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003862{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03003863 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003864 pdrxj_data_t ext_attr = NULL;
3865 struct i2c_device_addr *dev_addr = NULL;
3866 drxuio_cfg_t uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003867
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003868 dev_addr = demod->my_i2c_dev_addr;
3869 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003870
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003871 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003872 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003873 /* init smart antenna */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003874 RR16(dev_addr, SIO_SA_TX_COMMAND__A, &data);
3875 if (ext_attr->smart_ant_inverted)
3876 WR16(dev_addr, SIO_SA_TX_COMMAND__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003877 (data | SIO_SA_TX_COMMAND_TX_INVERT__M)
3878 | SIO_SA_TX_COMMAND_TX_ENABLE__M);
3879 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003880 WR16(dev_addr, SIO_SA_TX_COMMAND__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003881 (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M))
3882 | SIO_SA_TX_COMMAND_TX_ENABLE__M);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003883
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003884 /* config SMA_TX pin to smart antenna mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003885 CHK_ERROR(ctrl_set_uio_cfg(demod, &uio_cfg));
3886 WR16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13);
3887 WR16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003888
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003889 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003890 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003891
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003892 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003893rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003894 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003895}
3896
3897/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003898* \fn int ctrl_set_cfg_smart_ant()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003899* \brief Set Smart Antenna.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003900* \param pointer to drxj_cfg_smart_ant_t.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003901* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003902*
3903*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03003904static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003905ctrl_set_cfg_smart_ant(pdrx_demod_instance_t demod, p_drxj_cfg_smart_ant_t smart_ant)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003906{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003907 pdrxj_data_t ext_attr = NULL;
3908 struct i2c_device_addr *dev_addr = NULL;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03003909 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003910 u32 start_time = 0;
3911 static bool bit_inverted;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003912
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003913 dev_addr = demod->my_i2c_dev_addr;
3914 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003915
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003916 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003917 if (smart_ant == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003918 return (DRX_STS_INVALID_ARG);
3919 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003920
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003921 if (bit_inverted != ext_attr->smart_ant_inverted
3922 || ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SMA) {
3923 CHK_ERROR(smart_ant_init(demod));
3924 bit_inverted = ext_attr->smart_ant_inverted;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003925 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003926
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003927 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003928 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003929
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003930 switch (smart_ant->io) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003931 case DRXJ_SMT_ANT_OUTPUT:
3932 /* enable Tx if Mode B (input) is supported */
3933 /*
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003934 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
3935 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003936 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003937 start_time = drxbsp_hst_clock();
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003938 do {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003939 RR16(dev_addr, SIO_SA_TX_STATUS__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003940 } while ((data & SIO_SA_TX_STATUS_BUSY__M)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003941 && ((drxbsp_hst_clock() - start_time) <
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003942 DRXJ_MAX_WAITTIME));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003943
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003944 if (data & SIO_SA_TX_STATUS_BUSY__M) {
3945 return (DRX_STS_ERROR);
3946 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003947
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003948 /* write to smart antenna configuration register */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003949 WR16(dev_addr, SIO_SA_TX_DATA0__A, 0x9200
3950 | ((smart_ant->ctrl_data & 0x0001) << 8)
3951 | ((smart_ant->ctrl_data & 0x0002) << 10)
3952 | ((smart_ant->ctrl_data & 0x0004) << 12)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003953 );
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003954 WR16(dev_addr, SIO_SA_TX_DATA1__A, 0x4924
3955 | ((smart_ant->ctrl_data & 0x0008) >> 2)
3956 | ((smart_ant->ctrl_data & 0x0010))
3957 | ((smart_ant->ctrl_data & 0x0020) << 2)
3958 | ((smart_ant->ctrl_data & 0x0040) << 4)
3959 | ((smart_ant->ctrl_data & 0x0080) << 6)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003960 );
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003961 WR16(dev_addr, SIO_SA_TX_DATA2__A, 0x2492
3962 | ((smart_ant->ctrl_data & 0x0100) >> 8)
3963 | ((smart_ant->ctrl_data & 0x0200) >> 6)
3964 | ((smart_ant->ctrl_data & 0x0400) >> 4)
3965 | ((smart_ant->ctrl_data & 0x0800) >> 2)
3966 | ((smart_ant->ctrl_data & 0x1000))
3967 | ((smart_ant->ctrl_data & 0x2000) << 2)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003968 );
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003969 WR16(dev_addr, SIO_SA_TX_DATA3__A, 0xff8d);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003970
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003971 /* trigger the sending */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003972 WR16(dev_addr, SIO_SA_TX_LENGTH__A, 56);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003973
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003974 break;
3975 case DRXJ_SMT_ANT_INPUT:
3976 /* disable Tx if Mode B (input) is supported */
3977 /*
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003978 RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
3979 WR16( dev_addr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003980 */
3981 default:
3982 return (DRX_STS_INVALID_ARG);
3983 }
3984 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003985 WR16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003986
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003987 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003988rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003989 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003990}
3991
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003992static int scu_command(struct i2c_device_addr *dev_addr, p_drxjscu_cmd_t cmd)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003993{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03003994 u16 cur_cmd = 0;
3995 u32 start_time = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03003996
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03003997 /* Check param */
3998 if (cmd == NULL)
3999 return (DRX_STS_INVALID_ARG);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004000
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004001 /* Wait until SCU command interface is ready to receive command */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004002 RR16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd);
4003 if (cur_cmd != DRX_SCU_READY) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004004 return (DRX_STS_ERROR);
4005 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004006
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004007 switch (cmd->parameter_len) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004008 case 5:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004009 WR16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4)); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004010 case 4:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004011 WR16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3)); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004012 case 3:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004013 WR16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2)); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004014 case 2:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004015 WR16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1)); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004016 case 1:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004017 WR16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0)); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004018 case 0:
4019 /* do nothing */
4020 break;
4021 default:
4022 /* this number of parameters is not supported */
4023 return (DRX_STS_ERROR);
4024 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004025 WR16(dev_addr, SCU_RAM_COMMAND__A, cmd->command);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004026
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004027 /* Wait until SCU has processed command */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004028 start_time = drxbsp_hst_clock();
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004029 do {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004030 RR16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd);
4031 } while (!(cur_cmd == DRX_SCU_READY)
4032 && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004033
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004034 if (cur_cmd != DRX_SCU_READY) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004035 return (DRX_STS_ERROR);
4036 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004037
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004038 /* read results */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004039 if ((cmd->result_len > 0) && (cmd->result != NULL)) {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004040 s16 err;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004041
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004042 switch (cmd->result_len) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004043 case 4:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004044 RR16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004045 case 3:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004046 RR16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004047 case 2:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004048 RR16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004049 case 1:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004050 RR16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0); /* fallthrough */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004051 case 0:
4052 /* do nothing */
4053 break;
4054 default:
4055 /* this number of parameters is not supported */
4056 return (DRX_STS_ERROR);
4057 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004058
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004059 /* Check if an error was reported by SCU */
4060 err = cmd->result[0];
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004061
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004062 /* check a few fixed error codes */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004063 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4064 || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4065 || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4066 || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004067 ) {
4068 return DRX_STS_INVALID_ARG;
4069 }
4070 /* here it is assumed that negative means error, and positive no error */
4071 else if (err < 0) {
4072 return DRX_STS_ERROR;
4073 } else {
4074 return DRX_STS_OK;
4075 }
4076 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004077
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004078 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004079
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004080rw_error:
4081 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004082}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004083
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004084/**
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004085* \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004086* \brief Basic access routine for SCU atomic read or write access
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004087* \param dev_addr pointer to i2c dev address
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004088* \param addr destination/source address
4089* \param datasize size of data buffer in bytes
4090* \param data pointer to data buffer
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004091* \return int
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004092* \retval DRX_STS_OK Succes
4093* \retval DRX_STS_ERROR Timeout, I2C error, illegal bank
4094*
4095*/
4096#define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4097static
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004098int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, dr_xaddr_t addr, u16 datasize, /* max 30 bytes because the limit of SCU parameter */
4099 u8 *data, bool read_flag)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004100{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004101 drxjscu_cmd_t scu_cmd;
4102 u16 set_param_parameters[15];
4103 u16 cmd_result[15];
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004104
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004105 /* Parameter check */
4106 if ((data == NULL) ||
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004107 (dev_addr == NULL) || ((datasize % 2) != 0) || ((datasize / 2) > 16)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004108 ) {
4109 return (DRX_STS_INVALID_ARG);
4110 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004111
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004112 set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4113 if (read_flag) { /* read */
4114 set_param_parameters[0] = ((~(0x0080)) & datasize);
4115 scu_cmd.parameter_len = 2;
4116 scu_cmd.result_len = datasize / 2 + 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004117 } else {
4118 int i = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004119
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004120 set_param_parameters[0] = 0x0080 | datasize;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004121 for (i = 0; i < (datasize / 2); i++) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004122 set_param_parameters[i + 2] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004123 (data[2 * i] | (data[(2 * i) + 1] << 8));
4124 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004125 scu_cmd.parameter_len = datasize / 2 + 2;
4126 scu_cmd.result_len = 1;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004127 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004128
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004129 scu_cmd.command =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004130 SCU_RAM_COMMAND_STANDARD_TOP |
4131 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004132 scu_cmd.result = cmd_result;
4133 scu_cmd.parameter = set_param_parameters;
4134 CHK_ERROR(scu_command(dev_addr, &scu_cmd));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004135
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004136 if (read_flag == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004137 int i = 0;
4138 /* read data from buffer */
4139 for (i = 0; i < (datasize / 2); i++) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004140 data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4141 data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004142 }
4143 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004144
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004145 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004146
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004147rw_error:
4148 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004149
4150}
4151
4152/*============================================================================*/
4153
4154/**
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004155* \fn int DRXJ_DAP_AtomicReadReg16()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004156* \brief Atomic read of 16 bits words
4157*/
4158static
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004159int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4160 dr_xaddr_t addr,
4161 u16 *data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004162{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004163 u8 buf[2];
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004164 int rc = DRX_STS_ERROR;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004165 u16 word = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004166
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004167 if (!data) {
4168 return DRX_STS_INVALID_ARG;
4169 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004170
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004171 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004172
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004173 word = (u16) (buf[0] + (buf[1] << 8));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004174
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004175 *data = word;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004176
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004177 return rc;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004178}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004179
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004180/*============================================================================*/
4181/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004182* \fn int drxj_dap_scu_atomic_write_reg16()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004183* \brief Atomic read of 16 bits words
4184*/
4185static
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004186int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4187 dr_xaddr_t addr,
4188 u16 data, dr_xflags_t flags)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004189{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004190 u8 buf[2];
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004191 int rc = DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004192
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004193 buf[0] = (u8) (data & 0xff);
4194 buf[1] = (u8) ((data >> 8) & 0xff);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004195
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004196 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004197
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004198 return rc;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004199}
4200
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004201static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004202ctrl_i2c_write_read(pdrx_demod_instance_t demod, pdrxi2c_data_t i2c_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004203{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004204 return (DRX_STS_FUNC_NOT_AVAILABLE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004205}
4206
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004207int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004208tuner_i2c_write_read(struct tuner_instance *tuner,
4209 struct i2c_device_addr *w_dev_addr,
4210 u16 w_count,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004211 u8 *wData,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004212 struct i2c_device_addr *r_dev_addr, u16 r_count, u8 *r_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004213{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004214 pdrx_demod_instance_t demod;
4215 drxi2c_data_t i2c_data =
4216 { 2, w_dev_addr, w_count, wData, r_dev_addr, r_count, r_data };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004217
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004218 demod = (pdrx_demod_instance_t) (tuner->my_common_attr->myUser_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004219
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004220 return (ctrl_i2c_write_read(demod, &i2c_data));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004221}
4222
4223/* -------------------------------------------------------------------------- */
4224/**
4225* \brief Measure result of ADC synchronisation
4226* \param demod demod instance
4227* \param count (returned) count
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004228* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004229* \retval DRX_STS_OK Success
4230* \retval DRX_STS_ERROR Failure: I2C error
4231*
4232*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004233static int adc_sync_measurement(pdrx_demod_instance_t demod, u16 *count)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004234{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004235 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004236 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004237
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004238 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004239
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004240 /* Start measurement */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004241 WR16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
4242 WR16(dev_addr, IQM_AF_START_LOCK__A, 1);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004243
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004244 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004245 CHK_ERROR(drxbsp_hst_sleep(1));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004246
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004247 *count = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004248 RR16(dev_addr, IQM_AF_PHASE0__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004249 if (data == 127) {
4250 *count = *count + 1;
4251 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004252 RR16(dev_addr, IQM_AF_PHASE1__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004253 if (data == 127) {
4254 *count = *count + 1;
4255 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004256 RR16(dev_addr, IQM_AF_PHASE2__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004257 if (data == 127) {
4258 *count = *count + 1;
4259 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004260
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004261 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004262rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004263 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004264}
4265
4266/**
4267* \brief Synchronize analog and digital clock domains
4268* \param demod demod instance
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004269* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004270* \retval DRX_STS_OK Success
4271* \retval DRX_STS_ERROR Failure: I2C error or failure to synchronize
4272*
4273* An IQM reset will also reset the results of this synchronization.
4274* After an IQM reset this routine needs to be called again.
4275*
4276*/
4277
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004278static int adc_synchronization(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004279{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004280 u16 count = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004281 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004282
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004283 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004284
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004285 CHK_ERROR(adc_sync_measurement(demod, &count));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004286
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004287 if (count == 1) {
4288 /* Try sampling on a diffrent edge */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004289 u16 clk_neg = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004290
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004291 RR16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004292
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004293 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4294 WR16(dev_addr, IQM_AF_CLKNEG__A, clk_neg);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004295
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004296 CHK_ERROR(adc_sync_measurement(demod, &count));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004297 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004298
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004299 if (count < 2) {
4300 /* TODO: implement fallback scenarios */
4301 return (DRX_STS_ERROR);
4302 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004303
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004304 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004305rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004306 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004307}
4308
4309/**
4310* \brief Configure IQM AF registers
4311* \param demod instance of demodulator.
4312* \param active
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004313* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004314*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004315static int iqm_set_af(pdrx_demod_instance_t demod, bool active)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004316{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004317 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004318 struct i2c_device_addr *dev_addr = NULL;
4319 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004320
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004321 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
4322 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004323
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004324 /* Configure IQM */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004325 RR16(dev_addr, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004326 if (!active) {
4327 data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE)
4328 & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE)
4329 & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE)
4330 & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE)
4331 & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE)
4332 );
4333 } else { /* active */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004334
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004335 data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE
4336 | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE
4337 | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE
4338 | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
4339 | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
4340 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004341 WR16(dev_addr, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004342
4343 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004344rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004345 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004346}
4347
4348/* -------------------------------------------------------------------------- */
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004349static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004350ctrl_set_cfg_atv_output(pdrx_demod_instance_t demod, p_drxj_cfg_atv_output_t output_cfg);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004351
4352/**
4353* \brief set configuration of pin-safe mode
4354* \param demod instance of demodulator.
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03004355* \param enable boolean; true: activate pin-safe mode, false: de-activate p.s.m.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004356* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004357*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004358static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004359ctrl_set_cfg_pdr_safe_mode(pdrx_demod_instance_t demod, bool *enable)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004360{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004361 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
4362 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
4363 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004364
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004365 if (enable == NULL) {
4366 return (DRX_STS_INVALID_ARG);
4367 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004368
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004369 dev_addr = demod->my_i2c_dev_addr;
4370 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
4371 common_attr = demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004372
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004373 /* Write magic word to enable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004374 WR16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004375
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03004376 if (*enable == true) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004377 bool bridge_enabled = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004378
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004379 /* MPEG pins to input */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004380 WR16(dev_addr, SIO_PDR_MSTRT_CFG__A, DRXJ_PIN_SAFE_MODE);
4381 WR16(dev_addr, SIO_PDR_MERR_CFG__A, DRXJ_PIN_SAFE_MODE);
4382 WR16(dev_addr, SIO_PDR_MCLK_CFG__A, DRXJ_PIN_SAFE_MODE);
4383 WR16(dev_addr, SIO_PDR_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE);
4384 WR16(dev_addr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE);
4385 WR16(dev_addr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE);
4386 WR16(dev_addr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE);
4387 WR16(dev_addr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE);
4388 WR16(dev_addr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE);
4389 WR16(dev_addr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE);
4390 WR16(dev_addr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE);
4391 WR16(dev_addr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004392
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004393 /* PD_I2C_SDA2 Bridge off, Port2 Inactive
4394 PD_I2C_SCL2 Bridge off, Port2 Inactive */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004395 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_enabled));
4396 WR16(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, DRXJ_PIN_SAFE_MODE);
4397 WR16(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004398
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004399 /* PD_GPIO Store and set to input
4400 PD_VSYNC Store and set to input
4401 PD_SMA_RX Store and set to input
4402 PD_SMA_TX Store and set to input */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004403 RR16(dev_addr, SIO_PDR_GPIO_CFG__A,
4404 &ext_attr->pdr_safe_restore_val_gpio);
4405 RR16(dev_addr, SIO_PDR_VSYNC_CFG__A,
4406 &ext_attr->pdr_safe_restore_val_v_sync);
4407 RR16(dev_addr, SIO_PDR_SMA_RX_CFG__A,
4408 &ext_attr->pdr_safe_restore_val_sma_rx);
4409 RR16(dev_addr, SIO_PDR_SMA_TX_CFG__A,
4410 &ext_attr->pdr_safe_restore_val_sma_tx);
4411 WR16(dev_addr, SIO_PDR_GPIO_CFG__A, DRXJ_PIN_SAFE_MODE);
4412 WR16(dev_addr, SIO_PDR_VSYNC_CFG__A, DRXJ_PIN_SAFE_MODE);
4413 WR16(dev_addr, SIO_PDR_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE);
4414 WR16(dev_addr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004415
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004416 /* PD_RF_AGC Analog DAC outputs, cannot be set to input or tristate!
4417 PD_IF_AGC Analog DAC outputs, cannot be set to input or tristate! */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004418 CHK_ERROR(iqm_set_af(demod, false));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004419
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004420 /* PD_CVBS Analog DAC output, standby mode
4421 PD_SIF Analog DAC output, standby mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004422 WR16(dev_addr, ATV_TOP_STDBY__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004423 (ATV_TOP_STDBY_SIF_STDBY_STANDBY &
4424 (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004425
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004426 /* PD_I2S_CL Input
4427 PD_I2S_DA Input
4428 PD_I2S_WS Input */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004429 WR16(dev_addr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE);
4430 WR16(dev_addr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE);
4431 WR16(dev_addr, SIO_PDR_I2S_WS_CFG__A, DRXJ_PIN_SAFE_MODE);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004432 } else {
4433 /* No need to restore MPEG pins;
4434 is done in SetStandard/SetChannel */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004435
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004436 /* PD_I2C_SDA2 Port2 active
4437 PD_I2C_SCL2 Port2 active */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004438 WR16(dev_addr, SIO_PDR_I2C_SDA2_CFG__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004439 SIO_PDR_I2C_SDA2_CFG__PRE);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004440 WR16(dev_addr, SIO_PDR_I2C_SCL2_CFG__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004441 SIO_PDR_I2C_SCL2_CFG__PRE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004442
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004443 /* PD_GPIO Restore
4444 PD_VSYNC Restore
4445 PD_SMA_RX Restore
4446 PD_SMA_TX Restore */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004447 WR16(dev_addr, SIO_PDR_GPIO_CFG__A,
4448 ext_attr->pdr_safe_restore_val_gpio);
4449 WR16(dev_addr, SIO_PDR_VSYNC_CFG__A,
4450 ext_attr->pdr_safe_restore_val_v_sync);
4451 WR16(dev_addr, SIO_PDR_SMA_RX_CFG__A,
4452 ext_attr->pdr_safe_restore_val_sma_rx);
4453 WR16(dev_addr, SIO_PDR_SMA_TX_CFG__A,
4454 ext_attr->pdr_safe_restore_val_sma_tx);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004455
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004456 /* PD_RF_AGC, PD_IF_AGC
4457 No need to restore; will be restored in SetStandard/SetChannel */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004458
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004459 /* PD_CVBS, PD_SIF
4460 No need to restore; will be restored in SetStandard/SetChannel */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004461
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004462 /* PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
4463 Should be restored via DRX_CTRL_SET_AUD */
4464 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004465
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004466 /* Write magic word to disable pdr reg write */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004467 WR16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000);
4468 ext_attr->pdr_safe_mode = *enable;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004469
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004470 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004471
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004472rw_error:
4473 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004474}
4475
4476/* -------------------------------------------------------------------------- */
4477
4478/**
4479* \brief get configuration of pin-safe mode
4480* \param demod instance of demodulator.
4481* \param enable boolean indicating whether pin-safe mode is active
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004482* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004483*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004484static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004485ctrl_get_cfg_pdr_safe_mode(pdrx_demod_instance_t demod, bool *enabled)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004486{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004487 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004488
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004489 if (enabled == NULL) {
4490 return (DRX_STS_INVALID_ARG);
4491 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004492
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004493 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
4494 *enabled = ext_attr->pdr_safe_mode;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004495
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004496 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004497}
4498
4499/**
4500* \brief Verifies whether microcode can be loaded.
4501* \param demod Demodulator instance.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004502* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004503*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004504static int ctrl_validate_u_code(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004505{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004506 u32 mc_dev, mc_patch;
4507 u16 ver_type;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004508
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004509 /* Check device.
4510 * Disallow microcode if:
4511 * - MC has version record AND
4512 * - device ID in version record is not 0 AND
4513 * - product ID in version record's device ID does not
4514 * match DRXJ1 product IDs - 0x393 or 0x394
4515 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004516 DRX_GET_MCVERTYPE(demod, ver_type);
4517 DRX_GET_MCDEV(demod, mc_dev);
4518 DRX_GET_MCPATCH(demod, mc_patch);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004519
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004520 if (DRX_ISMCVERTYPE(ver_type)) {
4521 if ((mc_dev != 0) &&
4522 (((mc_dev >> 16) & 0xFFF) != 0x393) &&
4523 (((mc_dev >> 16) & 0xFFF) != 0x394)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004524 /* Microcode is marked for another device - error */
4525 return DRX_STS_INVALID_ARG;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004526 } else if (mc_patch != 0) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004527 /* Patch not allowed because there is no ROM */
4528 return DRX_STS_INVALID_ARG;
4529 }
4530 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004531
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004532 /* Everything else: OK */
4533 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004534}
4535
4536/*============================================================================*/
4537/*== END AUXILIARY FUNCTIONS ==*/
4538/*============================================================================*/
4539
4540/*============================================================================*/
4541/*============================================================================*/
4542/*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
4543/*============================================================================*/
4544/*============================================================================*/
4545/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004546* \fn int init_agc ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004547* \brief Initialize AGC for all standards.
4548* \param demod instance of demodulator.
4549* \param channel pointer to channel data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004550* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004551*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004552static int init_agc(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004553{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004554 struct i2c_device_addr *dev_addr = NULL;
4555 pdrx_common_attr_t common_attr = NULL;
4556 pdrxj_data_t ext_attr = NULL;
4557 p_drxj_cfg_agc_t p_agc_rf_settings = NULL;
4558 p_drxj_cfg_agc_t p_agc_if_settings = NULL;
4559 u16 ingain_tgt_max = 0;
4560 u16 clp_dir_to = 0;
4561 u16 sns_sum_max = 0;
4562 u16 clp_sum_max = 0;
4563 u16 sns_dir_to = 0;
4564 u16 ki_innergain_min = 0;
4565 u16 agc_ki = 0;
4566 u16 ki_max = 0;
4567 u16 if_iaccu_hi_tgt_min = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004568 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004569 u16 agc_kiDgain = 0;
4570 u16 ki_min = 0;
4571 u16 clp_ctrl_mode = 0;
4572 u16 agc_rf = 0;
4573 u16 agc_if = 0;
4574 dev_addr = demod->my_i2c_dev_addr;
4575 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
4576 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004577
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004578 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004579 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004580 clp_sum_max = 1023;
4581 clp_dir_to = (u16) (-9);
4582 sns_sum_max = 1023;
4583 sns_dir_to = (u16) (-9);
4584 ki_innergain_min = (u16) (-32768);
4585 ki_max = 0x032C;
4586 agc_kiDgain = 0xC;
4587 if_iaccu_hi_tgt_min = 2047;
4588 ki_min = 0x0117;
4589 ingain_tgt_max = 16383;
4590 clp_ctrl_mode = 0;
4591 WR16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
4592 WR16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
4593 WR16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0);
4594 WR16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
4595 WR16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
4596 WR16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
4597 WR16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0);
4598 WR16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
4599 WR16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
4600 WR16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
4601 WR16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024);
4602 WR16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600);
4603 WR16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200);
4604 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
4605 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004606 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004607#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004608 case DRX_STANDARD_ITU_A:
4609 case DRX_STANDARD_ITU_C:
4610 case DRX_STANDARD_ITU_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004611 ingain_tgt_max = 5119;
4612 clp_sum_max = 1023;
4613 clp_dir_to = (u16) (-5);
4614 sns_sum_max = 127;
4615 sns_dir_to = (u16) (-3);
4616 ki_innergain_min = 0;
4617 ki_max = 0x0657;
4618 if_iaccu_hi_tgt_min = 2047;
4619 agc_kiDgain = 0x7;
4620 ki_min = 0x0117;
4621 clp_ctrl_mode = 0;
4622 WR16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
4623 WR16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
4624 WR16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0);
4625 WR16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
4626 WR16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
4627 WR16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
4628 WR16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0);
4629 WR16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
4630 WR16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
4631 WR16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
4632 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
4633 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
4634 WR16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004635
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004636 RR16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki);
4637 agc_ki &= 0xf000;
4638 WR16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004639 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004640#endif
4641#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004642 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004643 clp_sum_max = 1023;
4644 sns_sum_max = 1023;
4645 ki_innergain_min = (u16) (-32768);
4646 if_iaccu_hi_tgt_min = 2047;
4647 agc_kiDgain = 0x7;
4648 ki_min = 0x0225;
4649 ki_max = 0x0547;
4650 clp_dir_to = (u16) (-9);
4651 sns_dir_to = (u16) (-9);
4652 ingain_tgt_max = 9000;
4653 clp_ctrl_mode = 1;
4654 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
4655 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
4656 WR16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004657 break;
4658 case DRX_STANDARD_NTSC:
4659 case DRX_STANDARD_PAL_SECAM_BG:
4660 case DRX_STANDARD_PAL_SECAM_DK:
4661 case DRX_STANDARD_PAL_SECAM_I:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004662 clp_sum_max = 1023;
4663 sns_sum_max = 1023;
4664 ki_innergain_min = (u16) (-32768);
4665 if_iaccu_hi_tgt_min = 2047;
4666 agc_kiDgain = 0x7;
4667 ki_min = 0x0225;
4668 ki_max = 0x0547;
4669 clp_dir_to = (u16) (-9);
4670 ingain_tgt_max = 9000;
4671 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
4672 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
4673 sns_dir_to = (u16) (-9);
4674 clp_ctrl_mode = 1;
4675 WR16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004676 break;
4677 case DRX_STANDARD_PAL_SECAM_L:
4678 case DRX_STANDARD_PAL_SECAM_LP:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004679 clp_sum_max = 1023;
4680 sns_sum_max = 1023;
4681 ki_innergain_min = (u16) (-32768);
4682 if_iaccu_hi_tgt_min = 2047;
4683 agc_kiDgain = 0x7;
4684 ki_min = 0x0225;
4685 ki_max = 0x0547;
4686 clp_dir_to = (u16) (-9);
4687 sns_dir_to = (u16) (-9);
4688 ingain_tgt_max = 9000;
4689 clp_ctrl_mode = 1;
4690 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
4691 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
4692 WR16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004693 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004694#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004695 default:
4696 return (DRX_STS_INVALID_ARG);
4697 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004698
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004699 /* for new AGC interface */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004700 WR16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top);
4701 WR16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top); /* Gain fed from inner to outer AGC */
4702 WR16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
4703 WR16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min);
4704 WR16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0); /* set to p_agc_settings->top before */
4705 WR16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
4706 WR16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
4707 WR16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
4708 WR16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767);
4709 WR16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
4710 WR16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
4711 WR16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min);
4712 WR16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
4713 WR16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500);
4714 WR16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
4715 WR16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
4716 WR16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min);
4717 WR16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max);
4718 WR16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0);
4719 WR16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8);
4720 WR16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500);
4721 WR16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
4722 WR16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8);
4723 WR16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
4724 WR16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50);
4725 WR16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004726
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004727 agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
4728 if (common_attr->tuner_rf_agc_pol == true) {
4729 agc_rf = 0x87ff - agc_rf;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004730 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004731
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004732 agc_if = 0x800;
4733 if (common_attr->tuner_if_agc_pol == true) {
4734 agc_rf = 0x87ff - agc_rf;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004735 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004736
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004737 WR16(dev_addr, IQM_AF_AGC_RF__A, agc_rf);
4738 WR16(dev_addr, IQM_AF_AGC_IF__A, agc_if);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004739
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004740 /* Set/restore Ki DGAIN factor */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004741 RR16(dev_addr, SCU_RAM_AGC_KI__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004742 data &= ~SCU_RAM_AGC_KI_DGAIN__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004743 data |= (agc_kiDgain << SCU_RAM_AGC_KI_DGAIN__B);
4744 WR16(dev_addr, SCU_RAM_AGC_KI__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004745
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004746 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004747rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004748 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004749}
4750
4751/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004752* \fn int set_frequency ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004753* \brief Set frequency shift.
4754* \param demod instance of demodulator.
4755* \param channel pointer to channel data.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004756* \param tuner_freq_offset residual frequency from tuner.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004757* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004758*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004759static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004760set_frequency(pdrx_demod_instance_t demod,
4761 pdrx_channel_t channel, s32 tuner_freq_offset)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004762{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004763 struct i2c_device_addr *dev_addr = NULL;
4764 pdrx_common_attr_t common_attr = NULL;
4765 s32 sampling_frequency = 0;
4766 s32 frequency_shift = 0;
4767 s32 if_freq_actual = 0;
4768 s32 rf_freq_residual = 0;
4769 s32 adc_freq = 0;
4770 s32 intermediate_freq = 0;
4771 u32 iqm_fs_rate_ofs = 0;
4772 pdrxj_data_t ext_attr = NULL;
4773 bool adc_flip = true;
4774 bool select_pos_image = false;
4775 bool rf_mirror = false;
4776 bool tuner_mirror = true;
4777 bool image_to_select = true;
4778 s32 fm_frequency_shift = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004779
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004780 dev_addr = demod->my_i2c_dev_addr;
4781 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
4782 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
4783 rf_freq_residual = -1 * tuner_freq_offset;
4784 rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
4785 tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004786 /*
4787 Program frequency shifter
4788 No need to account for mirroring on RF
4789 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004790 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004791 case DRX_STANDARD_ITU_A: /* fallthrough */
4792 case DRX_STANDARD_ITU_C: /* fallthrough */
4793 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
4794 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004795 select_pos_image = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004796 break;
4797 case DRX_STANDARD_FM:
4798 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
4799 Sound carrier is already 3Mhz above centre frequency due
4800 to tuner setting so now add an extra shift of 1MHz... */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004801 fm_frequency_shift = 1000;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004802 case DRX_STANDARD_ITU_B: /* fallthrough */
4803 case DRX_STANDARD_NTSC: /* fallthrough */
4804 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
4805 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
4806 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
4807 case DRX_STANDARD_PAL_SECAM_L:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004808 select_pos_image = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004809 break;
4810 default:
4811 return (DRX_STS_INVALID_ARG);
4812 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004813 intermediate_freq = demod->my_common_attr->intermediate_freq;
4814 sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
4815 if (tuner_mirror == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004816 /* tuner doesn't mirror */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004817 if_freq_actual =
4818 intermediate_freq + rf_freq_residual + fm_frequency_shift;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004819 } else {
4820 /* tuner mirrors */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004821 if_freq_actual =
4822 intermediate_freq - rf_freq_residual - fm_frequency_shift;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004823 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004824 if (if_freq_actual > sampling_frequency / 2) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004825 /* adc mirrors */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004826 adc_freq = sampling_frequency - if_freq_actual;
4827 adc_flip = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004828 } else {
4829 /* adc doesn't mirror */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004830 adc_freq = if_freq_actual;
4831 adc_flip = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004832 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004833
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004834 frequency_shift = adc_freq;
4835 image_to_select =
4836 (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
4837 iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004838
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004839 if (image_to_select)
4840 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004841
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004842 /* Program frequency shifter with tuner offset compensation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004843 /* frequency_shift += tuner_freq_offset; TODO */
4844 WR32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs);
4845 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
4846 ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004847
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004848 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004849rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004850 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004851}
4852
4853/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004854* \fn int get_sig_strength()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004855* \brief Retrieve signal strength for VSB and QAM.
4856* \param demod Pointer to demod instance
4857* \param u16-t Pointer to signal strength data; range 0, .. , 100.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004858* \return int.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004859* \retval DRX_STS_OK sig_strength contains valid data.
4860* \retval DRX_STS_INVALID_ARG sig_strength is NULL.
4861* \retval DRX_STS_ERROR Erroneous data, sig_strength contains invalid data.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004862*/
4863#define DRXJ_AGC_TOP 0x2800
4864#define DRXJ_AGC_SNS 0x1600
4865#define DRXJ_RFAGC_MAX 0x3fff
4866#define DRXJ_RFAGC_MIN 0x800
4867
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004868static int get_sig_strength(pdrx_demod_instance_t demod, u16 *sig_strength)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004869{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004870 u16 rf_gain = 0;
4871 u16 if_gain = 0;
4872 u16 if_agc_sns = 0;
4873 u16 if_agc_top = 0;
4874 u16 rf_agc_max = 0;
4875 u16 rf_agc_min = 0;
4876 pdrxj_data_t ext_attr = NULL;
4877 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004878
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004879 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
4880 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004881
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004882 RR16(dev_addr, IQM_AF_AGC_IF__A, &if_gain);
4883 if_gain &= IQM_AF_AGC_IF__M;
4884 RR16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain);
4885 rf_gain &= IQM_AF_AGC_RF__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004886
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004887 if_agc_sns = DRXJ_AGC_SNS;
4888 if_agc_top = DRXJ_AGC_TOP;
4889 rf_agc_max = DRXJ_RFAGC_MAX;
4890 rf_agc_min = DRXJ_RFAGC_MIN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004891
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004892 if (if_gain > if_agc_top) {
4893 if (rf_gain > rf_agc_max)
4894 *sig_strength = 100;
4895 else if (rf_gain > rf_agc_min) {
4896 CHK_ZERO(rf_agc_max - rf_agc_min);
4897 *sig_strength =
4898 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
4899 rf_agc_min);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004900 } else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004901 *sig_strength = 75;
4902 } else if (if_gain > if_agc_sns) {
4903 CHK_ZERO(if_agc_top - if_agc_sns);
4904 *sig_strength =
4905 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004906 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004907 CHK_ZERO(if_agc_sns);
4908 *sig_strength = (20 * if_gain / if_agc_sns);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004909 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004910
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004911 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004912rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004913 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004914}
4915
4916/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004917* \fn int get_acc_pkt_err()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004918* \brief Retrieve signal strength for VSB and QAM.
4919* \param demod Pointer to demod instance
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004920* \param packet_err Pointer to packet error
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004921* \return int.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004922* \retval DRX_STS_OK sig_strength contains valid data.
4923* \retval DRX_STS_INVALID_ARG sig_strength is NULL.
4924* \retval DRX_STS_ERROR Erroneous data, sig_strength contains invalid data.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004925*/
4926#ifdef DRXJ_SIGNAL_ACCUM_ERR
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004927static int get_acc_pkt_err(pdrx_demod_instance_t demod, u16 *packet_err)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004928{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004929 static u16 pkt_err;
4930 static u16 last_pkt_err;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03004931 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004932 pdrxj_data_t ext_attr = NULL;
4933 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004934
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004935 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
4936 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004937
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004938 RR16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data);
4939 if (ext_attr->reset_pkt_err_acc == true) {
4940 last_pkt_err = data;
4941 pkt_err = 0;
4942 ext_attr->reset_pkt_err_acc = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004943 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004944
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004945 if (data < last_pkt_err) {
4946 pkt_err += 0xffff - last_pkt_err;
4947 pkt_err += data;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004948 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004949 pkt_err += (data - last_pkt_err);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004950 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004951 *packet_err = pkt_err;
4952 last_pkt_err = data;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004953
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004954 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004955rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004956 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004957}
4958#endif
4959
4960/**
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004961* \fn int ResetAccPktErr()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004962* \brief Reset Accumulating packet error count.
4963* \param demod Pointer to demod instance
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004964* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004965* \retval DRX_STS_OK.
4966* \retval DRX_STS_ERROR Erroneous data.
4967*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004968static int ctrl_set_cfg_reset_pkt_err(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004969{
4970#ifdef DRXJ_SIGNAL_ACCUM_ERR
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004971 pdrxj_data_t ext_attr = NULL;
4972 u16 packet_error = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004973
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004974 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
4975 ext_attr->reset_pkt_err_acc = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004976 /* call to reset counter */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004977 CHK_ERROR(get_acc_pkt_err(demod, &packet_error));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004978
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004979 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004980rw_error:
4981#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03004982 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004983}
4984
4985/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004986* \fn static short get_str_freq_offset()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004987* \brief Get symbol rate offset in QAM & 8VSB mode
4988* \return Error code
4989*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004990static int get_str_freq_offset(pdrx_demod_instance_t demod, s32 *str_freq)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004991{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004992 u32 symbol_frequency_ratio = 0;
4993 u32 symbol_nom_frequency_ratio = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004994
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03004995 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004996 struct i2c_device_addr *dev_addr = NULL;
4997 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03004998
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03004999 dev_addr = demod->my_i2c_dev_addr;
5000 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
5001 standard = ext_attr->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005002
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005003 ARR32(dev_addr, IQM_RC_RATE_LO__A, &symbol_frequency_ratio);
5004 symbol_nom_frequency_ratio = ext_attr->iqm_rc_rate_ofs;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005005
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005006 if (symbol_frequency_ratio > symbol_nom_frequency_ratio)
5007 *str_freq =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005008 -1 *
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005009 frac_times1e6((symbol_frequency_ratio -
5010 symbol_nom_frequency_ratio),
5011 (symbol_frequency_ratio + (1 << 23)));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005012 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005013 *str_freq =
5014 frac_times1e6((symbol_nom_frequency_ratio -
5015 symbol_frequency_ratio),
5016 (symbol_frequency_ratio + (1 << 23)));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005017
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005018 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005019rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005020 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005021}
5022
5023/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005024* \fn static short get_ctl_freq_offset
5025* \brief Get the value of ctl_freq in QAM & ATSC mode
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005026* \return Error code
5027*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005028static int get_ctl_freq_offset(pdrx_demod_instance_t demod, s32 *ctl_freq)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005029{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005030 s32 sampling_frequency = 0;
5031 s32 current_frequency = 0;
5032 s32 nominal_frequency = 0;
5033 s32 carrier_frequency_shift = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005034 s32 sign = 1;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005035 u32 data64hi = 0;
5036 u32 data64lo = 0;
5037 pdrxj_data_t ext_attr = NULL;
5038 pdrx_common_attr_t common_attr = NULL;
5039 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005040
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005041 dev_addr = demod->my_i2c_dev_addr;
5042 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
5043 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005044
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005045 sampling_frequency = common_attr->sys_clock_freq / 3;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005046
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005047 /* both registers are sign extended */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005048 nominal_frequency = ext_attr->iqm_fs_rate_ofs;
5049 ARR32(dev_addr, IQM_FS_RATE_LO__A, (u32 *) &current_frequency);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005050
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005051 if (ext_attr->pos_image == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005052 /* negative image */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005053 carrier_frequency_shift = nominal_frequency - current_frequency;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005054 } else {
5055 /* positive image */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005056 carrier_frequency_shift = current_frequency - nominal_frequency;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005057 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005058
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005059 /* carrier Frequency Shift In Hz */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005060 if (carrier_frequency_shift < 0) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005061 sign = -1;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005062 carrier_frequency_shift *= sign;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005063 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005064
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005065 /* *ctl_freq = carrier_frequency_shift * 50.625e6 / (1 << 28); */
5066 mult32(carrier_frequency_shift, sampling_frequency, &data64hi, &data64lo);
5067 *ctl_freq =
5068 (s32) ((((data64lo >> 28) & 0xf) | (data64hi << 4)) * sign);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005069
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005070 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005071rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005072 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005073}
5074
5075/*============================================================================*/
5076
5077/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005078* \fn int set_agc_rf ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005079* \brief Configure RF AGC
5080* \param demod instance of demodulator.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005081* \param agc_settings AGC configuration structure
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005082* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005083*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005084static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005085set_agc_rf(pdrx_demod_instance_t demod, p_drxj_cfg_agc_t agc_settings, bool atomic)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005086{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005087 struct i2c_device_addr *dev_addr = NULL;
5088 pdrxj_data_t ext_attr = NULL;
5089 p_drxj_cfg_agc_t p_agc_settings = NULL;
5090 pdrx_common_attr_t common_attr = NULL;
5091 drx_write_reg16func_t scu_wr16 = NULL;
5092 drx_read_reg16func_t scu_rr16 = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005093
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005094 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
5095 dev_addr = demod->my_i2c_dev_addr;
5096 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005097
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005098 if (atomic) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005099 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
5100 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005101 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005102 scu_rr16 = DRXJ_DAP.read_reg16func;
5103 scu_wr16 = DRXJ_DAP.write_reg16func;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005104 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005105
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005106 /* Configure AGC only if standard is currently active */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005107 if ((ext_attr->standard == agc_settings->standard) ||
5108 (DRXJ_ISQAMSTD(ext_attr->standard) &&
5109 DRXJ_ISQAMSTD(agc_settings->standard)) ||
5110 (DRXJ_ISATVSTD(ext_attr->standard) &&
5111 DRXJ_ISATVSTD(agc_settings->standard))) {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005112 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005113
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005114 switch (agc_settings->ctrl_mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005115 case DRX_AGC_CTRL_AUTO:
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005116
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005117 /* Enable RF AGC DAC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005118 RR16(dev_addr, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005119 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005120 WR16(dev_addr, IQM_AF_STDBY__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005121
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005122 /* Enable SCU RF AGC loop */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005123 CHK_ERROR((*scu_rr16)
5124 (dev_addr, SCU_RAM_AGC_KI__A, &data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005125 data &= ~SCU_RAM_AGC_KI_RF__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005126 if (ext_attr->standard == DRX_STANDARD_8VSB) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005127 data |= (2 << SCU_RAM_AGC_KI_RF__B);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005128 } else if (DRXJ_ISQAMSTD(ext_attr->standard)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005129 data |= (5 << SCU_RAM_AGC_KI_RF__B);
5130 } else {
5131 data |= (4 << SCU_RAM_AGC_KI_RF__B);
5132 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005133
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005134 if (common_attr->tuner_rf_agc_pol) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005135 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
5136 } else {
5137 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
5138 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005139 CHK_ERROR((*scu_wr16)
5140 (dev_addr, SCU_RAM_AGC_KI__A, data, 0));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005141
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005142 /* Set speed ( using complementary reduction value ) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005143 CHK_ERROR((*scu_rr16)
5144 (dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005145 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005146 CHK_ERROR((*scu_wr16) (dev_addr, SCU_RAM_AGC_KI_RED__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005147 (~
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005148 (agc_settings->
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005149 speed <<
5150 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
5151& SCU_RAM_AGC_KI_RED_RAGC_RED__M)
5152 | data, 0));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005153
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005154 if (agc_settings->standard == DRX_STANDARD_8VSB)
5155 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
5156 else if (DRXJ_ISQAMSTD(agc_settings->standard))
5157 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
5158 else if (DRXJ_ISATVSTD(agc_settings->standard))
5159 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005160 else
5161 return (DRX_STS_INVALID_ARG);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005162
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005163 /* Set TOP, only if IF-AGC is in AUTO mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005164 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5165 CHK_ERROR((*scu_wr16)
5166 (dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005167 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005168 agc_settings->top, 0));
5169 CHK_ERROR((*scu_wr16)
5170 (dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005171 SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005172 agc_settings->top, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005173 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005174
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005175 /* Cut-Off current */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005176 CHK_ERROR((*scu_wr16)
5177 (dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
5178 agc_settings->cut_off_current, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005179 break;
5180 case DRX_AGC_CTRL_USER:
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005181
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005182 /* Enable RF AGC DAC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005183 RR16(dev_addr, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005184 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005185 WR16(dev_addr, IQM_AF_STDBY__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005186
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005187 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005188 CHK_ERROR((*scu_rr16)
5189 (dev_addr, SCU_RAM_AGC_KI__A, &data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005190 data &= ~SCU_RAM_AGC_KI_RF__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005191 if (common_attr->tuner_rf_agc_pol) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005192 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
5193 } else {
5194 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
5195 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005196 CHK_ERROR((*scu_wr16)
5197 (dev_addr, SCU_RAM_AGC_KI__A, data, 0));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005198
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005199 /* Write value to output pin */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005200 CHK_ERROR((*scu_wr16)
5201 (dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A,
5202 agc_settings->output_level, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005203 break;
5204 case DRX_AGC_CTRL_OFF:
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005205
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005206 /* Disable RF AGC DAC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005207 RR16(dev_addr, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005208 data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005209 WR16(dev_addr, IQM_AF_STDBY__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005210
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005211 /* Disable SCU RF AGC loop */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005212 CHK_ERROR((*scu_rr16)
5213 (dev_addr, SCU_RAM_AGC_KI__A, &data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005214 data &= ~SCU_RAM_AGC_KI_RF__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005215 CHK_ERROR((*scu_wr16)
5216 (dev_addr, SCU_RAM_AGC_KI__A, data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005217 break;
5218 default:
5219 return (DRX_STS_INVALID_ARG);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005220 } /* switch ( agcsettings->ctrl_mode ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005221 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005222
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005223 /* Store rf agc settings */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005224 switch (agc_settings->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005225 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005226 ext_attr->vsb_rf_agc_cfg = *agc_settings;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005227 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005228#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005229 case DRX_STANDARD_ITU_A:
5230 case DRX_STANDARD_ITU_B:
5231 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005232 ext_attr->qam_rf_agc_cfg = *agc_settings;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005233 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005234#endif
5235#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005236 case DRX_STANDARD_PAL_SECAM_BG:
5237 case DRX_STANDARD_PAL_SECAM_DK:
5238 case DRX_STANDARD_PAL_SECAM_I:
5239 case DRX_STANDARD_PAL_SECAM_L:
5240 case DRX_STANDARD_PAL_SECAM_LP:
5241 case DRX_STANDARD_NTSC:
5242 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005243 ext_attr->atv_rf_agc_cfg = *agc_settings;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005244 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005245#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005246 default:
5247 return (DRX_STS_ERROR);
5248 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005249
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005250 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005251rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005252 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005253}
5254
5255/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005256* \fn int get_agc_rf ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005257* \brief get configuration of RF AGC
5258* \param demod instance of demodulator.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005259* \param agc_settings AGC configuration structure
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005260* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005261*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005262static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005263get_agc_rf(pdrx_demod_instance_t demod, p_drxj_cfg_agc_t agc_settings)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005264{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005265 struct i2c_device_addr *dev_addr = NULL;
5266 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005267 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005268
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005269 dev_addr = demod->my_i2c_dev_addr;
5270 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005271
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005272 /* Return stored AGC settings */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005273 standard = agc_settings->standard;
5274 switch (agc_settings->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005275 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005276 *agc_settings = ext_attr->vsb_rf_agc_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005277 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005278#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005279 case DRX_STANDARD_ITU_A:
5280 case DRX_STANDARD_ITU_B:
5281 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005282 *agc_settings = ext_attr->qam_rf_agc_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005283 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005284#endif
5285#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005286 case DRX_STANDARD_PAL_SECAM_BG:
5287 case DRX_STANDARD_PAL_SECAM_DK:
5288 case DRX_STANDARD_PAL_SECAM_I:
5289 case DRX_STANDARD_PAL_SECAM_L:
5290 case DRX_STANDARD_PAL_SECAM_LP:
5291 case DRX_STANDARD_NTSC:
5292 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005293 *agc_settings = ext_attr->atv_rf_agc_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005294 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005295#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005296 default:
5297 return (DRX_STS_ERROR);
5298 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005299 agc_settings->standard = standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005300
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005301 /* Get AGC output only if standard is currently active. */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005302 if ((ext_attr->standard == agc_settings->standard) ||
5303 (DRXJ_ISQAMSTD(ext_attr->standard) &&
5304 DRXJ_ISQAMSTD(agc_settings->standard)) ||
5305 (DRXJ_ISATVSTD(ext_attr->standard) &&
5306 DRXJ_ISATVSTD(agc_settings->standard))) {
5307 SARR16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A,
5308 &(agc_settings->output_level));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005309 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005310
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005311 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005312rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005313 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005314}
5315
5316/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005317* \fn int set_agc_if ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005318* \brief Configure If AGC
5319* \param demod instance of demodulator.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005320* \param agc_settings AGC configuration structure
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005321* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005322*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005323static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005324set_agc_if(pdrx_demod_instance_t demod, p_drxj_cfg_agc_t agc_settings, bool atomic)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005325{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005326 struct i2c_device_addr *dev_addr = NULL;
5327 pdrxj_data_t ext_attr = NULL;
5328 p_drxj_cfg_agc_t p_agc_settings = NULL;
5329 pdrx_common_attr_t common_attr = NULL;
5330 drx_write_reg16func_t scu_wr16 = NULL;
5331 drx_read_reg16func_t scu_rr16 = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005332
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005333 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
5334 dev_addr = demod->my_i2c_dev_addr;
5335 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005336
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005337 if (atomic) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005338 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
5339 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005340 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005341 scu_rr16 = DRXJ_DAP.read_reg16func;
5342 scu_wr16 = DRXJ_DAP.write_reg16func;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005343 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005344
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005345 /* Configure AGC only if standard is currently active */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005346 if ((ext_attr->standard == agc_settings->standard) ||
5347 (DRXJ_ISQAMSTD(ext_attr->standard) &&
5348 DRXJ_ISQAMSTD(agc_settings->standard)) ||
5349 (DRXJ_ISATVSTD(ext_attr->standard) &&
5350 DRXJ_ISATVSTD(agc_settings->standard))) {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005351 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005352
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005353 switch (agc_settings->ctrl_mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005354 case DRX_AGC_CTRL_AUTO:
5355 /* Enable IF AGC DAC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005356 RR16(dev_addr, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005357 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005358 WR16(dev_addr, IQM_AF_STDBY__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005359
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005360 /* Enable SCU IF AGC loop */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005361 CHK_ERROR((*scu_rr16)
5362 (dev_addr, SCU_RAM_AGC_KI__A, &data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005363 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5364 data &= ~SCU_RAM_AGC_KI_IF__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005365 if (ext_attr->standard == DRX_STANDARD_8VSB) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005366 data |= (3 << SCU_RAM_AGC_KI_IF__B);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005367 } else if (DRXJ_ISQAMSTD(ext_attr->standard)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005368 data |= (6 << SCU_RAM_AGC_KI_IF__B);
5369 } else {
5370 data |= (5 << SCU_RAM_AGC_KI_IF__B);
5371 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005372
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005373 if (common_attr->tuner_if_agc_pol) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005374 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5375 } else {
5376 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5377 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005378 CHK_ERROR((*scu_wr16)
5379 (dev_addr, SCU_RAM_AGC_KI__A, data, 0));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005380
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005381 /* Set speed (using complementary reduction value) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005382 CHK_ERROR((*scu_rr16)
5383 (dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005384 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005385 CHK_ERROR((*scu_wr16) (dev_addr, SCU_RAM_AGC_KI_RED__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005386 (~
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005387 (agc_settings->
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005388 speed <<
5389 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
5390& SCU_RAM_AGC_KI_RED_IAGC_RED__M)
5391 | data, 0));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005392
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005393 if (agc_settings->standard == DRX_STANDARD_8VSB)
5394 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
5395 else if (DRXJ_ISQAMSTD(agc_settings->standard))
5396 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
5397 else if (DRXJ_ISATVSTD(agc_settings->standard))
5398 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005399 else
5400 return (DRX_STS_INVALID_ARG);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005401
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005402 /* Restore TOP */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005403 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5404 CHK_ERROR((*scu_wr16)
5405 (dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005406 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005407 p_agc_settings->top, 0));
5408 CHK_ERROR((*scu_wr16)
5409 (dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005410 SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005411 p_agc_settings->top, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005412 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005413 CHK_ERROR((*scu_wr16)
5414 (dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005415 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
5416 0, 0));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005417 CHK_ERROR((*scu_wr16)
5418 (dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005419 SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0,
5420 0));
5421 }
5422 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005423
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005424 case DRX_AGC_CTRL_USER:
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005425
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005426 /* Enable IF AGC DAC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005427 RR16(dev_addr, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005428 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005429 WR16(dev_addr, IQM_AF_STDBY__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005430
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005431 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005432 CHK_ERROR((*scu_rr16)
5433 (dev_addr, SCU_RAM_AGC_KI__A, &data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005434 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5435 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005436 if (common_attr->tuner_if_agc_pol) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005437 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5438 } else {
5439 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5440 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005441 CHK_ERROR((*scu_wr16)
5442 (dev_addr, SCU_RAM_AGC_KI__A, data, 0));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005443
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005444 /* Write value to output pin */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005445 CHK_ERROR((*scu_wr16)
5446 (dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
5447 agc_settings->output_level, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005448 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005449
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005450 case DRX_AGC_CTRL_OFF:
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005451
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005452 /* Disable If AGC DAC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005453 RR16(dev_addr, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005454 data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005455 WR16(dev_addr, IQM_AF_STDBY__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005456
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005457 /* Disable SCU IF AGC loop */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005458 CHK_ERROR((*scu_rr16)
5459 (dev_addr, SCU_RAM_AGC_KI__A, &data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005460 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5461 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005462 CHK_ERROR((*scu_wr16)
5463 (dev_addr, SCU_RAM_AGC_KI__A, data, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005464 break;
5465 default:
5466 return (DRX_STS_INVALID_ARG);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005467 } /* switch ( agcsettings->ctrl_mode ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005468
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005469 /* always set the top to support configurations without if-loop */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005470 CHK_ERROR((*scu_wr16) (dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005471 SCU_RAM_AGC_INGAIN_TGT_MIN__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005472 agc_settings->top, 0));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005473 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005474
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005475 /* Store if agc settings */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005476 switch (agc_settings->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005477 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005478 ext_attr->vsb_if_agc_cfg = *agc_settings;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005479 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005480#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005481 case DRX_STANDARD_ITU_A:
5482 case DRX_STANDARD_ITU_B:
5483 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005484 ext_attr->qam_if_agc_cfg = *agc_settings;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005485 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005486#endif
5487#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005488 case DRX_STANDARD_PAL_SECAM_BG:
5489 case DRX_STANDARD_PAL_SECAM_DK:
5490 case DRX_STANDARD_PAL_SECAM_I:
5491 case DRX_STANDARD_PAL_SECAM_L:
5492 case DRX_STANDARD_PAL_SECAM_LP:
5493 case DRX_STANDARD_NTSC:
5494 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005495 ext_attr->atv_if_agc_cfg = *agc_settings;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005496 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005497#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005498 default:
5499 return (DRX_STS_ERROR);
5500 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005501
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005502 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005503rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005504 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005505}
5506
5507/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005508* \fn int get_agc_if ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005509* \brief get configuration of If AGC
5510* \param demod instance of demodulator.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005511* \param agc_settings AGC configuration structure
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005512* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005513*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005514static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005515get_agc_if(pdrx_demod_instance_t demod, p_drxj_cfg_agc_t agc_settings)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005516{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005517 struct i2c_device_addr *dev_addr = NULL;
5518 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005519 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005520
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005521 dev_addr = demod->my_i2c_dev_addr;
5522 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005523
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005524 /* Return stored ATV AGC settings */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005525 standard = agc_settings->standard;
5526 switch (agc_settings->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005527 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005528 *agc_settings = ext_attr->vsb_if_agc_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005529 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005530#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005531 case DRX_STANDARD_ITU_A:
5532 case DRX_STANDARD_ITU_B:
5533 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005534 *agc_settings = ext_attr->qam_if_agc_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005535 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005536#endif
5537#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005538 case DRX_STANDARD_PAL_SECAM_BG:
5539 case DRX_STANDARD_PAL_SECAM_DK:
5540 case DRX_STANDARD_PAL_SECAM_I:
5541 case DRX_STANDARD_PAL_SECAM_L:
5542 case DRX_STANDARD_PAL_SECAM_LP:
5543 case DRX_STANDARD_NTSC:
5544 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005545 *agc_settings = ext_attr->atv_if_agc_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005546 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005547#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005548 default:
5549 return (DRX_STS_ERROR);
5550 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005551 agc_settings->standard = standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005552
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005553 /* Get AGC output only if standard is currently active */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005554 if ((ext_attr->standard == agc_settings->standard) ||
5555 (DRXJ_ISQAMSTD(ext_attr->standard) &&
5556 DRXJ_ISQAMSTD(agc_settings->standard)) ||
5557 (DRXJ_ISATVSTD(ext_attr->standard) &&
5558 DRXJ_ISATVSTD(agc_settings->standard))) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005559 /* read output level */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005560 SARR16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A,
5561 &(agc_settings->output_level));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005562 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005563
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005564 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005565rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005566 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005567}
5568
5569/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005570* \fn int set_iqm_af ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005571* \brief Configure IQM AF registers
5572* \param demod instance of demodulator.
5573* \param active
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005574* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005575*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005576static int set_iqm_af(pdrx_demod_instance_t demod, bool active)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005577{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005578 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005579 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005580
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005581 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005582
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005583 /* Configure IQM */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005584 RR16(dev_addr, IQM_AF_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005585 if (!active) {
5586 data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE)
5587 & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE)
5588 & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE)
5589 & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE)
5590 & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE)
5591 );
5592 } else { /* active */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005593
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005594 data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE
5595 | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE
5596 | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE
5597 | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE
5598 | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
5599 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005600 WR16(dev_addr, IQM_AF_STDBY__A, data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005601
5602 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005603rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005604 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005605}
5606
5607/*============================================================================*/
5608/*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5609/*============================================================================*/
5610
5611/*============================================================================*/
5612/*============================================================================*/
5613/*== 8VSB DATAPATH FUNCTIONS ==*/
5614/*============================================================================*/
5615/*============================================================================*/
5616
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005617/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005618* \fn int power_down_vsb ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005619* \brief Powr down QAM related blocks.
5620* \param demod instance of demodulator.
5621* \param channel pointer to channel data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005622* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005623*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005624static int power_down_vsb(pdrx_demod_instance_t demod, bool primary)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005625{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005626 struct i2c_device_addr *dev_addr = NULL;
5627 drxjscu_cmd_t cmd_scu = { /* command */ 0,
5628 /* parameter_len */ 0,
5629 /* result_len */ 0,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005630 /* *parameter */ NULL,
5631 /* *result */ NULL
5632 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005633 u16 cmd_result = 0;
5634 pdrxj_data_t ext_attr = NULL;
5635 drx_cfg_mpeg_output_t cfg_mpeg_output;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005636
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005637 dev_addr = demod->my_i2c_dev_addr;
5638 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005639 /*
5640 STOP demodulator
5641 reset of FEC and VSB HW
5642 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005643 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005644 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005645 cmd_scu.parameter_len = 0;
5646 cmd_scu.result_len = 1;
5647 cmd_scu.parameter = NULL;
5648 cmd_scu.result = &cmd_result;
5649 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005650
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005651 /* stop all comm_exec */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005652 WR16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
5653 WR16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP);
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03005654 if (primary == true) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005655 WR16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP);
5656 CHK_ERROR(set_iqm_af(demod, false));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005657 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005658 WR16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
5659 WR16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
5660 WR16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
5661 WR16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
5662 WR16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005663 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005664
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005665 cfg_mpeg_output.enable_mpeg_output = false;
5666 CHK_ERROR(ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005667
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005668 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005669rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005670 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005671}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005672
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005673/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005674* \fn int set_vsb_leak_n_gain ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005675* \brief Set ATSC demod.
5676* \param demod instance of demodulator.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005677* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005678*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005679static int set_vsb_leak_n_gain(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005680{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005681 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005682
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005683 const u8 vsb_ffe_leak_gain_ram0[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005684 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
5685 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
5686 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
5687 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
5688 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
5689 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
5690 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
5691 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
5692 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
5693 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
5694 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
5695 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
5696 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
5697 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
5698 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
5699 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
5700 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
5701 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
5702 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
5703 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
5704 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
5705 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
5706 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
5707 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
5708 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
5709 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
5710 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
5711 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
5712 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
5713 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
5714 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
5715 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
5716 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
5717 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
5718 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
5719 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
5720 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
5721 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
5722 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
5723 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
5724 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
5725 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
5726 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
5727 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
5728 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
5729 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
5730 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
5731 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
5732 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
5733 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
5734 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
5735 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
5736 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
5737 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
5738 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
5739 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
5740 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
5741 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
5742 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
5743 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
5744 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
5745 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
5746 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
5747 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
5748 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
5749 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
5750 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
5751 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
5752 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
5753 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
5754 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
5755 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
5756 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
5757 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
5758 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
5759 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
5760 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
5761 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
5762 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
5763 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
5764 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
5765 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
5766 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
5767 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
5768 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
5769 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
5770 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
5771 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
5772 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
5773 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
5774 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
5775 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
5776 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
5777 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
5778 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
5779 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
5780 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
5781 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
5782 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
5783 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
5784 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
5785 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
5786 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
5787 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
5788 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
5789 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
5790 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
5791 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
5792 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
5793 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
5794 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
5795 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
5796 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
5797 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
5798 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
5799 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
5800 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
5801 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
5802 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
5803 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
5804 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
5805 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
5806 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
5807 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
5808 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
5809 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
5810 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
5811 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
5812 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005813
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005814 const u8 vsb_ffe_leak_gain_ram1[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005815 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
5816 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
5817 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
5818 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
5819 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
5820 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
5821 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
5822 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
5823 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
5824 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
5825 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
5826 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
5827 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
5828 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
5829 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
5830 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
5831 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
5832 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
5833 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
5834 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
5835 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
5836 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
5837 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
5838 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
5839 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
5840 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
5841 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
5842 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
5843 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
5844 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
5845 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
5846 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
5847 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
5848 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
5849 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
5850 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
5851 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
5852 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
5853 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
5854 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
5855 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
5856 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
5857 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
5858 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
5859 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
5860 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
5861 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
5862 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
5863 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
5864 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
5865 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
5866 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
5867 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
5868 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
5869 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005870
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005871 dev_addr = demod->my_i2c_dev_addr;
5872 WRB(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005873 sizeof(vsb_ffe_leak_gain_ram0), ((u8 *) vsb_ffe_leak_gain_ram0));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005874 WRB(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005875 sizeof(vsb_ffe_leak_gain_ram1), ((u8 *) vsb_ffe_leak_gain_ram1));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005876
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005877 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005878rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005879 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005880}
5881
5882/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005883* \fn int set_vsb()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005884* \brief Set 8VSB demod.
5885* \param demod instance of demodulator.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03005886* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005887*
5888*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005889static int set_vsb(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005890{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005891 struct i2c_device_addr *dev_addr = NULL;
5892 u16 cmd_result = 0;
5893 u16 cmd_param = 0;
5894 pdrx_common_attr_t common_attr = NULL;
5895 drxjscu_cmd_t cmd_scu;
5896 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005897 const u8 vsb_taps_re[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005898 DRXJ_16TO8(-2), /* re0 */
5899 DRXJ_16TO8(4), /* re1 */
5900 DRXJ_16TO8(1), /* re2 */
5901 DRXJ_16TO8(-4), /* re3 */
5902 DRXJ_16TO8(1), /* re4 */
5903 DRXJ_16TO8(4), /* re5 */
5904 DRXJ_16TO8(-3), /* re6 */
5905 DRXJ_16TO8(-3), /* re7 */
5906 DRXJ_16TO8(6), /* re8 */
5907 DRXJ_16TO8(1), /* re9 */
5908 DRXJ_16TO8(-9), /* re10 */
5909 DRXJ_16TO8(3), /* re11 */
5910 DRXJ_16TO8(12), /* re12 */
5911 DRXJ_16TO8(-9), /* re13 */
5912 DRXJ_16TO8(-15), /* re14 */
5913 DRXJ_16TO8(17), /* re15 */
5914 DRXJ_16TO8(19), /* re16 */
5915 DRXJ_16TO8(-29), /* re17 */
5916 DRXJ_16TO8(-22), /* re18 */
5917 DRXJ_16TO8(45), /* re19 */
5918 DRXJ_16TO8(25), /* re20 */
5919 DRXJ_16TO8(-70), /* re21 */
5920 DRXJ_16TO8(-28), /* re22 */
5921 DRXJ_16TO8(111), /* re23 */
5922 DRXJ_16TO8(30), /* re24 */
5923 DRXJ_16TO8(-201), /* re25 */
5924 DRXJ_16TO8(-31), /* re26 */
5925 DRXJ_16TO8(629) /* re27 */
5926 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005927
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005928 dev_addr = demod->my_i2c_dev_addr;
5929 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
5930 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005931
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005932 /* stop all comm_exec */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005933 WR16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
5934 WR16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP);
5935 WR16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
5936 WR16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
5937 WR16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
5938 WR16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
5939 WR16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005940
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005941 /* reset demodulator */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005942 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005943 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005944 cmd_scu.parameter_len = 0;
5945 cmd_scu.result_len = 1;
5946 cmd_scu.parameter = NULL;
5947 cmd_scu.result = &cmd_result;
5948 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005949
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005950 WR16(dev_addr, IQM_AF_DCF_BYPASS__A, 1);
5951 WR16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB);
5952 WR16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB);
5953 ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
5954 WR32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs);
5955 WR16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4);
5956 WR16(dev_addr, VSB_TOP_CYGN1TRK__A, 1);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005957
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005958 WR16(dev_addr, IQM_RC_CROUT_ENA__A, 1);
5959 WR16(dev_addr, IQM_RC_STRETCH__A, 28);
5960 WR16(dev_addr, IQM_RT_ACTIVE__A, 0);
5961 WR16(dev_addr, IQM_CF_SYMMETRIC__A, 0);
5962 WR16(dev_addr, IQM_CF_MIDTAP__A, 3);
5963 WR16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M);
5964 WR16(dev_addr, IQM_CF_SCALE__A, 1393);
5965 WR16(dev_addr, IQM_CF_SCALE_SH__A, 0);
5966 WR16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005967
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005968 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005969 ((u8 *) vsb_taps_re));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005970 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03005971 ((u8 *) vsb_taps_re));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005972
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005973 WR16(dev_addr, VSB_TOP_BNTHRESH__A, 330); /* set higher threshold */
5974 WR16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90); /* burst detection on */
5975 WR16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042); /* drop thresholds by 1 dB */
5976 WR16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053); /* drop thresholds by 2 dB */
5977 WR16(dev_addr, VSB_TOP_EQCTRL__A, 0x1); /* cma on */
5978 WR16(dev_addr, SCU_RAM_GPIO__A, 0); /* GPIO */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005979
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005980 /* Initialize the FEC Subsystem */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005981 WR16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005982 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005983 u16 fec_oc_snc_mode = 0;
5984 RR16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005985 /* output data even when not locked */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005986 WR16(dev_addr, FEC_OC_SNC_MODE__A,
5987 fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005988 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03005989
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005990 /* set clip */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005991 WR16(dev_addr, IQM_AF_CLP_LEN__A, 0);
5992 WR16(dev_addr, IQM_AF_CLP_TH__A, 470);
5993 WR16(dev_addr, IQM_AF_SNS_LEN__A, 0);
5994 WR16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03005995 /* no transparent, no A&C framing; parity is set in mpegoutput */
5996 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03005997 u16 fec_oc_reg_mode = 0;
5998 RR16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode);
5999 WR16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006000 (~(FEC_OC_MODE_TRANSPARENT__M
6001 | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)
6002 ));
6003 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006004
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006005 WR16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0); /* timeout counter for restarting */
6006 WR16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3);
6007 WR16(dev_addr, FEC_RS_MODE__A, 0); /* bypass disabled */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006008 /* initialize RS packet error measurement parameters */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006009 WR16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD);
6010 WR16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006011 FEC_RS_MEASUREMENT_PRESCALE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006012
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006013 /* init measurement period of MER/SER */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006014 WR16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006015 VSB_TOP_MEASUREMENT_PERIOD);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006016 WR32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0);
6017 WR16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0);
6018 WR16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006019
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006020 WR16(dev_addr, VSB_TOP_CKGN1TRK__A, 128);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006021 /* B-Input to ADC, PGA+filter in standby */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006022 if (ext_attr->has_lna == false) {
6023 WR16(dev_addr, IQM_AF_AMUX__A, 0x02);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006024 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006025
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006026 /* turn on IQMAF. It has to be in front of setAgc**() */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006027 CHK_ERROR(set_iqm_af(demod, true));
6028 CHK_ERROR(adc_synchronization(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006029
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006030 CHK_ERROR(init_agc(demod));
6031 CHK_ERROR(set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false));
6032 CHK_ERROR(set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006033 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006034 /* TODO fix this, store a drxj_cfg_afe_gain_t structure in drxj_data_t instead
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006035 of only the gain */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006036 drxj_cfg_afe_gain_t vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006037
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006038 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
6039 CHK_ERROR(ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006040 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006041 CHK_ERROR(ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg)));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006042
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006043 /* Mpeg output has to be in front of FEC active */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006044 CHK_ERROR(set_mpegtei_handling(demod));
6045 CHK_ERROR(bit_reverse_mpeg_output(demod));
6046 CHK_ERROR(set_mpeg_start_width(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006047 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006048 /* TODO: move to set_standard after hardware reset value problem is solved */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006049 /* Configure initial MPEG output */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006050 drx_cfg_mpeg_output_t cfg_mpeg_output;
6051 cfg_mpeg_output.enable_mpeg_output = true;
6052 cfg_mpeg_output.insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
6053 cfg_mpeg_output.enable_parallel =
6054 common_attr->mpeg_cfg.enable_parallel;
6055 cfg_mpeg_output.invert_data = common_attr->mpeg_cfg.invert_data;
6056 cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
6057 cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
6058 cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
6059 cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
6060 cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
6061 cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
6062 CHK_ERROR(ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006063 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006064
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006065 /* TBD: what parameters should be set */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006066 cmd_param = 0x00; /* Default mode AGC on, etc */
6067 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006068 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006069 cmd_scu.parameter_len = 1;
6070 cmd_scu.result_len = 1;
6071 cmd_scu.parameter = &cmd_param;
6072 cmd_scu.result = &cmd_result;
6073 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006074
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006075 WR16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004);
6076 WR16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2);
6077 WR16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006078 | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006079 WR16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142);
6080 WR16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640);
6081 WR16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4);
6082 WR16(dev_addr, VSB_TOP_CYGN1TRK__A, 2);
6083 WR16(dev_addr, VSB_TOP_CYGN2TRK__A, 3);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006084
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006085 /* start demodulator */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006086 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006087 | SCU_RAM_COMMAND_CMD_DEMOD_START;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006088 cmd_scu.parameter_len = 0;
6089 cmd_scu.result_len = 1;
6090 cmd_scu.parameter = NULL;
6091 cmd_scu.result = &cmd_result;
6092 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006093
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006094 WR16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE);
6095 WR16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE);
6096 WR16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006097
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006098 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006099rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006100 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006101}
6102
6103/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006104* \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006105* \brief Get the values of packet error in 8VSB mode
6106* \return Error code
6107*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006108static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *pck_errs)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006109{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03006110 u16 data = 0;
6111 u16 period = 0;
6112 u16 prescale = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006113 u16 packet_errorsMant = 0;
6114 u16 packet_errorsExp = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006115
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006116 RR16(dev_addr, FEC_RS_NR_FAILURES__A, &data);
6117 packet_errorsMant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
6118 packet_errorsExp = (data & FEC_RS_NR_FAILURES_EXP__M)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006119 >> FEC_RS_NR_FAILURES_EXP__B;
6120 period = FEC_RS_MEASUREMENT_PERIOD;
6121 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6122 /* packet error rate = (error packet number) per second */
6123 /* 77.3 us is time for per packet */
6124 CHK_ZERO(period * prescale);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006125 *pck_errs =
6126 (u16) frac_times1e6(packet_errorsMant * (1 << packet_errorsExp),
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006127 (period * prescale * 77));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006128
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006129 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006130rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006131 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006132}
6133
6134/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006135* \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006136* \brief Get the values of ber in VSB mode
6137* \return Error code
6138*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006139static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006140{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03006141 u16 data = 0;
6142 u16 period = 0;
6143 u16 prescale = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006144 u16 bit_errors_mant = 0;
6145 u16 bit_errors_exp = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006146
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006147 RR16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006148 period = FEC_RS_MEASUREMENT_PERIOD;
6149 prescale = FEC_RS_MEASUREMENT_PRESCALE;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006150
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006151 bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
6152 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006153 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006154
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006155 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006156 *ber = 26570;
6157 else {
6158 CHK_ZERO(period * prescale);
6159 *ber =
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006160 frac_times1e6(bit_errors_mant <<
6161 ((bit_errors_exp >
6162 2) ? (bit_errors_exp - 3) : bit_errors_exp),
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006163 period * prescale * 207 *
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006164 ((bit_errors_exp > 2) ? 1 : 8));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006165 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006166
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006167 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006168rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006169 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006170}
6171
6172/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006173* \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006174* \brief Get the values of ber in VSB mode
6175* \return Error code
6176*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006177static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006178{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03006179 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006180
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006181 RR16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006182 *ber =
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006183 frac_times1e6(data,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006184 VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006185
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006186 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006187rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006188 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006189}
6190
6191/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006192* \fn static short get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ber)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006193* \brief Get the values of ber in VSB mode
6194* \return Error code
6195*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006196static int get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ser)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006197{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03006198 u16 data = 0;
6199 u16 period = 0;
6200 u16 prescale = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006201 u16 symb_errors_mant = 0;
6202 u16 symb_errors_exp = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006203
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006204 RR16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006205 period = FEC_RS_MEASUREMENT_PERIOD;
6206 prescale = FEC_RS_MEASUREMENT_PRESCALE;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006207
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006208 symb_errors_mant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M;
6209 symb_errors_exp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006210 >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006211
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006212 CHK_ZERO(period * prescale);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006213 *ser = (u32) frac_times1e6((symb_errors_mant << symb_errors_exp) * 1000,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006214 (period * prescale * 77318));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006215
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006216 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006217rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006218 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006219}
6220
6221/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006222* \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006223* \brief Get the values of MER
6224* \return Error code
6225*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006226static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006227{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006228 u16 data_hi = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006229
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006230 RR16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006231 *mer =
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006232 (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006233
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006234 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006235rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006236 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006237}
6238
6239/*============================================================================*/
6240/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006241* \fn int ctrl_get_vsb_constel()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006242* \brief Retreive a VSB constellation point via I2C.
6243* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006244* \param complex_nr Pointer to the structure in which to store the
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006245 constellation point.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006246* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006247*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006248static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006249ctrl_get_vsb_constel(pdrx_demod_instance_t demod, pdrx_complex_t complex_nr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006250{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006251 struct i2c_device_addr *dev_addr = NULL;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006252 /**< device address */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006253 u16 vsb_top_comm_mb = 0; /**< VSB SL MB configuration */
6254 u16 vsb_top_comm_mbInit = 0; /**< VSB SL MB intial configuration */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03006255 u16 re = 0; /**< constellation Re part */
6256 u32 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006257
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006258 /* read device info */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006259 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006260
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006261 /* TODO: */
6262 /* Monitor bus grabbing is an open external interface issue */
6263 /* Needs to be checked when external interface PG is updated */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006264
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006265 /* Configure MB (Monitor bus) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006266 RR16(dev_addr, VSB_TOP_COMM_MB__A, &vsb_top_comm_mbInit);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006267 /* set observe flag & MB mux */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006268 vsb_top_comm_mb = (vsb_top_comm_mbInit |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006269 VSB_TOP_COMM_MB_OBS_OBS_ON |
6270 VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006271 WR16(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006272
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006273 /* Enable MB grabber in the FEC OC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006274 WR16(dev_addr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006275
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006276 /* Disable MB grabber in the FEC OC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006277 WR16(dev_addr, FEC_OC_OCR_MODE__A, 0x0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006278
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006279 /* read data */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006280 RR32(dev_addr, FEC_OC_OCR_GRAB_RD1__A, &data);
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03006281 re = (u16) (((data >> 10) & 0x300) | ((data >> 2) & 0xff));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006282 if (re & 0x0200) {
6283 re |= 0xfc00;
6284 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006285 complex_nr->re = re;
6286 complex_nr->im = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006287
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006288 /* Restore MB (Monitor bus) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006289 WR16(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mbInit);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006290
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006291 return (DRX_STS_OK);
6292rw_error:
6293 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006294}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006295
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006296/*============================================================================*/
6297/*== END 8VSB DATAPATH FUNCTIONS ==*/
6298/*============================================================================*/
6299
6300/*============================================================================*/
6301/*============================================================================*/
6302/*== QAM DATAPATH FUNCTIONS ==*/
6303/*============================================================================*/
6304/*============================================================================*/
6305
6306/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006307* \fn int power_down_qam ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006308* \brief Powr down QAM related blocks.
6309* \param demod instance of demodulator.
6310* \param channel pointer to channel data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006311* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006312*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006313static int power_down_qam(pdrx_demod_instance_t demod, bool primary)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006314{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006315 drxjscu_cmd_t cmd_scu = { /* command */ 0,
6316 /* parameter_len */ 0,
6317 /* result_len */ 0,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006318 /* *parameter */ NULL,
6319 /* *result */ NULL
6320 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006321 u16 cmd_result = 0;
6322 struct i2c_device_addr *dev_addr = NULL;
6323 pdrxj_data_t ext_attr = NULL;
6324 drx_cfg_mpeg_output_t cfg_mpeg_output;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006325
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006326 dev_addr = demod->my_i2c_dev_addr;
6327 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006328
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006329 /*
6330 STOP demodulator
6331 resets IQM, QAM and FEC HW blocks
6332 */
6333 /* stop all comm_exec */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006334 WR16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6335 WR16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006336
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006337 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006338 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006339 cmd_scu.parameter_len = 0;
6340 cmd_scu.result_len = 1;
6341 cmd_scu.parameter = NULL;
6342 cmd_scu.result = &cmd_result;
6343 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006344
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03006345 if (primary == true) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006346 WR16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP);
6347 CHK_ERROR(set_iqm_af(demod, false));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006348 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006349 WR16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
6350 WR16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
6351 WR16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
6352 WR16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
6353 WR16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006354 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006355
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006356 cfg_mpeg_output.enable_mpeg_output = false;
6357 CHK_ERROR(ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006358
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006359 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006360rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006361 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006362}
6363
6364/*============================================================================*/
6365
6366/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006367* \fn int set_qam_measurement ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006368* \brief Setup of the QAM Measuremnt intervals for signal quality
6369* \param demod instance of demod.
6370* \param constellation current constellation.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006371* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006372*
6373* NOTE:
6374* Take into account that for certain settings the errorcounters can overflow.
6375* The implementation does not check this.
6376*
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006377* TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
6378* constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006379* field ?
6380*
6381*/
6382#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006383static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006384set_qam_measurement(pdrx_demod_instance_t demod,
6385 enum drx_modulation constellation, u32 symbol_rate)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006386{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006387 struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */
6388 pdrxj_data_t ext_attr = NULL; /* Global data container for DRXJ specif data */
6389 u32 fec_bits_desired = 0; /* BER accounting period */
6390 u16 fec_rs_plen = 0; /* defines RS BER measurement period */
6391 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
6392 u32 fec_rs_period = 0; /* Value for corresponding I2C register */
6393 u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
6394 u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
6395 u32 qam_vd_period = 0; /* Value for corresponding I2C register */
6396 u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
6397 u16 fec_vd_plen = 0; /* no of trellis symbols: VD SER measur period */
6398 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006399
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006400 dev_addr = demod->my_i2c_dev_addr;
6401 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006402
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006403 fec_bits_desired = ext_attr->fec_bits_desired;
6404 fec_rs_prescale = ext_attr->fec_rs_prescale;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006405
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006406 switch (constellation) {
6407 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006408 fec_bits_desired = 4 * symbol_rate;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006409 break;
6410 case DRX_CONSTELLATION_QAM32:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006411 fec_bits_desired = 5 * symbol_rate;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006412 break;
6413 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006414 fec_bits_desired = 6 * symbol_rate;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006415 break;
6416 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006417 fec_bits_desired = 7 * symbol_rate;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006418 break;
6419 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006420 fec_bits_desired = 8 * symbol_rate;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006421 break;
6422 default:
6423 return (DRX_STS_INVALID_ARG);
6424 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006425
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006426 /* Parameters for Reed-Solomon Decoder */
6427 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
6428 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
6429 /* result is within 32 bit arithmetic -> */
6430 /* no need for mult or frac functions */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006431
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006432 /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
6433 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006434 case DRX_STANDARD_ITU_A:
6435 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006436 fec_rs_plen = 204 * 8;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006437 break;
6438 case DRX_STANDARD_ITU_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006439 fec_rs_plen = 128 * 7;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006440 break;
6441 default:
6442 return (DRX_STS_INVALID_ARG);
6443 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006444
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006445 ext_attr->fec_rs_plen = fec_rs_plen; /* for getSigQual */
6446 fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage */
6447 CHK_ZERO(fec_rs_bit_cnt);
6448 fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1; /* ceil */
6449 if (ext_attr->standard != DRX_STANDARD_ITU_B)
6450 fec_oc_snc_fail_period = fec_rs_period;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006451
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006452 /* limit to max 16 bit value (I2C register width) if needed */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006453 if (fec_rs_period > 0xFFFF)
6454 fec_rs_period = 0xFFFF;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006455
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006456 /* write corresponding registers */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006457 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006458 case DRX_STANDARD_ITU_A:
6459 case DRX_STANDARD_ITU_C:
6460 break;
6461 case DRX_STANDARD_ITU_B:
6462 switch (constellation) {
6463 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006464 fec_rs_period = 31581;
6465 fec_oc_snc_fail_period = 17932;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006466 break;
6467 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006468 fec_rs_period = 45446;
6469 fec_oc_snc_fail_period = 25805;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006470 break;
6471 default:
6472 return (DRX_STS_INVALID_ARG);
6473 }
6474 break;
6475 default:
6476 return (DRX_STS_INVALID_ARG);
6477 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006478
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006479 WR16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16) fec_oc_snc_fail_period);
6480 WR16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16) fec_rs_period);
6481 WR16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale);
6482 ext_attr->fec_rs_period = (u16) fec_rs_period;
6483 ext_attr->fec_rs_prescale = fec_rs_prescale;
6484 WR32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0);
6485 WR16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0);
6486 WR16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006487
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006488 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006489 /* Parameters for Viterbi Decoder */
6490 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
6491 /* (qamvd_prescale*plen*(qam_constellation+1))) */
6492 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
6493 /* result is within 32 bit arithmetic -> */
6494 /* no need for mult or frac functions */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006495
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006496 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
6497 fec_vd_plen = ext_attr->fec_vd_plen;
6498 qam_vd_prescale = ext_attr->qam_vd_prescale;
6499 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006500
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006501 switch (constellation) {
6502 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006503 /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
6504 qam_vd_period =
6505 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006506 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
6507 break;
6508 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006509 /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
6510 qam_vd_period =
6511 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006512 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
6513 break;
6514 default:
6515 return (DRX_STS_INVALID_ARG);
6516 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006517 CHK_ZERO(qam_vd_period);
6518 qam_vd_period = fec_bits_desired / qam_vd_period;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006519 /* limit to max 16 bit value (I2C register width) if needed */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006520 if (qam_vd_period > 0xFFFF)
6521 qam_vd_period = 0xFFFF;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006522
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006523 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
6524 qam_vd_bit_cnt *= qam_vd_period;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006525
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006526 WR16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A,
6527 (u16) qam_vd_period);
6528 WR16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale);
6529 ext_attr->qam_vd_period = (u16) qam_vd_period;
6530 ext_attr->qam_vd_prescale = qam_vd_prescale;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006531 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006532
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006533 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006534rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006535 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006536}
6537
6538/*============================================================================*/
6539
6540/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006541* \fn int set_qam16 ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006542* \brief QAM16 specific setup
6543* \param demod instance of demod.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006544* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006545*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006546static int set_qam16(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006547{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006548 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6549 const u8 qam_dq_qual_fun[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006550 DRXJ_16TO8(2), /* fun0 */
6551 DRXJ_16TO8(2), /* fun1 */
6552 DRXJ_16TO8(2), /* fun2 */
6553 DRXJ_16TO8(2), /* fun3 */
6554 DRXJ_16TO8(3), /* fun4 */
6555 DRXJ_16TO8(3), /* fun5 */
6556 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006557 const u8 qam_eq_cma_rad[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006558 DRXJ_16TO8(13517), /* RAD0 */
6559 DRXJ_16TO8(13517), /* RAD1 */
6560 DRXJ_16TO8(13517), /* RAD2 */
6561 DRXJ_16TO8(13517), /* RAD3 */
6562 DRXJ_16TO8(13517), /* RAD4 */
6563 DRXJ_16TO8(13517), /* RAD5 */
6564 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006565
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006566 WRB(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun),
6567 ((u8 *) qam_dq_qual_fun));
6568 WRB(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad),
6569 ((u8 *) qam_eq_cma_rad));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006570
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006571 WR16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140);
6572 WR16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50);
6573 WR16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120);
6574 WR16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230);
6575 WR16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95);
6576 WR16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006577
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006578 WR16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6579 WR16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56);
6580 WR16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006581
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006582 WR16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16);
6583 WR16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220);
6584 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25);
6585 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6);
6586 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) (-24));
6587 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) (-65));
6588 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) (-127));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006589
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006590 WR16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6591 WR16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6592 WR16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6593 WR16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
6594 WR16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6595 WR16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6596 WR16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10);
6597 WR16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
6598 WR16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6599 WR16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6600 WR16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6601 WR16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6602 WR16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6603 WR16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6604 WR16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6605 WR16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
6606 WR16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240);
6607 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6608 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6609 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006610
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006611 WR16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006612
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006613 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006614rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006615 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006616}
6617
6618/*============================================================================*/
6619
6620/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006621* \fn int set_qam32 ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006622* \brief QAM32 specific setup
6623* \param demod instance of demod.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006624* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006625*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006626static int set_qam32(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006627{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006628 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6629 const u8 qam_dq_qual_fun[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006630 DRXJ_16TO8(3), /* fun0 */
6631 DRXJ_16TO8(3), /* fun1 */
6632 DRXJ_16TO8(3), /* fun2 */
6633 DRXJ_16TO8(3), /* fun3 */
6634 DRXJ_16TO8(4), /* fun4 */
6635 DRXJ_16TO8(4), /* fun5 */
6636 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006637 const u8 qam_eq_cma_rad[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006638 DRXJ_16TO8(6707), /* RAD0 */
6639 DRXJ_16TO8(6707), /* RAD1 */
6640 DRXJ_16TO8(6707), /* RAD2 */
6641 DRXJ_16TO8(6707), /* RAD3 */
6642 DRXJ_16TO8(6707), /* RAD4 */
6643 DRXJ_16TO8(6707), /* RAD5 */
6644 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006645
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006646 WRB(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun),
6647 ((u8 *) qam_dq_qual_fun));
6648 WRB(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad),
6649 ((u8 *) qam_eq_cma_rad));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006650
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006651 WR16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90);
6652 WR16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50);
6653 WR16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100);
6654 WR16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170);
6655 WR16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80);
6656 WR16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006657
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006658 WR16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6659 WR16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56);
6660 WR16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006661
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006662 WR16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12);
6663 WR16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140);
6664 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) (-8));
6665 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) (-16));
6666 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) (-26));
6667 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) (-56));
6668 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) (-86));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006669
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006670 WR16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6671 WR16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6672 WR16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6673 WR16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
6674 WR16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6675 WR16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6676 WR16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10);
6677 WR16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
6678 WR16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6679 WR16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6680 WR16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6681 WR16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6682 WR16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6683 WR16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6684 WR16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6685 WR16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
6686 WR16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176);
6687 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6688 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6689 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006690
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006691 WR16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006692
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006693 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006694rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006695 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006696}
6697
6698/*============================================================================*/
6699
6700/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006701* \fn int set_qam64 ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006702* \brief QAM64 specific setup
6703* \param demod instance of demod.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006704* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006705*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006706static int set_qam64(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006707{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006708 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6709 const u8 qam_dq_qual_fun[] = { /* this is hw reset value. no necessary to re-write */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006710 DRXJ_16TO8(4), /* fun0 */
6711 DRXJ_16TO8(4), /* fun1 */
6712 DRXJ_16TO8(4), /* fun2 */
6713 DRXJ_16TO8(4), /* fun3 */
6714 DRXJ_16TO8(6), /* fun4 */
6715 DRXJ_16TO8(6), /* fun5 */
6716 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006717 const u8 qam_eq_cma_rad[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006718 DRXJ_16TO8(13336), /* RAD0 */
6719 DRXJ_16TO8(12618), /* RAD1 */
6720 DRXJ_16TO8(11988), /* RAD2 */
6721 DRXJ_16TO8(13809), /* RAD3 */
6722 DRXJ_16TO8(13809), /* RAD4 */
6723 DRXJ_16TO8(15609), /* RAD5 */
6724 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006725
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006726 WRB(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun),
6727 ((u8 *) qam_dq_qual_fun));
6728 WRB(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad),
6729 ((u8 *) qam_eq_cma_rad));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006730
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006731 WR16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105);
6732 WR16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60);
6733 WR16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100);
6734 WR16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195);
6735 WR16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80);
6736 WR16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006737
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006738 WR16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6739 WR16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32);
6740 WR16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006741
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006742 WR16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12);
6743 WR16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141);
6744 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7);
6745 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0);
6746 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) (-15));
6747 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) (-45));
6748 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) (-80));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006749
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006750 WR16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6751 WR16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6752 WR16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6753 WR16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
6754 WR16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6755 WR16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6756 WR16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15);
6757 WR16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
6758 WR16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6759 WR16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6760 WR16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6761 WR16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6762 WR16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6763 WR16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6764 WR16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6765 WR16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48);
6766 WR16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160);
6767 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6768 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6769 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006770
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006771 WR16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006772
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006773 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006774rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006775 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006776}
6777
6778/*============================================================================*/
6779
6780/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006781* \fn int set_qam128 ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006782* \brief QAM128 specific setup
6783* \param demod: instance of demod.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006784* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006785*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006786static int set_qam128(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006787{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006788 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6789 const u8 qam_dq_qual_fun[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006790 DRXJ_16TO8(6), /* fun0 */
6791 DRXJ_16TO8(6), /* fun1 */
6792 DRXJ_16TO8(6), /* fun2 */
6793 DRXJ_16TO8(6), /* fun3 */
6794 DRXJ_16TO8(9), /* fun4 */
6795 DRXJ_16TO8(9), /* fun5 */
6796 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006797 const u8 qam_eq_cma_rad[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006798 DRXJ_16TO8(6164), /* RAD0 */
6799 DRXJ_16TO8(6598), /* RAD1 */
6800 DRXJ_16TO8(6394), /* RAD2 */
6801 DRXJ_16TO8(6409), /* RAD3 */
6802 DRXJ_16TO8(6656), /* RAD4 */
6803 DRXJ_16TO8(7238), /* RAD5 */
6804 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006805
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006806 WRB(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun),
6807 ((u8 *) qam_dq_qual_fun));
6808 WRB(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad),
6809 ((u8 *) qam_eq_cma_rad));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006810
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006811 WR16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50);
6812 WR16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60);
6813 WR16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100);
6814 WR16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140);
6815 WR16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80);
6816 WR16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006817
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006818 WR16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6819 WR16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32);
6820 WR16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006821
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006822 WR16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8);
6823 WR16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65);
6824 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5);
6825 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3);
6826 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) (-1));
6827 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12);
6828 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) (-23));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006829
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006830 WR16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6831 WR16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6832 WR16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6833 WR16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
6834 WR16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6835 WR16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6836 WR16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
6837 WR16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
6838 WR16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6839 WR16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6840 WR16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6841 WR16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6842 WR16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6843 WR16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6844 WR16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6845 WR16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32);
6846 WR16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144);
6847 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6848 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6849 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006850
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006851 WR16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006852
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006853 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006854rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006855 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006856}
6857
6858/*============================================================================*/
6859
6860/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006861* \fn int set_qam256 ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006862* \brief QAM256 specific setup
6863* \param demod: instance of demod.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006864* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006865*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006866static int set_qam256(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006867{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006868 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6869 const u8 qam_dq_qual_fun[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006870 DRXJ_16TO8(8), /* fun0 */
6871 DRXJ_16TO8(8), /* fun1 */
6872 DRXJ_16TO8(8), /* fun2 */
6873 DRXJ_16TO8(8), /* fun3 */
6874 DRXJ_16TO8(12), /* fun4 */
6875 DRXJ_16TO8(12), /* fun5 */
6876 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006877 const u8 qam_eq_cma_rad[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006878 DRXJ_16TO8(12345), /* RAD0 */
6879 DRXJ_16TO8(12345), /* RAD1 */
6880 DRXJ_16TO8(13626), /* RAD2 */
6881 DRXJ_16TO8(12931), /* RAD3 */
6882 DRXJ_16TO8(14719), /* RAD4 */
6883 DRXJ_16TO8(15356), /* RAD5 */
6884 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006885
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006886 WRB(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun),
6887 ((u8 *) qam_dq_qual_fun));
6888 WRB(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad),
6889 ((u8 *) qam_eq_cma_rad));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006890
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006891 WR16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50);
6892 WR16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60);
6893 WR16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100);
6894 WR16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150);
6895 WR16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80);
6896 WR16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006897
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006898 WR16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
6899 WR16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16);
6900 WR16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006901
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006902 WR16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8);
6903 WR16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74);
6904 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18);
6905 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13);
6906 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7);
6907 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0);
6908 WR16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) (-8));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006909
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006910 WR16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15);
6911 WR16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
6912 WR16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2);
6913 WR16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
6914 WR16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255);
6915 WR16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2);
6916 WR16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25);
6917 WR16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80);
6918 WR16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12);
6919 WR16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
6920 WR16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
6921 WR16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12);
6922 WR16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
6923 WR16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
6924 WR16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16);
6925 WR16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48);
6926 WR16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80);
6927 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
6928 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15);
6929 WR16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006930
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006931 WR16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006932
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006933 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006934rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006935 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006936}
6937
6938/*============================================================================*/
6939#define QAM_SET_OP_ALL 0x1
6940#define QAM_SET_OP_CONSTELLATION 0x2
6941#define QAM_SET_OP_SPECTRUM 0X4
6942
6943/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006944* \fn int set_qam ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006945* \brief Set QAM demod.
6946* \param demod: instance of demod.
6947* \param channel: pointer to channel data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006948* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006949*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03006950static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006951set_qam(pdrx_demod_instance_t demod,
6952 pdrx_channel_t channel, s32 tuner_freq_offset, u32 op)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03006953{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006954 struct i2c_device_addr *dev_addr = NULL;
6955 pdrxj_data_t ext_attr = NULL;
6956 pdrx_common_attr_t common_attr = NULL;
6957 u16 cmd_result = 0;
6958 u32 adc_frequency = 0;
6959 u32 iqm_rc_rate = 0;
6960 u16 lc_symbol_freq = 0;
6961 u16 iqm_rc_stretch = 0;
6962 u16 set_env_parameters = 0;
6963 u16 set_param_parameters[2] = { 0 };
6964 drxjscu_cmd_t cmd_scu = { /* command */ 0,
6965 /* parameter_len */ 0,
6966 /* result_len */ 0,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006967 /* parameter */ NULL,
6968 /* result */ NULL
6969 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03006970 const u8 qam_a_taps[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03006971 DRXJ_16TO8(-1), /* re0 */
6972 DRXJ_16TO8(1), /* re1 */
6973 DRXJ_16TO8(1), /* re2 */
6974 DRXJ_16TO8(-1), /* re3 */
6975 DRXJ_16TO8(-1), /* re4 */
6976 DRXJ_16TO8(2), /* re5 */
6977 DRXJ_16TO8(1), /* re6 */
6978 DRXJ_16TO8(-2), /* re7 */
6979 DRXJ_16TO8(0), /* re8 */
6980 DRXJ_16TO8(3), /* re9 */
6981 DRXJ_16TO8(-1), /* re10 */
6982 DRXJ_16TO8(-3), /* re11 */
6983 DRXJ_16TO8(4), /* re12 */
6984 DRXJ_16TO8(1), /* re13 */
6985 DRXJ_16TO8(-8), /* re14 */
6986 DRXJ_16TO8(4), /* re15 */
6987 DRXJ_16TO8(13), /* re16 */
6988 DRXJ_16TO8(-13), /* re17 */
6989 DRXJ_16TO8(-19), /* re18 */
6990 DRXJ_16TO8(28), /* re19 */
6991 DRXJ_16TO8(25), /* re20 */
6992 DRXJ_16TO8(-53), /* re21 */
6993 DRXJ_16TO8(-31), /* re22 */
6994 DRXJ_16TO8(96), /* re23 */
6995 DRXJ_16TO8(37), /* re24 */
6996 DRXJ_16TO8(-190), /* re25 */
6997 DRXJ_16TO8(-40), /* re26 */
6998 DRXJ_16TO8(619) /* re27 */
6999 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007000 const u8 qam_b64_taps[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007001 DRXJ_16TO8(0), /* re0 */
7002 DRXJ_16TO8(-2), /* re1 */
7003 DRXJ_16TO8(1), /* re2 */
7004 DRXJ_16TO8(2), /* re3 */
7005 DRXJ_16TO8(-2), /* re4 */
7006 DRXJ_16TO8(0), /* re5 */
7007 DRXJ_16TO8(4), /* re6 */
7008 DRXJ_16TO8(-2), /* re7 */
7009 DRXJ_16TO8(-4), /* re8 */
7010 DRXJ_16TO8(4), /* re9 */
7011 DRXJ_16TO8(3), /* re10 */
7012 DRXJ_16TO8(-6), /* re11 */
7013 DRXJ_16TO8(0), /* re12 */
7014 DRXJ_16TO8(6), /* re13 */
7015 DRXJ_16TO8(-5), /* re14 */
7016 DRXJ_16TO8(-3), /* re15 */
7017 DRXJ_16TO8(11), /* re16 */
7018 DRXJ_16TO8(-4), /* re17 */
7019 DRXJ_16TO8(-19), /* re18 */
7020 DRXJ_16TO8(19), /* re19 */
7021 DRXJ_16TO8(28), /* re20 */
7022 DRXJ_16TO8(-45), /* re21 */
7023 DRXJ_16TO8(-36), /* re22 */
7024 DRXJ_16TO8(90), /* re23 */
7025 DRXJ_16TO8(42), /* re24 */
7026 DRXJ_16TO8(-185), /* re25 */
7027 DRXJ_16TO8(-46), /* re26 */
7028 DRXJ_16TO8(614) /* re27 */
7029 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007030 const u8 qam_b256_taps[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007031 DRXJ_16TO8(-2), /* re0 */
7032 DRXJ_16TO8(4), /* re1 */
7033 DRXJ_16TO8(1), /* re2 */
7034 DRXJ_16TO8(-4), /* re3 */
7035 DRXJ_16TO8(0), /* re4 */
7036 DRXJ_16TO8(4), /* re5 */
7037 DRXJ_16TO8(-2), /* re6 */
7038 DRXJ_16TO8(-4), /* re7 */
7039 DRXJ_16TO8(5), /* re8 */
7040 DRXJ_16TO8(2), /* re9 */
7041 DRXJ_16TO8(-8), /* re10 */
7042 DRXJ_16TO8(2), /* re11 */
7043 DRXJ_16TO8(11), /* re12 */
7044 DRXJ_16TO8(-8), /* re13 */
7045 DRXJ_16TO8(-15), /* re14 */
7046 DRXJ_16TO8(16), /* re15 */
7047 DRXJ_16TO8(19), /* re16 */
7048 DRXJ_16TO8(-27), /* re17 */
7049 DRXJ_16TO8(-22), /* re18 */
7050 DRXJ_16TO8(44), /* re19 */
7051 DRXJ_16TO8(26), /* re20 */
7052 DRXJ_16TO8(-69), /* re21 */
7053 DRXJ_16TO8(-28), /* re22 */
7054 DRXJ_16TO8(110), /* re23 */
7055 DRXJ_16TO8(31), /* re24 */
7056 DRXJ_16TO8(-201), /* re25 */
7057 DRXJ_16TO8(-32), /* re26 */
7058 DRXJ_16TO8(628) /* re27 */
7059 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007060 const u8 qam_c_taps[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007061 DRXJ_16TO8(-3), /* re0 */
7062 DRXJ_16TO8(3), /* re1 */
7063 DRXJ_16TO8(2), /* re2 */
7064 DRXJ_16TO8(-4), /* re3 */
7065 DRXJ_16TO8(0), /* re4 */
7066 DRXJ_16TO8(4), /* re5 */
7067 DRXJ_16TO8(-1), /* re6 */
7068 DRXJ_16TO8(-4), /* re7 */
7069 DRXJ_16TO8(3), /* re8 */
7070 DRXJ_16TO8(3), /* re9 */
7071 DRXJ_16TO8(-5), /* re10 */
7072 DRXJ_16TO8(0), /* re11 */
7073 DRXJ_16TO8(9), /* re12 */
7074 DRXJ_16TO8(-4), /* re13 */
7075 DRXJ_16TO8(-12), /* re14 */
7076 DRXJ_16TO8(10), /* re15 */
7077 DRXJ_16TO8(16), /* re16 */
7078 DRXJ_16TO8(-21), /* re17 */
7079 DRXJ_16TO8(-20), /* re18 */
7080 DRXJ_16TO8(37), /* re19 */
7081 DRXJ_16TO8(25), /* re20 */
7082 DRXJ_16TO8(-62), /* re21 */
7083 DRXJ_16TO8(-28), /* re22 */
7084 DRXJ_16TO8(105), /* re23 */
7085 DRXJ_16TO8(31), /* re24 */
7086 DRXJ_16TO8(-197), /* re25 */
7087 DRXJ_16TO8(-33), /* re26 */
7088 DRXJ_16TO8(626) /* re27 */
7089 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007090
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007091 dev_addr = demod->my_i2c_dev_addr;
7092 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
7093 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007094
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007095 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007096 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007097 switch (channel->constellation) {
7098 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007099 iqm_rc_rate = 0x00AE3562;
7100 lc_symbol_freq =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007101 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
7102 channel->symbolrate = 5360537;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007103 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007104 break;
7105 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007106 iqm_rc_rate = 0x00C05A0E;
7107 lc_symbol_freq = 409;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007108 channel->symbolrate = 5056941;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007109 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007110 break;
7111 default:
7112 return (DRX_STS_INVALID_ARG);
7113 }
7114 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007115 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007116 CHK_ZERO(channel->symbolrate);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007117 iqm_rc_rate =
7118 (adc_frequency / channel->symbolrate) * (1 << 21) +
7119 (frac28
7120 ((adc_frequency % channel->symbolrate),
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007121 channel->symbolrate) >> 7) - (1 << 23);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007122 lc_symbol_freq =
7123 (u16) (frac28
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007124 (channel->symbolrate +
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007125 (adc_frequency >> 13),
7126 adc_frequency) >> 16);
7127 if (lc_symbol_freq > 511)
7128 lc_symbol_freq = 511;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007129
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007130 iqm_rc_stretch = 21;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007131 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007132
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007133 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
7134 set_env_parameters = QAM_TOP_ANNEX_A; /* annex */
7135 set_param_parameters[0] = channel->constellation; /* constellation */
7136 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
7137 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
7138 set_env_parameters = QAM_TOP_ANNEX_B; /* annex */
7139 set_param_parameters[0] = channel->constellation; /* constellation */
7140 set_param_parameters[1] = channel->interleavemode; /* interleave mode */
7141 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
7142 set_env_parameters = QAM_TOP_ANNEX_C; /* annex */
7143 set_param_parameters[0] = channel->constellation; /* constellation */
7144 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007145 } else {
7146 return (DRX_STS_INVALID_ARG);
7147 }
7148 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007149
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007150 if (op & QAM_SET_OP_ALL) {
7151 /*
7152 STEP 1: reset demodulator
7153 resets IQM, QAM and FEC HW blocks
7154 resets SCU variables
7155 */
7156 /* stop all comm_exec */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007157 WR16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
7158 WR16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
7159 WR16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
7160 WR16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
7161 WR16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
7162 WR16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
7163 WR16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007164
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007165 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007166 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007167 cmd_scu.parameter_len = 0;
7168 cmd_scu.result_len = 1;
7169 cmd_scu.parameter = NULL;
7170 cmd_scu.result = &cmd_result;
7171 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007172 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007173
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007174 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
7175 /*
7176 STEP 2: configure demodulator
7177 -set env
7178 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
7179 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007180 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007181 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007182 cmd_scu.parameter_len = 1;
7183 cmd_scu.result_len = 1;
7184 cmd_scu.parameter = &set_env_parameters;
7185 cmd_scu.result = &cmd_result;
7186 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007187
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007188 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007189 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007190 cmd_scu.parameter_len = 2;
7191 cmd_scu.result_len = 1;
7192 cmd_scu.parameter = set_param_parameters;
7193 cmd_scu.result = &cmd_result;
7194 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007195 /* set symbol rate */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007196 WR32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
7197 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
7198 CHK_ERROR(set_qam_measurement
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007199 (demod, channel->constellation, channel->symbolrate));
7200 }
7201 /* STEP 3: enable the system in a mode where the ADC provides valid signal
7202 setup constellation independent registers */
7203 /* from qam_cmd.py script (qam_driver_b) */
7204 /* TODO: remove re-writes of HW reset values */
7205 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007206 CHK_ERROR(set_frequency(demod, channel, tuner_freq_offset));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007207 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007208
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007209 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007210
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007211 WR16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq);
7212 WR16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007213 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007214
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007215 if (op & QAM_SET_OP_ALL) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007216 if (ext_attr->has_lna == false) {
7217 WR16(dev_addr, IQM_AF_AMUX__A, 0x02);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007218 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007219 WR16(dev_addr, IQM_CF_SYMMETRIC__A, 0);
7220 WR16(dev_addr, IQM_CF_MIDTAP__A, 3);
7221 WR16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007222
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007223 WR16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f); /* scu temporary shut down agc */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007224
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007225 WR16(dev_addr, IQM_AF_SYNC_SEL__A, 3);
7226 WR16(dev_addr, IQM_AF_CLP_LEN__A, 0);
7227 WR16(dev_addr, IQM_AF_CLP_TH__A, 448);
7228 WR16(dev_addr, IQM_AF_SNS_LEN__A, 0);
7229 WR16(dev_addr, IQM_AF_PDREF__A, 4);
7230 WR16(dev_addr, IQM_AF_STDBY__A, 0x10);
7231 WR16(dev_addr, IQM_AF_PGA_GAIN__A, 11);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007232
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007233 WR16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1);
7234 WR16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE); /*! reset default val ! */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007235
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007236 WR16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE); /*! reset default val ! */
7237 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
7238 WR16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE); /*! reset default val ! */
7239 WR16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE); /*! reset default val ! */
7240 WR16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE); /*! reset default val ! */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007241 } else {
7242 switch (channel->constellation) {
7243 case DRX_CONSTELLATION_QAM16:
7244 case DRX_CONSTELLATION_QAM64:
7245 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007246 WR16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03);
7247 WR16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04);
7248 WR16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE); /*! reset default val ! */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007249 break;
7250 case DRX_CONSTELLATION_QAM32:
7251 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007252 WR16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03);
7253 WR16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05);
7254 WR16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007255 break;
7256 default:
7257 return (DRX_STS_ERROR);
7258 } /* switch */
7259 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007260
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007261 WR16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE); /*! reset default val ! */
7262 WR16(dev_addr, QAM_LC_RATE_LIMIT__A, 3);
7263 WR16(dev_addr, QAM_LC_LPF_FACTORP__A, 4);
7264 WR16(dev_addr, QAM_LC_LPF_FACTORI__A, 4);
7265 WR16(dev_addr, QAM_LC_MODE__A, 7);
7266 WR16(dev_addr, QAM_LC_QUAL_TAB0__A, 1);
7267 WR16(dev_addr, QAM_LC_QUAL_TAB1__A, 1);
7268 WR16(dev_addr, QAM_LC_QUAL_TAB2__A, 1);
7269 WR16(dev_addr, QAM_LC_QUAL_TAB3__A, 1);
7270 WR16(dev_addr, QAM_LC_QUAL_TAB4__A, 2);
7271 WR16(dev_addr, QAM_LC_QUAL_TAB5__A, 2);
7272 WR16(dev_addr, QAM_LC_QUAL_TAB6__A, 2);
7273 WR16(dev_addr, QAM_LC_QUAL_TAB8__A, 2);
7274 WR16(dev_addr, QAM_LC_QUAL_TAB9__A, 2);
7275 WR16(dev_addr, QAM_LC_QUAL_TAB10__A, 2);
7276 WR16(dev_addr, QAM_LC_QUAL_TAB12__A, 2);
7277 WR16(dev_addr, QAM_LC_QUAL_TAB15__A, 3);
7278 WR16(dev_addr, QAM_LC_QUAL_TAB16__A, 3);
7279 WR16(dev_addr, QAM_LC_QUAL_TAB20__A, 4);
7280 WR16(dev_addr, QAM_LC_QUAL_TAB25__A, 4);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007281
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007282 WR16(dev_addr, IQM_FS_ADJ_SEL__A, 1);
7283 WR16(dev_addr, IQM_RC_ADJ_SEL__A, 1);
7284 WR16(dev_addr, IQM_CF_ADJ_SEL__A, 1);
7285 WR16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0);
7286 WR16(dev_addr, SCU_RAM_GPIO__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007287
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007288 /* No more resets of the IQM, current standard correctly set =>
7289 now AGCs can be configured. */
7290 /* turn on IQMAF. It has to be in front of setAgc**() */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007291 CHK_ERROR(set_iqm_af(demod, true));
7292 CHK_ERROR(adc_synchronization(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007293
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007294 CHK_ERROR(init_agc(demod));
7295 CHK_ERROR(set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false));
7296 CHK_ERROR(set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007297 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007298 /* TODO fix this, store a drxj_cfg_afe_gain_t structure in drxj_data_t instead
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007299 of only the gain */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007300 drxj_cfg_afe_gain_t qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007301
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007302 qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
7303 CHK_ERROR(ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007304 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007305 CHK_ERROR(ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg)));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007306 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007307
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007308 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007309 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
7310 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps),
7311 ((u8 *) qam_a_taps));
7312 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps),
7313 ((u8 *) qam_a_taps));
7314 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007315 switch (channel->constellation) {
7316 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007317 WRB(dev_addr, IQM_CF_TAP_RE0__A,
7318 sizeof(qam_b64_taps), ((u8 *) qam_b64_taps));
7319 WRB(dev_addr, IQM_CF_TAP_IM0__A,
7320 sizeof(qam_b64_taps), ((u8 *) qam_b64_taps));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007321 break;
7322 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007323 WRB(dev_addr, IQM_CF_TAP_RE0__A,
7324 sizeof(qam_b256_taps),
7325 ((u8 *) qam_b256_taps));
7326 WRB(dev_addr, IQM_CF_TAP_IM0__A,
7327 sizeof(qam_b256_taps),
7328 ((u8 *) qam_b256_taps));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007329 break;
7330 default:
7331 return (DRX_STS_ERROR);
7332 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007333 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
7334 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps),
7335 ((u8 *) qam_c_taps));
7336 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps),
7337 ((u8 *) qam_c_taps));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007338 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007339
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007340 /* SETP 4: constellation specific setup */
7341 switch (channel->constellation) {
7342 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007343 CHK_ERROR(set_qam16(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007344 break;
7345 case DRX_CONSTELLATION_QAM32:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007346 CHK_ERROR(set_qam32(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007347 break;
7348 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007349 CHK_ERROR(set_qam64(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007350 break;
7351 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007352 CHK_ERROR(set_qam128(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007353 break;
7354 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007355 CHK_ERROR(set_qam256(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007356 break;
7357 default:
7358 return (DRX_STS_ERROR);
7359 } /* switch */
7360 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007361
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007362 if ((op & QAM_SET_OP_ALL)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007363 WR16(dev_addr, IQM_CF_SCALE_SH__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007364
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007365 /* Mpeg output has to be in front of FEC active */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007366 CHK_ERROR(set_mpegtei_handling(demod));
7367 CHK_ERROR(bit_reverse_mpeg_output(demod));
7368 CHK_ERROR(set_mpeg_start_width(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007369 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007370 /* TODO: move to set_standard after hardware reset value problem is solved */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007371 /* Configure initial MPEG output */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007372 drx_cfg_mpeg_output_t cfg_mpeg_output;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007373
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007374 cfg_mpeg_output.enable_mpeg_output = true;
7375 cfg_mpeg_output.insert_rs_byte =
7376 common_attr->mpeg_cfg.insert_rs_byte;
7377 cfg_mpeg_output.enable_parallel =
7378 common_attr->mpeg_cfg.enable_parallel;
7379 cfg_mpeg_output.invert_data =
7380 common_attr->mpeg_cfg.invert_data;
7381 cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
7382 cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
7383 cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
7384 cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
7385 cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
7386 cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
7387 CHK_ERROR(ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007388 }
7389 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007390
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007391 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007392
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007393 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007394 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007395 SCU_RAM_COMMAND_CMD_DEMOD_START;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007396 cmd_scu.parameter_len = 0;
7397 cmd_scu.result_len = 1;
7398 cmd_scu.parameter = NULL;
7399 cmd_scu.result = &cmd_result;
7400 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007401 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007402
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007403 WR16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE);
7404 WR16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
7405 WR16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007406
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007407 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007408rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007409 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007410}
7411
7412/*============================================================================*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007413static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007414ctrl_get_qam_sig_quality(pdrx_demod_instance_t demod, pdrx_sig_quality_t sig_quality);
7415static int qam_flip_spec(pdrx_demod_instance_t demod, pdrx_channel_t channel)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007416{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007417 u32 iqm_fs_rate_ofs = 0;
7418 u32 iqm_fs_rate_lo = 0;
7419 u16 qam_ctl_ena = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03007420 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007421 u16 equ_mode = 0;
7422 u16 fsm_state = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007423 int i = 0;
7424 int ofsofs = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007425 struct i2c_device_addr *dev_addr = NULL;
7426 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007427
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007428 dev_addr = demod->my_i2c_dev_addr;
7429 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007430
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007431 /* Silence the controlling of lc, equ, and the acquisition state machine */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007432 RR16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena);
7433 WR16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007434 & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M
7435 | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007436
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007437 /* freeze the frequency control loop */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007438 WR16(dev_addr, QAM_LC_CF__A, 0);
7439 WR16(dev_addr, QAM_LC_CF1__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007440
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007441 ARR32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs);
7442 ARR32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo);
7443 ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
7444 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
7445 iqm_fs_rate_ofs -= 2 * ofsofs;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007446
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007447 /* freeze dq/fq updating */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007448 RR16(dev_addr, QAM_DQ_MODE__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007449 data = (data & 0xfff9);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007450 WR16(dev_addr, QAM_DQ_MODE__A, data);
7451 WR16(dev_addr, QAM_FQ_MODE__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007452
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007453 /* lc_cp / _ci / _ca */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007454 WR16(dev_addr, QAM_LC_CI__A, 0);
7455 WR16(dev_addr, QAM_LC_EP__A, 0);
7456 WR16(dev_addr, QAM_FQ_LA_FACTOR__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007457
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007458 /* flip the spec */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007459 WR32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs);
7460 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
7461 ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007462
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007463 /* freeze dq/fq updating */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007464 RR16(dev_addr, QAM_DQ_MODE__A, &data);
7465 equ_mode = data;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007466 data = (data & 0xfff9);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007467 WR16(dev_addr, QAM_DQ_MODE__A, data);
7468 WR16(dev_addr, QAM_FQ_MODE__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007469
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007470 for (i = 0; i < 28; i++) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007471 RR16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data);
7472 WR16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007473 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007474
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007475 for (i = 0; i < 24; i++) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007476 RR16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data);
7477 WR16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007478 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007479
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007480 data = equ_mode;
7481 WR16(dev_addr, QAM_DQ_MODE__A, data);
7482 WR16(dev_addr, QAM_FQ_MODE__A, data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007483
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007484 WR16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007485
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007486 i = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007487 while ((fsm_state != 4) && (i++ < 100)) {
7488 RR16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007489 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007490 WR16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007491
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007492 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007493rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007494 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007495
7496}
7497
7498#define NO_LOCK 0x0
7499#define DEMOD_LOCKED 0x1
7500#define SYNC_FLIPPED 0x2
7501#define SPEC_MIRRORED 0x4
7502/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007503* \fn int qam64auto ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007504* \brief auto do sync pattern switching and mirroring.
7505* \param demod: instance of demod.
7506* \param channel: pointer to channel data.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007507* \param tuner_freq_offset: tuner frequency offset.
7508* \param lock_status: pointer to lock status.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007509* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007510*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007511static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007512qam64auto(pdrx_demod_instance_t demod,
7513 pdrx_channel_t channel,
7514 s32 tuner_freq_offset, pdrx_lock_status_t lock_status)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007515{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007516 drx_sig_quality_t sig_quality;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03007517 u16 data = 0;
7518 u32 state = NO_LOCK;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007519 u32 start_time = 0;
7520 u32 d_locked_time = 0;
7521 pdrxj_data_t ext_attr = NULL;
7522 u32 timeout_ofs = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007523
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007524 /* external attributes for storing aquired channel constellation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007525 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
7526 *lock_status = DRX_NOT_LOCKED;
7527 start_time = drxbsp_hst_clock();
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007528 state = NO_LOCK;
7529 do {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007530 CHK_ERROR(ctrl_lock_status(demod, lock_status));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007531
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007532 switch (state) {
7533 case NO_LOCK:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007534 if (*lock_status == DRXJ_DEMOD_LOCK) {
7535 CHK_ERROR(ctrl_get_qam_sig_quality
7536 (demod, &sig_quality));
7537 if (sig_quality.MER > 208) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007538 state = DEMOD_LOCKED;
7539 /* some delay to see if fec_lock possible TODO find the right value */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007540 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
7541 d_locked_time = drxbsp_hst_clock();
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007542 }
7543 }
7544 break;
7545 case DEMOD_LOCKED:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007546 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
7547 ((drxbsp_hst_clock() - d_locked_time) >
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007548 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007549 RR16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007550 &data);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007551 WR16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007552 data | 0x1);
7553 state = SYNC_FLIPPED;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007554 drxbsp_hst_sleep(10);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007555 }
7556 break;
7557 case SYNC_FLIPPED:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007558 if (*lock_status == DRXJ_DEMOD_LOCK) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007559 if (channel->mirror == DRX_MIRROR_AUTO) {
7560 /* flip sync pattern back */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007561 RR16(demod->my_i2c_dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007562 QAM_SY_TIMEOUT__A, &data);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007563 WR16(demod->my_i2c_dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007564 QAM_SY_TIMEOUT__A, data & 0xFFFE);
7565 /* flip spectrum */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007566 ext_attr->mirror = DRX_MIRROR_YES;
7567 CHK_ERROR(qam_flip_spec(demod, channel));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007568 state = SPEC_MIRRORED;
7569 /* reset timer TODO: still need 500ms? */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007570 start_time = d_locked_time =
7571 drxbsp_hst_clock();
7572 timeout_ofs = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007573 } else { /* no need to wait lock */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007574
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007575 start_time =
7576 drxbsp_hst_clock() -
7577 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007578 }
7579 }
7580 break;
7581 case SPEC_MIRRORED:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007582 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
7583 ((drxbsp_hst_clock() - d_locked_time) >
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007584 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007585 CHK_ERROR(ctrl_get_qam_sig_quality
7586 (demod, &sig_quality));
7587 if (sig_quality.MER > 208) {
7588 RR16(demod->my_i2c_dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007589 QAM_SY_TIMEOUT__A, &data);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007590 WR16(demod->my_i2c_dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007591 QAM_SY_TIMEOUT__A, data | 0x1);
7592 /* no need to wait lock */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007593 start_time =
7594 drxbsp_hst_clock() -
7595 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007596 }
7597 }
7598 break;
7599 default:
7600 break;
7601 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007602 drxbsp_hst_sleep(10);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007603 } while
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007604 ((*lock_status != DRX_LOCKED) &&
7605 (*lock_status != DRX_NEVER_LOCK) &&
7606 ((drxbsp_hst_clock() - start_time) <
7607 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007608 );
7609 /* Returning control to apllication ... */
7610
7611 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007612rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007613 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007614}
7615
7616/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007617* \fn int qam256auto ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007618* \brief auto do sync pattern switching and mirroring.
7619* \param demod: instance of demod.
7620* \param channel: pointer to channel data.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007621* \param tuner_freq_offset: tuner frequency offset.
7622* \param lock_status: pointer to lock status.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007623* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007624*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007625static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007626qam256auto(pdrx_demod_instance_t demod,
7627 pdrx_channel_t channel,
7628 s32 tuner_freq_offset, pdrx_lock_status_t lock_status)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007629{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007630 drx_sig_quality_t sig_quality;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03007631 u32 state = NO_LOCK;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007632 u32 start_time = 0;
7633 u32 d_locked_time = 0;
7634 pdrxj_data_t ext_attr = NULL;
7635 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007636
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007637 /* external attributes for storing aquired channel constellation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007638 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
7639 *lock_status = DRX_NOT_LOCKED;
7640 start_time = drxbsp_hst_clock();
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007641 state = NO_LOCK;
7642 do {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007643 CHK_ERROR(ctrl_lock_status(demod, lock_status));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007644 switch (state) {
7645 case NO_LOCK:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007646 if (*lock_status == DRXJ_DEMOD_LOCK) {
7647 CHK_ERROR(ctrl_get_qam_sig_quality
7648 (demod, &sig_quality));
7649 if (sig_quality.MER > 268) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007650 state = DEMOD_LOCKED;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007651 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
7652 d_locked_time = drxbsp_hst_clock();
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007653 }
7654 }
7655 break;
7656 case DEMOD_LOCKED:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007657 if (*lock_status == DRXJ_DEMOD_LOCK) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007658 if ((channel->mirror == DRX_MIRROR_AUTO) &&
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007659 ((drxbsp_hst_clock() - d_locked_time) >
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007660 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007661 ext_attr->mirror = DRX_MIRROR_YES;
7662 CHK_ERROR(qam_flip_spec(demod, channel));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007663 state = SPEC_MIRRORED;
7664 /* reset timer TODO: still need 300ms? */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007665 start_time = drxbsp_hst_clock();
7666 timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007667 }
7668 }
7669 break;
7670 case SPEC_MIRRORED:
7671 break;
7672 default:
7673 break;
7674 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007675 drxbsp_hst_sleep(10);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007676 } while
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007677 ((*lock_status < DRX_LOCKED) &&
7678 (*lock_status != DRX_NEVER_LOCK) &&
7679 ((drxbsp_hst_clock() - start_time) <
7680 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007681
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007682 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007683rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007684 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007685}
7686
7687/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007688* \fn int set_qamChannel ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007689* \brief Set QAM channel according to the requested constellation.
7690* \param demod: instance of demod.
7691* \param channel: pointer to channel data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007692* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007693*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007694static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007695set_qamChannel(pdrx_demod_instance_t demod,
7696 pdrx_channel_t channel, s32 tuner_freq_offset)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007697{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007698 drx_lock_status_t lock_status = DRX_NOT_LOCKED;
7699 pdrxj_data_t ext_attr = NULL;
7700 bool auto_flag = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007701
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007702 /* external attributes for storing aquired channel constellation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007703 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007704
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007705 /* set QAM channel constellation */
7706 switch (channel->constellation) {
7707 case DRX_CONSTELLATION_QAM16:
7708 case DRX_CONSTELLATION_QAM32:
7709 case DRX_CONSTELLATION_QAM64:
7710 case DRX_CONSTELLATION_QAM128:
7711 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007712 ext_attr->constellation = channel->constellation;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007713 if (channel->mirror == DRX_MIRROR_AUTO) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007714 ext_attr->mirror = DRX_MIRROR_NO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007715 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007716 ext_attr->mirror = channel->mirror;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007717 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007718 CHK_ERROR(set_qam
7719 (demod, channel, tuner_freq_offset, QAM_SET_OP_ALL));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007720
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007721 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007722 (channel->constellation == DRX_CONSTELLATION_QAM64)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007723 CHK_ERROR(qam64auto
7724 (demod, channel, tuner_freq_offset,
7725 &lock_status));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007726 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007727
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007728 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007729 (channel->mirror == DRX_MIRROR_AUTO) &&
7730 (channel->constellation == DRX_CONSTELLATION_QAM256)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007731 CHK_ERROR(qam256auto
7732 (demod, channel, tuner_freq_offset,
7733 &lock_status));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007734 }
7735 break;
7736 case DRX_CONSTELLATION_AUTO: /* for channel scan */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007737 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
7738 auto_flag = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007739 /* try to lock default QAM constellation: QAM64 */
7740 channel->constellation = DRX_CONSTELLATION_QAM256;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007741 ext_attr->constellation = DRX_CONSTELLATION_QAM256;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007742 if (channel->mirror == DRX_MIRROR_AUTO) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007743 ext_attr->mirror = DRX_MIRROR_NO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007744 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007745 ext_attr->mirror = channel->mirror;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007746 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007747 CHK_ERROR(set_qam
7748 (demod, channel, tuner_freq_offset,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007749 QAM_SET_OP_ALL));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007750 CHK_ERROR(qam256auto
7751 (demod, channel, tuner_freq_offset,
7752 &lock_status));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007753
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007754 if (lock_status < DRX_LOCKED) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007755 /* QAM254 not locked -> try to lock QAM64 constellation */
7756 channel->constellation =
7757 DRX_CONSTELLATION_QAM64;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007758 ext_attr->constellation =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007759 DRX_CONSTELLATION_QAM64;
7760 if (channel->mirror == DRX_MIRROR_AUTO) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007761 ext_attr->mirror = DRX_MIRROR_NO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007762 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007763 ext_attr->mirror = channel->mirror;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007764 }
7765 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007766 u16 qam_ctl_ena = 0;
7767 RR16(demod->my_i2c_dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007768 SCU_RAM_QAM_CTL_ENA__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007769 &qam_ctl_ena);
7770 WR16(demod->my_i2c_dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007771 SCU_RAM_QAM_CTL_ENA__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007772 qam_ctl_ena &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007773 ~SCU_RAM_QAM_CTL_ENA_ACQ__M);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007774 WR16(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2); /* force to rate hunting */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007775
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007776 CHK_ERROR(set_qam
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007777 (demod, channel,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007778 tuner_freq_offset,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007779 QAM_SET_OP_CONSTELLATION));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007780 WR16(demod->my_i2c_dev_addr,
7781 SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007782 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007783 CHK_ERROR(qam64auto
7784 (demod, channel, tuner_freq_offset,
7785 &lock_status));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007786 }
7787 channel->constellation = DRX_CONSTELLATION_AUTO;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007788 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007789 channel->constellation = DRX_CONSTELLATION_QAM64;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007790 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
7791 auto_flag = true;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007792
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007793 if (channel->mirror == DRX_MIRROR_AUTO) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007794 ext_attr->mirror = DRX_MIRROR_NO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007795 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007796 ext_attr->mirror = channel->mirror;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007797 }
7798 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007799 u16 qam_ctl_ena = 0;
7800 RR16(demod->my_i2c_dev_addr,
7801 SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena);
7802 WR16(demod->my_i2c_dev_addr,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007803 SCU_RAM_QAM_CTL_ENA__A,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007804 qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M);
7805 WR16(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2); /* force to rate hunting */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007806
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007807 CHK_ERROR(set_qam
7808 (demod, channel, tuner_freq_offset,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007809 QAM_SET_OP_CONSTELLATION));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007810 WR16(demod->my_i2c_dev_addr,
7811 SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007812 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007813 CHK_ERROR(qam64auto
7814 (demod, channel, tuner_freq_offset,
7815 &lock_status));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007816 channel->constellation = DRX_CONSTELLATION_AUTO;
7817 } else {
7818 channel->constellation = DRX_CONSTELLATION_AUTO;
7819 return (DRX_STS_INVALID_ARG);
7820 }
7821 break;
7822 default:
7823 return (DRX_STS_INVALID_ARG);
7824 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007825
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007826 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007827rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007828 /* restore starting value */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007829 if (auto_flag)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007830 channel->constellation = DRX_CONSTELLATION_AUTO;
7831 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007832}
7833
7834/*============================================================================*/
7835
7836/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007837* \fn static short GetQAMRSErr_count(struct i2c_device_addr *dev_addr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007838* \brief Get RS error count in QAM mode (used for post RS BER calculation)
7839* \return Error code
7840*
7841* precondition: measurement period & measurement prescale must be set
7842*
7843*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007844static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007845GetQAMRSErr_count(struct i2c_device_addr *dev_addr, p_drxjrs_errors_t rs_errors)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007846{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007847 u16 nr_bit_errors = 0,
7848 nr_symbol_errors = 0,
7849 nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007850
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007851 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007852 if (dev_addr == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007853 return (DRX_STS_INVALID_ARG);
7854 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007855
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007856 /* all reported errors are received in the */
7857 /* most recently finished measurment period */
7858 /* no of pre RS bit errors */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007859 RR16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007860 /* no of symbol errors */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007861 RR16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007862 /* no of packet errors */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007863 RR16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007864 /* no of failures to decode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007865 RR16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007866 /* no of post RS bit erros */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007867 RR16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007868 /* TODO: NOTE */
7869 /* These register values are fetched in non-atomic fashion */
7870 /* It is possible that the read values contain unrelated information */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007871
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007872 rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
7873 rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
7874 rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
7875 rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
7876 rs_errors->nr_snc_par_fail_count =
7877 nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007878
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007879 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007880rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007881 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007882}
7883
7884/*============================================================================*/
7885
7886/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007887* \fn int ctrl_get_qam_sig_quality()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007888* \brief Retreive QAM signal quality from device.
7889* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007890* \param sig_quality Pointer to signal quality data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007891* \return int.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007892* \retval DRX_STS_OK sig_quality contains valid data.
7893* \retval DRX_STS_INVALID_ARG sig_quality is NULL.
7894* \retval DRX_STS_ERROR Erroneous data, sig_quality contains invalid data.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007895
7896* Pre-condition: Device must be started and in lock.
7897*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007898static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007899ctrl_get_qam_sig_quality(pdrx_demod_instance_t demod, pdrx_sig_quality_t sig_quality)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007900{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007901 struct i2c_device_addr *dev_addr = NULL;
7902 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03007903 enum drx_modulation constellation = DRX_CONSTELLATION_UNKNOWN;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007904 DRXJrs_errors_t measuredrs_errors = { 0, 0, 0, 0, 0 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007905
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007906 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
7907 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
7908 u32 pkt_errs = 0; /* no of packet errors in RS */
7909 u16 qam_sl_err_power = 0; /* accumulated error between raw and sliced symbols */
7910 u16 qsym_err_vd = 0; /* quadrature symbol errors in QAM_VD */
7911 u16 fec_oc_period = 0; /* SNC sync failure measurement period */
7912 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
7913 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007914 /* calculation constants */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007915 u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
7916 u32 qam_sl_sig_power = 0; /* used for MER, depends of QAM constellation */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007917 /* intermediate results */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03007918 u32 e = 0; /* exponent value used for QAM BER/SER */
7919 u32 m = 0; /* mantisa value used for QAM BER/SER */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007920 u32 ber_cnt = 0; /* BER count */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007921 /* signal quality info */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007922 u32 qam_sl_mer = 0; /* QAM MER */
7923 u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
7924 u32 qam_post_rs_ber = 0; /* Post RedSolomon BER */
7925 u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
7926 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
7927 u16 qam_vd_period = 0; /* Viterbi Measurement period */
7928 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007929
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007930 /* get device basic information */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007931 dev_addr = demod->my_i2c_dev_addr;
7932 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
7933 constellation = ext_attr->constellation;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007934
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007935 /* read the physical registers */
7936 /* Get the RS error data */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007937 CHK_ERROR(GetQAMRSErr_count(dev_addr, &measuredrs_errors));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007938 /* get the register value needed for MER */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007939 RR16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007940 /* get the register value needed for post RS BER */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007941 RR16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007942
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007943 /* get constants needed for signal quality calculation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007944 fec_rs_period = ext_attr->fec_rs_period;
7945 fec_rs_prescale = ext_attr->fec_rs_prescale;
7946 rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
7947 qam_vd_period = ext_attr->qam_vd_period;
7948 qam_vd_prescale = ext_attr->qam_vd_prescale;
7949 vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007950
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007951 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
7952 switch (constellation) {
7953 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007954 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007955 break;
7956 case DRX_CONSTELLATION_QAM32:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007957 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007958 break;
7959 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007960 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007961 break;
7962 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007963 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007964 break;
7965 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007966 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007967 break;
7968 default:
7969 return (DRX_STS_ERROR);
7970 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007971
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007972 /* ------------------------------ */
7973 /* MER Calculation */
7974 /* ------------------------------ */
7975 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007976
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007977 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007978 if (qam_sl_err_power == 0)
7979 qam_sl_mer = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007980 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007981 qam_sl_mer =
7982 log1_times100(qam_sl_sig_power) -
7983 log1_times100((u32) qam_sl_err_power);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007984
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007985 /* ----------------------------------------- */
7986 /* Pre Viterbi Symbol Error Rate Calculation */
7987 /* ----------------------------------------- */
7988 /* pre viterbi SER is good if it is bellow 0.025 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007989
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007990 /* get the register value */
7991 /* no of quadrature symbol errors */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007992 RR16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007993 /* Extract the Exponent and the Mantisa */
7994 /* of number of quadrature symbol errors */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007995 e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007996 QAM_VD_NR_QSYM_ERRORS_EXP__B;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03007997 m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03007998 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03007999
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008000 if ((m << e) >> 3 > 549752) { /* the max of frac_times1e6 */
8001 qam_vd_ser = 500000; /* clip BER 0.5 */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008002 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008003 qam_vd_ser =
8004 frac_times1e6(m << ((e > 2) ? (e - 3) : e),
8005 vd_bit_cnt * ((e > 2) ? 1 : 8) / 8);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008006 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008007
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008008 /* --------------------------------------- */
8009 /* pre and post RedSolomon BER Calculation */
8010 /* --------------------------------------- */
8011 /* pre RS BER is good if it is below 3.5e-4 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008012
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008013 /* get the register values */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008014 pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
8015 pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008016
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008017 /* Extract the Exponent and the Mantisa of the */
8018 /* pre Reed-Solomon bit error count */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008019 e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008020 FEC_RS_NR_BIT_ERRORS_EXP__B;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008021 m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008022 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008023
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008024 ber_cnt = m << e;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008025
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008026 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
8027 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0) {
8028 qam_pre_rs_ber = 500000; /* clip BER 0.5 */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008029 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008030 qam_pre_rs_ber = frac_times1e6(m, rs_bit_cnt >> e);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008031 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008032
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008033 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
8034 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
8035 /*
8036 => c = (1000000*100*11.17)/1504 =
8037 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
8038 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
8039 *100 and /100 is for more precision.
8040 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008041
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008042 Precision errors still possible.
8043 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008044 e = post_bit_err_rs * 742686;
8045 m = fec_oc_period * 100;
8046 if (fec_oc_period == 0)
8047 qam_post_rs_ber = 0xFFFFFFFF;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008048 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008049 qam_post_rs_ber = e / m;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008050
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008051 /* fill signal quality data structure */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008052 sig_quality->MER = ((u16) qam_sl_mer);
8053 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8054 sig_quality->pre_viterbi_ber = qam_vd_ser;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008055 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008056 sig_quality->pre_viterbi_ber = qam_pre_rs_ber;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008057 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008058 sig_quality->post_viterbi_ber = qam_pre_rs_ber;
8059 sig_quality->post_reed_solomon_ber = qam_post_rs_ber;
8060 sig_quality->scale_factor_ber = ((u32) 1000000);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008061#ifdef DRXJ_SIGNAL_ACCUM_ERR
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008062 CHK_ERROR(get_acc_pkt_err(demod, &sig_quality->packet_error));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008063#else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008064 sig_quality->packet_error = ((u16) pkt_errs);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008065#endif
8066
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008067 return (DRX_STS_OK);
8068rw_error:
8069 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008070}
8071
8072/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008073* \fn int ctrl_get_qam_constel()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008074* \brief Retreive a QAM constellation point via I2C.
8075* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008076* \param complex_nr Pointer to the structure in which to store the
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008077 constellation point.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008078* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008079*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008080static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008081ctrl_get_qam_constel(pdrx_demod_instance_t demod, pdrx_complex_t complex_nr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008082{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008083 u16 fec_oc_ocr_mode = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008084 /**< FEC OCR grabber configuration */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008085 u16 qam_sl_comm_mb = 0;/**< QAM SL MB configuration */
8086 u16 qam_sl_comm_mbInit = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008087 /**< QAM SL MB intial configuration */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008088 u16 im = 0; /**< constellation Im part */
8089 u16 re = 0; /**< constellation Re part */
8090 u32 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008091 struct i2c_device_addr *dev_addr = NULL;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008092 /**< device address */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008093
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008094 /* read device info */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008095 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008096
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008097 /* TODO: */
8098 /* Monitor bus grabbing is an open external interface issue */
8099 /* Needs to be checked when external interface PG is updated */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008100
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008101 /* Configure MB (Monitor bus) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008102 RR16(dev_addr, QAM_SL_COMM_MB__A, &qam_sl_comm_mbInit);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008103 /* set observe flag & MB mux */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008104 qam_sl_comm_mb = qam_sl_comm_mbInit & (~(QAM_SL_COMM_MB_OBS__M +
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008105 QAM_SL_COMM_MB_MUX_OBS__M));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008106 qam_sl_comm_mb |= (QAM_SL_COMM_MB_OBS_ON +
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008107 QAM_SL_COMM_MB_MUX_OBS_CONST_CORR);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008108 WR16(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008109
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008110 /* Enable MB grabber in the FEC OC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008111 fec_oc_ocr_mode = (/* output select: observe bus */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008112 (FEC_OC_OCR_MODE_MB_SELECT__M &
8113 (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B)) |
8114 /* grabber enable: on */
8115 (FEC_OC_OCR_MODE_GRAB_ENABLE__M &
8116 (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B)) |
8117 /* grabber select: observe bus */
8118 (FEC_OC_OCR_MODE_GRAB_SELECT__M &
8119 (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B)) |
8120 /* grabber mode: continuous */
8121 (FEC_OC_OCR_MODE_GRAB_COUNTED__M &
8122 (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B)));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008123 WR16(dev_addr, FEC_OC_OCR_MODE__A, fec_oc_ocr_mode);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008124
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008125 /* Disable MB grabber in the FEC OC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008126 WR16(dev_addr, FEC_OC_OCR_MODE__A, 0x00);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008127
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008128 /* read data */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008129 RR32(dev_addr, FEC_OC_OCR_GRAB_RD0__A, &data);
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008130 re = (u16) (data & FEC_OC_OCR_GRAB_RD0__M);
8131 im = (u16) ((data >> 16) & FEC_OC_OCR_GRAB_RD1__M);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008132
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008133 /* TODO: */
8134 /* interpret data (re & im) according to the Monitor bus mapping ?? */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008135
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008136 /* sign extension, 10th bit is sign bit */
8137 if ((re & 0x0200) == 0x0200) {
8138 re |= 0xFC00;
8139 }
8140 if ((im & 0x0200) == 0x0200) {
8141 im |= 0xFC00;
8142 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008143 complex_nr->re = ((s16) re);
8144 complex_nr->im = ((s16) im);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008145
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008146 /* Restore MB (Monitor bus) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008147 WR16(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mbInit);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008148
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008149 return (DRX_STS_OK);
8150rw_error:
8151 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008152}
8153#endif /* #ifndef DRXJ_VSB_ONLY */
8154
8155/*============================================================================*/
8156/*== END QAM DATAPATH FUNCTIONS ==*/
8157/*============================================================================*/
8158
8159/*============================================================================*/
8160/*============================================================================*/
8161/*== ATV DATAPATH FUNCTIONS ==*/
8162/*============================================================================*/
8163/*============================================================================*/
8164
8165/*
8166 Implementation notes.
8167
8168 NTSC/FM AGCs
8169
8170 Four AGCs are used for NTSC:
8171 (1) RF (used to attenuate the input signal in case of to much power)
8172 (2) IF (used to attenuate the input signal in case of to much power)
8173 (3) Video AGC (used to amplify the output signal in case input to low)
8174 (4) SIF AGC (used to amplify the output signal in case input to low)
8175
8176 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
8177 that the coupling between Video AGC and the RF and IF AGCs also works in
8178 favor of the SIF AGC.
8179
8180 Three AGCs are used for FM:
8181 (1) RF (used to attenuate the input signal in case of to much power)
8182 (2) IF (used to attenuate the input signal in case of to much power)
8183 (3) SIF AGC (used to amplify the output signal in case input to low)
8184
8185 The SIF AGC is now coupled to the RF/IF AGCs.
8186 The SIF AGC is needed for both SIF ouput and the internal SIF signal to
8187 the AUD block.
8188
8189 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
8190 the ATV block. The AGC control algorithms are all implemented in
8191 microcode.
8192
8193 ATV SETTINGS
8194
8195 (Shadow settings will not be used for now, they will be implemented
8196 later on because of the schedule)
8197
8198 Several HW/SCU "settings" can be used for ATV. The standard selection
8199 will reset most of these settings. To avoid that the end user apllication
8200 has to perform these settings each time the ATV or FM standards is
8201 selected the driver will shadow these settings. This enables the end user
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008202 to perform the settings only once after a drx_open(). The driver must
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008203 write the shadow settings to HW/SCU incase:
8204 ( setstandard FM/ATV) ||
8205 ( settings have changed && FM/ATV standard is active)
8206 The shadow settings will be stored in the device specific data container.
8207 A set of flags will be defined to flag changes in shadow settings.
8208 A routine will be implemented to write all changed shadow settings to
8209 HW/SCU.
8210
8211 The "settings" will consist of: AGC settings, filter settings etc.
8212
8213 Disadvantage of use of shadow settings:
8214 Direct changes in HW/SCU registers will not be reflected in the
8215 shadow settings and these changes will be overwritten during a next
8216 update. This can happen during evaluation. This will not be a problem
8217 for normal customer usage.
8218*/
8219/* -------------------------------------------------------------------------- */
8220
8221/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008222* \brief Get array index for atv coef (ext_attr->atvTopCoefX[index])
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008223* \param standard
8224* \param pointer to index
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008225* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008226*
8227*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008228static int atv_equ_coef_index(enum drx_standard standard, int *index)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008229{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008230 switch (standard) {
8231 case DRX_STANDARD_PAL_SECAM_BG:
8232 *index = (int)DRXJ_COEF_IDX_BG;
8233 break;
8234 case DRX_STANDARD_PAL_SECAM_DK:
8235 *index = (int)DRXJ_COEF_IDX_DK;
8236 break;
8237 case DRX_STANDARD_PAL_SECAM_I:
8238 *index = (int)DRXJ_COEF_IDX_I;
8239 break;
8240 case DRX_STANDARD_PAL_SECAM_L:
8241 *index = (int)DRXJ_COEF_IDX_L;
8242 break;
8243 case DRX_STANDARD_PAL_SECAM_LP:
8244 *index = (int)DRXJ_COEF_IDX_LP;
8245 break;
8246 case DRX_STANDARD_NTSC:
8247 *index = (int)DRXJ_COEF_IDX_MN;
8248 break;
8249 case DRX_STANDARD_FM:
8250 *index = (int)DRXJ_COEF_IDX_FM;
8251 break;
8252 default:
8253 *index = (int)DRXJ_COEF_IDX_MN; /* still return a valid index */
8254 return DRX_STS_ERROR;
8255 break;
8256 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008257
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008258 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008259}
8260
8261/* -------------------------------------------------------------------------- */
8262/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008263* \fn int atv_update_config ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008264* \brief Flush changes in ATV shadow registers to physical registers.
8265* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008266* \param force_update don't look at standard or change flags, flush all.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008267* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008268*
8269*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008270static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008271atv_update_config(pdrx_demod_instance_t demod, bool force_update)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008272{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008273 struct i2c_device_addr *dev_addr = NULL;
8274 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008275
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008276 dev_addr = demod->my_i2c_dev_addr;
8277 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008278
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008279 /* equalizer coefficients */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008280 if (force_update ||
8281 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_COEF) != 0)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008282 int index = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008283
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008284 CHK_ERROR(atv_equ_coef_index(ext_attr->standard, &index));
8285 WR16(dev_addr, ATV_TOP_EQU0__A, ext_attr->atv_top_equ0[index]);
8286 WR16(dev_addr, ATV_TOP_EQU1__A, ext_attr->atv_top_equ1[index]);
8287 WR16(dev_addr, ATV_TOP_EQU2__A, ext_attr->atv_top_equ2[index]);
8288 WR16(dev_addr, ATV_TOP_EQU3__A, ext_attr->atv_top_equ3[index]);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008289 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008290
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008291 /* bypass fast carrier recovery */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008292 if (force_update) {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008293 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008294
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008295 RR16(dev_addr, IQM_RT_ROT_BP__A, &data);
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008296 data &= (~((u16) IQM_RT_ROT_BP_ROT_OFF__M));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008297 if (ext_attr->phase_correction_bypass) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008298 data |= IQM_RT_ROT_BP_ROT_OFF_OFF;
8299 } else {
8300 data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE;
8301 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008302 WR16(dev_addr, IQM_RT_ROT_BP__A, data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008303 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008304
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008305 /* peak filter setting */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008306 if (force_update ||
8307 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0)) {
8308 WR16(dev_addr, ATV_TOP_VID_PEAK__A, ext_attr->atv_top_vid_peak);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008309 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008310
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008311 /* noise filter setting */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008312 if (force_update ||
8313 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0)) {
8314 WR16(dev_addr, ATV_TOP_NOISE_TH__A, ext_attr->atv_top_noise_th);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008315 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008316
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008317 /* SIF attenuation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008318 if (force_update ||
8319 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_SIF_ATT) != 0)) {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008320 u16 attenuation = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008321
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008322 switch (ext_attr->sif_attenuation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008323 case DRXJ_SIF_ATTENUATION_0DB:
8324 attenuation = ATV_TOP_AF_SIF_ATT_0DB;
8325 break;
8326 case DRXJ_SIF_ATTENUATION_3DB:
8327 attenuation = ATV_TOP_AF_SIF_ATT_M3DB;
8328 break;
8329 case DRXJ_SIF_ATTENUATION_6DB:
8330 attenuation = ATV_TOP_AF_SIF_ATT_M6DB;
8331 break;
8332 case DRXJ_SIF_ATTENUATION_9DB:
8333 attenuation = ATV_TOP_AF_SIF_ATT_M9DB;
8334 break;
8335 default:
8336 return DRX_STS_ERROR;
8337 break;
8338 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008339 WR16(dev_addr, ATV_TOP_AF_SIF_ATT__A, attenuation);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008340 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008341
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008342 /* SIF & CVBS enable */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008343 if (force_update ||
8344 ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_OUTPUT) != 0)) {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008345 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008346
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008347 RR16(dev_addr, ATV_TOP_STDBY__A, &data);
8348 if (ext_attr->enable_cvbs_output) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008349 data |= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE;
8350 } else {
8351 data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE);
8352 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008353
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008354 if (ext_attr->enable_sif_output) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008355 data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY);
8356 } else {
8357 data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY;
8358 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008359 WR16(dev_addr, ATV_TOP_STDBY__A, data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008360 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008361
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008362 ext_attr->atv_cfg_changed_flags = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008363
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008364 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008365rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008366 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008367}
8368
8369/* -------------------------------------------------------------------------- */
8370/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008371* \fn int ctrl_set_cfg_atv_output()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008372* \brief Configure ATV ouputs
8373* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008374* \param output_cfg output configuaration
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008375* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008376*
8377*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008378static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008379ctrl_set_cfg_atv_output(pdrx_demod_instance_t demod, p_drxj_cfg_atv_output_t output_cfg)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008380{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008381 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008382
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008383 /* Check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008384 if (output_cfg == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008385 return (DRX_STS_INVALID_ARG);
8386 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008387
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008388 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
8389 if (output_cfg->enable_sif_output) {
8390 switch (output_cfg->sif_attenuation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008391 case DRXJ_SIF_ATTENUATION_0DB: /* fallthrough */
8392 case DRXJ_SIF_ATTENUATION_3DB: /* fallthrough */
8393 case DRXJ_SIF_ATTENUATION_6DB: /* fallthrough */
8394 case DRXJ_SIF_ATTENUATION_9DB:
8395 /* Do nothing */
8396 break;
8397 default:
8398 return DRX_STS_INVALID_ARG;
8399 break;
8400 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008401
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008402 if (ext_attr->sif_attenuation != output_cfg->sif_attenuation) {
8403 ext_attr->sif_attenuation = output_cfg->sif_attenuation;
8404 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_SIF_ATT;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008405 }
8406 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008407
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008408 if (ext_attr->enable_cvbs_output != output_cfg->enable_cvbs_output) {
8409 ext_attr->enable_cvbs_output = output_cfg->enable_cvbs_output;
8410 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008411 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008412
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008413 if (ext_attr->enable_sif_output != output_cfg->enable_sif_output) {
8414 ext_attr->enable_sif_output = output_cfg->enable_sif_output;
8415 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008416 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008417
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008418 CHK_ERROR(atv_update_config(demod, false));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008419
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008420 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008421rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008422 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008423}
8424
8425/* -------------------------------------------------------------------------- */
8426#ifndef DRXJ_DIGITAL_ONLY
8427/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008428* \fn int ctrl_set_cfg_atv_equ_coef()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008429* \brief Set ATV equalizer coefficients
8430* \param demod instance of demodulator
8431* \param coef the equalizer coefficients
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008432* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008433*
8434*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008435static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008436ctrl_set_cfg_atv_equ_coef(pdrx_demod_instance_t demod, p_drxj_cfg_atv_equ_coef_t coef)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008437{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008438 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008439 int index;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008440
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008441 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008442
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008443 /* current standard needs to be an ATV standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008444 if (!DRXJ_ISATVSTD(ext_attr->standard)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008445 return DRX_STS_ERROR;
8446 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008447
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008448 /* Check arguments */
8449 if ((coef == NULL) ||
8450 (coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2)) ||
8451 (coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2)) ||
8452 (coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2)) ||
8453 (coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2)) ||
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -03008454 (coef->coef0 < ((s16) ~(ATV_TOP_EQU0_EQU_C0__M >> 1))) ||
8455 (coef->coef1 < ((s16) ~(ATV_TOP_EQU1_EQU_C1__M >> 1))) ||
8456 (coef->coef2 < ((s16) ~(ATV_TOP_EQU2_EQU_C2__M >> 1))) ||
8457 (coef->coef3 < ((s16) ~(ATV_TOP_EQU3_EQU_C3__M >> 1)))) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008458 return (DRX_STS_INVALID_ARG);
8459 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008460
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008461 CHK_ERROR(atv_equ_coef_index(ext_attr->standard, &index));
8462 ext_attr->atv_top_equ0[index] = coef->coef0;
8463 ext_attr->atv_top_equ1[index] = coef->coef1;
8464 ext_attr->atv_top_equ2[index] = coef->coef2;
8465 ext_attr->atv_top_equ3[index] = coef->coef3;
8466 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_COEF;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008467
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008468 CHK_ERROR(atv_update_config(demod, false));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008469
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008470 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008471rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008472 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008473}
8474
8475/* -------------------------------------------------------------------------- */
8476/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008477* \fn int ctrl_get_cfg_atv_equ_coef()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008478* \brief Get ATV equ coef settings
8479* \param demod instance of demodulator
8480* \param coef The ATV equ coefficients
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008481* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008482*
8483* The values are read from the shadow registers maintained by the drxdriver
8484* If registers are manipulated outside of the drxdriver scope the reported
8485* settings will not reflect these changes because of the use of shadow
8486* regitsers.
8487*
8488*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008489static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008490ctrl_get_cfg_atv_equ_coef(pdrx_demod_instance_t demod, p_drxj_cfg_atv_equ_coef_t coef)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008491{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008492 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008493 int index = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008494
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008495 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008496
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008497 /* current standard needs to be an ATV standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008498 if (!DRXJ_ISATVSTD(ext_attr->standard)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008499 return DRX_STS_ERROR;
8500 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008501
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008502 /* Check arguments */
8503 if (coef == NULL) {
8504 return DRX_STS_INVALID_ARG;
8505 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008506
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008507 CHK_ERROR(atv_equ_coef_index(ext_attr->standard, &index));
8508 coef->coef0 = ext_attr->atv_top_equ0[index];
8509 coef->coef1 = ext_attr->atv_top_equ1[index];
8510 coef->coef2 = ext_attr->atv_top_equ2[index];
8511 coef->coef3 = ext_attr->atv_top_equ3[index];
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008512
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008513 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008514rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008515 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008516}
8517
8518/* -------------------------------------------------------------------------- */
8519/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008520* \fn int ctrl_set_cfg_atv_misc()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008521* \brief Set misc. settings for ATV.
8522* \param demod instance of demodulator
8523* \param
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008524* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008525*
8526*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008527static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008528ctrl_set_cfg_atv_misc(pdrx_demod_instance_t demod, p_drxj_cfg_atv_misc_t settings)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008529{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008530 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008531
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008532 /* Check arguments */
8533 if ((settings == NULL) ||
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008534 ((settings->peak_filter) < (s16) (-8)) ||
8535 ((settings->peak_filter) > (s16) (15)) ||
8536 ((settings->noise_filter) > 15)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008537 return (DRX_STS_INVALID_ARG);
8538 }
8539 /* if */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008540 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008541
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008542 if (settings->peak_filter != ext_attr->atv_top_vid_peak) {
8543 ext_attr->atv_top_vid_peak = settings->peak_filter;
8544 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_PEAK_FLT;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008545 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008546
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008547 if (settings->noise_filter != ext_attr->atv_top_noise_th) {
8548 ext_attr->atv_top_noise_th = settings->noise_filter;
8549 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_NOISE_FLT;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008550 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008551
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008552 CHK_ERROR(atv_update_config(demod, false));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008553
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008554 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008555rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008556 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008557}
8558
8559/* -------------------------------------------------------------------------- */
8560/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008561* \fn int ctrl_get_cfg_atv_misc()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008562* \brief Get misc settings of ATV.
8563* \param demod instance of demodulator
8564* \param settings misc. ATV settings
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008565* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008566*
8567* The values are read from the shadow registers maintained by the drxdriver
8568* If registers are manipulated outside of the drxdriver scope the reported
8569* settings will not reflect these changes because of the use of shadow
8570* regitsers.
8571*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008572static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008573ctrl_get_cfg_atv_misc(pdrx_demod_instance_t demod, p_drxj_cfg_atv_misc_t settings)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008574{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008575 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008576
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008577 /* Check arguments */
8578 if (settings == NULL) {
8579 return DRX_STS_INVALID_ARG;
8580 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008581
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008582 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008583
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008584 settings->peak_filter = ext_attr->atv_top_vid_peak;
8585 settings->noise_filter = ext_attr->atv_top_noise_th;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008586
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008587 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008588}
8589
8590/* -------------------------------------------------------------------------- */
8591
8592/* -------------------------------------------------------------------------- */
8593/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008594* \fn int ctrl_get_cfg_atv_output()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008595* \brief
8596* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008597* \param output_cfg output configuaration
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008598* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008599*
8600*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008601static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008602ctrl_get_cfg_atv_output(pdrx_demod_instance_t demod, p_drxj_cfg_atv_output_t output_cfg)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008603{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008604 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008605
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008606 /* Check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008607 if (output_cfg == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008608 return DRX_STS_INVALID_ARG;
8609 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008610
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008611 RR16(demod->my_i2c_dev_addr, ATV_TOP_STDBY__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008612 if (data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008613 output_cfg->enable_cvbs_output = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008614 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008615 output_cfg->enable_cvbs_output = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008616 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008617
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008618 if (data & ATV_TOP_STDBY_SIF_STDBY_STANDBY) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008619 output_cfg->enable_sif_output = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008620 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008621 output_cfg->enable_sif_output = true;
8622 RR16(demod->my_i2c_dev_addr, ATV_TOP_AF_SIF_ATT__A, &data);
8623 output_cfg->sif_attenuation = (drxjsif_attenuation_t) data;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008624 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008625
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008626 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008627rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008628 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008629}
8630
8631/* -------------------------------------------------------------------------- */
8632/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008633* \fn int ctrl_get_cfg_atv_agc_status()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008634* \brief
8635* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008636* \param agc_status agc status
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008637* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008638*
8639*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008640static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008641ctrl_get_cfg_atv_agc_status(pdrx_demod_instance_t demod,
8642 p_drxj_cfg_atv_agc_status_t agc_status)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008643{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008644 struct i2c_device_addr *dev_addr = NULL;
8645 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008646 u16 data = 0;
8647 u32 tmp = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008648
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008649 /* Check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008650 if (agc_status == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008651 return DRX_STS_INVALID_ARG;
8652 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008653
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008654 dev_addr = demod->my_i2c_dev_addr;
8655 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008656
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008657 /*
8658 RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
8659 = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008660
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008661 IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
8662 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008663 RR16(dev_addr, IQM_AF_AGC_RF__A, &data);
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008664 tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008665 agc_status->rf_agc_gain = (u16) (tmp / 1000); /* uA */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008666 /* rounding */
8667 if (tmp % 1000 >= 500) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008668 (agc_status->rf_agc_gain)++;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008669 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008670
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008671 /*
8672 IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
8673 = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008674
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008675 IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
8676 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008677 RR16(dev_addr, IQM_AF_AGC_IF__A, &data);
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008678 tmp = ((u32) data) * 27 - ((u32) (data >> 2)); /* nA */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008679 agc_status->if_agc_gain = (u16) (tmp / 1000); /* uA */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008680 /* rounding */
8681 if (tmp % 1000 >= 500) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008682 (agc_status->if_agc_gain)++;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008683 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008684
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008685 /*
8686 videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
8687 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
8688 = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
8689 = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
8690 = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
8691 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008692
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008693 SARR16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008694 /* dividing by 32 inclusive rounding */
8695 data >>= 4;
8696 if ((data & 1) != 0) {
8697 data++;
8698 }
8699 data >>= 1;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008700 agc_status->video_agc_gain = ((s16) data) - 75; /* 0.1 dB */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008701
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008702 /*
8703 audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
8704 = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
8705 = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
8706 = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
8707 = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
8708 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008709
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008710 SARR16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008711 data &= SCU_RAM_ATV_SIF_GAIN__M;
8712 /* dividing by 2 inclusive rounding */
8713 if ((data & 1) != 0) {
8714 data++;
8715 }
8716 data >>= 1;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008717 agc_status->audio_agc_gain = ((s16) data) - 4; /* 0.1 dB */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008718
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008719 /* Loop gain's */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008720 SARR16(dev_addr, SCU_RAM_AGC_KI__A, &data);
8721 agc_status->video_agc_loop_gain =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008722 ((data & SCU_RAM_AGC_KI_DGAIN__M) >> SCU_RAM_AGC_KI_DGAIN__B);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008723 agc_status->rf_agc_loop_gain =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008724 ((data & SCU_RAM_AGC_KI_RF__M) >> SCU_RAM_AGC_KI_RF__B);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008725 agc_status->if_agc_loop_gain =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008726 ((data & SCU_RAM_AGC_KI_IF__M) >> SCU_RAM_AGC_KI_IF__B);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008727
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008728 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008729rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008730 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008731}
8732
8733/* -------------------------------------------------------------------------- */
8734
8735/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008736* \fn int power_up_atv ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008737* \brief Power up ATV.
8738* \param demod instance of demodulator
8739* \param standard either NTSC or FM (sub strandard for ATV )
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008740* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008741*
8742* * Starts ATV and IQM
8743* * AUdio already started during standard init for ATV.
8744*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008745static int power_up_atv(pdrx_demod_instance_t demod, enum drx_standard standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008746{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008747 struct i2c_device_addr *dev_addr = NULL;
8748 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008749
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008750 dev_addr = demod->my_i2c_dev_addr;
8751 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008752
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008753 /* ATV NTSC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008754 WR16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008755 /* turn on IQM_AF */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008756 CHK_ERROR(set_iqm_af(demod, true));
8757 CHK_ERROR(adc_synchronization(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008758
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008759 WR16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008760
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008761 /* Audio, already done during set standard */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008762
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008763 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008764rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008765 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008766}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008767#endif /* #ifndef DRXJ_DIGITAL_ONLY */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008768
8769/* -------------------------------------------------------------------------- */
8770
8771/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008772* \fn int power_down_atv ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008773* \brief Power down ATV.
8774* \param demod instance of demodulator
8775* \param standard either NTSC or FM (sub strandard for ATV )
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008776* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008777*
8778* Stops and thus resets ATV and IQM block
8779* SIF and CVBS ADC are powered down
8780* Calls audio power down
8781*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008782static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008783power_down_atv(pdrx_demod_instance_t demod, enum drx_standard standard, bool primary)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008784{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008785 struct i2c_device_addr *dev_addr = NULL;
8786 drxjscu_cmd_t cmd_scu = { /* command */ 0,
8787 /* parameter_len */ 0,
8788 /* result_len */ 0,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008789 /* *parameter */ NULL,
8790 /* *result */ NULL
8791 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008792 u16 cmd_result = 0;
8793 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008794
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008795 dev_addr = demod->my_i2c_dev_addr;
8796 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008797 /* ATV NTSC */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008798
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008799 /* Stop ATV SCU (will reset ATV and IQM hardware */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008800 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008801 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008802 cmd_scu.parameter_len = 0;
8803 cmd_scu.result_len = 1;
8804 cmd_scu.parameter = NULL;
8805 cmd_scu.result = &cmd_result;
8806 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008807 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008808 WR16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008809 (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008810
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008811 WR16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP);
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03008812 if (primary == true) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008813 WR16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP);
8814 CHK_ERROR(set_iqm_af(demod, false));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008815 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008816 WR16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
8817 WR16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
8818 WR16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
8819 WR16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
8820 WR16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008821 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008822 CHK_ERROR(power_down_aud(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008823
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008824 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008825rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008826 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008827}
8828
8829/* -------------------------------------------------------------------------- */
8830/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008831* \fn int set_atv_standard ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008832* \brief Set up ATV demodulator.
8833* \param demod instance of demodulator
8834* \param standard either NTSC or FM (sub strandard for ATV )
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008835* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008836*
8837* Init all channel independent registers.
8838* Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
8839*
8840*/
8841#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008842#define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D /* TODO remove after done with reg import */
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03008843static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03008844set_atv_standard(pdrx_demod_instance_t demod, enum drx_standard *standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03008845{
8846/* TODO: enable alternative for tap settings via external file
8847
8848something like:
8849#ifdef DRXJ_ATV_COEF_FILE
8850#include DRXJ_ATV_COEF_FILE
8851#else
8852... code defining fixed coef's ...
8853#endif
8854
8855Cutsomer must create file "customer_coefs.c.inc" containing
8856modified copy off the constants below, and define the compiler
8857switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
8858
8859Still to check if this will work; DRXJ_16TO8 macro may cause
8860trouble ?
8861*/
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008862 const u8 ntsc_taps_re[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008863 DRXJ_16TO8(-12), /* re0 */
8864 DRXJ_16TO8(-9), /* re1 */
8865 DRXJ_16TO8(9), /* re2 */
8866 DRXJ_16TO8(19), /* re3 */
8867 DRXJ_16TO8(-4), /* re4 */
8868 DRXJ_16TO8(-24), /* re5 */
8869 DRXJ_16TO8(-6), /* re6 */
8870 DRXJ_16TO8(16), /* re7 */
8871 DRXJ_16TO8(6), /* re8 */
8872 DRXJ_16TO8(-16), /* re9 */
8873 DRXJ_16TO8(-5), /* re10 */
8874 DRXJ_16TO8(13), /* re11 */
8875 DRXJ_16TO8(-2), /* re12 */
8876 DRXJ_16TO8(-20), /* re13 */
8877 DRXJ_16TO8(4), /* re14 */
8878 DRXJ_16TO8(25), /* re15 */
8879 DRXJ_16TO8(-6), /* re16 */
8880 DRXJ_16TO8(-36), /* re17 */
8881 DRXJ_16TO8(2), /* re18 */
8882 DRXJ_16TO8(38), /* re19 */
8883 DRXJ_16TO8(-10), /* re20 */
8884 DRXJ_16TO8(-48), /* re21 */
8885 DRXJ_16TO8(35), /* re22 */
8886 DRXJ_16TO8(94), /* re23 */
8887 DRXJ_16TO8(-59), /* re24 */
8888 DRXJ_16TO8(-217), /* re25 */
8889 DRXJ_16TO8(50), /* re26 */
8890 DRXJ_16TO8(679) /* re27 */
8891 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008892 const u8 ntsc_taps_im[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008893 DRXJ_16TO8(11), /* im0 */
8894 DRXJ_16TO8(1), /* im1 */
8895 DRXJ_16TO8(-10), /* im2 */
8896 DRXJ_16TO8(2), /* im3 */
8897 DRXJ_16TO8(24), /* im4 */
8898 DRXJ_16TO8(21), /* im5 */
8899 DRXJ_16TO8(1), /* im6 */
8900 DRXJ_16TO8(-4), /* im7 */
8901 DRXJ_16TO8(7), /* im8 */
8902 DRXJ_16TO8(14), /* im9 */
8903 DRXJ_16TO8(27), /* im10 */
8904 DRXJ_16TO8(42), /* im11 */
8905 DRXJ_16TO8(22), /* im12 */
8906 DRXJ_16TO8(-20), /* im13 */
8907 DRXJ_16TO8(2), /* im14 */
8908 DRXJ_16TO8(98), /* im15 */
8909 DRXJ_16TO8(122), /* im16 */
8910 DRXJ_16TO8(0), /* im17 */
8911 DRXJ_16TO8(-85), /* im18 */
8912 DRXJ_16TO8(51), /* im19 */
8913 DRXJ_16TO8(247), /* im20 */
8914 DRXJ_16TO8(192), /* im21 */
8915 DRXJ_16TO8(-55), /* im22 */
8916 DRXJ_16TO8(-95), /* im23 */
8917 DRXJ_16TO8(217), /* im24 */
8918 DRXJ_16TO8(544), /* im25 */
8919 DRXJ_16TO8(553), /* im26 */
8920 DRXJ_16TO8(302) /* im27 */
8921 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008922 const u8 bg_taps_re[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008923 DRXJ_16TO8(-18), /* re0 */
8924 DRXJ_16TO8(18), /* re1 */
8925 DRXJ_16TO8(19), /* re2 */
8926 DRXJ_16TO8(-26), /* re3 */
8927 DRXJ_16TO8(-20), /* re4 */
8928 DRXJ_16TO8(36), /* re5 */
8929 DRXJ_16TO8(5), /* re6 */
8930 DRXJ_16TO8(-51), /* re7 */
8931 DRXJ_16TO8(15), /* re8 */
8932 DRXJ_16TO8(45), /* re9 */
8933 DRXJ_16TO8(-46), /* re10 */
8934 DRXJ_16TO8(-24), /* re11 */
8935 DRXJ_16TO8(71), /* re12 */
8936 DRXJ_16TO8(-17), /* re13 */
8937 DRXJ_16TO8(-83), /* re14 */
8938 DRXJ_16TO8(74), /* re15 */
8939 DRXJ_16TO8(75), /* re16 */
8940 DRXJ_16TO8(-134), /* re17 */
8941 DRXJ_16TO8(-40), /* re18 */
8942 DRXJ_16TO8(191), /* re19 */
8943 DRXJ_16TO8(-11), /* re20 */
8944 DRXJ_16TO8(-233), /* re21 */
8945 DRXJ_16TO8(74), /* re22 */
8946 DRXJ_16TO8(271), /* re23 */
8947 DRXJ_16TO8(-132), /* re24 */
8948 DRXJ_16TO8(-341), /* re25 */
8949 DRXJ_16TO8(172), /* re26 */
8950 DRXJ_16TO8(801) /* re27 */
8951 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008952 const u8 bg_taps_im[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008953 DRXJ_16TO8(-24), /* im0 */
8954 DRXJ_16TO8(-10), /* im1 */
8955 DRXJ_16TO8(9), /* im2 */
8956 DRXJ_16TO8(-5), /* im3 */
8957 DRXJ_16TO8(-51), /* im4 */
8958 DRXJ_16TO8(-17), /* im5 */
8959 DRXJ_16TO8(31), /* im6 */
8960 DRXJ_16TO8(-48), /* im7 */
8961 DRXJ_16TO8(-95), /* im8 */
8962 DRXJ_16TO8(25), /* im9 */
8963 DRXJ_16TO8(37), /* im10 */
8964 DRXJ_16TO8(-123), /* im11 */
8965 DRXJ_16TO8(-77), /* im12 */
8966 DRXJ_16TO8(94), /* im13 */
8967 DRXJ_16TO8(-10), /* im14 */
8968 DRXJ_16TO8(-149), /* im15 */
8969 DRXJ_16TO8(10), /* im16 */
8970 DRXJ_16TO8(108), /* im17 */
8971 DRXJ_16TO8(-49), /* im18 */
8972 DRXJ_16TO8(-59), /* im19 */
8973 DRXJ_16TO8(90), /* im20 */
8974 DRXJ_16TO8(73), /* im21 */
8975 DRXJ_16TO8(55), /* im22 */
8976 DRXJ_16TO8(148), /* im23 */
8977 DRXJ_16TO8(86), /* im24 */
8978 DRXJ_16TO8(146), /* im25 */
8979 DRXJ_16TO8(687), /* im26 */
8980 DRXJ_16TO8(877) /* im27 */
8981 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03008982 const u8 dk_i_l_lp_taps_re[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03008983 DRXJ_16TO8(-23), /* re0 */
8984 DRXJ_16TO8(9), /* re1 */
8985 DRXJ_16TO8(16), /* re2 */
8986 DRXJ_16TO8(-26), /* re3 */
8987 DRXJ_16TO8(-3), /* re4 */
8988 DRXJ_16TO8(13), /* re5 */
8989 DRXJ_16TO8(-19), /* re6 */
8990 DRXJ_16TO8(-3), /* re7 */
8991 DRXJ_16TO8(13), /* re8 */
8992 DRXJ_16TO8(-26), /* re9 */
8993 DRXJ_16TO8(-4), /* re10 */
8994 DRXJ_16TO8(28), /* re11 */
8995 DRXJ_16TO8(-15), /* re12 */
8996 DRXJ_16TO8(-14), /* re13 */
8997 DRXJ_16TO8(10), /* re14 */
8998 DRXJ_16TO8(1), /* re15 */
8999 DRXJ_16TO8(39), /* re16 */
9000 DRXJ_16TO8(-18), /* re17 */
9001 DRXJ_16TO8(-90), /* re18 */
9002 DRXJ_16TO8(109), /* re19 */
9003 DRXJ_16TO8(113), /* re20 */
9004 DRXJ_16TO8(-235), /* re21 */
9005 DRXJ_16TO8(-49), /* re22 */
9006 DRXJ_16TO8(359), /* re23 */
9007 DRXJ_16TO8(-79), /* re24 */
9008 DRXJ_16TO8(-459), /* re25 */
9009 DRXJ_16TO8(206), /* re26 */
9010 DRXJ_16TO8(894) /* re27 */
9011 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009012 const u8 dk_i_l_lp_taps_im[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009013 DRXJ_16TO8(-8), /* im0 */
9014 DRXJ_16TO8(-20), /* im1 */
9015 DRXJ_16TO8(17), /* im2 */
9016 DRXJ_16TO8(-14), /* im3 */
9017 DRXJ_16TO8(-52), /* im4 */
9018 DRXJ_16TO8(4), /* im5 */
9019 DRXJ_16TO8(9), /* im6 */
9020 DRXJ_16TO8(-62), /* im7 */
9021 DRXJ_16TO8(-47), /* im8 */
9022 DRXJ_16TO8(0), /* im9 */
9023 DRXJ_16TO8(-20), /* im10 */
9024 DRXJ_16TO8(-48), /* im11 */
9025 DRXJ_16TO8(-65), /* im12 */
9026 DRXJ_16TO8(-23), /* im13 */
9027 DRXJ_16TO8(44), /* im14 */
9028 DRXJ_16TO8(-60), /* im15 */
9029 DRXJ_16TO8(-113), /* im16 */
9030 DRXJ_16TO8(92), /* im17 */
9031 DRXJ_16TO8(81), /* im18 */
9032 DRXJ_16TO8(-125), /* im19 */
9033 DRXJ_16TO8(28), /* im20 */
9034 DRXJ_16TO8(182), /* im21 */
9035 DRXJ_16TO8(35), /* im22 */
9036 DRXJ_16TO8(94), /* im23 */
9037 DRXJ_16TO8(180), /* im24 */
9038 DRXJ_16TO8(134), /* im25 */
9039 DRXJ_16TO8(657), /* im26 */
9040 DRXJ_16TO8(1023) /* im27 */
9041 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009042 const u8 fm_taps_re[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009043 DRXJ_16TO8(0), /* re0 */
9044 DRXJ_16TO8(0), /* re1 */
9045 DRXJ_16TO8(0), /* re2 */
9046 DRXJ_16TO8(0), /* re3 */
9047 DRXJ_16TO8(0), /* re4 */
9048 DRXJ_16TO8(0), /* re5 */
9049 DRXJ_16TO8(0), /* re6 */
9050 DRXJ_16TO8(0), /* re7 */
9051 DRXJ_16TO8(0), /* re8 */
9052 DRXJ_16TO8(0), /* re9 */
9053 DRXJ_16TO8(0), /* re10 */
9054 DRXJ_16TO8(0), /* re11 */
9055 DRXJ_16TO8(0), /* re12 */
9056 DRXJ_16TO8(0), /* re13 */
9057 DRXJ_16TO8(0), /* re14 */
9058 DRXJ_16TO8(0), /* re15 */
9059 DRXJ_16TO8(0), /* re16 */
9060 DRXJ_16TO8(0), /* re17 */
9061 DRXJ_16TO8(0), /* re18 */
9062 DRXJ_16TO8(0), /* re19 */
9063 DRXJ_16TO8(0), /* re20 */
9064 DRXJ_16TO8(0), /* re21 */
9065 DRXJ_16TO8(0), /* re22 */
9066 DRXJ_16TO8(0), /* re23 */
9067 DRXJ_16TO8(0), /* re24 */
9068 DRXJ_16TO8(0), /* re25 */
9069 DRXJ_16TO8(0), /* re26 */
9070 DRXJ_16TO8(0) /* re27 */
9071 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009072 const u8 fm_taps_im[] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009073 DRXJ_16TO8(-6), /* im0 */
9074 DRXJ_16TO8(2), /* im1 */
9075 DRXJ_16TO8(14), /* im2 */
9076 DRXJ_16TO8(-38), /* im3 */
9077 DRXJ_16TO8(58), /* im4 */
9078 DRXJ_16TO8(-62), /* im5 */
9079 DRXJ_16TO8(42), /* im6 */
9080 DRXJ_16TO8(0), /* im7 */
9081 DRXJ_16TO8(-45), /* im8 */
9082 DRXJ_16TO8(73), /* im9 */
9083 DRXJ_16TO8(-65), /* im10 */
9084 DRXJ_16TO8(23), /* im11 */
9085 DRXJ_16TO8(34), /* im12 */
9086 DRXJ_16TO8(-77), /* im13 */
9087 DRXJ_16TO8(80), /* im14 */
9088 DRXJ_16TO8(-39), /* im15 */
9089 DRXJ_16TO8(-25), /* im16 */
9090 DRXJ_16TO8(78), /* im17 */
9091 DRXJ_16TO8(-90), /* im18 */
9092 DRXJ_16TO8(52), /* im19 */
9093 DRXJ_16TO8(16), /* im20 */
9094 DRXJ_16TO8(-77), /* im21 */
9095 DRXJ_16TO8(97), /* im22 */
9096 DRXJ_16TO8(-62), /* im23 */
9097 DRXJ_16TO8(-8), /* im24 */
9098 DRXJ_16TO8(75), /* im25 */
9099 DRXJ_16TO8(-100), /* im26 */
9100 DRXJ_16TO8(70) /* im27 */
9101 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009102
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009103 struct i2c_device_addr *dev_addr = NULL;
9104 drxjscu_cmd_t cmd_scu = { /* command */ 0,
9105 /* parameter_len */ 0,
9106 /* result_len */ 0,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009107 /* *parameter */ NULL,
9108 /* *result */ NULL
9109 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009110 u16 cmd_result = 0;
9111 u16 cmd_param = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009112#ifdef DRXJ_SPLIT_UCODE_UPLOAD
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009113 drxu_code_info_t ucode_info;
9114 pdrx_common_attr_t common_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009115#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009116 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009117
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009118 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
9119 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009120
9121#ifdef DRXJ_SPLIT_UCODE_UPLOAD
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009122 common_attr = demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009123
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009124 /* Check if audio microcode is already uploaded */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009125 if (!(ext_attr->flag_aud_mc_uploaded)) {
9126 ucode_info.mc_data = common_attr->microcode;
9127 ucode_info.mc_size = common_attr->microcode_size;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009128
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009129 /* Upload only audio microcode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009130 CHK_ERROR(ctrl_u_codeUpload
9131 (demod, &ucode_info, UCODE_UPLOAD, true));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009132
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009133 if (common_attr->verify_microcode == true) {
9134 CHK_ERROR(ctrl_u_codeUpload
9135 (demod, &ucode_info, UCODE_VERIFY, true));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009136 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009137
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009138 /* Prevent uploading audio microcode again */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009139 ext_attr->flag_aud_mc_uploaded = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009140 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009141#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
9142
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009143 WR16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP);
9144 WR16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP);
9145 WR16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP);
9146 WR16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP);
9147 WR16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP);
9148 WR16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009149 /* Reset ATV SCU */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009150 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009151 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009152 cmd_scu.parameter_len = 0;
9153 cmd_scu.result_len = 1;
9154 cmd_scu.parameter = NULL;
9155 cmd_scu.result = &cmd_result;
9156 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009157
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009158 WR16(dev_addr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009159
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009160 /* TODO remove AUTO/OFF patches after ucode fix. */
9161 switch (*standard) {
9162 case DRX_STANDARD_NTSC:
9163 /* NTSC */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009164 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_MN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009165
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009166 WR16(dev_addr, IQM_RT_LO_INCR__A, IQM_RT_LO_INCR_MN);
9167 WR16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9168 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(ntsc_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009169 ((u8 *) ntsc_taps_re));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009170 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(ntsc_taps_im),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009171 ((u8 *) ntsc_taps_im));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009172
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009173 WR16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_MN);
9174 WR16(dev_addr, ATV_TOP_CR_CONT__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009175 (ATV_TOP_CR_CONT_CR_P_MN |
9176 ATV_TOP_CR_CONT_CR_D_MN | ATV_TOP_CR_CONT_CR_I_MN));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009177 WR16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_MN);
9178 WR16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_MN |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009179 ATV_TOP_STD_VID_POL_MN));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009180 WR16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_MN);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009181
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009182 WR16(dev_addr, SCU_RAM_ATV_AGC_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009183 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
9184 SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009185 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9186 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9187 WR16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009188 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009189 ext_attr->phase_correction_bypass = false;
9190 ext_attr->enable_cvbs_output = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009191 break;
9192 case DRX_STANDARD_FM:
9193 /* FM */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009194 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_FM;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009195
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009196 WR16(dev_addr, IQM_RT_LO_INCR__A, 2994);
9197 WR16(dev_addr, IQM_CF_MIDTAP__A, 0);
9198 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(fm_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009199 ((u8 *) fm_taps_re));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009200 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(fm_taps_im),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009201 ((u8 *) fm_taps_im));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009202 WR16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_FM |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009203 ATV_TOP_STD_VID_POL_FM));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009204 WR16(dev_addr, ATV_TOP_MOD_CONTROL__A, 0);
9205 WR16(dev_addr, ATV_TOP_CR_CONT__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009206
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009207 WR16(dev_addr, SCU_RAM_ATV_AGC_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009208 (SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW |
9209 SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009210 WR16(dev_addr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF);
9211 ext_attr->phase_correction_bypass = true;
9212 ext_attr->enable_cvbs_output = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009213 break;
9214 case DRX_STANDARD_PAL_SECAM_BG:
9215 /* PAL/SECAM B/G */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009216 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_B;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009217
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009218 WR16(dev_addr, IQM_RT_LO_INCR__A, 1820); /* TODO check with IS */
9219 WR16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9220 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(bg_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009221 ((u8 *) bg_taps_re));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009222 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(bg_taps_im),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009223 ((u8 *) bg_taps_im));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009224 WR16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_BG);
9225 WR16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG);
9226 WR16(dev_addr, ATV_TOP_CR_CONT__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009227 (ATV_TOP_CR_CONT_CR_P_BG |
9228 ATV_TOP_CR_CONT_CR_D_BG | ATV_TOP_CR_CONT_CR_I_BG));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009229 WR16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_BG);
9230 WR16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_BG |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009231 ATV_TOP_STD_VID_POL_BG));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009232 WR16(dev_addr, SCU_RAM_ATV_AGC_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009233 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
9234 SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009235 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9236 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9237 WR16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009238 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009239 ext_attr->phase_correction_bypass = false;
9240 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
9241 ext_attr->enable_cvbs_output = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009242 break;
9243 case DRX_STANDARD_PAL_SECAM_DK:
9244 /* PAL/SECAM D/K */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009245 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_DK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009246
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009247 WR16(dev_addr, IQM_RT_LO_INCR__A, 2225); /* TODO check with IS */
9248 WR16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9249 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009250 ((u8 *) dk_i_l_lp_taps_re));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009251 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009252 ((u8 *) dk_i_l_lp_taps_im));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009253 WR16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_DK);
9254 WR16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_DK);
9255 WR16(dev_addr, ATV_TOP_CR_CONT__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009256 (ATV_TOP_CR_CONT_CR_P_DK |
9257 ATV_TOP_CR_CONT_CR_D_DK | ATV_TOP_CR_CONT_CR_I_DK));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009258 WR16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_DK);
9259 WR16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_DK |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009260 ATV_TOP_STD_VID_POL_DK));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009261 WR16(dev_addr, SCU_RAM_ATV_AGC_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009262 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
9263 SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009264 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9265 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9266 WR16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009267 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_DK);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009268 ext_attr->phase_correction_bypass = false;
9269 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
9270 ext_attr->enable_cvbs_output = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009271 break;
9272 case DRX_STANDARD_PAL_SECAM_I:
9273 /* PAL/SECAM I */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009274 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_I;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009275
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009276 WR16(dev_addr, IQM_RT_LO_INCR__A, 2225); /* TODO check with IS */
9277 WR16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9278 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009279 ((u8 *) dk_i_l_lp_taps_re));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009280 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009281 ((u8 *) dk_i_l_lp_taps_im));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009282 WR16(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_I);
9283 WR16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_I);
9284 WR16(dev_addr, ATV_TOP_CR_CONT__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009285 (ATV_TOP_CR_CONT_CR_P_I |
9286 ATV_TOP_CR_CONT_CR_D_I | ATV_TOP_CR_CONT_CR_I_I));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009287 WR16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_I);
9288 WR16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_I |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009289 ATV_TOP_STD_VID_POL_I));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009290 WR16(dev_addr, SCU_RAM_ATV_AGC_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009291 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM |
9292 SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009293 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9294 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9295 WR16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009296 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_I);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009297 ext_attr->phase_correction_bypass = false;
9298 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
9299 ext_attr->enable_cvbs_output = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009300 break;
9301 case DRX_STANDARD_PAL_SECAM_L:
9302 /* PAL/SECAM L with negative modulation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009303 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_L;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009304
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009305 WR16(dev_addr, IQM_RT_LO_INCR__A, 2225); /* TODO check with IS */
9306 WR16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_L);
9307 WR16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9308 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009309 ((u8 *) dk_i_l_lp_taps_re));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009310 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009311 ((u8 *) dk_i_l_lp_taps_im));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009312 WR16(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2); /* TODO check with IS */
9313 WR16(dev_addr, ATV_TOP_CR_CONT__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009314 (ATV_TOP_CR_CONT_CR_P_L |
9315 ATV_TOP_CR_CONT_CR_D_L | ATV_TOP_CR_CONT_CR_I_L));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009316 WR16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_L);
9317 WR16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_L |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009318 ATV_TOP_STD_VID_POL_L));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009319 WR16(dev_addr, SCU_RAM_ATV_AGC_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009320 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM |
9321 SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE |
9322 SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009323 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9324 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9325 WR16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009326 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009327 ext_attr->phase_correction_bypass = false;
9328 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
9329 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
9330 ext_attr->enable_cvbs_output = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009331 break;
9332 case DRX_STANDARD_PAL_SECAM_LP:
9333 /* PAL/SECAM L with positive modulation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009334 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_LP;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009335
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009336 WR16(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_LP);
9337 WR16(dev_addr, IQM_RT_LO_INCR__A, 2225); /* TODO check with IS */
9338 WR16(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M);
9339 WRB(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009340 ((u8 *) dk_i_l_lp_taps_re));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009341 WRB(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im),
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -03009342 ((u8 *) dk_i_l_lp_taps_im));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009343 WR16(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2); /* TODO check with IS */
9344 WR16(dev_addr, ATV_TOP_CR_CONT__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009345 (ATV_TOP_CR_CONT_CR_P_LP |
9346 ATV_TOP_CR_CONT_CR_D_LP | ATV_TOP_CR_CONT_CR_I_LP));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009347 WR16(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_LP);
9348 WR16(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_LP |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009349 ATV_TOP_STD_VID_POL_LP));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009350 WR16(dev_addr, SCU_RAM_ATV_AGC_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009351 (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM |
9352 SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE |
9353 SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009354 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000);
9355 WR16(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000);
9356 WR16(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009357 SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009358 ext_attr->phase_correction_bypass = false;
9359 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
9360 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
9361 ext_attr->enable_cvbs_output = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009362 break;
9363 default:
9364 return (DRX_STS_ERROR);
9365 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009366
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009367 /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009368 if (ext_attr->has_lna == false) {
9369 WR16(dev_addr, IQM_AF_AMUX__A, 0x01);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009370 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009371
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009372 WR16(dev_addr, SCU_RAM_ATV_STANDARD__A, 0x002);
9373 WR16(dev_addr, IQM_AF_CLP_LEN__A, IQM_AF_CLP_LEN_ATV);
9374 WR16(dev_addr, IQM_AF_CLP_TH__A, IQM_AF_CLP_TH_ATV);
9375 WR16(dev_addr, IQM_AF_SNS_LEN__A, IQM_AF_SNS_LEN_ATV);
9376 CHK_ERROR(ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg)));
9377 WR16(dev_addr, IQM_AF_AGC_IF__A, 10248);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009378
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009379 ext_attr->iqm_rc_rate_ofs = 0x00200000L;
9380 WR32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs);
9381 WR16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_OFF);
9382 WR16(dev_addr, IQM_RC_STRETCH__A, IQM_RC_STRETCH_ATV);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009383
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009384 WR16(dev_addr, IQM_RT_ACTIVE__A, IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_ON |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009385 IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_ON);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009386
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009387 WR16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_ATV__M);
9388 WR16(dev_addr, IQM_CF_SYMMETRIC__A, IQM_CF_SYMMETRIC_IM__M);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009389 /* default: SIF in standby */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009390 WR16(dev_addr, ATV_TOP_SYNC_SLICE__A, ATV_TOP_SYNC_SLICE_MN);
9391 WR16(dev_addr, ATV_TOP_MOD_ACCU__A, ATV_TOP_MOD_ACCU__PRE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009392
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009393 WR16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, 0x080);
9394 WR16(dev_addr, SCU_RAM_ATV_FAGC_TH_RED__A, 10);
9395 WR16(dev_addr, SCU_RAM_ATV_AAGC_CNT__A, 7);
9396 WR16(dev_addr, SCU_RAM_ATV_NAGC_KI_MIN__A, 0x0225);
9397 WR16(dev_addr, SCU_RAM_ATV_NAGC_KI_MAX__A, 0x0547);
9398 WR16(dev_addr, SCU_RAM_ATV_KI_CHANGE_TH__A, 20);
9399 WR16(dev_addr, SCU_RAM_ATV_LOCK__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009400
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009401 WR16(dev_addr, IQM_RT_DELAY__A, IQM_RT_DELAY__PRE);
9402 WR16(dev_addr, SCU_RAM_ATV_BPC_KI_MIN__A, 531);
9403 WR16(dev_addr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061);
9404 WR16(dev_addr, SCU_RAM_ATV_BP_REF_MIN__A, 100);
9405 WR16(dev_addr, SCU_RAM_ATV_BP_REF_MAX__A, 260);
9406 WR16(dev_addr, SCU_RAM_ATV_BP_LVL__A, 0);
9407 WR16(dev_addr, SCU_RAM_ATV_AMS_MAX__A, 0);
9408 WR16(dev_addr, SCU_RAM_ATV_AMS_MIN__A, 2047);
9409 WR16(dev_addr, SCU_RAM_GPIO__A, 0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009410
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009411 /* Override reset values with current shadow settings */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009412 CHK_ERROR(atv_update_config(demod, true));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009413
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009414 /* Configure/restore AGC settings */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009415 CHK_ERROR(init_agc(demod));
9416 CHK_ERROR(set_agc_if(demod, &(ext_attr->atv_if_agc_cfg), false));
9417 CHK_ERROR(set_agc_rf(demod, &(ext_attr->atv_rf_agc_cfg), false));
9418 CHK_ERROR(ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg)));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009419
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009420 /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009421 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009422 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009423 cmd_scu.parameter_len = 1;
9424 cmd_scu.result_len = 1;
9425 cmd_scu.parameter = &cmd_param;
9426 cmd_scu.result = &cmd_result;
9427 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009428
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009429 /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009430 if (ext_attr->mfx == 0x03) {
9431 WR16(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009432 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009433 WR16(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1);
9434 WR16(dev_addr, SCU_RAM_ATV_IIR_CRIT__A, 225);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009435 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009436
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009437 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009438rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009439 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009440}
9441#endif
9442
9443/* -------------------------------------------------------------------------- */
9444
9445#ifndef DRXJ_DIGITAL_ONLY
9446/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009447* \fn int set_atv_channel ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009448* \brief Set ATV channel.
9449* \param demod: instance of demod.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009450* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009451*
9452* Not much needs to be done here, only start the SCU for NTSC/FM.
9453* Mirrored channels are not expected in the RF domain, so IQM FS setting
9454* doesn't need to be remembered.
9455* The channel->mirror parameter is therefor ignored.
9456*
9457*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009458static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009459set_atv_channel(pdrx_demod_instance_t demod,
9460 s32 tuner_freq_offset,
9461 pdrx_channel_t channel, enum drx_standard standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009462{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009463 drxjscu_cmd_t cmd_scu = { /* command */ 0,
9464 /* parameter_len */ 0,
9465 /* result_len */ 0,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009466 /* parameter */ NULL,
9467 /* result */ NULL
9468 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009469 u16 cmd_result = 0;
9470 pdrxj_data_t ext_attr = NULL;
9471 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009472
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009473 dev_addr = demod->my_i2c_dev_addr;
9474 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009475
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009476 /*
9477 Program frequency shifter
9478 No need to account for mirroring on RF
9479 */
9480 if (channel->mirror == DRX_MIRROR_AUTO) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009481 ext_attr->mirror = DRX_MIRROR_NO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009482 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009483 ext_attr->mirror = channel->mirror;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009484 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009485
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009486 CHK_ERROR(set_frequency(demod, channel, tuner_freq_offset));
9487 WR16(dev_addr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009488
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009489 /* Start ATV SCU */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009490 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009491 SCU_RAM_COMMAND_CMD_DEMOD_START;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009492 cmd_scu.parameter_len = 0;
9493 cmd_scu.result_len = 1;
9494 cmd_scu.parameter = NULL;
9495 cmd_scu.result = &cmd_result;
9496 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009497
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009498/* if ( (ext_attr->standard == DRX_STANDARD_FM) && (ext_attr->flagSetAUDdone == true) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009499 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009500 ext_attr->detectedRDS = (bool)false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009501 }*/
9502
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009503 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009504rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009505 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009506}
9507#endif
9508
9509/* -------------------------------------------------------------------------- */
9510
9511/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009512* \fn int get_atv_channel ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009513* \brief Set ATV channel.
9514* \param demod: instance of demod.
9515* \param channel: pointer to channel data.
9516* \param standard: NTSC or FM.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009517* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009518*
9519* Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
9520* Computes the frequency offset in te RF domain and adds it to
9521* channel->frequency. Determines the value for channel->bandwidth.
9522*
9523*/
9524#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009525static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009526get_atv_channel(pdrx_demod_instance_t demod,
9527 pdrx_channel_t channel, enum drx_standard standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009528{
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03009529 s32 offset = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009530 struct i2c_device_addr *dev_addr = NULL;
9531 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009532
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009533 dev_addr = demod->my_i2c_dev_addr;
9534 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009535
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009536 /* Bandwidth */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009537 channel->bandwidth = ((pdrxj_data_t) demod->my_ext_attr)->curr_bandwidth;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009538
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009539 switch (standard) {
9540 case DRX_STANDARD_NTSC:
9541 case DRX_STANDARD_PAL_SECAM_BG:
9542 case DRX_STANDARD_PAL_SECAM_DK:
9543 case DRX_STANDARD_PAL_SECAM_I:
9544 case DRX_STANDARD_PAL_SECAM_L:
9545 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009546 u16 measured_offset = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009547
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009548 /* get measured frequency offset */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009549 RR16(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009550 /* Signed 8 bit register => sign extension needed */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009551 if ((measured_offset & 0x0080) != 0) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009552 /* sign extension */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009553 measured_offset |= 0xFF80;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009554 }
9555 offset +=
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009556 (s32) (((s16) measured_offset) * 10);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009557 break;
9558 }
9559 case DRX_STANDARD_PAL_SECAM_LP:
9560 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009561 u16 measured_offset = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009562
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009563 /* get measured frequency offset */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009564 RR16(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009565 /* Signed 8 bit register => sign extension needed */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009566 if ((measured_offset & 0x0080) != 0) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009567 /* sign extension */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009568 measured_offset |= 0xFF80;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009569 }
9570 offset -=
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009571 (s32) (((s16) measured_offset) * 10);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009572 }
9573 break;
9574 case DRX_STANDARD_FM:
9575 /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
9576 AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
9577 */
9578 /* No bandwidth know for FM */
9579 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
9580 break;
9581 default:
9582 return (DRX_STS_ERROR);
9583 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009584
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009585 channel->frequency -= offset;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009586
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009587 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009588rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009589 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009590}
9591
9592/* -------------------------------------------------------------------------- */
9593/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009594* \fn int get_atv_sig_strength()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009595* \brief Retrieve signal strength for ATV & FM.
9596* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009597* \param sig_quality Pointer to signal strength data; range 0, .. , 100.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009598* \return int.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009599* \retval DRX_STS_OK sig_strength contains valid data.
9600* \retval DRX_STS_ERROR Erroneous data, sig_strength equals 0.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009601*
9602* Taking into account:
9603* * digital gain
9604* * IF gain (not implemented yet, waiting for IF gain control by ucode)
9605* * RF gain
9606*
9607* All weights (digital, if, rf) must add up to 100.
9608*
9609* TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
9610* is not used ?
9611*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009612static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009613get_atv_sig_strength(pdrx_demod_instance_t demod, u16 *sig_strength)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009614{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009615 struct i2c_device_addr *dev_addr = NULL;
9616 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009617
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009618 /* All weights must add up to 100 (%)
9619 TODO: change weights when IF ctrl is available */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009620 u32 digital_weight = 50; /* 0 .. 100 */
9621 u32 rf_weight = 50; /* 0 .. 100 */
9622 u32 if_weight = 0; /* 0 .. 100 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009623
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009624 u16 digital_curr_gain = 0;
9625 u32 digital_max_gain = 0;
9626 u32 digital_min_gain = 0;
9627 u16 rf_curr_gain = 0;
9628 u32 rf_max_gain = 0x800; /* taken from ucode */
9629 u32 rf_min_gain = 0x7fff;
9630 u16 if_curr_gain = 0;
9631 u32 if_max_gain = 0x800; /* taken from ucode */
9632 u32 if_min_gain = 0x7fff;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009633
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009634 u32 digital_strength = 0; /* 0.. 100 */
9635 u32 rf_strength = 0; /* 0.. 100 */
9636 u32 if_strength = 0; /* 0.. 100 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009637
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009638 dev_addr = demod->my_i2c_dev_addr;
9639 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009640
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009641 *sig_strength = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009642
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009643 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009644 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
9645 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
9646 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
9647 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
9648 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
9649 case DRX_STANDARD_NTSC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009650 SARR16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &digital_curr_gain);
9651 digital_max_gain = 22512; /* taken from ucode */
9652 digital_min_gain = 2400; /* taken from ucode */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009653 break;
9654 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009655 SARR16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &digital_curr_gain);
9656 digital_max_gain = 0x4ff; /* taken from ucode */
9657 digital_min_gain = 0; /* taken from ucode */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009658 break;
9659 default:
9660 return (DRX_STS_ERROR);
9661 break;
9662 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009663 RR16(dev_addr, IQM_AF_AGC_RF__A, &rf_curr_gain);
9664 RR16(dev_addr, IQM_AF_AGC_IF__A, &if_curr_gain);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009665
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009666 /* clipping */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009667 if (digital_curr_gain >= digital_max_gain)
9668 digital_curr_gain = (u16) digital_max_gain;
9669 if (digital_curr_gain <= digital_min_gain)
9670 digital_curr_gain = (u16) digital_min_gain;
9671 if (if_curr_gain <= if_max_gain)
9672 if_curr_gain = (u16) if_max_gain;
9673 if (if_curr_gain >= if_min_gain)
9674 if_curr_gain = (u16) if_min_gain;
9675 if (rf_curr_gain <= rf_max_gain)
9676 rf_curr_gain = (u16) rf_max_gain;
9677 if (rf_curr_gain >= rf_min_gain)
9678 rf_curr_gain = (u16) rf_min_gain;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009679
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009680 /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
9681 of clipping at ADC */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009682
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009683 /* Compute signal strength (in %) per "gain domain" */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009684
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009685 /* Digital gain */
9686 /* TODO: ADC clipping not handled */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009687 digital_strength = (100 * (digital_max_gain - (u32) digital_curr_gain)) /
9688 (digital_max_gain - digital_min_gain);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009689
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009690 /* TODO: IF gain not implemented yet in microcode, check after impl. */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009691 if_strength = (100 * ((u32) if_curr_gain - if_max_gain)) /
9692 (if_min_gain - if_max_gain);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009693
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009694 /* Rf gain */
9695 /* TODO: ADC clipping not handled */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009696 rf_strength = (100 * ((u32) rf_curr_gain - rf_max_gain)) /
9697 (rf_min_gain - rf_max_gain);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009698
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009699 /* Compute a weighted signal strength (in %) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009700 *sig_strength = (u16) (digital_weight * digital_strength +
9701 rf_weight * rf_strength + if_weight * if_strength);
9702 *sig_strength /= 100;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009703
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009704 return (DRX_STS_OK);
9705rw_error:
9706 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009707}
9708
9709/* -------------------------------------------------------------------------- */
9710/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009711* \fn int atv_sig_quality()
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009712* \brief Retrieve signal quality indication for ATV.
9713* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009714* \param sig_quality Pointer to signal quality structure.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009715* \return int.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009716* \retval DRX_STS_OK sig_quality contains valid data.
9717* \retval DRX_STS_ERROR Erroneous data, sig_quality indicator equals 0.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009718*
9719*
9720*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009721static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009722atv_sig_quality(pdrx_demod_instance_t demod, pdrx_sig_quality_t sig_quality)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009723{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009724 struct i2c_device_addr *dev_addr = NULL;
9725 u16 quality_indicator = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009726
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009727 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009728
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009729 /* defined values for fields not used */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009730 sig_quality->MER = 0;
9731 sig_quality->pre_viterbi_ber = 0;
9732 sig_quality->post_viterbi_ber = 0;
9733 sig_quality->scale_factor_ber = 1;
9734 sig_quality->packet_error = 0;
9735 sig_quality->post_reed_solomon_ber = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009736
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009737 /*
9738 Mapping:
9739 0x000..0x080: strong signal => 80% .. 100%
9740 0x080..0x700: weak signal => 30% .. 80%
9741 0x700..0x7ff: no signal => 0% .. 30%
9742 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009743
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009744 SARR16(dev_addr, SCU_RAM_ATV_CR_LOCK__A, &quality_indicator);
9745 quality_indicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
9746 if (quality_indicator <= 0x80) {
9747 sig_quality->indicator =
9748 80 + ((20 * (0x80 - quality_indicator)) / 0x80);
9749 } else if (quality_indicator <= 0x700) {
9750 sig_quality->indicator = 30 +
9751 ((50 * (0x700 - quality_indicator)) / (0x700 - 0x81));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009752 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009753 sig_quality->indicator =
9754 (30 * (0x7FF - quality_indicator)) / (0x7FF - 0x701);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009755 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009756
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009757 return (DRX_STS_OK);
9758rw_error:
9759 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009760}
9761#endif /* DRXJ_DIGITAL_ONLY */
9762
9763/*============================================================================*/
9764/*== END ATV DATAPATH FUNCTIONS ==*/
9765/*============================================================================*/
9766
9767#ifndef DRXJ_EXCLUDE_AUDIO
9768/*===========================================================================*/
9769/*===========================================================================*/
9770/*== AUDIO DATAPATH FUNCTIONS ==*/
9771/*===========================================================================*/
9772/*===========================================================================*/
9773
9774/*
9775* \brief Power up AUD.
9776* \param demod instance of demodulator
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009777* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009778*
9779*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009780static int power_up_aud(pdrx_demod_instance_t demod, bool set_standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009781{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009782 drx_aud_standard_t aud_standard = DRX_AUD_STANDARD_AUTO;
9783 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009784
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009785 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009786
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009787 WR16(dev_addr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009788 /* setup TR interface: R/W mode, fifosize=8 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009789 WR16(dev_addr, AUD_TOP_TR_MDE__A, 8);
9790 WR16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009791
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009792 if (set_standard == true) {
9793 CHK_ERROR(aud_ctrl_set_standard(demod, &aud_standard));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009794 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009795
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009796 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009797rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009798 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009799}
9800
9801/*============================================================================*/
9802
9803/**
9804* \brief Power up AUD.
9805* \param demod instance of demodulator
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009806* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009807*
9808*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009809static int power_down_aud(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009810{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009811 struct i2c_device_addr *dev_addr = NULL;
9812 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009813
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009814 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
9815 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009816
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009817 WR16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009818
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009819 ext_attr->aud_data.audio_is_active = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009820
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009821 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009822rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009823 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009824}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009825
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009826/*============================================================================*/
9827/**
9828* \brief Get Modus data from audio RAM
9829* \param demod instance of demodulator
9830* \param pointer to modus
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009831* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009832*
9833*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009834static int aud_get_modus(pdrx_demod_instance_t demod, u16 *modus)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009835{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009836 struct i2c_device_addr *dev_addr = NULL;
9837 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009838
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009839 u16 r_modus = 0;
9840 u16 r_modusHi = 0;
9841 u16 r_modusLo = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009842
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009843 if (modus == NULL) {
9844 return DRX_STS_INVALID_ARG;
9845 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009846
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009847 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
9848 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009849
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009850 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009851 if (ext_attr->aud_data.audio_is_active == false) {
9852 CHK_ERROR(power_up_aud(demod, true));
9853 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009854 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009855
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009856 /* Modus register is combined in to RAM location */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009857 RR16(dev_addr, AUD_DEM_RAM_MODUS_HI__A, &r_modusHi);
9858 RR16(dev_addr, AUD_DEM_RAM_MODUS_LO__A, &r_modusLo);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009859
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009860 r_modus = ((r_modusHi << 12) & AUD_DEM_RAM_MODUS_HI__M)
9861 | (((r_modusLo & AUD_DEM_RAM_MODUS_LO__M)));
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009862
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009863 *modus = r_modus;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009864
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009865 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009866rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009867 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009868
9869}
9870
9871/*============================================================================*/
9872/**
9873* \brief Get audio RDS dat
9874* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009875* \param pointer to drx_cfg_aud_rds_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009876* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009877*
9878*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009879static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009880aud_ctrl_get_cfg_rds(pdrx_demod_instance_t demod, pdrx_cfg_aud_rds_t status)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009881{
Mauro Carvalho Chehab5b223b32012-03-20 00:33:46 -03009882 struct i2c_device_addr *addr = NULL;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009883 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009884
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009885 u16 r_rds_array_cnt_init = 0;
9886 u16 r_rds_array_cnt_check = 0;
9887 u16 r_rds_data = 0;
9888 u16 rds_data_cnt = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009889
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009890 addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
9891 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009892
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009893 if (status == NULL) {
9894 return DRX_STS_INVALID_ARG;
9895 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009896
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009897 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009898 if (ext_attr->aud_data.audio_is_active == false) {
9899 CHK_ERROR(power_up_aud(demod, true));
9900 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009901 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009902
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03009903 status->valid = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009904
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009905 RR16(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_init);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009906
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009907 if (r_rds_array_cnt_init ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009908 AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID) {
9909 /* invalid data */
9910 return DRX_STS_OK;
9911 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009912
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009913 if (ext_attr->aud_data.rds_data_counter == r_rds_array_cnt_init) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009914 /* no new data */
9915 return DRX_STS_OK;
9916 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009917
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009918 /* RDS is detected, as long as FM radio is selected assume
9919 RDS will be available */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009920 ext_attr->aud_data.rds_data_present = true;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009921
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009922 /* new data */
9923 /* read the data */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009924 for (rds_data_cnt = 0; rds_data_cnt < AUD_RDS_ARRAY_SIZE; rds_data_cnt++) {
9925 RR16(addr, AUD_DEM_RD_RDS_DATA__A, &r_rds_data);
9926 status->data[rds_data_cnt] = r_rds_data;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009927 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009928
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009929 RR16(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_check);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009930
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009931 if (r_rds_array_cnt_check == r_rds_array_cnt_init) {
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03009932 status->valid = true;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009933 ext_attr->aud_data.rds_data_counter = r_rds_array_cnt_check;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009934 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009935
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009936 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009937rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009938 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009939}
9940
9941/*============================================================================*/
9942/**
9943* \brief Get the current audio carrier detection status
9944* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009945* \param pointer to aud_ctrl_get_status
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009946* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009947*
9948*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -03009949static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009950aud_ctrl_get_carrier_detect_status(pdrx_demod_instance_t demod, pdrx_aud_status_t status)
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009951{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009952 pdrxj_data_t ext_attr = NULL;
9953 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009954
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009955 u16 r_data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009956
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009957 if (status == NULL) {
9958 return DRX_STS_INVALID_ARG;
9959 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009960
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009961 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
9962 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009963
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009964 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009965 if (ext_attr->aud_data.audio_is_active == false) {
9966 CHK_ERROR(power_up_aud(demod, true));
9967 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009968 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009969
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009970 /* initialize the variables */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009971 status->carrier_a = false;
9972 status->carrier_b = false;
9973 status->nicam_status = DRX_AUD_NICAM_NOT_DETECTED;
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -03009974 status->sap = false;
9975 status->stereo = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009976
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009977 /* read stereo sound mode indication */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009978 RR16(dev_addr, AUD_DEM_RD_STATUS__A, &r_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009979
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009980 /* carrier a detected */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009981 if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_A__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009982 AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009983 status->carrier_a = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009984 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -03009985
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009986 /* carrier b detected */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009987 if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_B__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009988 AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009989 status->carrier_b = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009990 }
9991 /* nicam detected */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009992 if ((r_data & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009993 AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009994 if ((r_data & AUD_DEM_RD_STATUS_BAD_NICAM__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009995 AUD_DEM_RD_STATUS_BAD_NICAM_OK) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009996 status->nicam_status = DRX_AUD_NICAM_DETECTED;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009997 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -03009998 status->nicam_status = DRX_AUD_NICAM_BAD;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -03009999 }
10000 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010001
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010002 /* audio mode bilingual or SAP detected */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010003 if ((r_data & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010004 AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP) {
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030010005 status->sap = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010006 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010007
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010008 /* stereo detected */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010009 if ((r_data & AUD_DEM_RD_STATUS_STAT_STEREO__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010010 AUD_DEM_RD_STATUS_STAT_STEREO_STEREO) {
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030010011 status->stereo = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010012 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010013
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010014 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010015rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010016 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010017}
10018
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010019/*============================================================================*/
10020/**
10021* \brief Get the current audio status parameters
10022* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010023* \param pointer to aud_ctrl_get_status
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010024* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010025*
10026*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010027static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010028aud_ctrl_get_status(pdrx_demod_instance_t demod, pdrx_aud_status_t status)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010029{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010030 pdrxj_data_t ext_attr = NULL;
10031 struct i2c_device_addr *dev_addr = NULL;
10032 drx_cfg_aud_rds_t rds = { false, {0} };
10033 u16 r_data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010034
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010035 if (status == NULL) {
10036 return DRX_STS_INVALID_ARG;
10037 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010038
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010039 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
10040 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010041
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010042 /* carrier detection */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010043 CHK_ERROR(aud_ctrl_get_carrier_detect_status(demod, status));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010044
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010045 /* rds data */
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030010046 status->rds = false;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010047 CHK_ERROR(aud_ctrl_get_cfg_rds(demod, &rds));
10048 status->rds = ext_attr->aud_data.rds_data_present;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010049
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010050 /* fm_ident */
10051 RR16(dev_addr, AUD_DSP_RD_FM_IDENT_VALUE__A, &r_data);
10052 r_data >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
10053 status->fm_ident = (s8) r_data;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010054
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010055 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010056rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010057 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010058}
10059
10060/*============================================================================*/
10061/**
10062* \brief Get the current volume settings
10063* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010064* \param pointer to drx_cfg_aud_volume_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010065* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010066*
10067*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010068static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010069aud_ctrl_get_cfg_volume(pdrx_demod_instance_t demod, pdrx_cfg_aud_volume_t volume)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010070{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010071 struct i2c_device_addr *dev_addr = NULL;
10072 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010073
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010074 u16 r_volume = 0;
10075 u16 r_avc = 0;
10076 u16 r_strength_left = 0;
10077 u16 r_strength_right = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010078
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010079 if (volume == NULL) {
10080 return DRX_STS_INVALID_ARG;
10081 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010082
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010083 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
10084 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010085
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010086 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010087 if (ext_attr->aud_data.audio_is_active == false) {
10088 CHK_ERROR(power_up_aud(demod, true));
10089 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010090 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010091
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010092 /* volume */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010093 volume->mute = ext_attr->aud_data.volume.mute;
10094 RR16(dev_addr, AUD_DSP_WR_VOLUME__A, &r_volume);
10095 if (r_volume == 0) {
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030010096 volume->mute = true;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010097 volume->volume = ext_attr->aud_data.volume.volume;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010098 } else {
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030010099 volume->mute = false;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010100 volume->volume = ((r_volume & AUD_DSP_WR_VOLUME_VOL_MAIN__M) >>
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010101 AUD_DSP_WR_VOLUME_VOL_MAIN__B) -
10102 AUD_VOLUME_ZERO_DB;
10103 if (volume->volume < AUD_VOLUME_DB_MIN) {
10104 volume->volume = AUD_VOLUME_DB_MIN;
10105 }
10106 if (volume->volume > AUD_VOLUME_DB_MAX) {
10107 volume->volume = AUD_VOLUME_DB_MAX;
10108 }
10109 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010110
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010111 /* automatic volume control */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010112 RR16(dev_addr, AUD_DSP_WR_AVC__A, &r_avc);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010113
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010114 if ((r_avc & AUD_DSP_WR_AVC_AVC_ON__M) == AUD_DSP_WR_AVC_AVC_ON_OFF)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010115 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010116 volume->avc_mode = DRX_AUD_AVC_OFF;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010117 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010118 switch (r_avc & AUD_DSP_WR_AVC_AVC_DECAY__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010119 case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010120 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_20MS;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010121 break;
10122 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010123 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_8S;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010124 break;
10125 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010126 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_4S;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010127 break;
10128 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010129 volume->avc_mode = DRX_AUD_AVC_DECAYTIME_2S;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010130 break;
10131 default:
10132 return DRX_STS_ERROR;
10133 break;
10134 }
10135 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010136
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010137 /* max attenuation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010138 switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_ATT__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010139 case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010140 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_12DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010141 break;
10142 case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010143 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_18DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010144 break;
10145 case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010146 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_24DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010147 break;
10148 default:
10149 return DRX_STS_ERROR;
10150 break;
10151 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010152
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010153 /* max gain */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010154 switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010155 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010156 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_0DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010157 break;
10158 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010159 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_6DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010160 break;
10161 case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010162 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_12DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010163 break;
10164 default:
10165 return DRX_STS_ERROR;
10166 break;
10167 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010168
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010169 /* reference level */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010170 volume->avc_ref_level = (u16) ((r_avc & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010171 AUD_DSP_WR_AVC_AVC_REF_LEV__B);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010172
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010173 /* read qpeak registers and calculate strength of left and right carrier */
10174 /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
10175 /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
10176 /* left carrier */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010177
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010178 /* QP vaues */
10179 /* left carrier */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010180 RR16(dev_addr, AUD_DSP_RD_QPEAK_L__A, &r_strength_left);
10181 volume->strength_left = (((s16) log1_times100(r_strength_left)) -
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010182 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010183
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010184 /* right carrier */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010185 RR16(dev_addr, AUD_DSP_RD_QPEAK_R__A, &r_strength_right);
10186 volume->strength_right = (((s16) log1_times100(r_strength_right)) -
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010187 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010188
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010189 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010190rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010191 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010192}
10193
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010194/*============================================================================*/
10195/**
10196* \brief Set the current volume settings
10197* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010198* \param pointer to drx_cfg_aud_volume_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010199* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010200*
10201*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010202static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010203aud_ctrl_set_cfg_volume(pdrx_demod_instance_t demod, pdrx_cfg_aud_volume_t volume)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010204{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010205 struct i2c_device_addr *dev_addr = NULL;
10206 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010207
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010208 u16 w_volume = 0;
10209 u16 w_avc = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010210
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010211 if (volume == NULL) {
10212 return DRX_STS_INVALID_ARG;
10213 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010214
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010215 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
10216 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010217
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010218 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010219 if (ext_attr->aud_data.audio_is_active == false) {
10220 CHK_ERROR(power_up_aud(demod, true));
10221 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010222 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010223
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010224 /* volume */
10225 /* volume range from -60 to 12 (expressed in dB) */
10226 if ((volume->volume < AUD_VOLUME_DB_MIN) ||
10227 (volume->volume > AUD_VOLUME_DB_MAX)) {
10228 return DRX_STS_INVALID_ARG;
10229 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010230
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010231 RR16(dev_addr, AUD_DSP_WR_VOLUME__A, &w_volume);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010232
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010233 /* clear the volume mask */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010234 w_volume &= (u16) ~AUD_DSP_WR_VOLUME_VOL_MAIN__M;
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030010235 if (volume->mute == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010236 /* mute */
10237 /* mute overrules volume */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010238 w_volume |= (u16) (0);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010239
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010240 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010241 w_volume |= (u16) ((volume->volume + AUD_VOLUME_ZERO_DB) <<
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010242 AUD_DSP_WR_VOLUME_VOL_MAIN__B);
10243 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010244
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010245 WR16(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010246
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010247 /* automatic volume control */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010248 RR16(dev_addr, AUD_DSP_WR_AVC__A, &w_avc);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010249
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010250 /* clear masks that require writing */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010251 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_ON__M;
10252 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_DECAY__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010253
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010254 if (volume->avc_mode == DRX_AUD_AVC_OFF) {
10255 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_OFF);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010256 } else {
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010257
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010258 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_ON);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010259
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010260 /* avc decay */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010261 switch (volume->avc_mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010262 case DRX_AUD_AVC_DECAYTIME_20MS:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010263 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010264 break;
10265 case DRX_AUD_AVC_DECAYTIME_8S:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010266 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010267 break;
10268 case DRX_AUD_AVC_DECAYTIME_4S:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010269 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010270 break;
10271 case DRX_AUD_AVC_DECAYTIME_2S:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010272 w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010273 break;
10274 default:
10275 return DRX_STS_INVALID_ARG;
10276 }
10277 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010278
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010279 /* max attenuation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010280 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
10281 switch (volume->avc_max_atten) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010282 case DRX_AUD_AVC_MAX_ATTEN_12DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010283 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010284 break;
10285 case DRX_AUD_AVC_MAX_ATTEN_18DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010286 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010287 break;
10288 case DRX_AUD_AVC_MAX_ATTEN_24DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010289 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010290 break;
10291 default:
10292 return DRX_STS_INVALID_ARG;
10293 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010294
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010295 /* max gain */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010296 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
10297 switch (volume->avc_max_gain) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010298 case DRX_AUD_AVC_MAX_GAIN_0DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010299 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010300 break;
10301 case DRX_AUD_AVC_MAX_GAIN_6DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010302 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010303 break;
10304 case DRX_AUD_AVC_MAX_GAIN_12DB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010305 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010306 break;
10307 default:
10308 return DRX_STS_INVALID_ARG;
10309 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010310
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010311 /* avc reference level */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010312 if (volume->avc_ref_level > AUD_MAX_AVC_REF_LEVEL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010313 return DRX_STS_INVALID_ARG;
10314 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010315
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010316 w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_REF_LEV__M;
10317 w_avc |= (u16) (volume->avc_ref_level << AUD_DSP_WR_AVC_AVC_REF_LEV__B);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010318
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010319 WR16(dev_addr, AUD_DSP_WR_AVC__A, w_avc);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010320
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010321 /* all done, store config in data structure */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010322 ext_attr->aud_data.volume = *volume;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010323
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010324 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010325rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010326 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010327}
10328
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010329/*============================================================================*/
10330/**
10331* \brief Get the I2S settings
10332* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010333* \param pointer to drx_cfg_i2s_output_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010334* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010335*
10336*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010337static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010338aud_ctrl_get_cfg_output_i2s(pdrx_demod_instance_t demod, pdrx_cfg_i2s_output_t output)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010339{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010340 struct i2c_device_addr *dev_addr = NULL;
10341 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010342
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010343 u16 w_i2s_config = 0;
10344 u16 r_i2s_freq = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010345
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010346 if (output == NULL) {
10347 return DRX_STS_INVALID_ARG;
10348 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010349
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010350 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
10351 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010352
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010353 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010354 if (ext_attr->aud_data.audio_is_active == false) {
10355 CHK_ERROR(power_up_aud(demod, true));
10356 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010357 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010358
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010359 RR16(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config);
10360 RR16(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, &r_i2s_freq);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010361
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010362 /* I2S mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010363 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010364 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
10365 output->mode = DRX_I2S_MODE_MASTER;
10366 break;
10367 case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
10368 output->mode = DRX_I2S_MODE_SLAVE;
10369 break;
10370 default:
10371 return DRX_STS_ERROR;
10372 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010373
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010374 /* I2S format */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010375 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010376 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
10377 output->format = DRX_I2S_FORMAT_WS_ADVANCED;
10378 break;
10379 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
10380 output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
10381 break;
10382 default:
10383 return DRX_STS_ERROR;
10384 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010385
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010386 /* I2S word length */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010387 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010388 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010389 output->word_length = DRX_I2S_WORDLENGTH_16;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010390 break;
10391 case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010392 output->word_length = DRX_I2S_WORDLENGTH_32;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010393 break;
10394 default:
10395 return DRX_STS_ERROR;
10396 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010397
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010398 /* I2S polarity */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010399 switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010400 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
10401 output->polarity = DRX_I2S_POLARITY_LEFT;
10402 break;
10403 case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
10404 output->polarity = DRX_I2S_POLARITY_RIGHT;
10405 break;
10406 default:
10407 return DRX_STS_ERROR;
10408 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010409
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010410 /* I2S output enabled */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010411 if ((w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010412 == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010413 output->output_enable = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010414 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010415 output->output_enable = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010416 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010417
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010418 if (r_i2s_freq > 0) {
10419 output->frequency = 6144UL * 48000 / r_i2s_freq;
10420 if (output->word_length == DRX_I2S_WORDLENGTH_16) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010421 output->frequency *= 2;
10422 }
10423 } else {
10424 output->frequency = AUD_I2S_FREQUENCY_MAX;
10425 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010426
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010427 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010428rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010429 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010430}
10431
10432/*============================================================================*/
10433/**
10434* \brief Set the I2S settings
10435* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010436* \param pointer to drx_cfg_i2s_output_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010437* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010438*
10439*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010440static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010441aud_ctrl_set_cfg_output_i2s(pdrx_demod_instance_t demod, pdrx_cfg_i2s_output_t output)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010442{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010443 struct i2c_device_addr *dev_addr = NULL;
10444 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010445
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010446 u16 w_i2s_config = 0;
10447 u16 w_i2s_pads_data_da = 0;
10448 u16 w_i2s_pads_data_cl = 0;
10449 u16 w_i2s_pads_data_ws = 0;
10450 u32 w_i2s_freq = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010451
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010452 if (output == NULL) {
10453 return DRX_STS_INVALID_ARG;
10454 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010455
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010456 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
10457 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010458
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010459 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010460 if (ext_attr->aud_data.audio_is_active == false) {
10461 CHK_ERROR(power_up_aud(demod, true));
10462 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010463 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010464
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010465 RR16(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010466
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010467 /* I2S mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010468 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010469
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010470 switch (output->mode) {
10471 case DRX_I2S_MODE_MASTER:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010472 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010473 break;
10474 case DRX_I2S_MODE_SLAVE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010475 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010476 break;
10477 default:
10478 return DRX_STS_INVALID_ARG;
10479 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010480
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010481 /* I2S format */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010482 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010483
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010484 switch (output->format) {
10485 case DRX_I2S_FORMAT_WS_ADVANCED:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010486 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010487 break;
10488 case DRX_I2S_FORMAT_WS_WITH_DATA:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010489 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010490 break;
10491 default:
10492 return DRX_STS_INVALID_ARG;
10493 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010494
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010495 /* I2S word length */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010496 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010497
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010498 switch (output->word_length) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010499 case DRX_I2S_WORDLENGTH_16:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010500 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010501 break;
10502 case DRX_I2S_WORDLENGTH_32:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010503 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010504 break;
10505 default:
10506 return DRX_STS_INVALID_ARG;
10507 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010508
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010509 /* I2S polarity */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010510 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010511 switch (output->polarity) {
10512 case DRX_I2S_POLARITY_LEFT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010513 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010514 break;
10515 case DRX_I2S_POLARITY_RIGHT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010516 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010517 break;
10518 default:
10519 return DRX_STS_INVALID_ARG;
10520 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010521
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010522 /* I2S output enabled */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010523 w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
10524 if (output->output_enable == true) {
10525 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010526 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010527 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010528 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010529
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010530 /*
10531 I2S frequency
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010532
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010533 w_i2s_freq = 6144 * 48000 * nrbits / ( 32 * frequency )
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010534
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010535 16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
10536 32bit: 6144 * 48000 / freq = ( 6144 * 48000 / freq )
10537 */
10538 if ((output->frequency > AUD_I2S_FREQUENCY_MAX) ||
10539 output->frequency < AUD_I2S_FREQUENCY_MIN) {
10540 return DRX_STS_INVALID_ARG;
10541 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010542
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010543 w_i2s_freq = (6144UL * 48000UL) + (output->frequency >> 1);
10544 w_i2s_freq /= output->frequency;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010545
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010546 if (output->word_length == DRX_I2S_WORDLENGTH_16) {
10547 w_i2s_freq *= 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010548 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010549
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010550 WR16(dev_addr, AUD_DEM_WR_I2S_CONFIG2__A, w_i2s_config);
10551 WR16(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, (u16) w_i2s_freq);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010552
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010553 /* configure I2S output pads for master or slave mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010554 WR16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010555
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010556 if (output->mode == DRX_I2S_MODE_MASTER) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010557 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010558 SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010559 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010560 SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010561 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010562 SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
10563 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010564 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010565 SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010566 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010567 SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010568 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010569 SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
10570 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010571
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010572 WR16(dev_addr, SIO_PDR_I2S_DA_CFG__A, w_i2s_pads_data_da);
10573 WR16(dev_addr, SIO_PDR_I2S_CL_CFG__A, w_i2s_pads_data_cl);
10574 WR16(dev_addr, SIO_PDR_I2S_WS_CFG__A, w_i2s_pads_data_ws);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010575
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010576 WR16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010577
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010578 /* all done, store config in data structure */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010579 ext_attr->aud_data.i2sdata = *output;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010580
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010581 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010582rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010583 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010584}
10585
10586/*============================================================================*/
10587/**
10588* \brief Get the Automatic Standard Select (ASS)
10589* and Automatic Sound Change (ASC)
10590* \param demod instance of demodulator
10591* \param pointer to pDRXAudAutoSound_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010592* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010593*
10594*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010595static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010596aud_ctrl_get_cfg_auto_sound(pdrx_demod_instance_t demod,
10597 pdrx_cfg_aud_auto_sound_t auto_sound)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010598{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010599 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
10600 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010601
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010602 u16 r_modus = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010603
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010604 if (auto_sound == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010605 return DRX_STS_INVALID_ARG;
10606 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010607
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010608 dev_addr = demod->my_i2c_dev_addr;
10609 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010610
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010611 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010612 if (ext_attr->aud_data.audio_is_active == false) {
10613 CHK_ERROR(power_up_aud(demod, true));
10614 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010615 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010616
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010617 CHK_ERROR(aud_get_modus(demod, &r_modus));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010618
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010619 switch (r_modus & (AUD_DEM_WR_MODUS_MOD_ASS__M |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010620 AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M)) {
10621 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
10622 case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010623 *auto_sound =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010624 DRX_AUD_AUTO_SOUND_OFF;
10625 break;
10626 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010627 *auto_sound =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010628 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
10629 break;
10630 case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010631 *auto_sound =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010632 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
10633 break;
10634 default:
10635 return DRX_STS_ERROR;
10636 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010637
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010638 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010639rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010640 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010641}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010642
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010643/*============================================================================*/
10644/**
10645* \brief Set the Automatic Standard Select (ASS)
10646* and Automatic Sound Change (ASC)
10647* \param demod instance of demodulator
10648* \param pointer to pDRXAudAutoSound_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010649* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010650*
10651*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010652static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010653aud_ctr_setl_cfg_auto_sound(pdrx_demod_instance_t demod,
10654 pdrx_cfg_aud_auto_sound_t auto_sound)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010655{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010656 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
10657 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010658
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010659 u16 r_modus = 0;
10660 u16 w_modus = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010661
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010662 if (auto_sound == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010663 return DRX_STS_INVALID_ARG;
10664 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010665
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010666 dev_addr = demod->my_i2c_dev_addr;
10667 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010668
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010669 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010670 if (ext_attr->aud_data.audio_is_active == false) {
10671 CHK_ERROR(power_up_aud(demod, true));
10672 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010673 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010674
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010675 CHK_ERROR(aud_get_modus(demod, &r_modus));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010676
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010677 w_modus = r_modus;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010678 /* clear ASS & ASC bits */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010679 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_ASS__M;
10680 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010681
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010682 switch (*auto_sound) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010683 case DRX_AUD_AUTO_SOUND_OFF:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010684 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
10685 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010686 break;
10687 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010688 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
10689 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010690 break;
10691 case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010692 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
10693 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010694 break;
10695 default:
10696 return DRX_STS_INVALID_ARG;
10697 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010698
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010699 if (w_modus != r_modus) {
10700 WR16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010701 }
10702 /* copy to data structure */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010703 ext_attr->aud_data.auto_sound = *auto_sound;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010704
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010705 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010706rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010707 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010708}
10709
10710/*============================================================================*/
10711/**
10712* \brief Get the Automatic Standard Select thresholds
10713* \param demod instance of demodulator
10714* \param pointer to pDRXAudASSThres_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010715* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010716*
10717*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010718static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010719aud_ctrl_get_cfg_ass_thres(pdrx_demod_instance_t demod, pdrx_cfg_aud_ass_thres_t thres)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010720{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010721 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
10722 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010723
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010724 u16 thres_a2 = 0;
10725 u16 thres_btsc = 0;
10726 u16 thres_nicam = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010727
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010728 if (thres == NULL) {
10729 return DRX_STS_INVALID_ARG;
10730 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010731
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010732 dev_addr = demod->my_i2c_dev_addr;
10733 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010734
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010735 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010736 if (ext_attr->aud_data.audio_is_active == false) {
10737 CHK_ERROR(power_up_aud(demod, true));
10738 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010739 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010740
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010741 RR16(dev_addr, AUD_DEM_RAM_A2_THRSHLD__A, &thres_a2);
10742 RR16(dev_addr, AUD_DEM_RAM_BTSC_THRSHLD__A, &thres_btsc);
10743 RR16(dev_addr, AUD_DEM_RAM_NICAM_THRSHLD__A, &thres_nicam);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010744
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010745 thres->a2 = thres_a2;
10746 thres->btsc = thres_btsc;
10747 thres->nicam = thres_nicam;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010748
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010749 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010750rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010751 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010752}
10753
10754/*============================================================================*/
10755/**
10756* \brief Get the Automatic Standard Select thresholds
10757* \param demod instance of demodulator
10758* \param pointer to pDRXAudASSThres_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010759* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010760*
10761*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010762static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010763aud_ctrl_set_cfg_ass_thres(pdrx_demod_instance_t demod, pdrx_cfg_aud_ass_thres_t thres)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010764{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010765 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
10766 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010767
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010768 if (thres == NULL) {
10769 return DRX_STS_INVALID_ARG;
10770 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010771
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010772 dev_addr = demod->my_i2c_dev_addr;
10773 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010774
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010775 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010776 if (ext_attr->aud_data.audio_is_active == false) {
10777 CHK_ERROR(power_up_aud(demod, true));
10778 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010779 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010780
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010781 WR16(dev_addr, AUD_DEM_WR_A2_THRSHLD__A, thres->a2);
10782 WR16(dev_addr, AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc);
10783 WR16(dev_addr, AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010784
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010785 /* update DRXK data structure with hardware values */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010786 ext_attr->aud_data.ass_thresholds = *thres;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010787
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010788 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010789rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010790 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010791}
10792
10793/*============================================================================*/
10794/**
10795* \brief Get Audio Carrier settings
10796* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010797* \param pointer to pdrx_aud_carrier_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010798* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010799*
10800*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010801static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010802aud_ctrl_get_cfg_carrier(pdrx_demod_instance_t demod, pdrx_cfg_aud_carriers_t carriers)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010803{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010804 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
10805 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010806
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010807 u16 w_modus = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010808
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010809 u16 dco_a_hi = 0;
10810 u16 dco_a_lo = 0;
10811 u16 dco_b_hi = 0;
10812 u16 dco_b_lo = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010813
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030010814 u32 valA = 0;
10815 u32 valB = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010816
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010817 u16 dc_lvl_a = 0;
10818 u16 dc_lvl_b = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010819
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010820 u16 cm_thes_a = 0;
10821 u16 cm_thes_b = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010822
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010823 if (carriers == NULL) {
10824 return DRX_STS_INVALID_ARG;
10825 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010826
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010827 dev_addr = demod->my_i2c_dev_addr;
10828 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010829
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010830 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010831 if (ext_attr->aud_data.audio_is_active == false) {
10832 CHK_ERROR(power_up_aud(demod, true));
10833 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010834 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010835
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010836 CHK_ERROR(aud_get_modus(demod, &w_modus));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010837
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010838 /* Behaviour of primary audio channel */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010839 switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_A__M)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010840 case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
10841 carriers->a.opt = DRX_NO_CARRIER_MUTE;
10842 break;
10843 case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
10844 carriers->a.opt = DRX_NO_CARRIER_NOISE;
10845 break;
10846 default:
10847 return DRX_STS_ERROR;
10848 break;
10849 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010850
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010851 /* Behaviour of secondary audio channel */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010852 switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_B__M)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010853 case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
10854 carriers->b.opt = DRX_NO_CARRIER_MUTE;
10855 break;
10856 case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
10857 carriers->b.opt = DRX_NO_CARRIER_NOISE;
10858 break;
10859 default:
10860 return DRX_STS_ERROR;
10861 break;
10862 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010863
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010864 /* frequency adjustment for primary & secondary audio channel */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010865 RR16(dev_addr, AUD_DEM_RAM_DCO_A_HI__A, &dco_a_hi);
10866 RR16(dev_addr, AUD_DEM_RAM_DCO_A_LO__A, &dco_a_lo);
10867 RR16(dev_addr, AUD_DEM_RAM_DCO_B_HI__A, &dco_b_hi);
10868 RR16(dev_addr, AUD_DEM_RAM_DCO_B_LO__A, &dco_b_lo);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010869
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010870 valA = (((u32) dco_a_hi) << 12) | ((u32) dco_a_lo & 0xFFF);
10871 valB = (((u32) dco_b_hi) << 12) | ((u32) dco_b_lo & 0xFFF);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010872
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010873 /* Multiply by 20250 * 1>>24 ~= 2 / 1657 */
10874 carriers->a.dco = DRX_S24TODRXFREQ(valA) * 2L / 1657L;
10875 carriers->b.dco = DRX_S24TODRXFREQ(valB) * 2L / 1657L;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010876
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010877 /* DC level of the incoming FM signal on the primary
10878 & seconday sound channel */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010879 RR16(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dc_lvl_a);
10880 RR16(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dc_lvl_b);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010881
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010882 /* offset (kHz) = (dcLvl / 322) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010883 carriers->a.shift = (DRX_U16TODRXFREQ(dc_lvl_a) / 322L);
10884 carriers->b.shift = (DRX_U16TODRXFREQ(dc_lvl_b) / 322L);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010885
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010886 /* Carrier detetcion threshold for primary & secondary channel */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010887 RR16(dev_addr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cm_thes_a);
10888 RR16(dev_addr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cm_thes_b);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010889
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010890 carriers->a.thres = cm_thes_a;
10891 carriers->b.thres = cm_thes_b;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010892
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010893 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010894rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010895 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010896}
10897
10898/*============================================================================*/
10899/**
10900* \brief Set Audio Carrier settings
10901* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010902* \param pointer to pdrx_aud_carrier_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010903* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010904*
10905*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030010906static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010907aud_ctrl_set_cfg_carrier(pdrx_demod_instance_t demod, pdrx_cfg_aud_carriers_t carriers)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010908{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010909 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
10910 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010911
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010912 u16 w_modus = 0;
10913 u16 r_modus = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010914
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010915 u16 dco_a_hi = 0;
10916 u16 dco_a_lo = 0;
10917 u16 dco_b_hi = 0;
10918 u16 dco_b_lo = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010919
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030010920 s32 valA = 0;
10921 s32 valB = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010922
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010923 if (carriers == NULL) {
10924 return DRX_STS_INVALID_ARG;
10925 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010926
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010927 dev_addr = demod->my_i2c_dev_addr;
10928 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010929
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010930 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010931 if (ext_attr->aud_data.audio_is_active == false) {
10932 CHK_ERROR(power_up_aud(demod, true));
10933 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010934 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010935
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010936 CHK_ERROR(aud_get_modus(demod, &r_modus));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010937
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010938 w_modus = r_modus;
10939 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_A__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010940 /* Behaviour of primary audio channel */
10941 switch (carriers->a.opt) {
10942 case DRX_NO_CARRIER_MUTE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010943 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010944 break;
10945 case DRX_NO_CARRIER_NOISE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010946 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010947 break;
10948 default:
10949 return DRX_STS_INVALID_ARG;
10950 break;
10951 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010952
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010953 /* Behaviour of secondary audio channel */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010954 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_B__M;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010955 switch (carriers->b.opt) {
10956 case DRX_NO_CARRIER_MUTE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010957 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010958 break;
10959 case DRX_NO_CARRIER_NOISE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010960 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010961 break;
10962 default:
10963 return DRX_STS_INVALID_ARG;
10964 break;
10965 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010966
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010967 /* now update the modus register */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010968 if (w_modus != r_modus) {
10969 WR16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010970 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010971
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010972 /* frequency adjustment for primary & secondary audio channel */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030010973 valA = (s32) ((carriers->a.dco) * 1657L / 2);
10974 valB = (s32) ((carriers->b.dco) * 1657L / 2);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010975
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010976 dco_a_hi = (u16) ((valA >> 12) & 0xFFF);
10977 dco_a_lo = (u16) (valA & 0xFFF);
10978 dco_b_hi = (u16) ((valB >> 12) & 0xFFF);
10979 dco_b_lo = (u16) (valB & 0xFFF);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010980
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010981 WR16(dev_addr, AUD_DEM_WR_DCO_A_HI__A, dco_a_hi);
10982 WR16(dev_addr, AUD_DEM_WR_DCO_A_LO__A, dco_a_lo);
10983 WR16(dev_addr, AUD_DEM_WR_DCO_B_HI__A, dco_b_hi);
10984 WR16(dev_addr, AUD_DEM_WR_DCO_B_LO__A, dco_b_lo);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010985
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010986 /* Carrier detetcion threshold for primary & secondary channel */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010987 WR16(dev_addr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres);
10988 WR16(dev_addr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010989
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010990 /* update DRXK data structure */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030010991 ext_attr->aud_data.carriers = *carriers;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010992
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010993 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010994rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030010995 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030010996}
10997
10998/*============================================================================*/
10999/**
11000* \brief Get I2S Source, I2S matrix and FM matrix
11001* \param demod instance of demodulator
11002* \param pointer to pDRXAudmixer_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011003* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011004*
11005*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011006static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011007aud_ctrl_get_cfg_mixer(pdrx_demod_instance_t demod, pdrx_cfg_aud_mixer_t mixer)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011008{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011009 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11010 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011011
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011012 u16 src_i2s_matr = 0;
11013 u16 fm_matr = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011014
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011015 if (mixer == NULL) {
11016 return DRX_STS_INVALID_ARG;
11017 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011018
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011019 dev_addr = demod->my_i2c_dev_addr;
11020 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011021
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011022 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011023 if (ext_attr->aud_data.audio_is_active == false) {
11024 CHK_ERROR(power_up_aud(demod, true));
11025 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011026 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011027
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011028 /* Source Selctor */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011029 RR16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011030
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011031 switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011032 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011033 mixer->source_i2s = DRX_AUD_SRC_MONO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011034 break;
11035 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011036 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_AB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011037 break;
11038 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011039 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_A;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011040 break;
11041 case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011042 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_B;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011043 break;
11044 default:
11045 return DRX_STS_ERROR;
11046 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011047
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011048 /* Matrix */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011049 switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011050 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011051 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_MONO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011052 break;
11053 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011054 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_STEREO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011055 break;
11056 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011057 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_A_MONO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011058 break;
11059 case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011060 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_B_MONO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011061 break;
11062 default:
11063 return DRX_STS_ERROR;
11064 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011065
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011066 /* FM Matrix */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011067 RR16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr);
11068 switch (fm_matr & AUD_DEM_WR_FM_MATRIX__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011069 case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011070 mixer->matrix_fm = DRX_AUD_FM_MATRIX_NO_MATRIX;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011071 break;
11072 case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011073 mixer->matrix_fm = DRX_AUD_FM_MATRIX_GERMAN;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011074 break;
11075 case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011076 mixer->matrix_fm = DRX_AUD_FM_MATRIX_KOREAN;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011077 break;
11078 case AUD_DEM_WR_FM_MATRIX_SOUND_A:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011079 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_A;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011080 break;
11081 case AUD_DEM_WR_FM_MATRIX_SOUND_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011082 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_B;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011083 break;
11084 default:
11085 return DRX_STS_ERROR;
11086 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011087
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011088 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011089rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011090 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011091}
11092
11093/*============================================================================*/
11094/**
11095* \brief Set I2S Source, I2S matrix and FM matrix
11096* \param demod instance of demodulator
11097* \param pointer to DRXAudmixer_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011098* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011099*
11100*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011101static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011102aud_ctrl_set_cfg_mixer(pdrx_demod_instance_t demod, pdrx_cfg_aud_mixer_t mixer)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011103{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011104 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11105 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011106
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011107 u16 src_i2s_matr = 0;
11108 u16 fm_matr = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011109
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011110 if (mixer == NULL) {
11111 return DRX_STS_INVALID_ARG;
11112 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011113
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011114 dev_addr = demod->my_i2c_dev_addr;
11115 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011116
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011117 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011118 if (ext_attr->aud_data.audio_is_active == false) {
11119 CHK_ERROR(power_up_aud(demod, true));
11120 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011121 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011122
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011123 /* Source Selctor */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011124 RR16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr);
11125 src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011126
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011127 switch (mixer->source_i2s) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011128 case DRX_AUD_SRC_MONO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011129 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011130 break;
11131 case DRX_AUD_SRC_STEREO_OR_AB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011132 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011133 break;
11134 case DRX_AUD_SRC_STEREO_OR_A:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011135 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011136 break;
11137 case DRX_AUD_SRC_STEREO_OR_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011138 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011139 break;
11140 default:
11141 return DRX_STS_INVALID_ARG;
11142 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011143
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011144 /* Matrix */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011145 src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
11146 switch (mixer->matrix_i2s) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011147 case DRX_AUD_I2S_MATRIX_MONO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011148 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011149 break;
11150 case DRX_AUD_I2S_MATRIX_STEREO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011151 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011152 break;
11153 case DRX_AUD_I2S_MATRIX_A_MONO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011154 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011155 break;
11156 case DRX_AUD_I2S_MATRIX_B_MONO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011157 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011158 break;
11159 default:
11160 return DRX_STS_INVALID_ARG;
11161 }
11162 /* write the result */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011163 WR16(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, src_i2s_matr);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011164
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011165 /* FM Matrix */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011166 RR16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr);
11167 fm_matr &= (u16) ~AUD_DEM_WR_FM_MATRIX__M;
11168 switch (mixer->matrix_fm) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011169 case DRX_AUD_FM_MATRIX_NO_MATRIX:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011170 fm_matr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011171 break;
11172 case DRX_AUD_FM_MATRIX_GERMAN:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011173 fm_matr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011174 break;
11175 case DRX_AUD_FM_MATRIX_KOREAN:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011176 fm_matr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011177 break;
11178 case DRX_AUD_FM_MATRIX_SOUND_A:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011179 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011180 break;
11181 case DRX_AUD_FM_MATRIX_SOUND_B:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011182 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011183 break;
11184 default:
11185 return DRX_STS_INVALID_ARG;
11186 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011187
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011188 /* Only write if ASS is off */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011189 if (ext_attr->aud_data.auto_sound == DRX_AUD_AUTO_SOUND_OFF) {
11190 WR16(dev_addr, AUD_DEM_WR_FM_MATRIX__A, fm_matr);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011191 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011192
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011193 /* update the data structure with hardware state */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011194 ext_attr->aud_data.mixer = *mixer;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011195
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011196 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011197rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011198 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011199}
11200
11201/*============================================================================*/
11202/**
11203* \brief Set AV Sync settings
11204* \param demod instance of demodulator
11205* \param pointer to DRXICfgAVSync_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011206* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011207*
11208*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011209static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011210aud_ctrl_set_cfg_av_sync(pdrx_demod_instance_t demod, pdrx_cfg_aud_av_sync_t av_sync)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011211{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011212 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11213 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011214
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011215 u16 w_aud_vid_sync = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011216
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011217 if (av_sync == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011218 return DRX_STS_INVALID_ARG;
11219 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011220
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011221 dev_addr = demod->my_i2c_dev_addr;
11222 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011223
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011224 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011225 if (ext_attr->aud_data.audio_is_active == false) {
11226 CHK_ERROR(power_up_aud(demod, true));
11227 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011228 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011229
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011230 /* audio/video synchronisation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011231 RR16(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011232
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011233 w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_ON__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011234
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011235 if (*av_sync == DRX_AUD_AVSYNC_OFF) {
11236 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011237 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011238 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011239 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011240
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011241 w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011242
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011243 switch (*av_sync) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011244 case DRX_AUD_AVSYNC_NTSC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011245 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011246 break;
11247 case DRX_AUD_AVSYNC_MONOCHROME:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011248 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011249 break;
11250 case DRX_AUD_AVSYNC_PAL_SECAM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011251 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011252 break;
11253 case DRX_AUD_AVSYNC_OFF:
11254 /* OK */
11255 break;
11256 default:
11257 return DRX_STS_INVALID_ARG;
11258 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011259
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011260 WR16(dev_addr, AUD_DSP_WR_AV_SYNC__A, w_aud_vid_sync);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011261 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011262rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011263 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011264}
11265
11266/*============================================================================*/
11267/**
11268* \brief Get AV Sync settings
11269* \param demod instance of demodulator
11270* \param pointer to DRXICfgAVSync_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011271* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011272*
11273*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011274static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011275aud_ctrl_get_cfg_av_sync(pdrx_demod_instance_t demod, pdrx_cfg_aud_av_sync_t av_sync)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011276{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011277 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11278 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011279
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011280 u16 w_aud_vid_sync = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011281
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011282 if (av_sync == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011283 return DRX_STS_INVALID_ARG;
11284 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011285
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011286 dev_addr = demod->my_i2c_dev_addr;
11287 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011288
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011289 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011290 if (ext_attr->aud_data.audio_is_active == false) {
11291 CHK_ERROR(power_up_aud(demod, true));
11292 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011293 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011294
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011295 /* audio/video synchronisation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011296 RR16(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011297
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011298 if ((w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_ON__M) ==
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011299 AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011300 *av_sync = DRX_AUD_AVSYNC_OFF;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011301 return DRX_STS_OK;
11302 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011303
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011304 switch (w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011305 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011306 *av_sync = DRX_AUD_AVSYNC_NTSC;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011307 break;
11308 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011309 *av_sync = DRX_AUD_AVSYNC_MONOCHROME;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011310 break;
11311 case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011312 *av_sync = DRX_AUD_AVSYNC_PAL_SECAM;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011313 break;
11314 default:
11315 return DRX_STS_ERROR;
11316 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011317
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011318 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011319rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011320 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011321}
11322
11323/*============================================================================*/
11324/**
11325* \brief Get deviation mode
11326* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011327* \param pointer to drx_cfg_aud_deviation_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011328* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011329*
11330*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011331static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011332aud_ctrl_get_cfg_dev(pdrx_demod_instance_t demod, pdrx_cfg_aud_deviation_t dev)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011333{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011334 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11335 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011336
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011337 u16 r_modus = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011338
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011339 if (dev == NULL) {
11340 return DRX_STS_INVALID_ARG;
11341 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011342
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011343 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
11344 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011345
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011346 CHK_ERROR(aud_get_modus(demod, &r_modus));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011347
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011348 switch (r_modus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011349 case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
11350 *dev = DRX_AUD_DEVIATION_NORMAL;
11351 break;
11352 case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
11353 *dev = DRX_AUD_DEVIATION_HIGH;
11354 break;
11355 default:
11356 return DRX_STS_ERROR;
11357 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011358
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011359 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011360rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011361 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011362}
11363
11364/*============================================================================*/
11365/**
11366* \brief Get deviation mode
11367* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011368* \param pointer to drx_cfg_aud_deviation_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011369* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011370*
11371*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011372static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011373aud_ctrl_set_cfg_dev(pdrx_demod_instance_t demod, pdrx_cfg_aud_deviation_t dev)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011374{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011375 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11376 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011377
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011378 u16 w_modus = 0;
11379 u16 r_modus = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011380
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011381 if (dev == NULL) {
11382 return DRX_STS_INVALID_ARG;
11383 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011384
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011385 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
11386 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011387
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011388 CHK_ERROR(aud_get_modus(demod, &r_modus));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011389
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011390 w_modus = r_modus;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011391
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011392 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011393
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011394 switch (*dev) {
11395 case DRX_AUD_DEVIATION_NORMAL:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011396 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011397 break;
11398 case DRX_AUD_DEVIATION_HIGH:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011399 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011400 break;
11401 default:
11402 return DRX_STS_INVALID_ARG;
11403 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011404
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011405 /* now update the modus register */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011406 if (w_modus != r_modus) {
11407 WR16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011408 }
11409 /* store in drxk data struct */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011410 ext_attr->aud_data.deviation = *dev;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011411
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011412 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011413rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011414 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011415}
11416
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011417/*============================================================================*/
11418/**
11419* \brief Get Prescaler settings
11420* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011421* \param pointer to drx_cfg_aud_prescale_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011422* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011423*
11424*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011425static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011426aud_ctrl_get_cfg_prescale(pdrx_demod_instance_t demod, pdrx_cfg_aud_prescale_t presc)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011427{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011428 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11429 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011430
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011431 u16 r_max_fm_deviation = 0;
11432 u16 r_nicam_prescaler = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011433
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011434 if (presc == NULL) {
11435 return DRX_STS_INVALID_ARG;
11436 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011437
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011438 dev_addr = demod->my_i2c_dev_addr;
11439 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011440
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011441 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011442 if (ext_attr->aud_data.audio_is_active == false) {
11443 CHK_ERROR(power_up_aud(demod, true));
11444 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011445 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011446
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011447 /* read register data */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011448 RR16(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, &r_nicam_prescaler);
11449 RR16(dev_addr, AUD_DSP_WR_FM_PRESC__A, &r_max_fm_deviation);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011450
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011451 /* calculate max FM deviation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011452 r_max_fm_deviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
11453 if (r_max_fm_deviation > 0) {
11454 presc->fm_deviation = 3600UL + (r_max_fm_deviation >> 1);
11455 presc->fm_deviation /= r_max_fm_deviation;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011456 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011457 presc->fm_deviation = 380; /* kHz */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011458 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011459
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011460 /* calculate NICAM gain from pre-scaler */
11461 /*
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011462 nicam_gain = 20 * ( log10( preScaler / 16) )
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011463 = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011464
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011465 because log1_times100() cannot return negative numbers
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011466 = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011467
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011468 for 0.1dB resolution:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011469
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011470 nicam_gain = 200 * ( log10( preScaler / 16) )
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011471 = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
11472 = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011473
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011474 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011475 r_nicam_prescaler >>= 8;
11476 if (r_nicam_prescaler <= 1) {
11477 presc->nicam_gain = -241;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011478 } else {
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011479
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011480 presc->nicam_gain = (s16) (((s32)
11481 (log1_times100
11482 (10 * r_nicam_prescaler *
11483 r_nicam_prescaler)) - (s32)
11484 (log1_times100(10 * 16 * 16))));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011485 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011486
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011487 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011488rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011489 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011490}
11491
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011492/*============================================================================*/
11493/**
11494* \brief Set Prescaler settings
11495* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011496* \param pointer to drx_cfg_aud_prescale_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011497* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011498*
11499*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011500static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011501aud_ctrl_set_cfg_prescale(pdrx_demod_instance_t demod, pdrx_cfg_aud_prescale_t presc)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011502{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011503 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11504 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011505
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011506 u16 w_max_fm_deviation = 0;
11507 u16 nicam_prescaler;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011508
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011509 if (presc == NULL) {
11510 return DRX_STS_INVALID_ARG;
11511 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011512
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011513 dev_addr = demod->my_i2c_dev_addr;
11514 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011515
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011516 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011517 if (ext_attr->aud_data.audio_is_active == false) {
11518 CHK_ERROR(power_up_aud(demod, true));
11519 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011520 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011521
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011522 /* setting of max FM deviation */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011523 w_max_fm_deviation = (u16) (frac(3600UL, presc->fm_deviation, 0));
11524 w_max_fm_deviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
11525 if (w_max_fm_deviation >=
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011526 AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011527 w_max_fm_deviation =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011528 AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
11529 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011530
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011531 /* NICAM Prescaler */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011532 if ((presc->nicam_gain >= -241) && (presc->nicam_gain <= 180)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011533 /* calculation
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011534
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011535 prescaler = 16 * 10^( gd_b / 20 )
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011536
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011537 minval of gd_b = -20*log( 16 ) = -24.1dB
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011538
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011539 negative numbers not allowed for d_b2lin_times100, so
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011540
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011541 prescaler = 16 * 10^( gd_b / 20 )
11542 = 10^( (gd_b / 20) + log10(16) )
11543 = 10^( (gd_b + 20log10(16)) / 20 )
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011544
11545 in 0.1dB
11546
11547 = 10^( G0.1dB + 200log10(16)) / 200 )
11548
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011549 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011550 nicam_prescaler = (u16)
11551 ((d_b2lin_times100(presc->nicam_gain + 241UL) + 50UL) / 100UL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011552
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011553 /* clip result */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011554 if (nicam_prescaler > 127) {
11555 nicam_prescaler = 127;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011556 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011557
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011558 /* shift before writing to register */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011559 nicam_prescaler <<= 8;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011560 } else {
11561 return (DRX_STS_INVALID_ARG);
11562 }
11563 /* end of setting NICAM Prescaler */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011564
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011565 WR16(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, nicam_prescaler);
11566 WR16(dev_addr, AUD_DSP_WR_FM_PRESC__A, w_max_fm_deviation);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011567
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011568 ext_attr->aud_data.prescale = *presc;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011569
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011570 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011571rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011572 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011573}
11574
11575/*============================================================================*/
11576/**
11577* \brief Beep
11578* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011579* \param pointer to drx_aud_beep_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011580* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011581*
11582*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011583static int aud_ctrl_beep(pdrx_demod_instance_t demod, pdrx_aud_beep_t beep)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011584{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011585 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
11586 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011587
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011588 u16 the_beep = 0;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030011589 u16 volume = 0;
11590 u32 frequency = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011591
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011592 if (beep == NULL) {
11593 return DRX_STS_INVALID_ARG;
11594 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011595
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011596 dev_addr = demod->my_i2c_dev_addr;
11597 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011598
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011599 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011600 if (ext_attr->aud_data.audio_is_active == false) {
11601 CHK_ERROR(power_up_aud(demod, true));
11602 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011603 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011604
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011605 if ((beep->volume > 0) || (beep->volume < -127)) {
11606 return DRX_STS_INVALID_ARG;
11607 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011608
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011609 if (beep->frequency > 3000) {
11610 return DRX_STS_INVALID_ARG;
11611 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011612
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030011613 volume = (u16) beep->volume + 127;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011614 the_beep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011615
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030011616 frequency = ((u32) beep->frequency) * 23 / 500;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011617 if (frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M) {
11618 frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
11619 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011620 the_beep |= (u16) frequency;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011621
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030011622 if (beep->mute == true) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011623 the_beep = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011624 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011625
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011626 WR16(dev_addr, AUD_DSP_WR_BEEPER__A, the_beep);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011627
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011628 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011629rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011630 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011631}
11632
11633/*============================================================================*/
11634/**
11635* \brief Set an audio standard
11636* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011637* \param pointer to drx_aud_standard_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011638* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011639*
11640*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011641static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011642aud_ctrl_set_standard(pdrx_demod_instance_t demod, pdrx_aud_standard_t standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011643{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011644 struct i2c_device_addr *dev_addr = NULL;
11645 pdrxj_data_t ext_attr = NULL;
11646 enum drx_standard current_standard = DRX_STANDARD_UNKNOWN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011647
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011648 u16 w_standard = 0;
11649 u16 w_modus = 0;
11650 u16 r_modus = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011651
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011652 bool mute_buffer = false;
11653 s16 volume_buffer = 0;
11654 u16 w_volume = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011655
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011656 if (standard == NULL) {
11657 return DRX_STS_INVALID_ARG;
11658 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011659
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011660 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
11661 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011662
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011663 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011664 if (ext_attr->aud_data.audio_is_active == false) {
11665 CHK_ERROR(power_up_aud(demod, false));
11666 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011667 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011668
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011669 /* reset RDS data availability flag */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011670 ext_attr->aud_data.rds_data_present = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011671
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011672 /* we need to mute from here to avoid noise during standard switching */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011673 mute_buffer = ext_attr->aud_data.volume.mute;
11674 volume_buffer = ext_attr->aud_data.volume.volume;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011675
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011676 ext_attr->aud_data.volume.mute = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011677 /* restore data structure from DRX ExtAttr, call volume first to mute */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011678 CHK_ERROR(aud_ctrl_set_cfg_volume(demod, &ext_attr->aud_data.volume));
11679 CHK_ERROR(aud_ctrl_set_cfg_carrier(demod, &ext_attr->aud_data.carriers));
11680 CHK_ERROR(aud_ctrl_set_cfg_ass_thres
11681 (demod, &ext_attr->aud_data.ass_thresholds));
11682 CHK_ERROR(aud_ctr_setl_cfg_auto_sound(demod, &ext_attr->aud_data.auto_sound));
11683 CHK_ERROR(aud_ctrl_set_cfg_mixer(demod, &ext_attr->aud_data.mixer));
11684 CHK_ERROR(aud_ctrl_set_cfg_av_sync(demod, &ext_attr->aud_data.av_sync));
11685 CHK_ERROR(aud_ctrl_set_cfg_output_i2s(demod, &ext_attr->aud_data.i2sdata));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011686
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011687 /* get prescaler from presets */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011688 CHK_ERROR(aud_ctrl_set_cfg_prescale(demod, &ext_attr->aud_data.prescale));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011689
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011690 CHK_ERROR(aud_get_modus(demod, &r_modus));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011691
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011692 w_modus = r_modus;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011693
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011694 switch (*standard) {
11695 case DRX_AUD_STANDARD_AUTO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011696 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011697 break;
11698 case DRX_AUD_STANDARD_BTSC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011699 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
11700 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_MONO_AND_SAP) {
11701 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011702 }
11703 break;
11704 case DRX_AUD_STANDARD_A2:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011705 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011706 break;
11707 case DRX_AUD_STANDARD_EIAJ:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011708 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011709 break;
11710 case DRX_AUD_STANDARD_FM_STEREO:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011711 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011712 break;
11713 case DRX_AUD_STANDARD_BG_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011714 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011715 break;
11716 case DRX_AUD_STANDARD_D_K1:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011717 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011718 break;
11719 case DRX_AUD_STANDARD_D_K2:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011720 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011721 break;
11722 case DRX_AUD_STANDARD_D_K3:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011723 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011724 break;
11725 case DRX_AUD_STANDARD_BG_NICAM_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011726 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011727 break;
11728 case DRX_AUD_STANDARD_L_NICAM_AM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011729 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011730 break;
11731 case DRX_AUD_STANDARD_I_NICAM_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011732 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011733 break;
11734 case DRX_AUD_STANDARD_D_K_NICAM_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011735 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011736 break;
11737 case DRX_AUD_STANDARD_UNKNOWN:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011738 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011739 break;
11740 default:
11741 return DRX_STS_ERROR;
11742 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011743
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011744 if (*standard == DRX_AUD_STANDARD_AUTO) {
11745 /* we need the current standard here */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011746 current_standard = ext_attr->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011747
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011748 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011749
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011750 if ((current_standard == DRX_STANDARD_PAL_SECAM_L) ||
11751 (current_standard == DRX_STANDARD_PAL_SECAM_LP)) {
11752 w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011753 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011754 w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011755 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011756
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011757 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
11758 if (current_standard == DRX_STANDARD_NTSC) {
11759 w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011760
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011761 } else { /* non USA, ignore standard M to save time */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011762
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011763 w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011764 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011765
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011766 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011767
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011768 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011769
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011770 /* just get hardcoded deemphasis and activate here */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011771 if (ext_attr->aud_data.deemph == DRX_AUD_FM_DEEMPH_50US) {
11772 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011773 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011774 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011775 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011776
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011777 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_BTSC__M;
11778 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_STEREO) {
11779 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011780 } else { /* DRX_BTSC_MONO_AND_SAP */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011781
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011782 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011783 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011784
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011785 if (w_modus != r_modus) {
11786 WR16(dev_addr, AUD_DEM_WR_MODUS__A, w_modus);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011787 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011788
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011789 WR16(dev_addr, AUD_DEM_WR_STANDARD_SEL__A, w_standard);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011790
11791 /**************************************************************************/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011792 /* NOT calling aud_ctrl_set_cfg_volume to avoid interfering standard */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011793 /* detection, need to keep things very minimal here, but keep audio */
11794 /* buffers intact */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011795 /**************************************************************************/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011796 ext_attr->aud_data.volume.mute = mute_buffer;
11797 if (ext_attr->aud_data.volume.mute == false) {
11798 w_volume |= (u16) ((volume_buffer + AUD_VOLUME_ZERO_DB) <<
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011799 AUD_DSP_WR_VOLUME_VOL_MAIN__B);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011800 WR16(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011801 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011802
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011803 /* write standard selected */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011804 ext_attr->aud_data.audio_standard = *standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011805
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011806 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011807rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011808 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011809}
11810
11811/*============================================================================*/
11812/**
11813* \brief Get the current audio standard
11814* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011815* \param pointer to drx_aud_standard_t
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011816* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011817*
11818*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011819static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011820aud_ctrl_get_standard(pdrx_demod_instance_t demod, pdrx_aud_standard_t standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011821{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011822 struct i2c_device_addr *dev_addr = NULL;
11823 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011824
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011825 u16 r_data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011826
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011827 if (standard == NULL) {
11828 return DRX_STS_INVALID_ARG;
11829 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011830
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011831 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
11832 dev_addr = (struct i2c_device_addr *) demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011833
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011834 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011835 if (ext_attr->aud_data.audio_is_active == false) {
11836 CHK_ERROR(power_up_aud(demod, true));
11837 ext_attr->aud_data.audio_is_active = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011838 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011839
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011840 *standard = DRX_AUD_STANDARD_UNKNOWN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011841
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011842 RR16(dev_addr, AUD_DEM_RD_STANDARD_RES__A, &r_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011843
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011844 /* return OK if the detection is not ready yet */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011845 if (r_data >= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011846 *standard = DRX_AUD_STANDARD_NOT_READY;
11847 return DRX_STS_OK;
11848 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011849
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011850 /* detection done, return correct standard */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011851 switch (r_data) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011852 /* no standard detected */
11853 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
11854 *standard = DRX_AUD_STANDARD_UNKNOWN;
11855 break;
11856 /* standard is KOREA(A2) */
11857 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
11858 *standard = DRX_AUD_STANDARD_A2;
11859 break;
11860 /* standard is EIA-J (Japan) */
11861 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
11862 *standard = DRX_AUD_STANDARD_EIAJ;
11863 break;
11864 /* standard is BTSC-stereo */
11865 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
11866 *standard = DRX_AUD_STANDARD_BTSC;
11867 break;
11868 /* standard is BTSC-mono (SAP) */
11869 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
11870 *standard = DRX_AUD_STANDARD_BTSC;
11871 break;
11872 /* standard is FM radio */
11873 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
11874 *standard = DRX_AUD_STANDARD_FM_STEREO;
11875 break;
11876 /* standard is BG FM */
11877 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
11878 *standard = DRX_AUD_STANDARD_BG_FM;
11879 break;
11880 /* standard is DK-1 FM */
11881 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
11882 *standard = DRX_AUD_STANDARD_D_K1;
11883 break;
11884 /* standard is DK-2 FM */
11885 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
11886 *standard = DRX_AUD_STANDARD_D_K2;
11887 break;
11888 /* standard is DK-3 FM */
11889 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
11890 *standard = DRX_AUD_STANDARD_D_K3;
11891 break;
11892 /* standard is BG-NICAM FM */
11893 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
11894 *standard = DRX_AUD_STANDARD_BG_NICAM_FM;
11895 break;
11896 /* standard is L-NICAM AM */
11897 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
11898 *standard = DRX_AUD_STANDARD_L_NICAM_AM;
11899 break;
11900 /* standard is I-NICAM FM */
11901 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
11902 *standard = DRX_AUD_STANDARD_I_NICAM_FM;
11903 break;
11904 /* standard is DK-NICAM FM */
11905 case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
11906 *standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
11907 break;
11908 default:
11909 *standard = DRX_AUD_STANDARD_UNKNOWN;
11910 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011911
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011912 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011913rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011914 return DRX_STS_ERROR;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011915
11916}
11917
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011918/*============================================================================*/
11919/**
11920* \brief Retreive lock status in case of FM standard
11921* \param demod instance of demodulator
11922* \param pointer to lock status
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011923* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011924*
11925*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011926static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011927fm_lock_status(pdrx_demod_instance_t demod, pdrx_lock_status_t lock_stat)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011928{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011929 drx_aud_status_t status;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011930
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011931 /* Check detection of audio carriers */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011932 CHK_ERROR(aud_ctrl_get_carrier_detect_status(demod, &status));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011933
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011934 /* locked if either primary or secondary carrier is detected */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011935 if ((status.carrier_a == true) || (status.carrier_b == true)) {
11936 *lock_stat = DRX_LOCKED;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011937 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011938 *lock_stat = DRX_NOT_LOCKED;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011939 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011940
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011941 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011942
11943rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011944 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011945}
11946
11947/*============================================================================*/
11948/**
11949* \brief retreive signal quality in case of FM standard
11950* \param demod instance of demodulator
11951* \param pointer to signal quality
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011952* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011953*
11954* Only the quality indicator field is will be supplied.
11955* This will either be 0% or 100%, nothing in between.
11956*
11957*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011958static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011959fm_sig_quality(pdrx_demod_instance_t demod, pdrx_sig_quality_t sig_quality)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011960{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011961 drx_lock_status_t lock_status = DRX_NOT_LOCKED;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011962
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011963 CHK_ERROR(fm_lock_status(demod, &lock_status));
11964 if (lock_status == DRX_LOCKED) {
11965 sig_quality->indicator = 100;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011966 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011967 sig_quality->indicator = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011968 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011969
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011970 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011971
11972rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030011973 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011974}
11975
11976#endif
11977
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011978/*===========================================================================*/
11979/*== END AUDIO DATAPATH FUNCTIONS ==*/
11980/*===========================================================================*/
11981
11982/*============================================================================*/
11983/*============================================================================*/
11984/*== OOB DATAPATH FUNCTIONS ==*/
11985/*============================================================================*/
11986/*============================================================================*/
11987#ifndef DRXJ_DIGITAL_ONLY
11988/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011989* \fn int get_oob_lock_status ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011990* \brief Get OOB lock status.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011991* \param dev_addr I2C address
11992 \ oob_lock OOB lock status.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011993* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030011994*
11995* Gets OOB lock status
11996*
11997*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030011998static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030011999get_oob_lock_status(pdrx_demod_instance_t demod,
12000 struct i2c_device_addr *dev_addr, pdrx_lock_status_t oob_lock)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012001{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012002 drxjscu_cmd_t scu_cmd;
12003 u16 cmd_result[2];
12004 u16 oob_lock_state;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012005
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012006 *oob_lock = DRX_NOT_LOCKED;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012007
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012008 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012009 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012010 scu_cmd.result_len = 2;
12011 scu_cmd.result = cmd_result;
12012 scu_cmd.parameter_len = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012013
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012014 CHK_ERROR(scu_command(dev_addr, &scu_cmd));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012015
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012016 if (scu_cmd.result[1] < 0x4000) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012017 /* 0x00 NOT LOCKED */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012018 *oob_lock = DRX_NOT_LOCKED;
12019 } else if (scu_cmd.result[1] < 0x8000) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012020 /* 0x40 DEMOD LOCKED */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012021 *oob_lock = DRXJ_OOB_SYNC_LOCK;
12022 } else if (scu_cmd.result[1] < 0xC000) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012023 /* 0x80 DEMOD + OOB LOCKED (system lock) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012024 oob_lock_state = scu_cmd.result[1] & 0x00FF;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012025
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012026 if (oob_lock_state & 0x0008) {
12027 *oob_lock = DRXJ_OOB_SYNC_LOCK;
12028 } else if ((oob_lock_state & 0x0002) && (oob_lock_state & 0x0001)) {
12029 *oob_lock = DRXJ_OOB_AGC_LOCK;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012030 }
12031 } else {
12032 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012033 *oob_lock = DRX_NEVER_LOCK;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012034 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012035
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012036 /* *oob_lock = scu_cmd.result[1]; */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012037
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012038 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012039rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012040 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012041}
12042
12043/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012044* \fn int get_oob_symbol_rate_offset ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012045* \brief Get OOB Symbol rate offset. Unit is [ppm]
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012046* \param dev_addr I2C address
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012047* \ Symbol Rate Offset OOB parameter.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012048* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012049*
12050* Gets OOB frequency offset
12051*
12052*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012053static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012054get_oob_symbol_rate_offset(struct i2c_device_addr *dev_addr, s32 *symbol_rate_offset)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012055{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012056/* offset = -{(timing_offset/2^19)*(symbol_rate/12,656250MHz)}*10^6 [ppm] */
12057/* offset = -{(timing_offset/2^19)*(symbol_rate/12656250)}*10^6 [ppm] */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012058/* after reconfiguration: */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012059/* offset = -{(timing_offset*symbol_rate)/(2^19*12656250)}*10^6 [ppm] */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012060/* shift symbol rate left by 5 without lossing information */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012061/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012062/* shift 10^6 left by 6 without loosing information */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012063/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012064/* trim 12656250/15625 = 810 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012065/* offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*810)} [ppm] */
12066/* offset = -[(symbol_rate * 2^-5)*(timing_offset)/(2^8)]/810 [ppm] */
12067 s32 timing_offset = 0;
12068 u32 unsigned_timing_offset = 0;
12069 s32 division_factor = 810;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012070 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012071 u32 symbol_rate = 0;
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030012072 bool negative = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012073
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012074 *symbol_rate_offset = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012075 /* read data rate */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012076 SARR16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012077 switch (data & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
12078 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
12079 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
12080 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
12081 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012082 symbol_rate = 1024000; /* bps */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012083 break;
12084 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
12085 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012086 symbol_rate = 772000; /* bps */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012087 break;
12088 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
12089 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012090 symbol_rate = 1544000; /* bps */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012091 break;
12092 default:
12093 return (DRX_STS_ERROR);
12094 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012095
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012096 RR16(dev_addr, ORX_CON_CTI_DTI_R__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012097 /* convert data to positive and keep information about sign */
12098 if ((data & 0x8000) == 0x8000) {
12099 if (data == 0x8000)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012100 unsigned_timing_offset = 32768;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012101 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012102 unsigned_timing_offset = 0x00007FFF & (u32) (-data);
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030012103 negative = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012104 } else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012105 unsigned_timing_offset = (u32) data;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012106
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012107 symbol_rate = symbol_rate >> 5;
12108 unsigned_timing_offset = (unsigned_timing_offset * symbol_rate);
12109 unsigned_timing_offset = frac(unsigned_timing_offset, 256, FRAC_ROUND);
12110 unsigned_timing_offset = frac(unsigned_timing_offset,
12111 division_factor, FRAC_ROUND);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012112 if (negative)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012113 timing_offset = (s32) unsigned_timing_offset;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012114 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012115 timing_offset = -(s32) unsigned_timing_offset;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012116
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012117 *symbol_rate_offset = timing_offset;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012118
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012119 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012120rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012121 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012122}
12123
12124/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012125* \fn int get_oob_freq_offset ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012126* \brief Get OOB lock status.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012127* \param dev_addr I2C address
12128* \ freq_offset OOB frequency offset.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012129* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012130*
12131* Gets OOB frequency offset
12132*
12133*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012134static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012135get_oob_freq_offset(pdrx_demod_instance_t demod, s32 *freq_offset)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012136{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012137 u16 data = 0;
12138 u16 rot = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012139 u16 symbol_rateReg = 0;
12140 u32 symbol_rate = 0;
12141 s32 coarse_freq_offset = 0;
12142 s32 fine_freq_offset = 0;
12143 s32 fine_sign = 1;
12144 s32 coarse_sign = 1;
12145 u32 data64hi = 0;
12146 u32 data64lo = 0;
12147 u32 temp_freq_offset = 0;
12148 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) (NULL);
12149 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012150
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012151 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012152 if ((demod == NULL) || (freq_offset == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012153 return DRX_STS_INVALID_ARG;
12154 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012155
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012156 dev_addr = demod->my_i2c_dev_addr;
12157 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012158
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012159 *freq_offset = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012160
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012161 /* read sign (spectrum inversion) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012162 RR16(dev_addr, ORX_FWP_IQM_FRQ_W__A, &rot);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012163
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012164 /* read frequency offset */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012165 SARR16(dev_addr, SCU_RAM_ORX_FRQ_OFFSET__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012166 /* find COARSE frequency offset */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012167 /* coarse_freq_offset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012168 if (data & 0x8000) {
12169 data = (0xffff - data + 1);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012170 coarse_sign = -1;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012171 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012172 mult32(data, (common_attr->sys_clock_freq * 1000) / 6, &data64hi,
12173 &data64lo);
12174 temp_freq_offset = (((data64lo >> 21) & 0x7ff) | (data64hi << 11));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012175
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012176 /* get value in KHz */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012177 coarse_freq_offset = coarse_sign * frac(temp_freq_offset, 1000, FRAC_ROUND); /* KHz */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012178 /* read data rate */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012179 SARR16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbol_rateReg);
12180 switch (symbol_rateReg & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012181 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
12182 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
12183 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
12184 case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012185 symbol_rate = 1024000;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012186 break;
12187 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
12188 case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012189 symbol_rate = 772000;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012190 break;
12191 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
12192 case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012193 symbol_rate = 1544000;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012194 break;
12195 default:
12196 return (DRX_STS_ERROR);
12197 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012198
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012199 /* find FINE frequency offset */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012200 /* fine_freq_offset = ( (CORRECTION_VALUE*symbol_rate) >> 18 ); */
12201 RR16(dev_addr, ORX_CON_CPH_FRQ_R__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012202 /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012203 fine_freq_offset = (symbol_rate >> 5);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012204 if (data & 0x8000) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012205 fine_freq_offset *= 0xffff - data + 1; /* Hz */
12206 fine_sign = -1;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012207 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012208 fine_freq_offset *= data; /* Hz */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012209 }
12210 /* Left to divide with 8192 (2^13) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012211 fine_freq_offset = frac(fine_freq_offset, 8192, FRAC_ROUND);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012212 /* and to divide with 1000 to get KHz */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012213 fine_freq_offset = fine_sign * frac(fine_freq_offset, 1000, FRAC_ROUND); /* KHz */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012214
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012215 if ((rot & 0x8000) == 0x8000)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012216 *freq_offset = -(coarse_freq_offset + fine_freq_offset);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012217 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012218 *freq_offset = (coarse_freq_offset + fine_freq_offset);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012219
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012220 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012221rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012222 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012223}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012224
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012225/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012226* \fn int get_oob_frequency ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012227* \brief Get OOB frequency (Unit:KHz).
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012228* \param dev_addr I2C address
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012229* \ frequency OOB frequency parameters.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012230* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012231*
12232* Gets OOB frequency
12233*
12234*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012235static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012236get_oob_frequency(pdrx_demod_instance_t demod, s32 *frequency)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012237{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012238 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012239 s32 freq_offset = 0;
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030012240 s32 freq = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012241 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012242
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012243 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012244
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012245 *frequency = 0; /* KHz */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012246
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012247 SARR16(dev_addr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012248
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030012249 freq = (s32) ((s32) data * 50 + 50000L);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012250
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012251 CHK_ERROR(get_oob_freq_offset(demod, &freq_offset));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012252
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012253 *frequency = freq + freq_offset;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012254
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012255 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012256rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012257 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012258}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012259
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012260/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012261* \fn int get_oobmer ()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012262* \brief Get OOB MER.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012263* \param dev_addr I2C address
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012264 \ MER OOB parameter in dB.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012265* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012266*
12267* Gets OOB MER. Table for MER is in Programming guide.
12268*
12269*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012270static int get_oobmer(struct i2c_device_addr *dev_addr, u32 *mer)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012271{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012272 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012273
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012274 *mer = 0;
12275 /* READ MER */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012276 RR16(dev_addr, ORX_EQU_MER_MER_R__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012277 switch (data) {
12278 case 0: /* fall through */
12279 case 1:
12280 *mer = 39;
12281 break;
12282 case 2:
12283 *mer = 33;
12284 break;
12285 case 3:
12286 *mer = 29;
12287 break;
12288 case 4:
12289 *mer = 27;
12290 break;
12291 case 5:
12292 *mer = 25;
12293 break;
12294 case 6:
12295 *mer = 23;
12296 break;
12297 case 7:
12298 *mer = 22;
12299 break;
12300 case 8:
12301 *mer = 21;
12302 break;
12303 case 9:
12304 *mer = 20;
12305 break;
12306 case 10:
12307 *mer = 19;
12308 break;
12309 case 11:
12310 *mer = 18;
12311 break;
12312 case 12:
12313 *mer = 17;
12314 break;
12315 case 13: /* fall through */
12316 case 14:
12317 *mer = 16;
12318 break;
12319 case 15: /* fall through */
12320 case 16:
12321 *mer = 15;
12322 break;
12323 case 17: /* fall through */
12324 case 18:
12325 *mer = 14;
12326 break;
12327 case 19: /* fall through */
12328 case 20:
12329 *mer = 13;
12330 break;
12331 case 21: /* fall through */
12332 case 22:
12333 *mer = 12;
12334 break;
12335 case 23: /* fall through */
12336 case 24: /* fall through */
12337 case 25:
12338 *mer = 11;
12339 break;
12340 case 26: /* fall through */
12341 case 27: /* fall through */
12342 case 28:
12343 *mer = 10;
12344 break;
12345 case 29: /* fall through */
12346 case 30: /* fall through */
12347 case 31: /* fall through */
12348 case 32:
12349 *mer = 9;
12350 break;
12351 case 33: /* fall through */
12352 case 34: /* fall through */
12353 case 35: /* fall through */
12354 case 36:
12355 *mer = 8;
12356 break;
12357 case 37: /* fall through */
12358 case 38: /* fall through */
12359 case 39: /* fall through */
12360 case 40:
12361 *mer = 7;
12362 break;
12363 case 41: /* fall through */
12364 case 42: /* fall through */
12365 case 43: /* fall through */
12366 case 44: /* fall through */
12367 case 45:
12368 *mer = 6;
12369 break;
12370 case 46: /* fall through */
12371 case 47: /* fall through */
12372 case 48: /* fall through */
12373 case 49: /* fall through */
12374 case 50: /* fall through */
12375 *mer = 5;
12376 break;
12377 case 51: /* fall through */
12378 case 52: /* fall through */
12379 case 53: /* fall through */
12380 case 54: /* fall through */
12381 case 55: /* fall through */
12382 case 56: /* fall through */
12383 case 57:
12384 *mer = 4;
12385 break;
12386 case 58: /* fall through */
12387 case 59: /* fall through */
12388 case 60: /* fall through */
12389 case 61: /* fall through */
12390 case 62: /* fall through */
12391 case 63:
12392 *mer = 0;
12393 break;
12394 default:
12395 *mer = 0;
12396 break;
12397 }
12398 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012399rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012400 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012401}
12402#endif /*#ifndef DRXJ_DIGITAL_ONLY */
12403
12404/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012405* \fn int set_orx_nsu_aox()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012406* \brief Configure OrxNsuAox for OOB
12407* \param demod instance of demodulator.
12408* \param active
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012409* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012410*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012411static int set_orx_nsu_aox(pdrx_demod_instance_t demod, bool active)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012412{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012413 u16 data = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012414 struct i2c_device_addr *dev_addr = NULL;
12415 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012416
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012417 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
12418 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012419
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012420 /* Configure NSU_AOX */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012421 RR16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012422 if (!active) {
12423 data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON)
12424 & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON)
12425 & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON)
12426 & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON)
12427 & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON)
12428 & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON)
12429 & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON)
12430 & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON)
12431 );
12432 } else { /* active */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012433
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012434 data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON
12435 | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON
12436 | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON
12437 | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON
12438 | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON
12439 | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON
12440 | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON
12441 | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
12442 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012443 WR16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012444
12445 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012446rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012447 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012448}
12449
12450/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012451* \fn int ctrl_set_oob()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012452* \brief Set OOB channel to be used.
12453* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012454* \param oob_param OOB parameters for channel setting.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012455* \frequency should be in KHz
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012456* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012457*
12458* Accepts only. Returns error otherwise.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012459* Demapper value is written after scu_command START
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012460* because START command causes COMM_EXEC transition
12461* from 0 to 1 which causes all registers to be
12462* overwritten with initial value
12463*
12464*/
12465
12466/* Nyquist filter impulse response */
Mauro Carvalho Chehab7ef66752014-01-16 11:08:15 -030012467#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 */
12468#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 */
12469#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) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012470
12471/* Coefficients for the nyquist fitler (total: 27 taps) */
12472#define NYQFILTERLEN 27
12473
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012474static int ctrl_set_oob(pdrx_demod_instance_t demod, p_drxoob_t oob_param)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012475{
12476#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012477 drxoob_downstream_standard_t standard = DRX_OOB_MODE_A;
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030012478 s32 freq = 0; /* KHz */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012479 struct i2c_device_addr *dev_addr = NULL;
12480 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012481 u16 i = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012482 bool mirror_freq_spectOOB = false;
12483 u16 trk_filter_value = 0;
12484 drxjscu_cmd_t scu_cmd;
12485 u16 set_param_parameters[3];
12486 u16 cmd_result[2] = { 0, 0 };
12487 s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012488 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
12489 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
12490 IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
12491 IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
12492 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012493 u8 mode_val[4] = { 2, 2, 0, 1 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012494 u8 pfi_coeffs[4][6] = {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012495 {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) */
12496 {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) */
12497 {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) */
12498 {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) */
12499 };
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012500 u16 mode_index;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012501
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012502 dev_addr = demod->my_i2c_dev_addr;
12503 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
12504 mirror_freq_spectOOB = ext_attr->mirror_freq_spectOOB;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012505
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012506 /* Check parameters */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012507 if (oob_param == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012508 /* power off oob module */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012509 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012510 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012511 scu_cmd.parameter_len = 0;
12512 scu_cmd.result_len = 1;
12513 scu_cmd.result = cmd_result;
12514 CHK_ERROR(scu_command(dev_addr, &scu_cmd));
12515 CHK_ERROR(set_orx_nsu_aox(demod, false));
12516 WR16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012517
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012518 ext_attr->oob_power_on = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012519 return (DRX_STS_OK);
12520 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012521
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012522 standard = oob_param->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012523
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012524 freq = oob_param->frequency;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012525 if ((freq < 70000) || (freq > 130000))
12526 return (DRX_STS_ERROR);
12527 freq = (freq - 50000) / 50;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012528
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012529 {
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012530 u16 index = 0;
12531 u16 remainder = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012532 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012533
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012534 index = (u16) ((freq - 400) / 200);
12535 remainder = (u16) ((freq - 400) % 200);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012536 trk_filter_value =
12537 trk_filtercfg[index] - (trk_filtercfg[index] -
12538 trk_filtercfg[index +
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012539 1]) / 10 * remainder /
12540 20;
12541 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012542
12543 /*********/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012544 /* Stop */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012545 /*********/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012546 WR16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP);
12547 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012548 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012549 scu_cmd.parameter_len = 0;
12550 scu_cmd.result_len = 1;
12551 scu_cmd.result = cmd_result;
12552 CHK_ERROR(scu_command(dev_addr, &scu_cmd));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012553 /*********/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012554 /* Reset */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012555 /*********/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012556 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012557 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012558 scu_cmd.parameter_len = 0;
12559 scu_cmd.result_len = 1;
12560 scu_cmd.result = cmd_result;
12561 CHK_ERROR(scu_command(dev_addr, &scu_cmd));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012562 /***********/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012563 /* SET_ENV */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012564 /***********/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012565 /* set frequency, spectrum inversion and data rate */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012566 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012567 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012568 scu_cmd.parameter_len = 3;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012569 /* 1-data rate;2-frequency */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012570 switch (oob_param->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012571 case DRX_OOB_MODE_A:
12572 if (
12573 /* signal is transmitted inverted */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012574 ((oob_param->spectrum_inverted == true) &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012575 /* and tuner is not mirroring the signal */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012576 (mirror_freq_spectOOB == false)) |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012577 /* or */
12578 /* signal is transmitted noninverted */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012579 ((oob_param->spectrum_inverted == false) &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012580 /* and tuner is mirroring the signal */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012581 (mirror_freq_spectOOB == true))
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012582 )
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012583 set_param_parameters[0] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012584 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
12585 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012586 set_param_parameters[0] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012587 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
12588 break;
12589 case DRX_OOB_MODE_B_GRADE_A:
12590 if (
12591 /* signal is transmitted inverted */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012592 ((oob_param->spectrum_inverted == true) &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012593 /* and tuner is not mirroring the signal */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012594 (mirror_freq_spectOOB == false)) |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012595 /* or */
12596 /* signal is transmitted noninverted */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012597 ((oob_param->spectrum_inverted == false) &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012598 /* and tuner is mirroring the signal */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012599 (mirror_freq_spectOOB == true))
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012600 )
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012601 set_param_parameters[0] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012602 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
12603 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012604 set_param_parameters[0] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012605 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
12606 break;
12607 case DRX_OOB_MODE_B_GRADE_B:
12608 default:
12609 if (
12610 /* signal is transmitted inverted */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012611 ((oob_param->spectrum_inverted == true) &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012612 /* and tuner is not mirroring the signal */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012613 (mirror_freq_spectOOB == false)) |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012614 /* or */
12615 /* signal is transmitted noninverted */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012616 ((oob_param->spectrum_inverted == false) &
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012617 /* and tuner is mirroring the signal */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012618 (mirror_freq_spectOOB == true))
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012619 )
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012620 set_param_parameters[0] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012621 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
12622 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012623 set_param_parameters[0] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012624 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
12625 break;
12626 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012627 set_param_parameters[1] = (u16) (freq & 0xFFFF);
12628 set_param_parameters[2] = trk_filter_value;
12629 scu_cmd.parameter = set_param_parameters;
12630 scu_cmd.result_len = 1;
12631 scu_cmd.result = cmd_result;
12632 mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
12633 CHK_ERROR(scu_command(dev_addr, &scu_cmd));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012634
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012635 WR16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA); /* Write magic word to enable pdr reg write */
12636 WR16(dev_addr, SIO_PDR_OOB_CRX_CFG__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012637 OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B
12638 | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012639 WR16(dev_addr, SIO_PDR_OOB_DRX_CFG__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012640 OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B
12641 | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012642 WR16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000); /* Write magic word to disable pdr reg write */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012643
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012644 WR16(dev_addr, ORX_TOP_COMM_KEY__A, 0);
12645 WR16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000);
12646 WR16(dev_addr, ORX_FWP_AAG_THR_W__A, 40);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012647
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012648 /* ddc */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012649 WR16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012650
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012651 /* nsu */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012652 WR16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012653
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012654 /* initialization for target mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012655 WR16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012656 SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012657 WR16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012658 SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012659
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012660 /* Reset bits for timing and freq. recovery */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012661 WR16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001);
12662 WR16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002);
12663 WR16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004);
12664 WR16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012665
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012666 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012667 WR16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3);
12668 WR16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16) (-2048));
12669 WR16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8);
12670 WR16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16) (-8));
12671 WR16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012672
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012673 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012674 WR16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10);
12675 WR16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16) (-2048));
12676 WR16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8);
12677 WR16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16) (-8));
12678 WR16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012679
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012680 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012681 WR16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17);
12682 WR16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16) (-2048));
12683 WR16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8);
12684 WR16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16) (-8));
12685 WR16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012686
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012687 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012688 WR16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000);
12689 WR16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16) (-2048));
12690 WR16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8);
12691 WR16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16) (-8));
12692 WR16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012693
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012694 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012695 WR16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400);
12696 WR16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16) (-2048));
12697 WR16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8);
12698 WR16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16) (-8));
12699 WR16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012700
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012701 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012702 WR16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20);
12703 WR16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16) (-2048));
12704 WR16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4);
12705 WR16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16) (-4));
12706 WR16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012707
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012708 /* PRE-Filter coefficients (PFI) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012709 WRB(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]),
12710 ((u8 *) pfi_coeffs[mode_index]));
12711 WR16(dev_addr, ORX_TOP_MDE_W__A, mode_index);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012712
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012713 /* NYQUIST-Filter coefficients (NYQ) */
12714 for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012715 WR16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i);
12716 WR16(dev_addr, ORX_FWP_NYQ_COF_RW__A,
12717 nyquist_coeffs[mode_index][i]);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012718 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012719 WR16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31);
12720 WR16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012721 /*********/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012722 /* Start */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012723 /*********/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012724 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012725 | SCU_RAM_COMMAND_CMD_DEMOD_START;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012726 scu_cmd.parameter_len = 0;
12727 scu_cmd.result_len = 1;
12728 scu_cmd.result = cmd_result;
12729 CHK_ERROR(scu_command(dev_addr, &scu_cmd));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012730
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012731 CHK_ERROR(set_orx_nsu_aox(demod, true));
12732 WR16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012733
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012734 ext_attr->oob_power_on = true;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012735
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012736 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012737rw_error:
12738#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012739 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012740}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012741
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012742/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012743* \fn int ctrl_get_oob()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012744* \brief Set modulation standard to be used.
12745* \param demod instance of demodulator
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012746* \param oob_status OOB status parameters.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012747* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012748*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012749static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012750ctrl_get_oob(pdrx_demod_instance_t demod, pdrxoob_status_t oob_status)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012751{
12752#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012753 struct i2c_device_addr *dev_addr = NULL;
12754 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030012755 u16 data = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012756
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012757 dev_addr = demod->my_i2c_dev_addr;
12758 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012759
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012760 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012761 if (oob_status == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012762 return (DRX_STS_INVALID_ARG);
12763 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012764
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012765 if (ext_attr->oob_power_on == false)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012766 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012767
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012768 RR16(dev_addr, ORX_DDC_OFO_SET_W__A, &data);
12769 RR16(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &data);
12770 RR16(dev_addr, ORX_FWP_AAG_THR_W__A, &data);
12771 SARR16(dev_addr, SCU_RAM_ORX_DGN_KI__A, &data);
12772 RR16(dev_addr, ORX_FWP_SRC_DGN_W__A, &data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012773
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012774 CHK_ERROR(get_oob_lock_status(demod, dev_addr, &oob_status->lock));
12775 CHK_ERROR(get_oob_frequency(demod, &oob_status->frequency));
12776 CHK_ERROR(get_oobmer(dev_addr, &oob_status->mer));
12777 CHK_ERROR(get_oob_symbol_rate_offset
12778 (dev_addr, &oob_status->symbol_rate_offset));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012779
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012780 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012781rw_error:
12782#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012783 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012784}
12785
12786/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012787* \fn int ctrl_set_cfg_oob_pre_saw()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012788* \brief Configure PreSAW treshold value
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012789* \param cfg_data Pointer to configuration parameter
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012790* \return Error code
12791*/
12792#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012793static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012794ctrl_set_cfg_oob_pre_saw(pdrx_demod_instance_t demod, u16 *cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012795{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012796 struct i2c_device_addr *dev_addr = NULL;
12797 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012798
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012799 if (cfg_data == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012800 return (DRX_STS_INVALID_ARG);
12801 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012802 dev_addr = demod->my_i2c_dev_addr;
12803 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012804
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012805 WR16(dev_addr, ORX_NSU_AOX_STHR_W__A, *cfg_data);
12806 ext_attr->oob_pre_saw = *cfg_data;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012807 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012808rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012809 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012810}
12811#endif
12812
12813/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012814* \fn int ctrl_get_cfg_oob_pre_saw()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012815* \brief Configure PreSAW treshold value
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012816* \param cfg_data Pointer to configuration parameter
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012817* \return Error code
12818*/
12819#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012820static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012821ctrl_get_cfg_oob_pre_saw(pdrx_demod_instance_t demod, u16 *cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012822{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012823 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012824
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012825 if (cfg_data == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012826 return (DRX_STS_INVALID_ARG);
12827 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012828 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012829
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012830 *cfg_data = ext_attr->oob_pre_saw;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012831
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012832 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012833}
12834#endif
12835
12836/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012837* \fn int ctrl_set_cfg_oob_lo_power()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012838* \brief Configure LO Power value
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012839* \param cfg_data Pointer to p_drxj_cfg_oob_lo_power_t
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012840* \return Error code
12841*/
12842#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012843static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012844ctrl_set_cfg_oob_lo_power(pdrx_demod_instance_t demod, p_drxj_cfg_oob_lo_power_t cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012845{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012846 struct i2c_device_addr *dev_addr = NULL;
12847 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012848
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012849 if (cfg_data == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012850 return (DRX_STS_INVALID_ARG);
12851 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012852 dev_addr = demod->my_i2c_dev_addr;
12853 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012854
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012855 WR16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, *cfg_data);
12856 ext_attr->oob_lo_pow = *cfg_data;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012857 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012858rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012859 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012860}
12861#endif
12862
12863/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012864* \fn int ctrl_get_cfg_oob_lo_power()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012865* \brief Configure LO Power value
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012866* \param cfg_data Pointer to p_drxj_cfg_oob_lo_power_t
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012867* \return Error code
12868*/
12869#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012870static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012871ctrl_get_cfg_oob_lo_power(pdrx_demod_instance_t demod, p_drxj_cfg_oob_lo_power_t cfg_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012872{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012873 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012874
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012875 if (cfg_data == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012876 return (DRX_STS_INVALID_ARG);
12877 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012878 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012879
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012880 *cfg_data = ext_attr->oob_lo_pow;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012881
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012882 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012883}
12884#endif
12885/*============================================================================*/
12886/*== END OOB DATAPATH FUNCTIONS ==*/
12887/*============================================================================*/
12888
12889/*=============================================================================
12890 ===== MC command related functions ==========================================
12891 ===========================================================================*/
12892
12893/*=============================================================================
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012894 ===== ctrl_set_channel() ==========================================================
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012895 ===========================================================================*/
12896/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012897* \fn int ctrl_set_channel()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012898* \brief Select a new transmission channel.
12899* \param demod instance of demod.
12900* \param channel Pointer to channel data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012901* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012902*
12903* In case the tuner module is not used and in case of NTSC/FM the pogrammer
12904* must tune the tuner to the centre frequency of the NTSC/FM channel.
12905*
12906*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012907static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012908ctrl_set_channel(pdrx_demod_instance_t demod, pdrx_channel_t channel)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012909{
12910
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012911 s32 tuner_set_freq = 0;
12912 s32 tuner_get_freq = 0;
12913 s32 tuner_freq_offset = 0;
12914 s32 intermediate_freq = 0;
12915 pdrxj_data_t ext_attr = NULL;
12916 struct i2c_device_addr *dev_addr = NULL;
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030012917 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012918 u32 tuner_mode = 0;
12919 pdrx_common_attr_t common_attr = NULL;
12920 bool bridge_closed = false;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012921#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012922 u32 min_symbol_rate = 0;
12923 u32 max_symbol_rate = 0;
12924 int bandwidth_temp = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012925 int bandwidth = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012926#endif
12927 /*== check arguments ======================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012928 if ((demod == NULL) || (channel == NULL)) {
12929 return DRX_STS_INVALID_ARG;
12930 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012931
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030012932 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
12933 dev_addr = demod->my_i2c_dev_addr;
12934 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
12935 standard = ext_attr->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012936
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012937 /* check valid standards */
12938 switch (standard) {
12939 case DRX_STANDARD_8VSB:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012940#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012941 case DRX_STANDARD_ITU_A:
12942 case DRX_STANDARD_ITU_B:
12943 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012944#endif /* DRXJ_VSB_ONLY */
12945#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012946 case DRX_STANDARD_NTSC:
12947 case DRX_STANDARD_FM:
12948 case DRX_STANDARD_PAL_SECAM_BG:
12949 case DRX_STANDARD_PAL_SECAM_DK:
12950 case DRX_STANDARD_PAL_SECAM_I:
12951 case DRX_STANDARD_PAL_SECAM_L:
12952 case DRX_STANDARD_PAL_SECAM_LP:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012953#endif /* DRXJ_DIGITAL_ONLY */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012954 break;
12955 case DRX_STANDARD_UNKNOWN:
12956 default:
12957 return (DRX_STS_INVALID_ARG);
12958 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012959
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012960 /* check bandwidth QAM annex B, NTSC and 8VSB */
12961 if ((standard == DRX_STANDARD_ITU_B) ||
12962 (standard == DRX_STANDARD_8VSB) ||
12963 (standard == DRX_STANDARD_NTSC)) {
12964 switch (channel->bandwidth) {
12965 case DRX_BANDWIDTH_6MHZ:
12966 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
12967 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
12968 break;
12969 case DRX_BANDWIDTH_8MHZ: /* fall through */
12970 case DRX_BANDWIDTH_7MHZ: /* fall through */
12971 default:
12972 return (DRX_STS_INVALID_ARG);
12973 }
12974 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030012975#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030012976 if (standard == DRX_STANDARD_PAL_SECAM_BG) {
12977 switch (channel->bandwidth) {
12978 case DRX_BANDWIDTH_7MHZ: /* fall through */
12979 case DRX_BANDWIDTH_8MHZ:
12980 /* ok */
12981 break;
12982 case DRX_BANDWIDTH_6MHZ: /* fall through */
12983 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
12984 default:
12985 return (DRX_STS_INVALID_ARG);
12986 }
12987 }
12988 /* check bandwidth PAL/SECAM */
12989 if ((standard == DRX_STANDARD_PAL_SECAM_BG) ||
12990 (standard == DRX_STANDARD_PAL_SECAM_DK) ||
12991 (standard == DRX_STANDARD_PAL_SECAM_I) ||
12992 (standard == DRX_STANDARD_PAL_SECAM_L) ||
12993 (standard == DRX_STANDARD_PAL_SECAM_LP)) {
12994 switch (channel->bandwidth) {
12995 case DRX_BANDWIDTH_8MHZ:
12996 case DRX_BANDWIDTH_UNKNOWN: /* fall through */
12997 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
12998 break;
12999 case DRX_BANDWIDTH_6MHZ: /* fall through */
13000 case DRX_BANDWIDTH_7MHZ: /* fall through */
13001 default:
13002 return (DRX_STS_INVALID_ARG);
13003 }
13004 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013005#endif
13006
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013007 /* For QAM annex A and annex C:
13008 -check symbolrate and constellation
13009 -derive bandwidth from symbolrate (input bandwidth is ignored)
13010 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013011#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013012 if ((standard == DRX_STANDARD_ITU_A) ||
13013 (standard == DRX_STANDARD_ITU_C)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013014 drxuio_cfg_t uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
13015 int bw_rolloff_factor = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013016
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013017 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
13018 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
13019 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013020 /* config SMA_TX pin to SAW switch mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013021 CHK_ERROR(ctrl_set_uio_cfg(demod, &uio_cfg));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013022
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013023 if (channel->symbolrate < min_symbol_rate ||
13024 channel->symbolrate > max_symbol_rate) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013025 return (DRX_STS_INVALID_ARG);
13026 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013027
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013028 switch (channel->constellation) {
13029 case DRX_CONSTELLATION_QAM16: /* fall through */
13030 case DRX_CONSTELLATION_QAM32: /* fall through */
13031 case DRX_CONSTELLATION_QAM64: /* fall through */
13032 case DRX_CONSTELLATION_QAM128: /* fall through */
13033 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013034 bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
13035 bandwidth = bandwidth_temp / 100;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013036
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013037 if ((bandwidth_temp % 100) >= 50) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013038 bandwidth++;
13039 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013040
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013041 if (bandwidth <= 6100000) {
13042 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
13043 } else if ((bandwidth > 6100000)
13044 && (bandwidth <= 7100000)) {
13045 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
13046 } else if (bandwidth > 7100000) {
13047 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
13048 }
13049 break;
13050 default:
13051 return (DRX_STS_INVALID_ARG);
13052 }
13053 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013054
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013055 /* For QAM annex B:
13056 -check constellation
13057 */
13058 if (standard == DRX_STANDARD_ITU_B) {
13059 switch (channel->constellation) {
13060 case DRX_CONSTELLATION_AUTO:
13061 case DRX_CONSTELLATION_QAM256:
13062 case DRX_CONSTELLATION_QAM64:
13063 break;
13064 default:
13065 return (DRX_STS_INVALID_ARG);
13066 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013067
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013068 switch (channel->interleavemode) {
13069 case DRX_INTERLEAVEMODE_I128_J1:
13070 case DRX_INTERLEAVEMODE_I128_J1_V2:
13071 case DRX_INTERLEAVEMODE_I128_J2:
13072 case DRX_INTERLEAVEMODE_I64_J2:
13073 case DRX_INTERLEAVEMODE_I128_J3:
13074 case DRX_INTERLEAVEMODE_I32_J4:
13075 case DRX_INTERLEAVEMODE_I128_J4:
13076 case DRX_INTERLEAVEMODE_I16_J8:
13077 case DRX_INTERLEAVEMODE_I128_J5:
13078 case DRX_INTERLEAVEMODE_I8_J16:
13079 case DRX_INTERLEAVEMODE_I128_J6:
13080 case DRX_INTERLEAVEMODE_I128_J7:
13081 case DRX_INTERLEAVEMODE_I128_J8:
13082 case DRX_INTERLEAVEMODE_I12_J17:
13083 case DRX_INTERLEAVEMODE_I5_J4:
13084 case DRX_INTERLEAVEMODE_B52_M240:
13085 case DRX_INTERLEAVEMODE_B52_M720:
13086 case DRX_INTERLEAVEMODE_UNKNOWN:
13087 case DRX_INTERLEAVEMODE_AUTO:
13088 break;
13089 default:
13090 return (DRX_STS_INVALID_ARG);
13091 }
13092 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013093
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013094 if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013095 /* SAW SW, user UIO is used for switchable SAW */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013096 drxuio_data_t uio1 = { DRX_UIO1, false };
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013097
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013098 switch (channel->bandwidth) {
13099 case DRX_BANDWIDTH_8MHZ:
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030013100 uio1.value = true;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013101 break;
13102 case DRX_BANDWIDTH_7MHZ:
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030013103 uio1.value = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013104 break;
13105 case DRX_BANDWIDTH_6MHZ:
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030013106 uio1.value = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013107 break;
13108 case DRX_BANDWIDTH_UNKNOWN:
13109 default:
13110 return (DRX_STS_INVALID_ARG);
13111 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013112
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013113 CHK_ERROR(ctrl_uio_write(demod, &uio1));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013114 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013115#endif /* DRXJ_VSB_ONLY */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013116 WR16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013117 /*== Tune, fast mode ======================================================*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013118 if (demod->my_tuner != NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013119 /* Determine tuner mode and freq to tune to ... */
13120 switch (standard) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013121#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013122 case DRX_STANDARD_NTSC: /* fallthrough */
13123 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13124 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13125 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13126 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13127 case DRX_STANDARD_PAL_SECAM_LP:
13128 /* expecting center frequency, not picture carrier so no
13129 conversion .... */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013130 tuner_mode |= TUNER_MODE_ANALOG;
13131 tuner_set_freq = channel->frequency;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013132 break;
13133 case DRX_STANDARD_FM:
13134 /* center frequency (equals sound carrier) as input,
13135 tune to edge of SAW */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013136 tuner_mode |= TUNER_MODE_ANALOG;
13137 tuner_set_freq =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013138 channel->frequency + DRXJ_FM_CARRIER_FREQ_OFFSET;
13139 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013140#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013141 case DRX_STANDARD_8VSB: /* fallthrough */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013142#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013143 case DRX_STANDARD_ITU_A: /* fallthrough */
13144 case DRX_STANDARD_ITU_B: /* fallthrough */
13145 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013146#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013147 tuner_mode |= TUNER_MODE_DIGITAL;
13148 tuner_set_freq = channel->frequency;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013149 break;
13150 case DRX_STANDARD_UNKNOWN:
13151 default:
13152 return (DRX_STS_ERROR);
13153 } /* switch(standard) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013154
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013155 tuner_mode |= TUNER_MODE_SWITCH;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013156 switch (channel->bandwidth) {
13157 case DRX_BANDWIDTH_8MHZ:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013158 tuner_mode |= TUNER_MODE_8MHZ;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013159 break;
13160 case DRX_BANDWIDTH_7MHZ:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013161 tuner_mode |= TUNER_MODE_7MHZ;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013162 break;
13163 case DRX_BANDWIDTH_6MHZ:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013164 tuner_mode |= TUNER_MODE_6MHZ;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013165 break;
13166 default:
13167 /* TODO: for FM which bandwidth to use ?
13168 also check offset from centre frequency ?
13169 For now using 6MHz.
13170 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013171 tuner_mode |= TUNER_MODE_6MHZ;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013172 break;
13173 /* return (DRX_STS_INVALID_ARG); */
13174 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013175
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013176 /* store bandwidth for GetChannel() */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013177 ext_attr->curr_bandwidth = channel->bandwidth;
13178 ext_attr->curr_symbol_rate = channel->symbolrate;
13179 ext_attr->frequency = tuner_set_freq;
13180 if (common_attr->tuner_port_nr == 1) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013181 /* close tuner bridge */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013182 bridge_closed = true;
13183 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_closed));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013184 /* set tuner frequency */
13185 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013186
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013187 CHK_ERROR(drxbsp_tuner_set_frequency(demod->my_tuner,
13188 tuner_mode, tuner_set_freq));
13189 if (common_attr->tuner_port_nr == 1) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013190 /* open tuner bridge */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013191 bridge_closed = false;
13192 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_closed));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013193 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013194
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013195 /* Get actual frequency set by tuner and compute offset */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013196 CHK_ERROR(drxbsp_tuner_get_frequency(demod->my_tuner,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013197 0,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013198 &tuner_get_freq,
13199 &intermediate_freq));
13200 tuner_freq_offset = tuner_get_freq - tuner_set_freq;
13201 common_attr->intermediate_freq = intermediate_freq;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013202 } else {
13203 /* no tuner instance defined, use fixed intermediate frequency */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013204 tuner_freq_offset = 0;
13205 intermediate_freq = demod->my_common_attr->intermediate_freq;
13206 } /* if ( demod->my_tuner != NULL ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013207
13208 /*== Setup demod for specific standard ====================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013209 switch (standard) {
13210 case DRX_STANDARD_8VSB:
13211 if (channel->mirror == DRX_MIRROR_AUTO) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013212 ext_attr->mirror = DRX_MIRROR_NO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013213 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013214 ext_attr->mirror = channel->mirror;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013215 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013216 CHK_ERROR(set_vsb(demod));
13217 CHK_ERROR(set_frequency(demod, channel, tuner_freq_offset));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013218 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013219#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013220 case DRX_STANDARD_NTSC: /* fallthrough */
13221 case DRX_STANDARD_FM: /* fallthrough */
13222 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13223 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13224 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13225 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13226 case DRX_STANDARD_PAL_SECAM_LP:
13227 if (channel->mirror == DRX_MIRROR_AUTO) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013228 ext_attr->mirror = DRX_MIRROR_NO;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013229 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013230 ext_attr->mirror = channel->mirror;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013231 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013232 CHK_ERROR(set_atv_channel(demod,
13233 tuner_freq_offset, channel, standard));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013234 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013235#endif
13236#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013237 case DRX_STANDARD_ITU_A: /* fallthrough */
13238 case DRX_STANDARD_ITU_B: /* fallthrough */
13239 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013240 CHK_ERROR(set_qamChannel(demod, channel, tuner_freq_offset));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013241 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013242#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013243 case DRX_STANDARD_UNKNOWN:
13244 default:
13245 return (DRX_STS_ERROR);
13246 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013247
13248 /*== Re-tune, slow mode ===================================================*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013249 if (demod->my_tuner != NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013250 /* tune to slow mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013251 tuner_mode &= ~TUNER_MODE_SWITCH;
13252 tuner_mode |= TUNER_MODE_LOCK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013253
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013254 if (common_attr->tuner_port_nr == 1) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013255 /* close tuner bridge */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013256 bridge_closed = true;
13257 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_closed));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013258 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013259
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013260 /* set tuner frequency */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013261 CHK_ERROR(drxbsp_tuner_set_frequency(demod->my_tuner,
13262 tuner_mode, tuner_set_freq));
13263 if (common_attr->tuner_port_nr == 1) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013264 /* open tuner bridge */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013265 bridge_closed = false;
13266 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_closed));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013267 }
13268 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013269
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013270 /* if ( demod->my_tuner !=NULL ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013271 /* flag the packet error counter reset */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013272 ext_attr->reset_pkt_err_acc = true;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013273
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013274 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013275rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013276 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013277}
13278
13279/*=============================================================================
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013280 ===== ctrl_get_channel() ==========================================================
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013281 ===========================================================================*/
13282/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013283* \fn int ctrl_get_channel()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013284* \brief Retreive parameters of current transmission channel.
13285* \param demod Pointer to demod instance.
13286* \param channel Pointer to channel data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013287* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013288*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013289static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013290ctrl_get_channel(pdrx_demod_instance_t demod, pdrx_channel_t channel)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013291{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013292 struct i2c_device_addr *dev_addr = NULL;
13293 pdrxj_data_t ext_attr = NULL;
13294 drx_lock_status_t lock_status = DRX_NOT_LOCKED;
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013295 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013296 pdrx_common_attr_t common_attr = NULL;
13297 s32 intermediate_freq = 0;
13298 s32 ctl_freq_offset = 0;
13299 u32 iqm_rc_rateLo = 0;
13300 u32 adc_frequency = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013301#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013302 int bandwidth_temp = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013303 int bandwidth = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013304#endif
13305
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013306 /* check arguments */
13307 if ((demod == NULL) || (channel == NULL)) {
13308 return DRX_STS_INVALID_ARG;
13309 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013310
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013311 dev_addr = demod->my_i2c_dev_addr;
13312 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
13313 standard = ext_attr->standard;
13314 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013315
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013316 /* initialize channel fields */
13317 channel->mirror = DRX_MIRROR_UNKNOWN;
13318 channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
13319 channel->priority = DRX_PRIORITY_UNKNOWN;
13320 channel->coderate = DRX_CODERATE_UNKNOWN;
13321 channel->guard = DRX_GUARD_UNKNOWN;
13322 channel->fftmode = DRX_FFTMODE_UNKNOWN;
13323 channel->classification = DRX_CLASSIFICATION_UNKNOWN;
13324 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
13325 channel->constellation = DRX_CONSTELLATION_UNKNOWN;
13326 channel->symbolrate = 0;
13327 channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
13328 channel->carrier = DRX_CARRIER_UNKNOWN;
13329 channel->framemode = DRX_FRAMEMODE_UNKNOWN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013330/* channel->interleaver = DRX_INTERLEAVER_UNKNOWN;*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013331 channel->ldpc = DRX_LDPC_UNKNOWN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013332
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013333 if (demod->my_tuner != NULL) {
13334 s32 tuner_freq_offset = 0;
13335 bool tuner_mirror = common_attr->mirror_freq_spect ? false : true;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013336
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013337 /* Get frequency from tuner */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013338 CHK_ERROR(drxbsp_tuner_get_frequency(demod->my_tuner,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013339 0,
13340 &(channel->frequency),
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013341 &intermediate_freq));
13342 tuner_freq_offset = channel->frequency - ext_attr->frequency;
13343 if (tuner_mirror == true) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013344 /* positive image */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013345 channel->frequency += tuner_freq_offset;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013346 } else {
13347 /* negative image */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013348 channel->frequency -= tuner_freq_offset;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013349 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013350
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013351 /* Handle sound carrier offset in RF domain */
13352 if (standard == DRX_STANDARD_FM) {
13353 channel->frequency -= DRXJ_FM_CARRIER_FREQ_OFFSET;
13354 }
13355 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013356 intermediate_freq = common_attr->intermediate_freq;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013357 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013358
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013359 /* check lock status */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013360 CHK_ERROR(ctrl_lock_status(demod, &lock_status));
13361 if ((lock_status == DRX_LOCKED) || (lock_status == DRXJ_DEMOD_LOCK)) {
13362 ARR32(dev_addr, IQM_RC_RATE_LO__A, &iqm_rc_rateLo);
13363 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013364
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013365 channel->symbolrate =
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013366 frac28(adc_frequency, (iqm_rc_rateLo + (1 << 23))) >> 7;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013367
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013368 switch (standard) {
13369 case DRX_STANDARD_8VSB:
13370 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
13371 /* get the channel frequency */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013372 CHK_ERROR(get_ctl_freq_offset(demod, &ctl_freq_offset));
13373 channel->frequency -= ctl_freq_offset;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013374 /* get the channel constellation */
13375 channel->constellation = DRX_CONSTELLATION_AUTO;
13376 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013377#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013378 case DRX_STANDARD_ITU_A:
13379 case DRX_STANDARD_ITU_B:
13380 case DRX_STANDARD_ITU_C:
13381 {
13382 /* get the channel frequency */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013383 CHK_ERROR(get_ctl_freq_offset
13384 (demod, &ctl_freq_offset));
13385 channel->frequency -= ctl_freq_offset;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013386
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013387 if (standard == DRX_STANDARD_ITU_B) {
13388 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
13389 } else {
13390 /* annex A & C */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013391
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013392 u32 roll_off = 113; /* default annex C */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013393
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013394 if (standard == DRX_STANDARD_ITU_A) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013395 roll_off = 115;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013396 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013397
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013398 bandwidth_temp =
13399 channel->symbolrate * roll_off;
13400 bandwidth = bandwidth_temp / 100;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013401
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013402 if ((bandwidth_temp % 100) >= 50) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013403 bandwidth++;
13404 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013405
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013406 if (bandwidth <= 6000000) {
13407 channel->bandwidth =
13408 DRX_BANDWIDTH_6MHZ;
13409 } else if ((bandwidth > 6000000)
13410 && (bandwidth <= 7000000)) {
13411 channel->bandwidth =
13412 DRX_BANDWIDTH_7MHZ;
13413 } else if (bandwidth > 7000000) {
13414 channel->bandwidth =
13415 DRX_BANDWIDTH_8MHZ;
13416 }
13417 } /* if (standard == DRX_STANDARD_ITU_B) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013418
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013419 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013420 drxjscu_cmd_t cmd_scu =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013421 { /* command */ 0,
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013422 /* parameter_len */ 0,
13423 /* result_len */ 0,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013424 /* parameter */ NULL,
13425 /* result */ NULL
13426 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013427 u16 cmd_result[3] = { 0, 0, 0 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013428
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013429 cmd_scu.command =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013430 SCU_RAM_COMMAND_STANDARD_QAM |
13431 SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013432 cmd_scu.parameter_len = 0;
13433 cmd_scu.result_len = 3;
13434 cmd_scu.parameter = NULL;
13435 cmd_scu.result = cmd_result;
13436 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013437
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013438 channel->interleavemode =
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013439 (enum drx_interleave_mode) (cmd_scu.
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013440 result[2]);
13441 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013442
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013443 switch (ext_attr->constellation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013444 case DRX_CONSTELLATION_QAM256:
13445 channel->constellation =
13446 DRX_CONSTELLATION_QAM256;
13447 break;
13448 case DRX_CONSTELLATION_QAM128:
13449 channel->constellation =
13450 DRX_CONSTELLATION_QAM128;
13451 break;
13452 case DRX_CONSTELLATION_QAM64:
13453 channel->constellation =
13454 DRX_CONSTELLATION_QAM64;
13455 break;
13456 case DRX_CONSTELLATION_QAM32:
13457 channel->constellation =
13458 DRX_CONSTELLATION_QAM32;
13459 break;
13460 case DRX_CONSTELLATION_QAM16:
13461 channel->constellation =
13462 DRX_CONSTELLATION_QAM16;
13463 break;
13464 default:
13465 channel->constellation =
13466 DRX_CONSTELLATION_UNKNOWN;
13467 return (DRX_STS_ERROR);
13468 }
13469 }
13470 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013471#endif
13472#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013473 case DRX_STANDARD_NTSC: /* fall trough */
13474 case DRX_STANDARD_PAL_SECAM_BG:
13475 case DRX_STANDARD_PAL_SECAM_DK:
13476 case DRX_STANDARD_PAL_SECAM_I:
13477 case DRX_STANDARD_PAL_SECAM_L:
13478 case DRX_STANDARD_PAL_SECAM_LP:
13479 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013480 CHK_ERROR(get_atv_channel(demod, channel, standard));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013481 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013482#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013483 case DRX_STANDARD_UNKNOWN: /* fall trough */
13484 default:
13485 return (DRX_STS_ERROR);
13486 } /* switch ( standard ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013487
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013488 if (lock_status == DRX_LOCKED) {
13489 channel->mirror = ext_attr->mirror;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013490 }
13491 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013492 /* if ( lock_status == DRX_LOCKED ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013493 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013494rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013495 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013496}
13497
13498/*=============================================================================
13499 ===== SigQuality() ==========================================================
13500 ===========================================================================*/
13501
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030013502static u16
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013503mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013504{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030013505 u16 indicator = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013506
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013507 if (mer < min_mer) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013508 indicator = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013509 } else if (mer < threshold_mer) {
13510 if ((threshold_mer - min_mer) != 0) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013511 indicator =
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013512 25 * (mer - min_mer) / (threshold_mer - min_mer);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013513 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013514 } else if (mer < max_mer) {
13515 if ((max_mer - threshold_mer) != 0) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013516 indicator =
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013517 25 + 75 * (mer - threshold_mer) / (max_mer -
13518 threshold_mer);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013519 } else {
13520 indicator = 25;
13521 }
13522 } else {
13523 indicator = 100;
13524 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013525
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013526 return indicator;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013527}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013528
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013529/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013530* \fn int ctrl_sig_quality()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013531* \brief Retreive signal quality form device.
13532* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013533* \param sig_quality Pointer to signal quality data.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013534* \return int.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013535* \retval DRX_STS_OK sig_quality contains valid data.
13536* \retval DRX_STS_INVALID_ARG sig_quality is NULL.
13537* \retval DRX_STS_ERROR Erroneous data, sig_quality contains invalid data.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013538
13539*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013540static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013541ctrl_sig_quality(pdrx_demod_instance_t demod, pdrx_sig_quality_t sig_quality)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013542{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013543 struct i2c_device_addr *dev_addr = NULL;
13544 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013545 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013546 drx_lock_status_t lock_status = DRX_NOT_LOCKED;
13547 u16 min_mer = 0;
13548 u16 max_mer = 0;
13549 u16 threshold_mer = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013550
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013551 /* Check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013552 if ((sig_quality == NULL) || (demod == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013553 return (DRX_STS_INVALID_ARG);
13554 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013555
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013556 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
13557 standard = ext_attr->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013558
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013559 /* get basic information */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013560 dev_addr = demod->my_i2c_dev_addr;
13561 CHK_ERROR(ctrl_lock_status(demod, &lock_status));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013562 switch (standard) {
13563 case DRX_STANDARD_8VSB:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013564#ifdef DRXJ_SIGNAL_ACCUM_ERR
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013565 CHK_ERROR(get_acc_pkt_err(demod, &sig_quality->packet_error));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013566#else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013567 CHK_ERROR(get_vsb_post_rs_pck_err
13568 (dev_addr, &sig_quality->packet_error));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013569#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013570 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
13571 sig_quality->post_viterbi_ber = 500000;
13572 sig_quality->MER = 20;
13573 sig_quality->pre_viterbi_ber = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013574 } else {
13575 /* PostViterbi is compute in steps of 10^(-6) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013576 CHK_ERROR(get_vs_bpre_viterbi_ber
13577 (dev_addr, &sig_quality->pre_viterbi_ber));
13578 CHK_ERROR(get_vs_bpost_viterbi_ber
13579 (dev_addr, &sig_quality->post_viterbi_ber));
13580 CHK_ERROR(get_vsbmer(dev_addr, &sig_quality->MER));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013581 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013582 min_mer = 20;
13583 max_mer = 360;
13584 threshold_mer = 145;
13585 sig_quality->post_reed_solomon_ber = 0;
13586 sig_quality->scale_factor_ber = 1000000;
13587 sig_quality->indicator =
13588 mer2indicator(sig_quality->MER, min_mer, threshold_mer,
13589 max_mer);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013590 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013591#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013592 case DRX_STANDARD_ITU_A:
13593 case DRX_STANDARD_ITU_B:
13594 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013595 CHK_ERROR(ctrl_get_qam_sig_quality(demod, sig_quality));
13596 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
13597 switch (ext_attr->constellation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013598 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013599 sig_quality->MER = 210;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013600 break;
13601 case DRX_CONSTELLATION_QAM128:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013602 sig_quality->MER = 180;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013603 break;
13604 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013605 sig_quality->MER = 150;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013606 break;
13607 case DRX_CONSTELLATION_QAM32:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013608 sig_quality->MER = 120;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013609 break;
13610 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013611 sig_quality->MER = 90;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013612 break;
13613 default:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013614 sig_quality->MER = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013615 return (DRX_STS_ERROR);
13616 }
13617 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013618
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013619 switch (ext_attr->constellation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013620 case DRX_CONSTELLATION_QAM256:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013621 min_mer = 210;
13622 threshold_mer = 270;
13623 max_mer = 380;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013624 break;
13625 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013626 min_mer = 150;
13627 threshold_mer = 210;
13628 max_mer = 380;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013629 break;
13630 case DRX_CONSTELLATION_QAM128:
13631 case DRX_CONSTELLATION_QAM32:
13632 case DRX_CONSTELLATION_QAM16:
13633 break;
13634 default:
13635 return (DRX_STS_ERROR);
13636 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013637 sig_quality->indicator =
13638 mer2indicator(sig_quality->MER, min_mer, threshold_mer,
13639 max_mer);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013640 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013641#endif
13642#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013643 case DRX_STANDARD_PAL_SECAM_BG:
13644 case DRX_STANDARD_PAL_SECAM_DK:
13645 case DRX_STANDARD_PAL_SECAM_I:
13646 case DRX_STANDARD_PAL_SECAM_L:
13647 case DRX_STANDARD_PAL_SECAM_LP:
13648 case DRX_STANDARD_NTSC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013649 CHK_ERROR(atv_sig_quality(demod, sig_quality));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013650 break;
13651 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013652 CHK_ERROR(fm_sig_quality(demod, sig_quality));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013653 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013654#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013655 default:
13656 return (DRX_STS_ERROR);
13657 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013658
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013659 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013660rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013661 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013662}
13663
13664/*============================================================================*/
13665
13666/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013667* \fn int ctrl_lock_status()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013668* \brief Retreive lock status .
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013669* \param dev_addr Pointer to demodulator device address.
13670* \param lock_stat Pointer to lock status structure.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013671* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013672*
13673*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013674static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013675ctrl_lock_status(pdrx_demod_instance_t demod, pdrx_lock_status_t lock_stat)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013676{
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013677 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013678 pdrxj_data_t ext_attr = NULL;
13679 struct i2c_device_addr *dev_addr = NULL;
13680 drxjscu_cmd_t cmd_scu = { /* command */ 0,
13681 /* parameter_len */ 0,
13682 /* result_len */ 0,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013683 /* *parameter */ NULL,
13684 /* *result */ NULL
13685 };
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013686 u16 cmd_result[2] = { 0, 0 };
13687 u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013688
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013689 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013690 if ((demod == NULL) || (lock_stat == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013691 return (DRX_STS_INVALID_ARG);
13692 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013693
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013694 dev_addr = demod->my_i2c_dev_addr;
13695 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
13696 standard = ext_attr->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013697
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013698 *lock_stat = DRX_NOT_LOCKED;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013699
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013700 /* define the SCU command code */
13701 switch (standard) {
13702 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013703 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013704 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013705 demod_lock |= 0x6;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013706 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013707#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013708 case DRX_STANDARD_ITU_A:
13709 case DRX_STANDARD_ITU_B:
13710 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013711 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013712 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
13713 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013714#endif
13715#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013716 case DRX_STANDARD_NTSC:
13717 case DRX_STANDARD_PAL_SECAM_BG:
13718 case DRX_STANDARD_PAL_SECAM_DK:
13719 case DRX_STANDARD_PAL_SECAM_I:
13720 case DRX_STANDARD_PAL_SECAM_L:
13721 case DRX_STANDARD_PAL_SECAM_LP:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013722 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013723 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
13724 break;
13725 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013726 return fm_lock_status(demod, lock_stat);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013727#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013728 case DRX_STANDARD_UNKNOWN: /* fallthrough */
13729 default:
13730 return (DRX_STS_ERROR);
13731 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013732
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013733 /* define the SCU command paramters and execute the command */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013734 cmd_scu.parameter_len = 0;
13735 cmd_scu.result_len = 2;
13736 cmd_scu.parameter = NULL;
13737 cmd_scu.result = cmd_result;
13738 CHK_ERROR(scu_command(dev_addr, &cmd_scu));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013739
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013740 /* set the lock status */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013741 if (cmd_scu.result[1] < demod_lock) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013742 /* 0x0000 NOT LOCKED */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013743 *lock_stat = DRX_NOT_LOCKED;
13744 } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
13745 *lock_stat = DRXJ_DEMOD_LOCK;
13746 } else if (cmd_scu.result[1] <
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013747 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
13748 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013749 *lock_stat = DRX_LOCKED;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013750 } else {
13751 /* 0xC000 NEVER LOCKED */
13752 /* (system will never be able to lock to the signal) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013753 *lock_stat = DRX_NEVER_LOCK;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013754 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013755
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013756 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013757rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013758 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013759}
13760
13761/*============================================================================*/
13762
13763/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013764* \fn int ctrl_constel()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013765* \brief Retreive a constellation point via I2C.
13766* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013767* \param complex_nr Pointer to the structure in which to store the
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013768 constellation point.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013769* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013770*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013771static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013772ctrl_constel(pdrx_demod_instance_t demod, pdrx_complex_t complex_nr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013773{
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013774 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013775 /**< active standard */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013776
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013777 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013778 if ((demod == NULL) || (complex_nr == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013779 return (DRX_STS_INVALID_ARG);
13780 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013781
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013782 /* read device info */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013783 standard = ((pdrxj_data_t) demod->my_ext_attr)->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013784
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013785 /* Read constellation point */
13786 switch (standard) {
13787 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013788 CHK_ERROR(ctrl_get_vsb_constel(demod, complex_nr));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013789 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013790#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013791 case DRX_STANDARD_ITU_A: /* fallthrough */
13792 case DRX_STANDARD_ITU_B: /* fallthrough */
13793 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013794 CHK_ERROR(ctrl_get_qam_constel(demod, complex_nr));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013795 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013796#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013797 case DRX_STANDARD_UNKNOWN:
13798 default:
13799 return (DRX_STS_ERROR);
13800 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013801
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013802 return (DRX_STS_OK);
13803rw_error:
13804 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013805}
13806
13807/*============================================================================*/
13808
13809/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013810* \fn int ctrl_set_standard()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013811* \brief Set modulation standard to be used.
13812* \param standard Modulation standard.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013813* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013814*
13815* Setup stuff for the desired demodulation standard.
13816* Disable and power down the previous selected demodulation standard
13817*
13818*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013819static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013820ctrl_set_standard(pdrx_demod_instance_t demod, enum drx_standard *standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013821{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013822 pdrxj_data_t ext_attr = NULL;
13823 enum drx_standard prev_standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013824
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013825 /* check arguments */
13826 if ((standard == NULL) || (demod == NULL)) {
13827 return (DRX_STS_INVALID_ARG);
13828 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013829
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013830 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
13831 prev_standard = ext_attr->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013832
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013833 /*
13834 Stop and power down previous standard
13835 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013836 switch (prev_standard) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013837#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013838 case DRX_STANDARD_ITU_A: /* fallthrough */
13839 case DRX_STANDARD_ITU_B: /* fallthrough */
13840 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013841 CHK_ERROR(power_down_qam(demod, false));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013842 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013843#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013844 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013845 CHK_ERROR(power_down_vsb(demod, false));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013846 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013847#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013848 case DRX_STANDARD_NTSC: /* fallthrough */
13849 case DRX_STANDARD_FM: /* fallthrough */
13850 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13851 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13852 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13853 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13854 case DRX_STANDARD_PAL_SECAM_LP:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013855 CHK_ERROR(power_down_atv(demod, prev_standard, false));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013856 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013857#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013858 case DRX_STANDARD_UNKNOWN:
13859 /* Do nothing */
13860 break;
13861 case DRX_STANDARD_AUTO: /* fallthrough */
13862 default:
13863 return (DRX_STS_INVALID_ARG);
13864 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013865
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013866 /*
13867 Initialize channel independent registers
13868 Power up new standard
13869 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013870 ext_attr->standard = *standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013871
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013872 switch (*standard) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013873#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013874 case DRX_STANDARD_ITU_A: /* fallthrough */
13875 case DRX_STANDARD_ITU_B: /* fallthrough */
13876 case DRX_STANDARD_ITU_C:
13877 DUMMY_READ();
13878 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013879#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013880 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013881 CHK_ERROR(set_vsb_leak_n_gain(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013882 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013883#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013884 case DRX_STANDARD_NTSC: /* fallthrough */
13885 case DRX_STANDARD_FM: /* fallthrough */
13886 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13887 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13888 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
13889 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
13890 case DRX_STANDARD_PAL_SECAM_LP:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013891 CHK_ERROR(set_atv_standard(demod, standard));
13892 CHK_ERROR(power_up_atv(demod, *standard));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013893 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013894#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013895 default:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013896 ext_attr->standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013897 return (DRX_STS_INVALID_ARG);
13898 break;
13899 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013900
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013901 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013902rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013903 /* Don't know what the standard is now ... try again */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013904 ext_attr->standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013905 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013906}
13907
13908/*============================================================================*/
13909
13910/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013911* \fn int ctrl_get_standard()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013912* \brief Get modulation standard currently used to demodulate.
13913* \param standard Modulation standard.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013914* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013915*
13916* Returns 8VSB, NTSC, QAM only.
13917*
13918*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013919static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013920ctrl_get_standard(pdrx_demod_instance_t demod, enum drx_standard *standard)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013921{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013922 pdrxj_data_t ext_attr = NULL;
13923 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013924
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013925 /* check arguments */
13926 if (standard == NULL) {
13927 return (DRX_STS_INVALID_ARG);
13928 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013929 (*standard) = ext_attr->standard;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013930 DUMMY_READ();
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013931
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013932 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013933rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013934 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013935}
13936
13937/*============================================================================*/
13938
13939/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013940* \fn int ctrl_get_cfg_symbol_clock_offset()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013941* \brief Get frequency offsets of STR.
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030013942* \param pointer to s32.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013943* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013944*
13945*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013946static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013947ctrl_get_cfg_symbol_clock_offset(pdrx_demod_instance_t demod, s32 *rate_offset)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013948{
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013949 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013950 struct i2c_device_addr *dev_addr = NULL;
13951 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013952
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013953 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013954 if (rate_offset == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013955 return (DRX_STS_INVALID_ARG);
13956 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013957
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013958 dev_addr = demod->my_i2c_dev_addr;
13959 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
13960 standard = ext_attr->standard;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013961
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013962 switch (standard) {
13963 case DRX_STANDARD_8VSB: /* fallthrough */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013964#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013965 case DRX_STANDARD_ITU_A: /* fallthrough */
13966 case DRX_STANDARD_ITU_B: /* fallthrough */
13967 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013968#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013969 CHK_ERROR(get_str_freq_offset(demod, rate_offset));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013970 break;
13971 case DRX_STANDARD_NTSC:
13972 case DRX_STANDARD_UNKNOWN:
13973 default:
13974 return (DRX_STS_INVALID_ARG);
13975 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013976
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013977 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013978rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013979 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013980}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030013981
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013982/*============================================================================*/
13983
13984/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013985* \fn int ctrl_power_mode()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013986* \brief Set the power mode of the device to the specified power mode
13987* \param demod Pointer to demodulator instance.
13988* \param mode Pointer to new power mode.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013989* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013990* \retval DRX_STS_OK Success
13991* \retval DRX_STS_ERROR I2C error or other failure
13992* \retval DRX_STS_INVALID_ARG Invalid mode argument.
13993*
13994*
13995*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030013996static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013997ctrl_power_mode(pdrx_demod_instance_t demod, pdrx_power_mode_t mode)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030013998{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030013999 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) NULL;
14000 pdrxj_data_t ext_attr = (pdrxj_data_t) NULL;
14001 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) NULL;
14002 u16 sio_cc_pwd_mode = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014003
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014004 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
14005 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
14006 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014007
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014008 /* Check arguments */
14009 if (mode == NULL) {
14010 return (DRX_STS_INVALID_ARG);
14011 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014012
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014013 /* If already in requested power mode, do nothing */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014014 if (common_attr->current_power_mode == *mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014015 return (DRX_STS_OK);
14016 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014017
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014018 switch (*mode) {
14019 case DRX_POWER_UP:
14020 case DRXJ_POWER_DOWN_MAIN_PATH:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014021 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014022 break;
14023 case DRXJ_POWER_DOWN_CORE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014024 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014025 break;
14026 case DRXJ_POWER_DOWN_PLL:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014027 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014028 break;
14029 case DRX_POWER_DOWN:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014030 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014031 break;
14032 default:
14033 /* Unknow sleep mode */
14034 return (DRX_STS_INVALID_ARG);
14035 break;
14036 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014037
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014038 /* Check if device needs to be powered up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014039 if ((common_attr->current_power_mode != DRX_POWER_UP)) {
14040 CHK_ERROR(power_up_device(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014041 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014042
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014043 if ((*mode == DRX_POWER_UP)) {
14044 /* Restore analog & pin configuartion */
14045 } else {
14046 /* Power down to requested mode */
14047 /* Backup some register settings */
14048 /* Set pins with possible pull-ups connected to them in input mode */
14049 /* Analog power down */
14050 /* ADC power down */
14051 /* Power down device */
14052 /* stop all comm_exec */
14053 /*
14054 Stop and power down previous standard
14055 */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014056
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014057 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014058 case DRX_STANDARD_ITU_A:
14059 case DRX_STANDARD_ITU_B:
14060 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014061 CHK_ERROR(power_down_qam(demod, true));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014062 break;
14063 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014064 CHK_ERROR(power_down_vsb(demod, true));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014065 break;
14066 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14067 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14068 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14069 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14070 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14071 case DRX_STANDARD_NTSC: /* fallthrough */
14072 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014073 CHK_ERROR(power_down_atv(demod, ext_attr->standard, true));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014074 break;
14075 case DRX_STANDARD_UNKNOWN:
14076 /* Do nothing */
14077 break;
14078 case DRX_STANDARD_AUTO: /* fallthrough */
14079 default:
14080 return (DRX_STS_ERROR);
14081 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014082
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014083 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014084 WR16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
14085 WR16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014086
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014087 /* Initialize HI, wakeup key especially before put IC to sleep */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014088 CHK_ERROR(init_hi(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014089
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014090 ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
14091 CHK_ERROR(hi_cfg_command(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014092 }
14093 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014094
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014095 common_attr->current_power_mode = *mode;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014096
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014097 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014098rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014099 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014100}
14101
14102/*============================================================================*/
14103
14104/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014105* \fn int ctrl_version()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014106* \brief Report version of microcode and if possible version of device
14107* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014108* \param version_list Pointer to pointer of linked list of versions.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014109* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014110*
14111* Using static structures so no allocation of memory is needed.
14112* Filling in all the fields each time, cause you don't know if they are
14113* changed by the application.
14114*
14115* For device:
14116* Major version number will be last two digits of family number.
14117* Minor number will be full respin number
14118* Patch will be metal fix number+1
14119* Examples:
14120* DRX3942J A2 => number: 42.1.2 text: "DRX3942J:A2"
14121* DRX3933J B1 => number: 33.2.1 text: "DRX3933J:B1"
14122*
14123*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014124static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014125ctrl_version(pdrx_demod_instance_t demod, p_drx_version_list_t *version_list)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014126{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014127 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
14128 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
14129 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) (NULL);
14130 u16 ucode_major_minor = 0; /* BCD Ma:Ma:Ma:Mi */
14131 u16 ucode_patch = 0; /* BCD Pa:Pa:Pa:Pa */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014132 u16 major = 0;
14133 u16 minor = 0;
14134 u16 patch = 0;
14135 u16 idx = 0;
14136 u32 jtag = 0;
14137 u16 subtype = 0;
14138 u16 mfx = 0;
14139 u16 bid = 0;
14140 u16 key = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014141
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014142 static char ucode_name[] = "Microcode";
14143 static char device_name[] = "Device";
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014144
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014145 dev_addr = demod->my_i2c_dev_addr;
14146 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
14147 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014148
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014149 /* Microcode version *************************************** */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014150
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014151 ext_attr->v_version[0].module_type = DRX_MODULE_MICROCODE;
14152 ext_attr->v_version[0].module_name = ucode_name;
14153 ext_attr->v_version[0].v_string = ext_attr->v_text[0];
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014154
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014155 if (common_attr->is_opened == true) {
14156 SARR16(dev_addr, SCU_RAM_VERSION_HI__A, &ucode_major_minor);
14157 SARR16(dev_addr, SCU_RAM_VERSION_LO__A, &ucode_patch);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014158
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014159 /* Translate BCD to numbers and string */
14160 /* TODO: The most significant Ma and Pa will be ignored, check with spec */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014161 minor = (ucode_major_minor & 0xF);
14162 ucode_major_minor >>= 4;
14163 major = (ucode_major_minor & 0xF);
14164 ucode_major_minor >>= 4;
14165 major += (10 * (ucode_major_minor & 0xF));
14166 patch = (ucode_patch & 0xF);
14167 ucode_patch >>= 4;
14168 patch += (10 * (ucode_patch & 0xF));
14169 ucode_patch >>= 4;
14170 patch += (100 * (ucode_patch & 0xF));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014171 } else {
14172 /* No microcode uploaded, No Rom existed, set version to 0.0.0 */
14173 patch = 0;
14174 minor = 0;
14175 major = 0;
14176 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014177 ext_attr->v_version[0].v_major = major;
14178 ext_attr->v_version[0].v_minor = minor;
14179 ext_attr->v_version[0].v_patch = patch;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014180
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014181 if (major / 10 != 0) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014182 ext_attr->v_version[0].v_string[idx++] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014183 ((char)(major / 10)) + '0';
14184 major %= 10;
14185 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014186 ext_attr->v_version[0].v_string[idx++] = ((char)major) + '0';
14187 ext_attr->v_version[0].v_string[idx++] = '.';
14188 ext_attr->v_version[0].v_string[idx++] = ((char)minor) + '0';
14189 ext_attr->v_version[0].v_string[idx++] = '.';
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014190 if (patch / 100 != 0) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014191 ext_attr->v_version[0].v_string[idx++] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014192 ((char)(patch / 100)) + '0';
14193 patch %= 100;
14194 }
14195 if (patch / 10 != 0) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014196 ext_attr->v_version[0].v_string[idx++] =
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014197 ((char)(patch / 10)) + '0';
14198 patch %= 10;
14199 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014200 ext_attr->v_version[0].v_string[idx++] = ((char)patch) + '0';
14201 ext_attr->v_version[0].v_string[idx] = '\0';
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014202
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014203 ext_attr->v_list_elements[0].version = &(ext_attr->v_version[0]);
14204 ext_attr->v_list_elements[0].next = &(ext_attr->v_list_elements[1]);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014205
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014206 /* Device version *************************************** */
14207 /* Check device id */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014208 RR16(dev_addr, SIO_TOP_COMM_KEY__A, &key);
14209 WR16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA);
14210 RR32(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag);
14211 RR16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid);
14212 WR16(dev_addr, SIO_TOP_COMM_KEY__A, key);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014213
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014214 ext_attr->v_version[1].module_type = DRX_MODULE_DEVICE;
14215 ext_attr->v_version[1].module_name = device_name;
14216 ext_attr->v_version[1].v_string = ext_attr->v_text[1];
14217 ext_attr->v_version[1].v_string[0] = 'D';
14218 ext_attr->v_version[1].v_string[1] = 'R';
14219 ext_attr->v_version[1].v_string[2] = 'X';
14220 ext_attr->v_version[1].v_string[3] = '3';
14221 ext_attr->v_version[1].v_string[4] = '9';
14222 ext_attr->v_version[1].v_string[7] = 'J';
14223 ext_attr->v_version[1].v_string[8] = ':';
14224 ext_attr->v_version[1].v_string[11] = '\0';
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014225
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014226 /* DRX39xxJ type Ax */
14227 /* TODO semantics of mfx and spin are unclear */
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014228 subtype = (u16) ((jtag >> 12) & 0xFF);
14229 mfx = (u16) (jtag >> 29);
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014230 ext_attr->v_version[1].v_minor = 1;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014231 if (mfx == 0x03) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014232 ext_attr->v_version[1].v_patch = mfx + 2;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014233 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014234 ext_attr->v_version[1].v_patch = mfx + 1;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014235 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014236 ext_attr->v_version[1].v_string[6] = ((char)(subtype & 0xF)) + '0';
14237 ext_attr->v_version[1].v_major = (subtype & 0x0F);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014238 subtype >>= 4;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014239 ext_attr->v_version[1].v_string[5] = ((char)(subtype & 0xF)) + '0';
14240 ext_attr->v_version[1].v_major += 10 * subtype;
14241 ext_attr->v_version[1].v_string[9] = 'A';
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014242 if (mfx == 0x03) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014243 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '2';
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014244 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014245 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '1';
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014246 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014247
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014248 ext_attr->v_list_elements[1].version = &(ext_attr->v_version[1]);
14249 ext_attr->v_list_elements[1].next = (p_drx_version_list_t) (NULL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014250
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014251 *version_list = &(ext_attr->v_list_elements[0]);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014252
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014253 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014254
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014255rw_error:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014256 *version_list = (p_drx_version_list_t) (NULL);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014257 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014258
14259}
14260
14261/*============================================================================*/
14262
14263/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014264* \fn int ctrl_probe_device()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014265* \brief Probe device, check if it is present
14266* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014267* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014268* \retval DRX_STS_OK a drx39xxj device has been detected.
14269* \retval DRX_STS_ERROR no drx39xxj device detected.
14270*
14271* This funtion can be caled before open() and after close().
14272*
14273*/
14274
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014275static int ctrl_probe_device(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014276{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014277 drx_power_mode_t org_power_mode = DRX_POWER_UP;
14278 int ret_status = DRX_STS_OK;
14279 pdrx_common_attr_t common_attr = (pdrx_common_attr_t) (NULL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014280
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014281 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014282
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014283 if (common_attr->is_opened == false
14284 || common_attr->current_power_mode != DRX_POWER_UP) {
14285 struct i2c_device_addr *dev_addr = NULL;
14286 drx_power_mode_t power_mode = DRX_POWER_UP;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014287 u32 jtag = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014288
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014289 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014290
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014291 /* Remeber original power mode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014292 org_power_mode = common_attr->current_power_mode;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014293
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014294 if (demod->my_common_attr->is_opened == false) {
14295 CHK_ERROR(power_up_device(demod));
14296 common_attr->current_power_mode = DRX_POWER_UP;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014297 } else {
14298 /* Wake-up device, feedback from device */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014299 CHK_ERROR(ctrl_power_mode(demod, &power_mode));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014300 }
14301 /* Initialize HI, wakeup key especially */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014302 CHK_ERROR(init_hi(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014303
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014304 /* Check device id */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014305 RR32(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014306 jtag = (jtag >> 12) & 0xFFFF;
14307 switch (jtag) {
14308 case 0x3931: /* fallthrough */
14309 case 0x3932: /* fallthrough */
14310 case 0x3933: /* fallthrough */
14311 case 0x3934: /* fallthrough */
14312 case 0x3941: /* fallthrough */
14313 case 0x3942: /* fallthrough */
14314 case 0x3943: /* fallthrough */
14315 case 0x3944: /* fallthrough */
14316 case 0x3945: /* fallthrough */
14317 case 0x3946:
14318 /* ok , do nothing */
14319 break;
14320 default:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014321 ret_status = DRX_STS_ERROR;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014322 break;
14323 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014324
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014325 /* Device was not opened, return to orginal powermode,
14326 feedback from device */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014327 CHK_ERROR(ctrl_power_mode(demod, &org_power_mode));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014328 } else {
14329 /* dummy read to make this function fail in case device
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014330 suddenly disappears after a succesful drx_open */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014331 DUMMY_READ();
14332 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014333
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014334 return (ret_status);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014335
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014336rw_error:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014337 common_attr->current_power_mode = org_power_mode;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014338 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014339}
14340
14341#ifdef DRXJ_SPLIT_UCODE_UPLOAD
14342/*============================================================================*/
14343
14344/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014345* \fn int is_mc_block_audio()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014346* \brief Check if MC block is Audio or not Audio.
14347* \param addr Pointer to demodulator instance.
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030014348* \param audioUpload true if MC block is Audio
14349 false if MC block not Audio
14350* \return bool.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014351*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014352bool is_mc_block_audio(u32 addr)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014353{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014354 if ((addr == AUD_XFP_PRAM_4K__A) || (addr == AUD_XDFP_PRAM_4K__A)) {
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030014355 return (true);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014356 }
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030014357 return (false);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014358}
14359
14360/*============================================================================*/
14361
14362/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014363* \fn int ctrl_u_codeUpload()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014364* \brief Handle Audio or !Audio part of microcode upload.
14365* \param demod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014366* \param mc_info Pointer to information about microcode data.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014367* \param action Either UCODE_UPLOAD or UCODE_VERIFY.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014368* \param upload_audio_mc true if Audio MC need to be uploaded.
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030014369 false if !Audio MC need to be uploaded.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014370* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014371*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014372static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014373ctrl_u_codeUpload(pdrx_demod_instance_t demod,
14374 p_drxu_code_info_t mc_info,
14375 drxu_code_action_t action, bool upload_audio_mc)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014376{
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014377 u16 i = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014378 u16 mc_nr_of_blks = 0;
14379 u16 mc_magic_word = 0;
14380 u8 *mc_data = (u8 *) (NULL);
14381 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *) (NULL);
14382 pdrxj_data_t ext_attr = (pdrxj_data_t) (NULL);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014383
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014384 dev_addr = demod->my_i2c_dev_addr;
14385 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014386
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014387 /* Check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014388 if ((mc_info == NULL) ||
14389 (mc_info->mc_data == NULL) || (mc_info->mc_size == 0)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014390 return DRX_STS_INVALID_ARG;
14391 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014392
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014393 mc_data = mc_info->mc_data;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014394
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014395 /* Check data */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014396 mc_magic_word = u_code_read16(mc_data);
14397 mc_data += sizeof(u16);
14398 mc_nr_of_blks = u_code_read16(mc_data);
14399 mc_data += sizeof(u16);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014400
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014401 if ((mc_magic_word != DRXJ_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014402 /* wrong endianess or wrong data ? */
14403 return DRX_STS_INVALID_ARG;
14404 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014405
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014406 /* Process microcode blocks */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014407 for (i = 0; i < mc_nr_of_blks; i++) {
14408 drxu_code_block_hdr_t block_hdr;
14409 u16 mc_block_nr_bytes = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014410
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014411 /* Process block header */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014412 block_hdr.addr = u_code_read32(mc_data);
14413 mc_data += sizeof(u32);
14414 block_hdr.size = u_code_read16(mc_data);
14415 mc_data += sizeof(u16);
14416 block_hdr.flags = u_code_read16(mc_data);
14417 mc_data += sizeof(u16);
14418 block_hdr.CRC = u_code_read16(mc_data);
14419 mc_data += sizeof(u16);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014420
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014421 /* Check block header on:
14422 - no data
14423 - data larger then 64Kb
14424 - if CRC enabled check CRC
14425 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014426 if ((block_hdr.size == 0) ||
14427 (block_hdr.size > 0x7FFF) ||
14428 (((block_hdr.flags & DRXJ_UCODE_CRC_FLAG) != 0) &&
14429 (block_hdr.CRC != u_code_compute_crc(mc_data, block_hdr.size)))
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014430 ) {
14431 /* Wrong data ! */
14432 return DRX_STS_INVALID_ARG;
14433 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014434
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014435 mc_block_nr_bytes = block_hdr.size * sizeof(u16);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014436
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014437 /* Perform the desired action */
14438 /* Check which part of MC need to be uploaded - Audio or not Audio */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014439 if (is_mc_block_audio(block_hdr.addr) == upload_audio_mc) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014440 switch (action) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014441 /*===================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014442 case UCODE_UPLOAD:
14443 {
14444 /* Upload microcode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014445 if (demod->my_access_funct->
14446 write_block_func(dev_addr,
14447 (dr_xaddr_t) block_hdr.
14448 addr, mc_block_nr_bytes,
14449 mc_data,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014450 0x0000) !=
14451 DRX_STS_OK) {
14452 return (DRX_STS_ERROR);
14453 }
14454 };
14455 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014456
14457 /*===================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014458 case UCODE_VERIFY:
14459 {
14460 int result = 0;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014461 u8 mc_dataBuffer
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014462 [DRXJ_UCODE_MAX_BUF_SIZE];
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014463 u32 bytes_to_compare = 0;
14464 u32 bytes_left_to_compare = 0;
14465 dr_xaddr_t curr_addr = (dr_xaddr_t) 0;
14466 u8 *curr_ptr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014467
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014468 bytes_left_to_compare = mc_block_nr_bytes;
14469 curr_addr = block_hdr.addr;
14470 curr_ptr = mc_data;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014471
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014472 while (bytes_left_to_compare != 0) {
14473 if (bytes_left_to_compare >
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014474 ((u32)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014475 DRXJ_UCODE_MAX_BUF_SIZE)) {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014476 bytes_to_compare =
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014477 ((u32)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014478 DRXJ_UCODE_MAX_BUF_SIZE);
14479 } else {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014480 bytes_to_compare =
14481 bytes_left_to_compare;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014482 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014483
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014484 if (demod->my_access_funct->
14485 read_block_func(dev_addr,
14486 curr_addr,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014487 (u16)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014488 bytes_to_compare,
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014489 (u8 *)
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014490 mc_dataBuffer,
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014491 0x0000) !=
14492 DRX_STS_OK) {
14493 return (DRX_STS_ERROR);
14494 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014495
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014496 result =
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014497 drxbsp_hst_memcmp(curr_ptr,
14498 mc_dataBuffer,
14499 bytes_to_compare);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014500
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014501 if (result != 0) {
14502 return (DRX_STS_ERROR);
14503 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014504
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014505 curr_addr +=
14506 ((dr_xaddr_t)
14507 (bytes_to_compare / 2));
14508 curr_ptr =
14509 &(curr_ptr[bytes_to_compare]);
14510 bytes_left_to_compare -=
14511 ((u32) bytes_to_compare);
14512 } /* while( bytes_to_compare > DRXJ_UCODE_MAX_BUF_SIZE ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014513 };
14514 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014515
14516 /*===================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014517 default:
14518 return DRX_STS_INVALID_ARG;
14519 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014520
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014521 } /* switch ( action ) */
14522 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014523
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014524 /* if( is_mc_block_audio( block_hdr.addr ) == upload_audio_mc ) */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014525 /* Next block */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014526 mc_data += mc_block_nr_bytes;
14527 } /* for( i = 0 ; i<mc_nr_of_blks ; i++ ) */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014528
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014529 if (upload_audio_mc == false) {
14530 ext_attr->flag_aud_mc_uploaded = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014531 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014532
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014533 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014534}
14535#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
14536
14537/*============================================================================*/
14538/*== CTRL Set/Get Config related functions ===================================*/
14539/*============================================================================*/
14540
14541/*===== SigStrength() =========================================================*/
14542/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014543* \fn int ctrl_sig_strength()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014544* \brief Retrieve signal strength.
14545* \param devmod Pointer to demodulator instance.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014546* \param sig_quality Pointer to signal strength data; range 0, .. , 100.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014547* \return int.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014548* \retval DRX_STS_OK sig_strength contains valid data.
14549* \retval DRX_STS_INVALID_ARG sig_strength is NULL.
14550* \retval DRX_STS_ERROR Erroneous data, sig_strength contains invalid data.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014551
14552*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014553static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014554ctrl_sig_strength(pdrx_demod_instance_t demod, u16 *sig_strength)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014555{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014556 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014557 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014558
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014559 /* Check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014560 if ((sig_strength == NULL) || (demod == NULL)) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014561 return (DRX_STS_INVALID_ARG);
14562 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014563
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014564 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
14565 standard = ext_attr->standard;
14566 *sig_strength = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014567
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014568 /* Signal strength indication for each standard */
14569 switch (standard) {
14570 case DRX_STANDARD_8VSB: /* fallthrough */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014571#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014572 case DRX_STANDARD_ITU_A: /* fallthrough */
14573 case DRX_STANDARD_ITU_B: /* fallthrough */
14574 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014575#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014576 CHK_ERROR(get_sig_strength(demod, sig_strength));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014577 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014578#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014579 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14580 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14581 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14582 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14583 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14584 case DRX_STANDARD_NTSC: /* fallthrough */
14585 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014586 CHK_ERROR(get_atv_sig_strength(demod, sig_strength));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014587 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014588#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014589 case DRX_STANDARD_UNKNOWN: /* fallthrough */
14590 default:
14591 return (DRX_STS_INVALID_ARG);
14592 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014593
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014594 /* TODO */
14595 /* find out if signal strength is calculated in the same way for all standards */
14596 return (DRX_STS_OK);
14597rw_error:
14598 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014599}
14600
14601/*============================================================================*/
14602/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014603* \fn int ctrl_get_cfg_oob_misc()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014604* \brief Get current state information of OOB.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014605* \param pointer to drxj_cfg_oob_misc_t.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014606* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014607*
14608*/
14609#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014610static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014611ctrl_get_cfg_oob_misc(pdrx_demod_instance_t demod, p_drxj_cfg_oob_misc_t misc)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014612{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014613 struct i2c_device_addr *dev_addr = NULL;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014614 u16 lock = 0U;
14615 u16 state = 0U;
14616 u16 data = 0U;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014617 u16 digital_agc_mant = 0U;
14618 u16 digital_agc_exp = 0U;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014619
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014620 /* check arguments */
14621 if (misc == NULL) {
14622 return (DRX_STS_INVALID_ARG);
14623 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014624 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014625
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014626 /* TODO */
14627 /* check if the same registers are used for all standards (QAM/VSB/ATV) */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014628 RR16(dev_addr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC);
14629 RR16(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &misc->agc.RFAGC);
14630 RR16(dev_addr, ORX_FWP_SRC_DGN_W__A, &data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014631
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014632 digital_agc_mant = data & ORX_FWP_SRC_DGN_W_MANT__M;
14633 digital_agc_exp = (data & ORX_FWP_SRC_DGN_W_EXP__M)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014634 >> ORX_FWP_SRC_DGN_W_EXP__B;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014635 misc->agc.digital_agc = digital_agc_mant << digital_agc_exp;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014636
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014637 SARR16(dev_addr, SCU_RAM_ORX_SCU_LOCK__A, &lock);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014638
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014639 misc->ana_gain_lock = ((lock & 0x0001) ? true : false);
14640 misc->dig_gain_lock = ((lock & 0x0002) ? true : false);
14641 misc->freq_lock = ((lock & 0x0004) ? true : false);
14642 misc->phase_lock = ((lock & 0x0008) ? true : false);
14643 misc->sym_timing_lock = ((lock & 0x0010) ? true : false);
14644 misc->eq_lock = ((lock & 0x0020) ? true : false);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014645
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014646 SARR16(dev_addr, SCU_RAM_ORX_SCU_STATE__A, &state);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014647 misc->state = (state >> 8) & 0xff;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014648
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014649 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014650rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014651 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014652}
14653#endif
14654
14655/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014656* \fn int ctrl_get_cfg_vsb_misc()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014657* \brief Get current state information of OOB.
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014658* \param pointer to drxj_cfg_oob_misc_t.
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014659* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014660*
14661*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014662static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014663ctrl_get_cfg_vsb_misc(pdrx_demod_instance_t demod, p_drxj_cfg_vsb_misc_t misc)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014664{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014665 struct i2c_device_addr *dev_addr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014666
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014667 /* check arguments */
14668 if (misc == NULL) {
14669 return (DRX_STS_INVALID_ARG);
14670 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014671 dev_addr = demod->my_i2c_dev_addr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014672
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014673 CHK_ERROR(get_vsb_symb_err(dev_addr, &misc->symb_error));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014674
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014675 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014676rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014677 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014678}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014679
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014680/*============================================================================*/
14681
14682/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014683* \fn int ctrl_set_cfg_agc_if()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014684* \brief Set IF AGC.
14685* \param demod demod instance
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014686* \param agc_settings If agc configuration
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014687* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014688*
14689* Check arguments
14690* Dispatch handling to standard specific function.
14691*
14692*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014693static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014694ctrl_set_cfg_agc_if(pdrx_demod_instance_t demod, p_drxj_cfg_agc_t agc_settings)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014695{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014696 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014697 if (agc_settings == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014698 return (DRX_STS_INVALID_ARG);
14699 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014700
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014701 switch (agc_settings->ctrl_mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014702 case DRX_AGC_CTRL_AUTO: /* fallthrough */
14703 case DRX_AGC_CTRL_USER: /* fallthrough */
14704 case DRX_AGC_CTRL_OFF: /* fallthrough */
14705 break;
14706 default:
14707 return (DRX_STS_INVALID_ARG);
14708 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014709
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014710 /* Distpatch */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014711 switch (agc_settings->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014712 case DRX_STANDARD_8VSB: /* fallthrough */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014713#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014714 case DRX_STANDARD_ITU_A: /* fallthrough */
14715 case DRX_STANDARD_ITU_B: /* fallthrough */
14716 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014717#endif
14718#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014719 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14720 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14721 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14722 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14723 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14724 case DRX_STANDARD_NTSC: /* fallthrough */
14725 case DRX_STANDARD_FM:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014726#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014727 return set_agc_if(demod, agc_settings, true);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014728 case DRX_STANDARD_UNKNOWN:
14729 default:
14730 return (DRX_STS_INVALID_ARG);
14731 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014732
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014733 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014734}
14735
14736/*============================================================================*/
14737
14738/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014739* \fn int ctrl_get_cfg_agc_if()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014740* \brief Retrieve IF AGC settings.
14741* \param demod demod instance
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014742* \param agc_settings If agc configuration
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014743* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014744*
14745* Check arguments
14746* Dispatch handling to standard specific function.
14747*
14748*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014749static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014750ctrl_get_cfg_agc_if(pdrx_demod_instance_t demod, p_drxj_cfg_agc_t agc_settings)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014751{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014752 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014753 if (agc_settings == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014754 return (DRX_STS_INVALID_ARG);
14755 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014756
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014757 /* Distpatch */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014758 switch (agc_settings->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014759 case DRX_STANDARD_8VSB: /* fallthrough */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014760#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014761 case DRX_STANDARD_ITU_A: /* fallthrough */
14762 case DRX_STANDARD_ITU_B: /* fallthrough */
14763 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014764#endif
14765#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014766 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14767 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14768 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14769 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14770 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14771 case DRX_STANDARD_NTSC: /* fallthrough */
14772 case DRX_STANDARD_FM:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014773#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014774 return get_agc_if(demod, agc_settings);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014775 case DRX_STANDARD_UNKNOWN:
14776 default:
14777 return (DRX_STS_INVALID_ARG);
14778 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014779
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014780 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014781}
14782
14783/*============================================================================*/
14784
14785/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014786* \fn int ctrl_set_cfg_agc_rf()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014787* \brief Set RF AGC.
14788* \param demod demod instance
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014789* \param agc_settings rf agc configuration
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014790* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014791*
14792* Check arguments
14793* Dispatch handling to standard specific function.
14794*
14795*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014796static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014797ctrl_set_cfg_agc_rf(pdrx_demod_instance_t demod, p_drxj_cfg_agc_t agc_settings)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014798{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014799 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014800 if (agc_settings == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014801 return (DRX_STS_INVALID_ARG);
14802 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014803
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014804 switch (agc_settings->ctrl_mode) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014805 case DRX_AGC_CTRL_AUTO: /* fallthrough */
14806 case DRX_AGC_CTRL_USER: /* fallthrough */
14807 case DRX_AGC_CTRL_OFF:
14808 break;
14809 default:
14810 return (DRX_STS_INVALID_ARG);
14811 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014812
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014813 /* Distpatch */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014814 switch (agc_settings->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014815 case DRX_STANDARD_8VSB: /* fallthrough */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014816#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014817 case DRX_STANDARD_ITU_A: /* fallthrough */
14818 case DRX_STANDARD_ITU_B: /* fallthrough */
14819 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014820#endif
14821#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014822 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14823 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14824 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14825 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14826 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14827 case DRX_STANDARD_NTSC: /* fallthrough */
14828 case DRX_STANDARD_FM:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014829#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014830 return set_agc_rf(demod, agc_settings, true);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014831 case DRX_STANDARD_UNKNOWN:
14832 default:
14833 return (DRX_STS_INVALID_ARG);
14834 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014835
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014836 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014837}
14838
14839/*============================================================================*/
14840
14841/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014842* \fn int ctrl_get_cfg_agc_rf()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014843* \brief Retrieve RF AGC settings.
14844* \param demod demod instance
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014845* \param agc_settings Rf agc configuration
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014846* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014847*
14848* Check arguments
14849* Dispatch handling to standard specific function.
14850*
14851*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014852static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014853ctrl_get_cfg_agc_rf(pdrx_demod_instance_t demod, p_drxj_cfg_agc_t agc_settings)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014854{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014855 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014856 if (agc_settings == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014857 return (DRX_STS_INVALID_ARG);
14858 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014859
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014860 /* Distpatch */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014861 switch (agc_settings->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014862 case DRX_STANDARD_8VSB: /* fallthrough */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014863#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014864 case DRX_STANDARD_ITU_A: /* fallthrough */
14865 case DRX_STANDARD_ITU_B: /* fallthrough */
14866 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014867#endif
14868#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014869 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
14870 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
14871 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
14872 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
14873 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
14874 case DRX_STANDARD_NTSC: /* fallthrough */
14875 case DRX_STANDARD_FM:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014876#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014877 return get_agc_rf(demod, agc_settings);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014878 case DRX_STANDARD_UNKNOWN:
14879 default:
14880 return (DRX_STS_INVALID_ARG);
14881 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014882
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014883 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014884}
14885
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014886/*============================================================================*/
14887
14888/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014889* \fn int ctrl_get_cfg_agc_internal()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014890* \brief Retrieve internal AGC value.
14891* \param demod demod instance
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014892* \param u16
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014893* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014894*
14895* Check arguments
14896* Dispatch handling to standard specific function.
14897*
14898*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014899static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014900ctrl_get_cfg_agc_internal(pdrx_demod_instance_t demod, u16 *agc_internal)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014901{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014902 struct i2c_device_addr *dev_addr = NULL;
14903 drx_lock_status_t lock_status = DRX_NOT_LOCKED;
14904 pdrxj_data_t ext_attr = NULL;
14905 u16 iqm_cf_scale_sh = 0;
14906 u16 iqm_cf_power = 0;
14907 u16 iqm_cf_amp = 0;
14908 u16 iqm_cf_gain = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014909
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014910 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014911 if (agc_internal == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014912 return (DRX_STS_INVALID_ARG);
14913 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014914 dev_addr = demod->my_i2c_dev_addr;
14915 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014916
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014917 CHK_ERROR(ctrl_lock_status(demod, &lock_status));
14918 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
14919 *agc_internal = 0;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014920 return DRX_STS_OK;
14921 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014922
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014923 /* Distpatch */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014924 switch (ext_attr->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014925 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014926 iqm_cf_gain = 57;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014927 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014928#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014929 case DRX_STANDARD_ITU_A:
14930 case DRX_STANDARD_ITU_B:
14931 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014932 switch (ext_attr->constellation) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014933 case DRX_CONSTELLATION_QAM256:
14934 case DRX_CONSTELLATION_QAM128:
14935 case DRX_CONSTELLATION_QAM32:
14936 case DRX_CONSTELLATION_QAM16:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014937 iqm_cf_gain = 57;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014938 break;
14939 case DRX_CONSTELLATION_QAM64:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014940 iqm_cf_gain = 56;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014941 break;
14942 default:
14943 return (DRX_STS_ERROR);
14944 }
14945 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014946#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014947 default:
14948 return (DRX_STS_INVALID_ARG);
14949 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014950
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014951 RR16(dev_addr, IQM_CF_POW__A, &iqm_cf_power);
14952 RR16(dev_addr, IQM_CF_SCALE_SH__A, &iqm_cf_scale_sh);
14953 RR16(dev_addr, IQM_CF_AMP__A, &iqm_cf_amp);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014954 /* IQM_CF_PWR_CORRECTION_dB = 3;
14955 P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
14956 /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
14957 -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
14958 +6*7+10*log10(1+0.115/4); */
14959 /* PadcdB = P4dB +3 -6 +60; dBmV */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014960 *agc_internal = (u16) (log1_times100(iqm_cf_power)
14961 - 2 * log1_times100(iqm_cf_amp)
14962 - iqm_cf_gain - 120 * iqm_cf_scale_sh + 781);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014963
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014964 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014965rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014966 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014967}
14968
14969/*============================================================================*/
14970
14971/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014972* \fn int ctrl_set_cfg_pre_saw()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014973* \brief Set Pre-saw reference.
14974* \param demod demod instance
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030014975* \param u16 *
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014976* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014977*
14978* Check arguments
14979* Dispatch handling to standard specific function.
14980*
14981*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030014982static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014983ctrl_set_cfg_pre_saw(pdrx_demod_instance_t demod, p_drxj_cfg_pre_saw_t pre_saw)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014984{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014985 struct i2c_device_addr *dev_addr = NULL;
14986 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014987
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014988 dev_addr = demod->my_i2c_dev_addr;
14989 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014990
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014991 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014992 if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014993 ) {
14994 return (DRX_STS_INVALID_ARG);
14995 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030014996
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030014997 /* Only if standard is currently active */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030014998 if ((ext_attr->standard == pre_saw->standard) ||
14999 (DRXJ_ISQAMSTD(ext_attr->standard) &&
15000 DRXJ_ISQAMSTD(pre_saw->standard)) ||
15001 (DRXJ_ISATVSTD(ext_attr->standard) &&
15002 DRXJ_ISATVSTD(pre_saw->standard))) {
15003 WR16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015004 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015005
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015006 /* Store pre-saw settings */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015007 switch (pre_saw->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015008 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015009 ext_attr->vsb_pre_saw_cfg = *pre_saw;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015010 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015011#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015012 case DRX_STANDARD_ITU_A: /* fallthrough */
15013 case DRX_STANDARD_ITU_B: /* fallthrough */
15014 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015015 ext_attr->qam_pre_saw_cfg = *pre_saw;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015016 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015017#endif
15018#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015019 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
15020 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
15021 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
15022 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
15023 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
15024 case DRX_STANDARD_NTSC: /* fallthrough */
15025 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015026 ext_attr->atv_pre_saw_cfg = *pre_saw;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015027 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015028#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015029 default:
15030 return (DRX_STS_INVALID_ARG);
15031 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015032
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015033 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015034rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015035 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015036}
15037
15038/*============================================================================*/
15039
15040/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015041* \fn int ctrl_set_cfg_afe_gain()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015042* \brief Set AFE Gain.
15043* \param demod demod instance
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030015044* \param u16 *
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015045* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015046*
15047* Check arguments
15048* Dispatch handling to standard specific function.
15049*
15050*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015051static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015052ctrl_set_cfg_afe_gain(pdrx_demod_instance_t demod, p_drxj_cfg_afe_gain_t afe_gain)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015053{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015054 struct i2c_device_addr *dev_addr = NULL;
15055 pdrxj_data_t ext_attr = NULL;
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030015056 u8 gain = 0;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015057
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015058 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015059 if (afe_gain == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015060 return (DRX_STS_INVALID_ARG);
15061 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015062
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015063 dev_addr = demod->my_i2c_dev_addr;
15064 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015065
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015066 switch (afe_gain->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015067 case DRX_STANDARD_8VSB: /* fallthrough */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015068#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015069 case DRX_STANDARD_ITU_A: /* fallthrough */
15070 case DRX_STANDARD_ITU_B: /* fallthrough */
15071 case DRX_STANDARD_ITU_C:
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015072#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015073 /* Do nothing */
15074 break;
15075 default:
15076 return (DRX_STS_INVALID_ARG);
15077 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015078
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015079 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015080 So I (PJ) think interface requires choice between auto, user mode */
15081
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015082 if (afe_gain->gain >= 329)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015083 gain = 15;
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015084 else if (afe_gain->gain <= 147)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015085 gain = 0;
15086 else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015087 gain = (afe_gain->gain - 140 + 6) / 13;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015088
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015089 /* Only if standard is currently active */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015090 if (ext_attr->standard == afe_gain->standard)
15091 WR16(dev_addr, IQM_AF_PGA_GAIN__A, gain);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015092
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015093 /* Store AFE Gain settings */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015094 switch (afe_gain->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015095 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015096 ext_attr->vsb_pga_cfg = gain * 13 + 140;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015097 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015098#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015099 case DRX_STANDARD_ITU_A: /* fallthrough */
15100 case DRX_STANDARD_ITU_B: /* fallthrough */
15101 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015102 ext_attr->qam_pga_cfg = gain * 13 + 140;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015103 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015104#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015105 default:
15106 return (DRX_STS_ERROR);
15107 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015108
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015109 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015110rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015111 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015112}
15113
15114/*============================================================================*/
15115
15116/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015117* \fn int ctrl_get_cfg_pre_saw()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015118* \brief Get Pre-saw reference setting.
15119* \param demod demod instance
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030015120* \param u16 *
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015121* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015122*
15123* Check arguments
15124* Dispatch handling to standard specific function.
15125*
15126*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015127static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015128ctrl_get_cfg_pre_saw(pdrx_demod_instance_t demod, p_drxj_cfg_pre_saw_t pre_saw)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015129{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015130 struct i2c_device_addr *dev_addr = NULL;
15131 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015132
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015133 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015134 if (pre_saw == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015135 return (DRX_STS_INVALID_ARG);
15136 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015137
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015138 dev_addr = demod->my_i2c_dev_addr;
15139 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015140
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015141 switch (pre_saw->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015142 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015143 *pre_saw = ext_attr->vsb_pre_saw_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015144 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015145#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015146 case DRX_STANDARD_ITU_A: /* fallthrough */
15147 case DRX_STANDARD_ITU_B: /* fallthrough */
15148 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015149 *pre_saw = ext_attr->qam_pre_saw_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015150 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015151#endif
15152#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015153 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
15154 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
15155 case DRX_STANDARD_PAL_SECAM_I: /* fallthrough */
15156 case DRX_STANDARD_PAL_SECAM_L: /* fallthrough */
15157 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
15158 case DRX_STANDARD_NTSC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015159 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
15160 *pre_saw = ext_attr->atv_pre_saw_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015161 break;
15162 case DRX_STANDARD_FM:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015163 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_FM;
15164 *pre_saw = ext_attr->atv_pre_saw_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015165 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015166#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015167 default:
15168 return (DRX_STS_INVALID_ARG);
15169 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015170
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015171 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015172}
15173
15174/*============================================================================*/
15175
15176/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015177* \fn int ctrl_get_cfg_afe_gain()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015178* \brief Get AFE Gain.
15179* \param demod demod instance
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030015180* \param u16 *
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015181* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015182*
15183* Check arguments
15184* Dispatch handling to standard specific function.
15185*
15186*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015187static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015188ctrl_get_cfg_afe_gain(pdrx_demod_instance_t demod, p_drxj_cfg_afe_gain_t afe_gain)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015189{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015190 struct i2c_device_addr *dev_addr = NULL;
15191 pdrxj_data_t ext_attr = NULL;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015192
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015193 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015194 if (afe_gain == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015195 return (DRX_STS_INVALID_ARG);
15196 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015197
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015198 dev_addr = demod->my_i2c_dev_addr;
15199 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015200
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015201 switch (afe_gain->standard) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015202 case DRX_STANDARD_8VSB:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015203 afe_gain->gain = ext_attr->vsb_pga_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015204 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015205#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015206 case DRX_STANDARD_ITU_A: /* fallthrough */
15207 case DRX_STANDARD_ITU_B: /* fallthrough */
15208 case DRX_STANDARD_ITU_C:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015209 afe_gain->gain = ext_attr->qam_pga_cfg;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015210 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015211#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015212 default:
15213 return (DRX_STS_INVALID_ARG);
15214 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015215
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015216 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015217}
15218
15219/*============================================================================*/
15220
15221/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015222* \fn int ctrl_get_fec_meas_seq_count()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015223* \brief Get FEC measurement sequnce number.
15224* \param demod demod instance
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030015225* \param u16 *
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015226* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015227*
15228* Check arguments
15229* Dispatch handling to standard specific function.
15230*
15231*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015232static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015233ctrl_get_fec_meas_seq_count(pdrx_demod_instance_t demod, u16 *fec_meas_seq_count)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015234{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015235 /* check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015236 if (fec_meas_seq_count == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015237 return (DRX_STS_INVALID_ARG);
15238 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015239
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015240 RR16(demod->my_i2c_dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, fec_meas_seq_count);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015241
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015242 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015243rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015244 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015245}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015246
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015247/*============================================================================*/
15248
15249/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015250* \fn int ctrl_get_accum_cr_rs_cw_err()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015251* \brief Get accumulative corrected RS codeword number.
15252* \param demod demod instance
Mauro Carvalho Chehab43a431e2012-03-20 00:49:45 -030015253* \param u32 *
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015254* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015255*
15256* Check arguments
15257* Dispatch handling to standard specific function.
15258*
15259*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015260static int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015261ctrl_get_accum_cr_rs_cw_err(pdrx_demod_instance_t demod, u32 *accum_cr_rs_cw_err)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015262{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015263 if (accum_cr_rs_cw_err == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015264 return (DRX_STS_INVALID_ARG);
15265 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015266
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015267 RR32(demod->my_i2c_dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A,
15268 accum_cr_rs_cw_err);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015269
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015270 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015271rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015272 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015273}
15274
15275/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015276* \fn int ctrl_set_cfg()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015277* \brief Set 'some' configuration of the device.
15278* \param devmod Pointer to demodulator instance.
15279* \param config Pointer to configuration parameters (type and data).
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015280* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015281
15282*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015283static int ctrl_set_cfg(pdrx_demod_instance_t demod, pdrx_cfg_t config)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015284{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015285 if (config == NULL) {
15286 return (DRX_STS_INVALID_ARG);
15287 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015288
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015289 DUMMY_READ();
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015290 switch (config->cfg_type) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015291 case DRX_CFG_MPEG_OUTPUT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015292 return ctrl_set_cfg_mpeg_output(demod,
15293 (pdrx_cfg_mpeg_output_t) config->
15294 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015295 case DRX_CFG_PINS_SAFE_MODE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015296 return ctrl_set_cfg_pdr_safe_mode(demod, (bool *) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015297 case DRXJ_CFG_AGC_RF:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015298 return ctrl_set_cfg_agc_rf(demod, (p_drxj_cfg_agc_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015299 case DRXJ_CFG_AGC_IF:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015300 return ctrl_set_cfg_agc_if(demod, (p_drxj_cfg_agc_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015301 case DRXJ_CFG_PRE_SAW:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015302 return ctrl_set_cfg_pre_saw(demod,
15303 (p_drxj_cfg_pre_saw_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015304 case DRXJ_CFG_AFE_GAIN:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015305 return ctrl_set_cfg_afe_gain(demod,
15306 (p_drxj_cfg_afe_gain_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015307 case DRXJ_CFG_SMART_ANT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015308 return ctrl_set_cfg_smart_ant(demod,
15309 (p_drxj_cfg_smart_ant_t) (config->
15310 cfg_data));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015311 case DRXJ_CFG_RESET_PACKET_ERR:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015312 return ctrl_set_cfg_reset_pkt_err(demod);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015313#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015314 case DRXJ_CFG_OOB_PRE_SAW:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015315 return ctrl_set_cfg_oob_pre_saw(demod, (u16 *) (config->cfg_data));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015316 case DRXJ_CFG_OOB_LO_POW:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015317 return ctrl_set_cfg_oob_lo_power(demod,
15318 (p_drxj_cfg_oob_lo_power_t) (config->
15319 cfg_data));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015320 case DRXJ_CFG_ATV_MISC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015321 return ctrl_set_cfg_atv_misc(demod,
15322 (p_drxj_cfg_atv_misc_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015323 case DRXJ_CFG_ATV_EQU_COEF:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015324 return ctrl_set_cfg_atv_equ_coef(demod,
15325 (p_drxj_cfg_atv_equ_coef_t) config->
15326 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015327 case DRXJ_CFG_ATV_OUTPUT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015328 return ctrl_set_cfg_atv_output(demod,
15329 (p_drxj_cfg_atv_output_t) config->
15330 cfg_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015331#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015332 case DRXJ_CFG_MPEG_OUTPUT_MISC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015333 return ctrl_set_cfg_mpeg_output_misc(demod,
15334 (p_drxj_cfg_mpeg_output_misc_t)
15335 config->cfg_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015336#ifndef DRXJ_EXCLUDE_AUDIO
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015337 case DRX_CFG_AUD_VOLUME:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015338 return aud_ctrl_set_cfg_volume(demod,
15339 (pdrx_cfg_aud_volume_t) config->
15340 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015341 case DRX_CFG_I2S_OUTPUT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015342 return aud_ctrl_set_cfg_output_i2s(demod,
15343 (pdrx_cfg_i2s_output_t) config->
15344 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015345 case DRX_CFG_AUD_AUTOSOUND:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015346 return aud_ctr_setl_cfg_auto_sound(demod, (pdrx_cfg_aud_auto_sound_t)
15347 config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015348 case DRX_CFG_AUD_ASS_THRES:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015349 return aud_ctrl_set_cfg_ass_thres(demod, (pdrx_cfg_aud_ass_thres_t)
15350 config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015351 case DRX_CFG_AUD_CARRIER:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015352 return aud_ctrl_set_cfg_carrier(demod,
15353 (pdrx_cfg_aud_carriers_t) config->
15354 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015355 case DRX_CFG_AUD_DEVIATION:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015356 return aud_ctrl_set_cfg_dev(demod,
15357 (pdrx_cfg_aud_deviation_t) config->
15358 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015359 case DRX_CFG_AUD_PRESCALE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015360 return aud_ctrl_set_cfg_prescale(demod,
15361 (pdrx_cfg_aud_prescale_t) config->
15362 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015363 case DRX_CFG_AUD_MIXER:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015364 return aud_ctrl_set_cfg_mixer(demod,
15365 (pdrx_cfg_aud_mixer_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015366 case DRX_CFG_AUD_AVSYNC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015367 return aud_ctrl_set_cfg_av_sync(demod,
15368 (pdrx_cfg_aud_av_sync_t) config->
15369 cfg_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015370
15371#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015372 default:
15373 return (DRX_STS_INVALID_ARG);
15374 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015375
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015376 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015377rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015378 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015379}
15380
15381/*============================================================================*/
15382
15383/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015384* \fn int ctrl_get_cfg()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015385* \brief Get 'some' configuration of the device.
15386* \param devmod Pointer to demodulator instance.
15387* \param config Pointer to configuration parameters (type and data).
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015388* \return int.
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015389*/
15390
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015391static int ctrl_get_cfg(pdrx_demod_instance_t demod, pdrx_cfg_t config)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015392{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015393 if (config == NULL) {
15394 return (DRX_STS_INVALID_ARG);
15395 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015396
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015397 DUMMY_READ();
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015398
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015399 switch (config->cfg_type) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015400 case DRX_CFG_MPEG_OUTPUT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015401 return ctrl_get_cfg_mpeg_output(demod,
15402 (pdrx_cfg_mpeg_output_t) config->
15403 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015404 case DRX_CFG_PINS_SAFE_MODE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015405 return ctrl_get_cfg_pdr_safe_mode(demod, (bool *) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015406 case DRXJ_CFG_AGC_RF:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015407 return ctrl_get_cfg_agc_rf(demod, (p_drxj_cfg_agc_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015408 case DRXJ_CFG_AGC_IF:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015409 return ctrl_get_cfg_agc_if(demod, (p_drxj_cfg_agc_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015410 case DRXJ_CFG_AGC_INTERNAL:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015411 return ctrl_get_cfg_agc_internal(demod, (u16 *) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015412 case DRXJ_CFG_PRE_SAW:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015413 return ctrl_get_cfg_pre_saw(demod,
15414 (p_drxj_cfg_pre_saw_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015415 case DRXJ_CFG_AFE_GAIN:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015416 return ctrl_get_cfg_afe_gain(demod,
15417 (p_drxj_cfg_afe_gain_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015418 case DRXJ_CFG_ACCUM_CR_RS_CW_ERR:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015419 return ctrl_get_accum_cr_rs_cw_err(demod, (u32 *) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015420 case DRXJ_CFG_FEC_MERS_SEQ_COUNT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015421 return ctrl_get_fec_meas_seq_count(demod, (u16 *) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015422 case DRXJ_CFG_VSB_MISC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015423 return ctrl_get_cfg_vsb_misc(demod,
15424 (p_drxj_cfg_vsb_misc_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015425 case DRXJ_CFG_SYMBOL_CLK_OFFSET:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015426 return ctrl_get_cfg_symbol_clock_offset(demod,
15427 (s32 *) config->cfg_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015428#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015429 case DRXJ_CFG_OOB_MISC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015430 return ctrl_get_cfg_oob_misc(demod,
15431 (p_drxj_cfg_oob_misc_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015432 case DRXJ_CFG_OOB_PRE_SAW:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015433 return ctrl_get_cfg_oob_pre_saw(demod, (u16 *) (config->cfg_data));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015434 case DRXJ_CFG_OOB_LO_POW:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015435 return ctrl_get_cfg_oob_lo_power(demod,
15436 (p_drxj_cfg_oob_lo_power_t) (config->
15437 cfg_data));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015438 case DRXJ_CFG_ATV_EQU_COEF:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015439 return ctrl_get_cfg_atv_equ_coef(demod,
15440 (p_drxj_cfg_atv_equ_coef_t) config->
15441 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015442 case DRXJ_CFG_ATV_MISC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015443 return ctrl_get_cfg_atv_misc(demod,
15444 (p_drxj_cfg_atv_misc_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015445 case DRXJ_CFG_ATV_OUTPUT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015446 return ctrl_get_cfg_atv_output(demod,
15447 (p_drxj_cfg_atv_output_t) config->
15448 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015449 case DRXJ_CFG_ATV_AGC_STATUS:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015450 return ctrl_get_cfg_atv_agc_status(demod,
15451 (p_drxj_cfg_atv_agc_status_t) config->
15452 cfg_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015453#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015454 case DRXJ_CFG_MPEG_OUTPUT_MISC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015455 return ctrl_get_cfg_mpeg_output_misc(demod,
15456 (p_drxj_cfg_mpeg_output_misc_t)
15457 config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015458 case DRXJ_CFG_HW_CFG:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015459 return ctrl_get_cfg_hw_cfg(demod,
15460 (p_drxj_cfg_hw_cfg_t) config->cfg_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015461#ifndef DRXJ_EXCLUDE_AUDIO
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015462 case DRX_CFG_AUD_VOLUME:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015463 return aud_ctrl_get_cfg_volume(demod,
15464 (pdrx_cfg_aud_volume_t) config->
15465 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015466 case DRX_CFG_I2S_OUTPUT:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015467 return aud_ctrl_get_cfg_output_i2s(demod,
15468 (pdrx_cfg_i2s_output_t) config->
15469 cfg_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015470
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015471 case DRX_CFG_AUD_RDS:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015472 return aud_ctrl_get_cfg_rds(demod,
15473 (pdrx_cfg_aud_rds_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015474 case DRX_CFG_AUD_AUTOSOUND:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015475 return aud_ctrl_get_cfg_auto_sound(demod,
15476 (pdrx_cfg_aud_auto_sound_t) config->
15477 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015478 case DRX_CFG_AUD_ASS_THRES:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015479 return aud_ctrl_get_cfg_ass_thres(demod,
15480 (pdrx_cfg_aud_ass_thres_t) config->
15481 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015482 case DRX_CFG_AUD_CARRIER:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015483 return aud_ctrl_get_cfg_carrier(demod,
15484 (pdrx_cfg_aud_carriers_t) config->
15485 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015486 case DRX_CFG_AUD_DEVIATION:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015487 return aud_ctrl_get_cfg_dev(demod,
15488 (pdrx_cfg_aud_deviation_t) config->
15489 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015490 case DRX_CFG_AUD_PRESCALE:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015491 return aud_ctrl_get_cfg_prescale(demod,
15492 (pdrx_cfg_aud_prescale_t) config->
15493 cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015494 case DRX_CFG_AUD_MIXER:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015495 return aud_ctrl_get_cfg_mixer(demod,
15496 (pdrx_cfg_aud_mixer_t) config->cfg_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015497 case DRX_CFG_AUD_AVSYNC:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015498 return aud_ctrl_get_cfg_av_sync(demod,
15499 (pdrx_cfg_aud_av_sync_t) config->
15500 cfg_data);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015501#endif
15502
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015503 default:
15504 return (DRX_STS_INVALID_ARG);
15505 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015506
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015507 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015508rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015509 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015510}
15511
15512/*=============================================================================
15513===== EXPORTED FUNCTIONS ====================================================*/
15514/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015515* \fn drxj_open()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015516* \brief Open the demod instance, configure device, configure drxdriver
15517* \return Status_t Return status.
15518*
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015519* drxj_open() can be called with a NULL ucode image => no ucode upload.
15520* This means that drxj_open() must NOT contain SCU commands or, in general,
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015521* rely on SCU or AUD ucode to be present.
15522*
15523*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015524int drxj_open(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015525{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015526 struct i2c_device_addr *dev_addr = NULL;
15527 pdrxj_data_t ext_attr = NULL;
15528 pdrx_common_attr_t common_attr = NULL;
15529 u32 driver_version = 0;
15530 drxu_code_info_t ucode_info;
15531 drx_cfg_mpeg_output_t cfg_mpeg_output;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015532
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015533 /* Check arguments */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015534 if (demod->my_ext_attr == NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015535 return (DRX_STS_INVALID_ARG);
15536 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015537
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015538 dev_addr = demod->my_i2c_dev_addr;
15539 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
15540 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015541
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015542 CHK_ERROR(power_up_device(demod));
15543 common_attr->current_power_mode = DRX_POWER_UP;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015544
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015545 /* has to be in front of setIqmAf and setOrxNsuAox */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015546 CHK_ERROR(get_device_capabilities(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015547
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015548 /* Soft reset of sys- and osc-clockdomain */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015549 WR16(dev_addr, SIO_CC_SOFT_RST__A, (SIO_CC_SOFT_RST_SYS__M |
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015550 SIO_CC_SOFT_RST_OSC__M));
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015551 WR16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
15552 CHK_ERROR(drxbsp_hst_sleep(1));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015553
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015554 /* TODO first make sure that everything keeps working before enabling this */
15555 /* PowerDownAnalogBlocks() */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015556 WR16(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015557 | ATV_TOP_STDBY_SIF_STDBY_STANDBY);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015558
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015559 CHK_ERROR(set_iqm_af(demod, false));
15560 CHK_ERROR(set_orx_nsu_aox(demod, false));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015561
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015562 CHK_ERROR(init_hi(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015563
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015564 /* disable mpegoutput pins */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015565 cfg_mpeg_output.enable_mpeg_output = false;
15566 CHK_ERROR(ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015567 /* Stop AUD Inform SetAudio it will need to do all setting */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015568 CHK_ERROR(power_down_aud(demod));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015569 /* Stop SCU */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015570 WR16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015571
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015572 /* Upload microcode */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015573 if (common_attr->microcode != NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015574 /* Dirty trick to use common ucode upload & verify,
15575 pretend device is already open */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015576 common_attr->is_opened = true;
15577 ucode_info.mc_data = common_attr->microcode;
15578 ucode_info.mc_size = common_attr->microcode_size;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015579
15580#ifdef DRXJ_SPLIT_UCODE_UPLOAD
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015581 /* Upload microcode without audio part */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015582 CHK_ERROR(ctrl_u_codeUpload
15583 (demod, &ucode_info, UCODE_UPLOAD, false));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015584#else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015585 CHK_ERROR(drx_ctrl(demod, DRX_CTRL_LOAD_UCODE, &ucode_info));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015586#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015587 if (common_attr->verify_microcode == true) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015588#ifdef DRXJ_SPLIT_UCODE_UPLOAD
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015589 CHK_ERROR(ctrl_u_codeUpload
15590 (demod, &ucode_info, UCODE_VERIFY, false));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015591#else
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015592 CHK_ERROR(drx_ctrl
15593 (demod, DRX_CTRL_VERIFY_UCODE, &ucode_info));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015594#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015595 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015596 common_attr->is_opened = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015597 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015598
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015599 /* Run SCU for a little while to initialize microcode version numbers */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015600 WR16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015601
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015602 /* Open tuner instance */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015603 if (demod->my_tuner != NULL) {
15604 demod->my_tuner->my_common_attr->myUser_data = (void *)demod;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015605
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015606 if (common_attr->tuner_port_nr == 1) {
15607 bool bridge_closed = true;
15608 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_closed));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015609 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015610
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015611 CHK_ERROR(drxbsp_tuner_open(demod->my_tuner));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015612
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015613 if (common_attr->tuner_port_nr == 1) {
15614 bool bridge_closed = false;
15615 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_closed));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015616 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015617 common_attr->tuner_min_freq_rf =
15618 ((demod->my_tuner)->my_common_attr->min_freq_rf);
15619 common_attr->tuner_max_freq_rf =
15620 ((demod->my_tuner)->my_common_attr->max_freq_rf);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015621 }
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015622
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015623 /* Initialize scan timeout */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015624 common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
15625 common_attr->scan_desired_lock = DRX_LOCKED;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015626
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015627 /* Initialize default AFE configuartion for QAM */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015628 if (ext_attr->has_lna) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015629 /* IF AGC off, PGA active */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015630#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015631 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
15632 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
15633 ext_attr->qam_pga_cfg = 140 + (11 * 13);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015634#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015635 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
15636 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
15637 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015638 } else {
15639 /* IF AGC on, PGA not active */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015640#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015641 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
15642 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
15643 ext_attr->qam_if_agc_cfg.min_output_level = 0;
15644 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
15645 ext_attr->qam_if_agc_cfg.speed = 3;
15646 ext_attr->qam_if_agc_cfg.top = 1297;
15647 ext_attr->qam_pga_cfg = 140;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015648#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015649 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
15650 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
15651 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
15652 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
15653 ext_attr->vsb_if_agc_cfg.speed = 3;
15654 ext_attr->vsb_if_agc_cfg.top = 1024;
15655 ext_attr->vsb_pga_cfg = 140;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015656 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015657 /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015658 /* mc has not used them */
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015659#ifndef DRXJ_VSB_ONLY
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015660 ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
15661 ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
15662 ext_attr->qam_rf_agc_cfg.min_output_level = 0;
15663 ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
15664 ext_attr->qam_rf_agc_cfg.speed = 3;
15665 ext_attr->qam_rf_agc_cfg.top = 9500;
15666 ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
15667 ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
15668 ext_attr->qam_pre_saw_cfg.reference = 0x07;
15669 ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015670#endif
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015671 /* Initialize default AFE configuartion for VSB */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015672 ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
15673 ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
15674 ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
15675 ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
15676 ext_attr->vsb_rf_agc_cfg.speed = 3;
15677 ext_attr->vsb_rf_agc_cfg.top = 9500;
15678 ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
15679 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
15680 ext_attr->vsb_pre_saw_cfg.reference = 0x07;
15681 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015682
15683#ifndef DRXJ_DIGITAL_ONLY
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015684 /* Initialize default AFE configuartion for ATV */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015685 ext_attr->atv_rf_agc_cfg.standard = DRX_STANDARD_NTSC;
15686 ext_attr->atv_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
15687 ext_attr->atv_rf_agc_cfg.top = 9500;
15688 ext_attr->atv_rf_agc_cfg.cut_off_current = 4000;
15689 ext_attr->atv_rf_agc_cfg.speed = 3;
15690 ext_attr->atv_if_agc_cfg.standard = DRX_STANDARD_NTSC;
15691 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
15692 ext_attr->atv_if_agc_cfg.speed = 3;
15693 ext_attr->atv_if_agc_cfg.top = 2400;
15694 ext_attr->atv_pre_saw_cfg.reference = 0x0007;
15695 ext_attr->atv_pre_saw_cfg.use_pre_saw = true;
15696 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015697#endif
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015698 ext_attr->standard = DRX_STANDARD_UNKNOWN;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015699
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015700 CHK_ERROR(smart_ant_init(demod));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015701
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015702 /* Stamp driver version number in SCU data RAM in BCD code
15703 Done to enable field application engineers to retreive drxdriver version
15704 via I2C from SCU RAM
15705 */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015706 driver_version = (VERSION_MAJOR / 100) % 10;
15707 driver_version <<= 4;
15708 driver_version += (VERSION_MAJOR / 10) % 10;
15709 driver_version <<= 4;
15710 driver_version += (VERSION_MAJOR % 10);
15711 driver_version <<= 4;
15712 driver_version += (VERSION_MINOR % 10);
15713 driver_version <<= 4;
15714 driver_version += (VERSION_PATCH / 1000) % 10;
15715 driver_version <<= 4;
15716 driver_version += (VERSION_PATCH / 100) % 10;
15717 driver_version <<= 4;
15718 driver_version += (VERSION_PATCH / 10) % 10;
15719 driver_version <<= 4;
15720 driver_version += (VERSION_PATCH % 10);
15721 WR16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16) (driver_version >> 16));
15722 WR16(dev_addr, SCU_RAM_DRIVER_VER_LO__A,
15723 (u16) (driver_version & 0xFFFF));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015724
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015725 /* refresh the audio data structure with default */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015726 ext_attr->aud_data = drxj_default_aud_data_g;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015727
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015728 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015729rw_error:
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015730 common_attr->is_opened = false;
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015731 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015732}
15733
15734/*============================================================================*/
15735/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015736* \fn drxj_close()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015737* \brief Close the demod instance, power down the device
15738* \return Status_t Return status.
15739*
15740*/
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015741int drxj_close(pdrx_demod_instance_t demod)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015742{
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015743 struct i2c_device_addr *dev_addr = NULL;
15744 pdrxj_data_t ext_attr = NULL;
15745 pdrx_common_attr_t common_attr = NULL;
15746 drx_power_mode_t power_mode = DRX_POWER_UP;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015747
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015748 common_attr = (pdrx_common_attr_t) demod->my_common_attr;
15749 dev_addr = demod->my_i2c_dev_addr;
15750 ext_attr = (pdrxj_data_t) demod->my_ext_attr;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015751
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015752 /* power up */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015753 CHK_ERROR(ctrl_power_mode(demod, &power_mode));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015754
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015755 if (demod->my_tuner != NULL) {
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015756 /* Check if bridge is used */
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015757 if (common_attr->tuner_port_nr == 1) {
15758 bool bridge_closed = true;
15759 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_closed));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015760 }
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015761 CHK_ERROR(drxbsp_tuner_close(demod->my_tuner));
15762 if (common_attr->tuner_port_nr == 1) {
15763 bool bridge_closed = false;
15764 CHK_ERROR(ctrl_i2c_bridge(demod, &bridge_closed));
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015765 }
15766 };
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015767
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015768 WR16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
15769 power_mode = DRX_POWER_DOWN;
15770 CHK_ERROR(ctrl_power_mode(demod, &power_mode));
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015771
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015772 return DRX_STS_OK;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015773rw_error:
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015774 return (DRX_STS_ERROR);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015775}
15776
15777/*============================================================================*/
15778/**
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015779* \fn drxj_ctrl()
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015780* \brief DRXJ specific control function
15781* \return Status_t Return status.
15782*/
Mauro Carvalho Chehab61263c72012-03-20 01:18:02 -030015783int
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015784drxj_ctrl(pdrx_demod_instance_t demod, u32 ctrl, void *ctrl_data)
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015785{
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015786 switch (ctrl) {
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015787 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015788 case DRX_CTRL_SET_CHANNEL:
15789 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015790 return ctrl_set_channel(demod, (pdrx_channel_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015791 }
15792 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015793 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015794 case DRX_CTRL_GET_CHANNEL:
15795 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015796 return ctrl_get_channel(demod, (pdrx_channel_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015797 }
15798 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015799 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015800 case DRX_CTRL_SIG_QUALITY:
15801 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015802 return ctrl_sig_quality(demod,
15803 (pdrx_sig_quality_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015804 }
15805 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015806 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015807 case DRX_CTRL_SIG_STRENGTH:
15808 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015809 return ctrl_sig_strength(demod, (u16 *) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015810 }
15811 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015812 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015813 case DRX_CTRL_CONSTEL:
15814 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015815 return ctrl_constel(demod, (pdrx_complex_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015816 }
15817 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015818 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015819 case DRX_CTRL_SET_CFG:
15820 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015821 return ctrl_set_cfg(demod, (pdrx_cfg_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015822 }
15823 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015824 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015825 case DRX_CTRL_GET_CFG:
15826 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015827 return ctrl_get_cfg(demod, (pdrx_cfg_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015828 }
15829 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015830 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015831 case DRX_CTRL_I2C_BRIDGE:
15832 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015833 return ctrl_i2c_bridge(demod, (bool *) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015834 }
15835 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015836 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015837 case DRX_CTRL_LOCK_STATUS:
15838 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015839 return ctrl_lock_status(demod,
15840 (pdrx_lock_status_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015841 }
15842 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015843 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015844 case DRX_CTRL_SET_STANDARD:
15845 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015846 return ctrl_set_standard(demod,
15847 (enum drx_standard *) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015848 }
15849 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015850 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015851 case DRX_CTRL_GET_STANDARD:
15852 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015853 return ctrl_get_standard(demod,
15854 (enum drx_standard *) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015855 }
15856 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015857 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015858 case DRX_CTRL_POWER_MODE:
15859 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015860 return ctrl_power_mode(demod, (pdrx_power_mode_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015861 }
15862 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015863 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015864 case DRX_CTRL_VERSION:
15865 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015866 return ctrl_version(demod,
15867 (p_drx_version_list_t *) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015868 }
15869 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015870 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015871 case DRX_CTRL_PROBE_DEVICE:
15872 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015873 return ctrl_probe_device(demod);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015874 }
15875 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015876 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015877 case DRX_CTRL_SET_OOB:
15878 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015879 return ctrl_set_oob(demod, (p_drxoob_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015880 }
15881 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015882 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015883 case DRX_CTRL_GET_OOB:
15884 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015885 return ctrl_get_oob(demod, (pdrxoob_status_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015886 }
15887 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015888 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015889 case DRX_CTRL_SET_UIO_CFG:
15890 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015891 return ctrl_set_uio_cfg(demod, (pdrxuio_cfg_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015892 }
15893 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015894 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015895 case DRX_CTRL_GET_UIO_CFG:
15896 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015897 return CtrlGetuio_cfg(demod, (pdrxuio_cfg_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015898 }
15899 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015900 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015901 case DRX_CTRL_UIO_READ:
15902 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015903 return ctrl_uio_read(demod, (pdrxuio_data_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015904 }
15905 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015906 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015907 case DRX_CTRL_UIO_WRITE:
15908 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015909 return ctrl_uio_write(demod, (pdrxuio_data_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015910 }
15911 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015912 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015913 case DRX_CTRL_AUD_SET_STANDARD:
15914 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015915 return aud_ctrl_set_standard(demod,
15916 (pdrx_aud_standard_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015917 }
15918 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015919 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015920 case DRX_CTRL_AUD_GET_STANDARD:
15921 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015922 return aud_ctrl_get_standard(demod,
15923 (pdrx_aud_standard_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015924 }
15925 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015926 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015927 case DRX_CTRL_AUD_GET_STATUS:
15928 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015929 return aud_ctrl_get_status(demod,
15930 (pdrx_aud_status_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015931 }
15932 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015933 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015934 case DRX_CTRL_AUD_BEEP:
15935 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015936 return aud_ctrl_beep(demod, (pdrx_aud_beep_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015937 }
15938 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015939
15940 /*======================================================================*/
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015941 case DRX_CTRL_I2C_READWRITE:
15942 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015943 return ctrl_i2c_write_read(demod,
15944 (pdrxi2c_data_t) ctrl_data);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015945 }
15946 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015947#ifdef DRXJ_SPLIT_UCODE_UPLOAD
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015948 case DRX_CTRL_LOAD_UCODE:
15949 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015950 return ctrl_u_codeUpload(demod,
15951 (p_drxu_code_info_t) ctrl_data,
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030015952 UCODE_UPLOAD, false);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015953 }
15954 break;
15955 case DRX_CTRL_VERIFY_UCODE:
15956 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015957 return ctrl_u_codeUpload(demod,
15958 (p_drxu_code_info_t) ctrl_data,
Mauro Carvalho Chehab73f70652012-03-20 00:59:03 -030015959 UCODE_VERIFY, false);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015960 }
15961 break;
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015962#endif /* DRXJ_SPLIT_UCODE_UPLOAD */
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015963 case DRX_CTRL_VALIDATE_UCODE:
15964 {
Mauro Carvalho Chehab57afe2f2014-01-16 11:24:57 -030015965 return ctrl_validate_u_code(demod);
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015966 }
15967 break;
15968 default:
15969 return (DRX_STS_FUNC_NOT_AVAILABLE);
15970 }
15971 return (DRX_STS_OK);
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015972}
Mauro Carvalho Chehab443f18d2012-03-20 00:00:42 -030015973
Devin Heitmueller38b2df92012-08-13 21:18:02 -030015974/* END OF FILE */