[media] drx-j: remove the useless microcode_size
[cascardo/linux.git] / drivers / media / dvb-frontends / drx39xyj / drxj.c
1 /*
2   Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
3   All rights reserved.
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions are met:
7
8   * Redistributions of source code must retain the above copyright notice,
9     this list of conditions and the following disclaimer.
10   * Redistributions in binary form must reproduce the above copyright notice,
11     this list of conditions and the following disclaimer in the documentation
12         and/or other materials provided with the distribution.
13   * Neither the name of Trident Microsystems nor Hauppauge Computer Works
14     nor the names of its contributors may be used to endorse or promote
15         products derived from this software without specific prior written
16         permission.
17
18   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28   POSSIBILITY OF SUCH DAMAGE.
29
30   DRXJ specific implementation of DRX driver
31   authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
32 */
33
34 /*-----------------------------------------------------------------------------
35 INCLUDE FILES
36 ----------------------------------------------------------------------------*/
37
38 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
39
40 #include "drxj.h"
41 #include "drxj_map.h"
42
43 /*============================================================================*/
44 /*=== DEFINES ================================================================*/
45 /*============================================================================*/
46
47 /**
48 * \brief Maximum u32 value.
49 */
50 #ifndef MAX_U32
51 #define MAX_U32  ((u32) (0xFFFFFFFFL))
52 #endif
53
54 /* Customer configurable hardware settings, etc */
55 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
56 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
57 #endif
58
59 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
60 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
61 #endif
62
63 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
64 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
65 #endif
66
67 #ifndef OOB_CRX_DRIVE_STRENGTH
68 #define OOB_CRX_DRIVE_STRENGTH 0x02
69 #endif
70
71 #ifndef OOB_DRX_DRIVE_STRENGTH
72 #define OOB_DRX_DRIVE_STRENGTH 0x02
73 #endif
74 /**** START DJCOMBO patches to DRXJ registermap constants *********************/
75 /**** registermap 200706071303 from drxj **************************************/
76 #define   ATV_TOP_CR_AMP_TH_FM                                              0x0
77 #define   ATV_TOP_CR_AMP_TH_L                                               0xA
78 #define   ATV_TOP_CR_AMP_TH_LP                                              0xA
79 #define   ATV_TOP_CR_AMP_TH_BG                                              0x8
80 #define   ATV_TOP_CR_AMP_TH_DK                                              0x8
81 #define   ATV_TOP_CR_AMP_TH_I                                               0x8
82 #define     ATV_TOP_CR_CONT_CR_D_MN                                         0x18
83 #define     ATV_TOP_CR_CONT_CR_D_FM                                         0x0
84 #define     ATV_TOP_CR_CONT_CR_D_L                                          0x20
85 #define     ATV_TOP_CR_CONT_CR_D_LP                                         0x20
86 #define     ATV_TOP_CR_CONT_CR_D_BG                                         0x18
87 #define     ATV_TOP_CR_CONT_CR_D_DK                                         0x18
88 #define     ATV_TOP_CR_CONT_CR_D_I                                          0x18
89 #define     ATV_TOP_CR_CONT_CR_I_MN                                         0x80
90 #define     ATV_TOP_CR_CONT_CR_I_FM                                         0x0
91 #define     ATV_TOP_CR_CONT_CR_I_L                                          0x80
92 #define     ATV_TOP_CR_CONT_CR_I_LP                                         0x80
93 #define     ATV_TOP_CR_CONT_CR_I_BG                                         0x80
94 #define     ATV_TOP_CR_CONT_CR_I_DK                                         0x80
95 #define     ATV_TOP_CR_CONT_CR_I_I                                          0x80
96 #define     ATV_TOP_CR_CONT_CR_P_MN                                         0x4
97 #define     ATV_TOP_CR_CONT_CR_P_FM                                         0x0
98 #define     ATV_TOP_CR_CONT_CR_P_L                                          0x4
99 #define     ATV_TOP_CR_CONT_CR_P_LP                                         0x4
100 #define     ATV_TOP_CR_CONT_CR_P_BG                                         0x4
101 #define     ATV_TOP_CR_CONT_CR_P_DK                                         0x4
102 #define     ATV_TOP_CR_CONT_CR_P_I                                          0x4
103 #define   ATV_TOP_CR_OVM_TH_MN                                              0xA0
104 #define   ATV_TOP_CR_OVM_TH_FM                                              0x0
105 #define   ATV_TOP_CR_OVM_TH_L                                               0xA0
106 #define   ATV_TOP_CR_OVM_TH_LP                                              0xA0
107 #define   ATV_TOP_CR_OVM_TH_BG                                              0xA0
108 #define   ATV_TOP_CR_OVM_TH_DK                                              0xA0
109 #define   ATV_TOP_CR_OVM_TH_I                                               0xA0
110 #define     ATV_TOP_EQU0_EQU_C0_FM                                          0x0
111 #define     ATV_TOP_EQU0_EQU_C0_L                                           0x3
112 #define     ATV_TOP_EQU0_EQU_C0_LP                                          0x3
113 #define     ATV_TOP_EQU0_EQU_C0_BG                                          0x7
114 #define     ATV_TOP_EQU0_EQU_C0_DK                                          0x0
115 #define     ATV_TOP_EQU0_EQU_C0_I                                           0x3
116 #define     ATV_TOP_EQU1_EQU_C1_FM                                          0x0
117 #define     ATV_TOP_EQU1_EQU_C1_L                                           0x1F6
118 #define     ATV_TOP_EQU1_EQU_C1_LP                                          0x1F6
119 #define     ATV_TOP_EQU1_EQU_C1_BG                                          0x197
120 #define     ATV_TOP_EQU1_EQU_C1_DK                                          0x198
121 #define     ATV_TOP_EQU1_EQU_C1_I                                           0x1F6
122 #define     ATV_TOP_EQU2_EQU_C2_FM                                          0x0
123 #define     ATV_TOP_EQU2_EQU_C2_L                                           0x28
124 #define     ATV_TOP_EQU2_EQU_C2_LP                                          0x28
125 #define     ATV_TOP_EQU2_EQU_C2_BG                                          0xC5
126 #define     ATV_TOP_EQU2_EQU_C2_DK                                          0xB0
127 #define     ATV_TOP_EQU2_EQU_C2_I                                           0x28
128 #define     ATV_TOP_EQU3_EQU_C3_FM                                          0x0
129 #define     ATV_TOP_EQU3_EQU_C3_L                                           0x192
130 #define     ATV_TOP_EQU3_EQU_C3_LP                                          0x192
131 #define     ATV_TOP_EQU3_EQU_C3_BG                                          0x12E
132 #define     ATV_TOP_EQU3_EQU_C3_DK                                          0x18E
133 #define     ATV_TOP_EQU3_EQU_C3_I                                           0x192
134 #define     ATV_TOP_STD_MODE_MN                                             0x0
135 #define     ATV_TOP_STD_MODE_FM                                             0x1
136 #define     ATV_TOP_STD_MODE_L                                              0x0
137 #define     ATV_TOP_STD_MODE_LP                                             0x0
138 #define     ATV_TOP_STD_MODE_BG                                             0x0
139 #define     ATV_TOP_STD_MODE_DK                                             0x0
140 #define     ATV_TOP_STD_MODE_I                                              0x0
141 #define     ATV_TOP_STD_VID_POL_MN                                          0x0
142 #define     ATV_TOP_STD_VID_POL_FM                                          0x0
143 #define     ATV_TOP_STD_VID_POL_L                                           0x2
144 #define     ATV_TOP_STD_VID_POL_LP                                          0x2
145 #define     ATV_TOP_STD_VID_POL_BG                                          0x0
146 #define     ATV_TOP_STD_VID_POL_DK                                          0x0
147 #define     ATV_TOP_STD_VID_POL_I                                           0x0
148 #define   ATV_TOP_VID_AMP_MN                                                0x380
149 #define   ATV_TOP_VID_AMP_FM                                                0x0
150 #define   ATV_TOP_VID_AMP_L                                                 0xF50
151 #define   ATV_TOP_VID_AMP_LP                                                0xF50
152 #define   ATV_TOP_VID_AMP_BG                                                0x380
153 #define   ATV_TOP_VID_AMP_DK                                                0x394
154 #define   ATV_TOP_VID_AMP_I                                                 0x3D8
155 #define   IQM_CF_OUT_ENA_OFDM__M                                            0x4
156 #define     IQM_FS_ADJ_SEL_B_QAM                                            0x1
157 #define     IQM_FS_ADJ_SEL_B_OFF                                            0x0
158 #define     IQM_FS_ADJ_SEL_B_VSB                                            0x2
159 #define     IQM_RC_ADJ_SEL_B_OFF                                            0x0
160 #define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
161 #define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
162 /**** END DJCOMBO patches to DRXJ registermap *********************************/
163
164 #include "drx_driver_version.h"
165
166 /* #define DRX_DEBUG */
167 #ifdef DRX_DEBUG
168 #include <stdio.h>
169 #endif
170
171 /*-----------------------------------------------------------------------------
172 ENUMS
173 ----------------------------------------------------------------------------*/
174
175 /*-----------------------------------------------------------------------------
176 DEFINES
177 ----------------------------------------------------------------------------*/
178 #ifndef DRXJ_WAKE_UP_KEY
179 #define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
180 #endif
181
182 /**
183 * \def DRXJ_DEF_I2C_ADDR
184 * \brief Default I2C addres of a demodulator instance.
185 */
186 #define DRXJ_DEF_I2C_ADDR (0x52)
187
188 /**
189 * \def DRXJ_DEF_DEMOD_DEV_ID
190 * \brief Default device identifier of a demodultor instance.
191 */
192 #define DRXJ_DEF_DEMOD_DEV_ID      (1)
193
194 /**
195 * \def DRXJ_SCAN_TIMEOUT
196 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
197 */
198 #define DRXJ_SCAN_TIMEOUT    1000
199
200 /**
201 * \def DRXJ_DAP
202 * \brief Name of structure containing all data access protocol functions.
203 */
204 #define DRXJ_DAP drx_dap_drxj_funct_g
205
206 /**
207 * \def HI_I2C_DELAY
208 * \brief HI timing delay for I2C timing (in nano seconds)
209 *
210 *  Used to compute HI_CFG_DIV
211 */
212 #define HI_I2C_DELAY    42
213
214 /**
215 * \def HI_I2C_BRIDGE_DELAY
216 * \brief HI timing delay for I2C timing (in nano seconds)
217 *
218 *  Used to compute HI_CFG_BDL
219 */
220 #define HI_I2C_BRIDGE_DELAY   750
221
222 /**
223 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
224 */
225 #define VSB_TOP_MEASUREMENT_PERIOD  64
226 #define SYMBOLS_PER_SEGMENT         832
227
228 /**
229 * \brief bit rate and segment rate constants used for SER and BER.
230 */
231 /* values taken from the QAM microcode */
232 #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
233 #define DRXJ_QAM_SL_SIG_POWER_QPSK        32768
234 #define DRXJ_QAM_SL_SIG_POWER_QAM8        24576
235 #define DRXJ_QAM_SL_SIG_POWER_QAM16       40960
236 #define DRXJ_QAM_SL_SIG_POWER_QAM32       20480
237 #define DRXJ_QAM_SL_SIG_POWER_QAM64       43008
238 #define DRXJ_QAM_SL_SIG_POWER_QAM128      20992
239 #define DRXJ_QAM_SL_SIG_POWER_QAM256      43520
240 /**
241 * \brief Min supported symbolrates.
242 */
243 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
244 #define DRXJ_QAM_SYMBOLRATE_MIN          (520000)
245 #endif
246
247 /**
248 * \brief Max supported symbolrates.
249 */
250 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
251 #define DRXJ_QAM_SYMBOLRATE_MAX         (7233000)
252 #endif
253
254 /**
255 * \def DRXJ_QAM_MAX_WAITTIME
256 * \brief Maximal wait time for QAM auto constellation in ms
257 */
258 #ifndef DRXJ_QAM_MAX_WAITTIME
259 #define DRXJ_QAM_MAX_WAITTIME 900
260 #endif
261
262 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
263 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
264 #endif
265
266 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
267 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
268 #endif
269
270 /**
271 * \def SCU status and results
272 * \brief SCU
273 */
274 #define DRX_SCU_READY               0
275 #define DRXJ_MAX_WAITTIME           100 /* ms */
276 #define FEC_RS_MEASUREMENT_PERIOD   12894       /* 1 sec */
277 #define FEC_RS_MEASUREMENT_PRESCALE 1   /* n sec */
278
279 /**
280 * \def DRX_AUD_MAX_DEVIATION
281 * \brief Needed for calculation of prescale feature in AUD
282 */
283 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
284 #define DRXJ_AUD_MAX_FM_DEVIATION  100  /* kHz */
285 #endif
286
287 /**
288 * \brief Needed for calculation of NICAM prescale feature in AUD
289 */
290 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
291 #define DRXJ_AUD_MAX_NICAM_PRESCALE  (9)        /* dB */
292 #endif
293
294 /**
295 * \brief Needed for calculation of NICAM prescale feature in AUD
296 */
297 #ifndef DRXJ_AUD_MAX_WAITTIME
298 #define DRXJ_AUD_MAX_WAITTIME  250      /* ms */
299 #endif
300
301 /* ATV config changed flags */
302 #define DRXJ_ATV_CHANGED_COEF          (0x00000001UL)
303 #define DRXJ_ATV_CHANGED_PEAK_FLT      (0x00000008UL)
304 #define DRXJ_ATV_CHANGED_NOISE_FLT     (0x00000010UL)
305 #define DRXJ_ATV_CHANGED_OUTPUT        (0x00000020UL)
306 #define DRXJ_ATV_CHANGED_SIF_ATT       (0x00000040UL)
307
308 /* UIO define */
309 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
310 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
311
312 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
313 /*============================================================================*/
314 /*=== MICROCODE RELATED DEFINES ==============================================*/
315 /*============================================================================*/
316
317 /**
318 * \def DRXJ_UCODE_MAGIC_WORD
319 * \brief Magic word for checking correct Endianess of microcode data.
320 *
321 */
322
323 #ifndef DRXJ_UCODE_MAGIC_WORD
324 #define DRXJ_UCODE_MAGIC_WORD         ((((u16)'H')<<8)+((u16)'L'))
325 #endif
326
327 /**
328 * \def DRXJ_UCODE_CRC_FLAG
329 * \brief CRC flag in ucode header, flags field.
330 *
331 */
332
333 #ifndef DRXJ_UCODE_CRC_FLAG
334 #define DRXJ_UCODE_CRC_FLAG           (0x0001)
335 #endif
336
337 /**
338 * \def DRXJ_UCODE_COMPRESSION_FLAG
339 * \brief Compression flag in ucode header, flags field.
340 *
341 */
342
343 #ifndef DRXJ_UCODE_COMPRESSION_FLAG
344 #define DRXJ_UCODE_COMPRESSION_FLAG   (0x0002)
345 #endif
346
347 /**
348 * \def DRXJ_UCODE_MAX_BUF_SIZE
349 * \brief Maximum size of buffer used to verify the microcode.Must be an even number.
350 *
351 */
352
353 #ifndef DRXJ_UCODE_MAX_BUF_SIZE
354 #define DRXJ_UCODE_MAX_BUF_SIZE       (DRXDAP_MAX_RCHUNKSIZE)
355 #endif
356 #if DRXJ_UCODE_MAX_BUF_SIZE & 1
357 #error DRXJ_UCODE_MAX_BUF_SIZE must be an even number
358 #endif
359
360 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
361
362 /* Pin safe mode macro */
363 #define DRXJ_PIN_SAFE_MODE 0x0000
364 /*============================================================================*/
365 /*=== GLOBAL VARIABLEs =======================================================*/
366 /*============================================================================*/
367 /**
368 */
369
370 /**
371 * \brief Temporary register definitions.
372 *        (register definitions that are not yet available in register master)
373 */
374
375 /******************************************************************************/
376 /* Audio block 0x103 is write only. To avoid shadowing in driver accessing    */
377 /* RAM adresses directly. This must be READ ONLY to avoid problems.           */
378 /* Writing to the interface adresses is more than only writing the RAM        */
379 /* locations                                                                  */
380 /******************************************************************************/
381 /**
382 * \brief RAM location of MODUS registers
383 */
384 #define AUD_DEM_RAM_MODUS_HI__A              0x10204A3
385 #define AUD_DEM_RAM_MODUS_HI__M              0xF000
386
387 #define AUD_DEM_RAM_MODUS_LO__A              0x10204A4
388 #define AUD_DEM_RAM_MODUS_LO__M              0x0FFF
389
390 /**
391 * \brief RAM location of I2S config registers
392 */
393 #define AUD_DEM_RAM_I2S_CONFIG1__A           0x10204B1
394 #define AUD_DEM_RAM_I2S_CONFIG2__A           0x10204B2
395
396 /**
397 * \brief RAM location of DCO config registers
398 */
399 #define AUD_DEM_RAM_DCO_B_HI__A              0x1020461
400 #define AUD_DEM_RAM_DCO_B_LO__A              0x1020462
401 #define AUD_DEM_RAM_DCO_A_HI__A              0x1020463
402 #define AUD_DEM_RAM_DCO_A_LO__A              0x1020464
403
404 /**
405 * \brief RAM location of Threshold registers
406 */
407 #define AUD_DEM_RAM_NICAM_THRSHLD__A         0x102045A
408 #define AUD_DEM_RAM_A2_THRSHLD__A            0x10204BB
409 #define AUD_DEM_RAM_BTSC_THRSHLD__A          0x10204A6
410
411 /**
412 * \brief RAM location of Carrier Threshold registers
413 */
414 #define AUD_DEM_RAM_CM_A_THRSHLD__A          0x10204AF
415 #define AUD_DEM_RAM_CM_B_THRSHLD__A          0x10204B0
416
417 /**
418 * \brief FM Matrix register fix
419 */
420 #ifdef AUD_DEM_WR_FM_MATRIX__A
421 #undef  AUD_DEM_WR_FM_MATRIX__A
422 #endif
423 #define AUD_DEM_WR_FM_MATRIX__A              0x105006F
424
425 /*============================================================================*/
426 /**
427 * \brief Defines required for audio
428 */
429 #define AUD_VOLUME_ZERO_DB                      115
430 #define AUD_VOLUME_DB_MIN                       -60
431 #define AUD_VOLUME_DB_MAX                       12
432 #define AUD_CARRIER_STRENGTH_QP_0DB             0x4000
433 #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100   421
434 #define AUD_MAX_AVC_REF_LEVEL                   15
435 #define AUD_I2S_FREQUENCY_MAX                   48000UL
436 #define AUD_I2S_FREQUENCY_MIN                   12000UL
437 #define AUD_RDS_ARRAY_SIZE                      18
438
439 /**
440 * \brief Needed for calculation of prescale feature in AUD
441 */
442 #ifndef DRX_AUD_MAX_FM_DEVIATION
443 #define DRX_AUD_MAX_FM_DEVIATION  (100) /* kHz */
444 #endif
445
446 /**
447 * \brief Needed for calculation of NICAM prescale feature in AUD
448 */
449 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
450 #define DRX_AUD_MAX_NICAM_PRESCALE  (9) /* dB */
451 #endif
452
453 /*============================================================================*/
454 /* Values for I2S Master/Slave pin configurations */
455 #define SIO_PDR_I2S_CL_CFG_MODE__MASTER      0x0004
456 #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER     0x0008
457 #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE       0x0004
458 #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE      0x0000
459
460 #define SIO_PDR_I2S_DA_CFG_MODE__MASTER      0x0003
461 #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER     0x0008
462 #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE       0x0003
463 #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE      0x0008
464
465 #define SIO_PDR_I2S_WS_CFG_MODE__MASTER      0x0004
466 #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER     0x0008
467 #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE       0x0004
468 #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE      0x0000
469
470 /*============================================================================*/
471 /*=== REGISTER ACCESS MACROS =================================================*/
472 /*============================================================================*/
473
474 /**
475 * This macro is used to create byte arrays for block writes.
476 * Block writes speed up I2C traffic between host and demod.
477 * The macro takes care of the required byte order in a 16 bits word.
478 * x -> lowbyte(x), highbyte(x)
479 */
480 #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
481                        ((u8)((((u16)x)>>8)&0xFF))
482 /**
483 * This macro is used to convert byte array to 16 bit register value for block read.
484 * Block read speed up I2C traffic between host and demod.
485 * The macro takes care of the required byte order in a 16 bits word.
486 */
487 #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
488
489 /*============================================================================*/
490 /*=== MISC DEFINES ===========================================================*/
491 /*============================================================================*/
492
493 /*============================================================================*/
494 /*=== HI COMMAND RELATED DEFINES =============================================*/
495 /*============================================================================*/
496
497 /**
498 * \brief General maximum number of retries for ucode command interfaces
499 */
500 #define DRXJ_MAX_RETRIES (100)
501
502 /*============================================================================*/
503 /*=== STANDARD RELATED MACROS ================================================*/
504 /*============================================================================*/
505
506 #define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
507                                (std == DRX_STANDARD_PAL_SECAM_DK) || \
508                                (std == DRX_STANDARD_PAL_SECAM_I) || \
509                                (std == DRX_STANDARD_PAL_SECAM_L) || \
510                                (std == DRX_STANDARD_PAL_SECAM_LP) || \
511                                (std == DRX_STANDARD_NTSC) || \
512                                (std == DRX_STANDARD_FM))
513
514 #define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
515                                (std == DRX_STANDARD_ITU_B) || \
516                                (std == DRX_STANDARD_ITU_C) || \
517                                (std == DRX_STANDARD_ITU_D))
518
519 /*-----------------------------------------------------------------------------
520 GLOBAL VARIABLES
521 ----------------------------------------------------------------------------*/
522 /*
523  * DRXJ DAP structures
524  */
525
526 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
527                                       u32 addr,
528                                       u16 datasize,
529                                       u8 *data, u32 flags);
530
531 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
532                                                 u32 waddr,
533                                                 u32 raddr,
534                                                 u8 wdata, u8 *rdata);
535
536 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
537                                                  u32 waddr,
538                                                  u32 raddr,
539                                                  u16 wdata, u16 *rdata);
540
541 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
542                                                  u32 waddr,
543                                                  u32 raddr,
544                                                  u32 wdata, u32 *rdata);
545
546 static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
547                                      u32 addr,
548                                      u8 *data, u32 flags);
549
550 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
551                                       u32 addr,
552                                       u16 *data, u32 flags);
553
554 static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
555                                       u32 addr,
556                                       u32 *data, u32 flags);
557
558 static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
559                                        u32 addr,
560                                        u16 datasize,
561                                        u8 *data, u32 flags);
562
563 static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
564                                       u32 addr,
565                                       u8 data, u32 flags);
566
567 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
568                                        u32 addr,
569                                        u16 data, u32 flags);
570
571 static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
572                                        u32 addr,
573                                        u32 data, u32 flags);
574
575 /* The version structure of this protocol implementation */
576 char drx_dap_drxj_module_name[] = "DRXJ Data Access Protocol";
577 char drx_dap_drxj_version_text[] = "0.0.0";
578
579 struct drx_version drx_dap_drxj_version = {
580         DRX_MODULE_DAP,       /**< type identifier of the module  */
581         drx_dap_drxj_module_name, /**< name or description of module  */
582
583         0,                    /**< major version number           */
584         0,                    /**< minor version number           */
585         0,                    /**< patch version number           */
586         drx_dap_drxj_version_text /**< version as text string         */
587 };
588
589 /* The structure containing the protocol interface */
590 struct drx_access_func drx_dap_drxj_funct_g = {
591         &drx_dap_drxj_version,
592         drxj_dap_write_block,   /* Supported       */
593         drxj_dap_read_block,    /* Supported       */
594         drxj_dap_write_reg8,    /* Not supported   */
595         drxj_dap_read_reg8,     /* Not supported   */
596         drxj_dap_read_modify_write_reg8,        /* Not supported   */
597         drxj_dap_write_reg16,   /* Supported       */
598         drxj_dap_read_reg16,    /* Supported       */
599         drxj_dap_read_modify_write_reg16,       /* Supported       */
600         drxj_dap_write_reg32,   /* Supported       */
601         drxj_dap_read_reg32,    /* Supported       */
602         drxj_dap_read_modify_write_reg32,       /* Not supported   */
603 };
604
605 /**
606 * /var DRXJ_Func_g
607 * /brief The driver functions of the drxj
608 */
609 struct drx_demod_func drxj_functions_g = {
610         DRXJ_TYPE_ID,
611         drxj_open,
612         drxj_close,
613         drxj_ctrl
614 };
615
616 struct drxj_data drxj_data_g = {
617         false,                  /* has_lna : true if LNA (aka PGA) present      */
618         false,                  /* has_oob : true if OOB supported              */
619         false,                  /* has_ntsc: true if NTSC supported             */
620         false,                  /* has_btsc: true if BTSC supported             */
621         false,                  /* has_smatx: true if SMA_TX pin is available   */
622         false,                  /* has_smarx: true if SMA_RX pin is available   */
623         false,                  /* has_gpio : true if GPIO pin is available     */
624         false,                  /* has_irqn : true if IRQN pin is available     */
625         0,                      /* mfx A1/A2/A... */
626
627         /* tuner settings */
628         false,                  /* tuner mirrors RF signal    */
629         /* standard/channel settings */
630         DRX_STANDARD_UNKNOWN,   /* current standard           */
631         DRX_CONSTELLATION_AUTO, /* constellation              */
632         0,                      /* frequency in KHz           */
633         DRX_BANDWIDTH_UNKNOWN,  /* curr_bandwidth              */
634         DRX_MIRROR_NO,          /* mirror                     */
635
636         /* signal quality information: */
637         /* default values taken from the QAM Programming guide */
638         /*   fec_bits_desired should not be less than 4000000    */
639         4000000,                /* fec_bits_desired    */
640         5,                      /* fec_vd_plen         */
641         4,                      /* qam_vd_prescale     */
642         0xFFFF,                 /* qamVDPeriod       */
643         204 * 8,                /* fec_rs_plen annex A */
644         1,                      /* fec_rs_prescale     */
645         FEC_RS_MEASUREMENT_PERIOD,      /* fec_rs_period     */
646         true,                   /* reset_pkt_err_acc    */
647         0,                      /* pkt_err_acc_start    */
648
649         /* HI configuration */
650         0,                      /* hi_cfg_timing_div    */
651         0,                      /* hi_cfg_bridge_delay  */
652         0,                      /* hi_cfg_wake_up_key    */
653         0,                      /* hi_cfg_ctrl         */
654         0,                      /* HICfgTimeout      */
655         /* UIO configuartion */
656         DRX_UIO_MODE_DISABLE,   /* uio_sma_rx_mode      */
657         DRX_UIO_MODE_DISABLE,   /* uio_sma_tx_mode      */
658         DRX_UIO_MODE_DISABLE,   /* uioASELMode       */
659         DRX_UIO_MODE_DISABLE,   /* uio_irqn_mode       */
660         /* FS setting */
661         0UL,                    /* iqm_fs_rate_ofs      */
662         false,                  /* pos_image          */
663         /* RC setting */
664         0UL,                    /* iqm_rc_rate_ofs      */
665         /* AUD information */
666 /*   false,                  * flagSetAUDdone    */
667 /*   false,                  * detectedRDS       */
668 /*   true,                   * flagASDRequest    */
669 /*   false,                  * flagHDevClear     */
670 /*   false,                  * flagHDevSet       */
671 /*   (u16) 0xFFF,          * rdsLastCount      */
672
673 /*#ifdef DRXJ_SPLIT_UCODE_UPLOAD
674    false,                  * flag_aud_mc_uploaded */
675 /*#endif * DRXJ_SPLIT_UCODE_UPLOAD */
676         /* ATV configuartion */
677         0UL,                    /* flags cfg changes */
678         /* shadow of ATV_TOP_EQU0__A */
679         {-5,
680          ATV_TOP_EQU0_EQU_C0_FM,
681          ATV_TOP_EQU0_EQU_C0_L,
682          ATV_TOP_EQU0_EQU_C0_LP,
683          ATV_TOP_EQU0_EQU_C0_BG,
684          ATV_TOP_EQU0_EQU_C0_DK,
685          ATV_TOP_EQU0_EQU_C0_I},
686         /* shadow of ATV_TOP_EQU1__A */
687         {-50,
688          ATV_TOP_EQU1_EQU_C1_FM,
689          ATV_TOP_EQU1_EQU_C1_L,
690          ATV_TOP_EQU1_EQU_C1_LP,
691          ATV_TOP_EQU1_EQU_C1_BG,
692          ATV_TOP_EQU1_EQU_C1_DK,
693          ATV_TOP_EQU1_EQU_C1_I},
694         /* shadow of ATV_TOP_EQU2__A */
695         {210,
696          ATV_TOP_EQU2_EQU_C2_FM,
697          ATV_TOP_EQU2_EQU_C2_L,
698          ATV_TOP_EQU2_EQU_C2_LP,
699          ATV_TOP_EQU2_EQU_C2_BG,
700          ATV_TOP_EQU2_EQU_C2_DK,
701          ATV_TOP_EQU2_EQU_C2_I},
702         /* shadow of ATV_TOP_EQU3__A */
703         {-160,
704          ATV_TOP_EQU3_EQU_C3_FM,
705          ATV_TOP_EQU3_EQU_C3_L,
706          ATV_TOP_EQU3_EQU_C3_LP,
707          ATV_TOP_EQU3_EQU_C3_BG,
708          ATV_TOP_EQU3_EQU_C3_DK,
709          ATV_TOP_EQU3_EQU_C3_I},
710         false,                  /* flag: true=bypass             */
711         ATV_TOP_VID_PEAK__PRE,  /* shadow of ATV_TOP_VID_PEAK__A */
712         ATV_TOP_NOISE_TH__PRE,  /* shadow of ATV_TOP_NOISE_TH__A */
713         true,                   /* flag CVBS ouput enable        */
714         false,                  /* flag SIF ouput enable         */
715         DRXJ_SIF_ATTENUATION_0DB,       /* current SIF att setting       */
716         {                       /* qam_rf_agc_cfg */
717          DRX_STANDARD_ITU_B,    /* standard            */
718          DRX_AGC_CTRL_AUTO,     /* ctrl_mode            */
719          0,                     /* output_level         */
720          0,                     /* min_output_level      */
721          0xFFFF,                /* max_output_level      */
722          0x0000,                /* speed               */
723          0x0000,                /* top                 */
724          0x0000                 /* c.o.c.              */
725          },
726         {                       /* qam_if_agc_cfg */
727          DRX_STANDARD_ITU_B,    /* standard            */
728          DRX_AGC_CTRL_AUTO,     /* ctrl_mode            */
729          0,                     /* output_level         */
730          0,                     /* min_output_level      */
731          0xFFFF,                /* max_output_level      */
732          0x0000,                /* speed               */
733          0x0000,                /* top    (don't care) */
734          0x0000                 /* c.o.c. (don't care) */
735          },
736         {                       /* vsb_rf_agc_cfg */
737          DRX_STANDARD_8VSB,     /* standard       */
738          DRX_AGC_CTRL_AUTO,     /* ctrl_mode       */
739          0,                     /* output_level    */
740          0,                     /* min_output_level */
741          0xFFFF,                /* max_output_level */
742          0x0000,                /* speed          */
743          0x0000,                /* top    (don't care) */
744          0x0000                 /* c.o.c. (don't care) */
745          },
746         {                       /* vsb_if_agc_cfg */
747          DRX_STANDARD_8VSB,     /* standard       */
748          DRX_AGC_CTRL_AUTO,     /* ctrl_mode       */
749          0,                     /* output_level    */
750          0,                     /* min_output_level */
751          0xFFFF,                /* max_output_level */
752          0x0000,                /* speed          */
753          0x0000,                /* top    (don't care) */
754          0x0000                 /* c.o.c. (don't care) */
755          },
756         0,                      /* qam_pga_cfg */
757         0,                      /* vsb_pga_cfg */
758         {                       /* qam_pre_saw_cfg */
759          DRX_STANDARD_ITU_B,    /* standard  */
760          0,                     /* reference */
761          false                  /* use_pre_saw */
762          },
763         {                       /* vsb_pre_saw_cfg */
764          DRX_STANDARD_8VSB,     /* standard  */
765          0,                     /* reference */
766          false                  /* use_pre_saw */
767          },
768
769         /* Version information */
770 #ifndef _CH_
771         {
772          "01234567890",         /* human readable version microcode             */
773          "01234567890"          /* human readable version device specific code  */
774          },
775         {
776          {                      /* struct drx_version for microcode                   */
777           DRX_MODULE_UNKNOWN,
778           (char *)(NULL),
779           0,
780           0,
781           0,
782           (char *)(NULL)
783           },
784          {                      /* struct drx_version for device specific code */
785           DRX_MODULE_UNKNOWN,
786           (char *)(NULL),
787           0,
788           0,
789           0,
790           (char *)(NULL)
791           }
792          },
793         {
794          {                      /* struct drx_version_list for microcode */
795           (struct drx_version *) (NULL),
796           (struct drx_version_list *) (NULL)
797           },
798          {                      /* struct drx_version_list for device specific code */
799           (struct drx_version *) (NULL),
800           (struct drx_version_list *) (NULL)
801           }
802          },
803 #endif
804         false,                  /* smart_ant_inverted */
805         /* Tracking filter setting for OOB  */
806         {
807          12000,
808          9300,
809          6600,
810          5280,
811          3700,
812          3000,
813          2000,
814          0},
815         false,                  /* oob_power_on           */
816         0,                      /* mpeg_ts_static_bitrate  */
817         false,                  /* disable_te_ihandling   */
818         false,                  /* bit_reverse_mpeg_outout */
819         DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO,        /* mpeg_output_clock_rate */
820         DRXJ_MPEG_START_WIDTH_1CLKCYC,  /* mpeg_start_width */
821
822         /* Pre SAW & Agc configuration for ATV */
823         {
824          DRX_STANDARD_NTSC,     /* standard     */
825          7,                     /* reference    */
826          true                   /* use_pre_saw    */
827          },
828         {                       /* ATV RF-AGC */
829          DRX_STANDARD_NTSC,     /* standard              */
830          DRX_AGC_CTRL_AUTO,     /* ctrl_mode              */
831          0,                     /* output_level           */
832          0,                     /* min_output_level (d.c.) */
833          0,                     /* max_output_level (d.c.) */
834          3,                     /* speed                 */
835          9500,                  /* top                   */
836          4000                   /* cut-off current       */
837          },
838         {                       /* ATV IF-AGC */
839          DRX_STANDARD_NTSC,     /* standard              */
840          DRX_AGC_CTRL_AUTO,     /* ctrl_mode              */
841          0,                     /* output_level           */
842          0,                     /* min_output_level (d.c.) */
843          0,                     /* max_output_level (d.c.) */
844          3,                     /* speed                 */
845          2400,                  /* top                   */
846          0                      /* c.o.c.         (d.c.) */
847          },
848         140,                    /* ATV PGA config */
849         0,                      /* curr_symbol_rate */
850
851         false,                  /* pdr_safe_mode     */
852         SIO_PDR_GPIO_CFG__PRE,  /* pdr_safe_restore_val_gpio  */
853         SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
854         SIO_PDR_SMA_RX_CFG__PRE,        /* pdr_safe_restore_val_sma_rx */
855         SIO_PDR_SMA_TX_CFG__PRE,        /* pdr_safe_restore_val_sma_tx */
856
857         4,                      /* oob_pre_saw            */
858         DRXJ_OOB_LO_POW_MINUS10DB,      /* oob_lo_pow             */
859         {
860          false                  /* aud_data, only first member */
861          },
862 };
863
864 /**
865 * \var drxj_default_addr_g
866 * \brief Default I2C address and device identifier.
867 */
868 struct i2c_device_addr drxj_default_addr_g = {
869         DRXJ_DEF_I2C_ADDR,      /* i2c address */
870         DRXJ_DEF_DEMOD_DEV_ID   /* device id */
871 };
872
873 /**
874 * \var drxj_default_comm_attr_g
875 * \brief Default common attributes of a drxj demodulator instance.
876 */
877 struct drx_common_attr drxj_default_comm_attr_g = {
878         (u8 *)NULL,             /* ucode ptr            */
879         true,                   /* ucode verify switch  */
880         {0},                    /* version record       */
881
882         44000,                  /* IF in kHz in case no tuner instance is used  */
883         (151875 - 0),           /* system clock frequency in kHz                */
884         0,                      /* oscillator frequency kHz                     */
885         0,                      /* oscillator deviation in ppm, signed          */
886         false,                  /* If true mirror frequency spectrum            */
887         {
888          /* MPEG output configuration */
889          true,                  /* If true, enable MPEG ouput    */
890          false,                 /* If true, insert RS byte       */
891          true,                  /* If true, parallel out otherwise serial */
892          false,                 /* If true, invert DATA signals  */
893          false,                 /* If true, invert ERR signal    */
894          false,                 /* If true, invert STR signals   */
895          false,                 /* If true, invert VAL signals   */
896          false,                 /* If true, invert CLK signals   */
897          true,                  /* If true, static MPEG clockrate will
898                                    be used, otherwise clockrate will
899                                    adapt to the bitrate of the TS */
900          19392658UL,            /* Maximum bitrate in b/s in case
901                                    static clockrate is selected */
902          DRX_MPEG_STR_WIDTH_1   /* MPEG Start width in clock cycles */
903          },
904         /* Initilisations below can be ommited, they require no user input and
905            are initialy 0, NULL or false. The compiler will initialize them to these
906            values when ommited.  */
907         false,                  /* is_opened */
908
909         /* SCAN */
910         NULL,                   /* no scan params yet               */
911         0,                      /* current scan index               */
912         0,                      /* next scan frequency              */
913         false,                  /* scan ready flag                  */
914         0,                      /* max channels to scan             */
915         0,                      /* nr of channels scanned           */
916         NULL,                   /* default scan function            */
917         NULL,                   /* default context pointer          */
918         0,                      /* millisec to wait for demod lock  */
919         DRXJ_DEMOD_LOCK,        /* desired lock               */
920         false,
921
922         /* Power management */
923         DRX_POWER_UP,
924
925         /* Tuner */
926         1,                      /* nr of I2C port to wich tuner is     */
927         0L,                     /* minimum RF input frequency, in kHz  */
928         0L,                     /* maximum RF input frequency, in kHz  */
929         false,                  /* Rf Agc Polarity                     */
930         false,                  /* If Agc Polarity                     */
931         false,                  /* tuner slow mode                     */
932
933         {                       /* current channel (all 0)             */
934          0UL                    /* channel.frequency */
935          },
936         DRX_STANDARD_UNKNOWN,   /* current standard */
937         DRX_STANDARD_UNKNOWN,   /* previous standard */
938         DRX_STANDARD_UNKNOWN,   /* di_cache_standard   */
939         false,                  /* use_bootloader */
940         0UL,                    /* capabilities */
941         0                       /* mfx */
942 };
943
944 /**
945 * \var drxj_default_demod_g
946 * \brief Default drxj demodulator instance.
947 */
948 struct drx_demod_instance drxj_default_demod_g = {
949         &drxj_functions_g,      /* demod functions */
950         &DRXJ_DAP,              /* data access protocol functions */
951         NULL,                   /* tuner instance */
952         &drxj_default_addr_g,   /* i2c address & device id */
953         &drxj_default_comm_attr_g,      /* demod common attributes */
954         &drxj_data_g            /* demod device specific attributes */
955 };
956
957 /**
958 * \brief Default audio data structure for DRK demodulator instance.
959 *
960 * This structure is DRXK specific.
961 *
962 */
963 struct drx_aud_data drxj_default_aud_data_g = {
964         false,                  /* audio_is_active */
965         DRX_AUD_STANDARD_AUTO,  /* audio_standard  */
966
967         /* i2sdata */
968         {
969          false,                 /* output_enable   */
970          48000,                 /* frequency      */
971          DRX_I2S_MODE_MASTER,   /* mode           */
972          DRX_I2S_WORDLENGTH_32, /* word_length     */
973          DRX_I2S_POLARITY_RIGHT,        /* polarity       */
974          DRX_I2S_FORMAT_WS_WITH_DATA    /* format         */
975          },
976         /* volume            */
977         {
978          true,                  /* mute;          */
979          0,                     /* volume         */
980          DRX_AUD_AVC_OFF,       /* avc_mode        */
981          0,                     /* avc_ref_level    */
982          DRX_AUD_AVC_MAX_GAIN_12DB,     /* avc_max_gain     */
983          DRX_AUD_AVC_MAX_ATTEN_24DB,    /* avc_max_atten    */
984          0,                     /* strength_left   */
985          0                      /* strength_right  */
986          },
987         DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
988         /*  ass_thresholds */
989         {
990          440,                   /* A2    */
991          12,                    /* BTSC  */
992          700,                   /* NICAM */
993          },
994         /* carrier */
995         {
996          /* a */
997          {
998           42,                   /* thres */
999           DRX_NO_CARRIER_NOISE, /* opt   */
1000           0,                    /* shift */
1001           0                     /* dco   */
1002           },
1003          /* b */
1004          {
1005           42,                   /* thres */
1006           DRX_NO_CARRIER_MUTE,  /* opt   */
1007           0,                    /* shift */
1008           0                     /* dco   */
1009           },
1010
1011          },
1012         /* mixer */
1013         {
1014          DRX_AUD_SRC_STEREO_OR_A,       /* source_i2s */
1015          DRX_AUD_I2S_MATRIX_STEREO,     /* matrix_i2s */
1016          DRX_AUD_FM_MATRIX_SOUND_A      /* matrix_fm  */
1017          },
1018         DRX_AUD_DEVIATION_NORMAL,       /* deviation */
1019         DRX_AUD_AVSYNC_OFF,     /* av_sync */
1020
1021         /* prescale */
1022         {
1023          DRX_AUD_MAX_FM_DEVIATION,      /* fm_deviation */
1024          DRX_AUD_MAX_NICAM_PRESCALE     /* nicam_gain */
1025          },
1026         DRX_AUD_FM_DEEMPH_75US, /* deemph */
1027         DRX_BTSC_STEREO,        /* btsc_detect */
1028         0,                      /* rds_data_counter */
1029         false                   /* rds_data_present */
1030 };
1031
1032 /*-----------------------------------------------------------------------------
1033 STRUCTURES
1034 ----------------------------------------------------------------------------*/
1035 struct drxjeq_stat {
1036         u16 eq_mse;
1037         u8 eq_mode;
1038         u8 eq_ctrl;
1039         u8 eq_stat;
1040 };
1041
1042 /* HI command */
1043 struct drxj_hi_cmd {
1044         u16 cmd;
1045         u16 param1;
1046         u16 param2;
1047         u16 param3;
1048         u16 param4;
1049         u16 param5;
1050         u16 param6;
1051 };
1052
1053 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1054 /*============================================================================*/
1055 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
1056 /*============================================================================*/
1057
1058 struct drxu_code_block_hdr {
1059         u32 addr;
1060         u16 size;
1061         u16 flags;              /* bit[15..2]=reserved,
1062                                    bit[1]= compression on/off
1063                                    bit[0]= CRC on/off */
1064         u16 CRC;
1065 };
1066 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1067
1068 /*-----------------------------------------------------------------------------
1069 FUNCTIONS
1070 ----------------------------------------------------------------------------*/
1071 /* Some prototypes */
1072 static int
1073 hi_command(struct i2c_device_addr *dev_addr,
1074            const struct drxj_hi_cmd *cmd, u16 *result);
1075
1076 static int
1077 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
1078
1079 static int
1080 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
1081
1082 static int power_down_aud(struct drx_demod_instance *demod);
1083
1084 #ifndef DRXJ_DIGITAL_ONLY
1085 static int power_up_aud(struct drx_demod_instance *demod, bool set_standard);
1086 #endif
1087
1088 static int
1089 aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard);
1090
1091 static int
1092 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1093
1094 static int
1095 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
1096
1097 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1098 static int
1099 ctrl_u_code_upload(struct drx_demod_instance *demod,
1100                   struct drxu_code_info *mc_info,
1101                 enum drxu_code_actionaction, bool audio_mc_upload);
1102 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1103
1104 /*============================================================================*/
1105 /*============================================================================*/
1106 /*==                          HELPER FUNCTIONS                              ==*/
1107 /*============================================================================*/
1108 /*============================================================================*/
1109
1110 /**
1111 * \fn void mult32(u32 a, u32 b, u32 *h, u32 *l)
1112 * \brief 32bitsx32bits signed multiplication
1113 * \param a 32 bits multiplicant, typecast from signed to unisgned
1114 * \param b 32 bits multiplier, typecast from signed to unisgned
1115 * \param h pointer to high part 64 bits result, typecast from signed to unisgned
1116 * \param l pointer to low part 64 bits result
1117 *
1118 * For the 2n+n addition a + b:
1119 * if a >= 0, then h += 0 (sign extension = 0)
1120 * but if a < 0, then h += 2^n-1 ==> h -= 1.
1121 *
1122 * Also, if a + b < 2^n, then a + b  >= a && a + b >= b
1123 * but if a + b >= 2^n, then R = a + b - 2^n,
1124 * and because a < 2^n && b < 2*n ==> R < a && R < b.
1125 * Therefore, to detect overflow, simply compare the addition result with
1126 * one of the operands; if the result is smaller, overflow has occurred and
1127 * h must be incremented.
1128 *
1129 * Booth multiplication uses additions and subtractions to reduce the number
1130 * of iterations. This is done by taking three subsequent bits abc and calculating
1131 * the following multiplication factor: -2a + b + c. This factor is multiplied
1132 * by the second operand and added to the result. Next, the first operand is
1133 * shifted two bits (hence one of the three bits is reused) and the process
1134 * repeated. The last iteration has only two bits left, but we simply add
1135 * a zero to the end.
1136 *
1137 * Hence: (n=4)
1138 *  1 * a =  0 * 4a + 1 * a
1139 *  2 * a =  1 * 4a - 2 * a
1140 *  3 * a =  1 * 4a - 1 * a
1141 * -1 * a =  0 * 4a - 1 * a
1142 * -5 * a = -1 * 4a - 1 * a
1143 *
1144 * etc.
1145 *
1146 * Note that the function is type size independent. Any unsigned integer type
1147 * can be substituted for booth_t.
1148 *
1149 */
1150
1151 #define DRX_IS_BOOTH_NEGATIVE(__a)  (((__a) & (1 << (sizeof(u32) * 8 - 1))) != 0)
1152
1153 static void mult32(u32 a, u32 b, u32 *h, u32 *l)
1154 {
1155         unsigned int i;
1156         *h = *l = 0;
1157
1158         /* n/2 iterations; shift operand a left two bits after each iteration.      */
1159         /* This automatically appends a zero to the operand for the last iteration. */
1160         for (i = 0; i < sizeof(a) * 8; i += 2, a = a << 2) {
1161                 /* Shift result left two bits */
1162                 *h = (*h << 2) + (*l >> (sizeof(*l) * 8 - 2));
1163                 *l = (*l << 2);
1164
1165                 /* Take the first three bits of operand a for the Booth conversion: */
1166                 /* 0, 7: do nothing  */
1167                 /* 1, 2: add b       */
1168                 /* 3   : add 2b      */
1169                 /* 4   : subtract 2b */
1170                 /* 5, 6: subtract b  */
1171                 switch (a >> (sizeof(a) * 8 - 3)) {
1172                 case 3:
1173                         *l += b;
1174                         *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1175                 case 1:
1176                 case 2:
1177                         *l += b;
1178                         *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1179                         break;
1180                 case 4:
1181                         *l -= b;
1182                         *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1183                                                                     ((u32)
1184                                                                      (-
1185                                                                       ((s32)
1186                                                                        b))));
1187                 case 5:
1188                 case 6:
1189                         *l -= b;
1190                         *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1191                                                                     ((u32)
1192                                                                      (-
1193                                                                       ((s32)
1194                                                                        b))));
1195                         break;
1196                 }
1197         }
1198 }
1199
1200 /*============================================================================*/
1201
1202 /*
1203 * \fn u32 frac28(u32 N, u32 D)
1204 * \brief Compute: (1<<28)*N/D
1205 * \param N 32 bits
1206 * \param D 32 bits
1207 * \return (1<<28)*N/D
1208 * This function is used to avoid floating-point calculations as they may
1209 * not be present on the target platform.
1210
1211 * frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1212 * fraction used for setting the Frequency Shifter registers.
1213 * N and D can hold numbers up to width: 28-bits.
1214 * The 4 bits integer part and the 28 bits fractional part are calculated.
1215
1216 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1217
1218 * N: 0...(1<<28)-1 = 268435454
1219 * D: 0...(1<<28)-1
1220 * Q: 0...(1<<32)-1
1221 */
1222 static u32 frac28(u32 N, u32 D)
1223 {
1224         int i = 0;
1225         u32 Q1 = 0;
1226         u32 R0 = 0;
1227
1228         R0 = (N % D) << 4;      /* 32-28 == 4 shifts possible at max */
1229         Q1 = N / D;             /* integer part, only the 4 least significant bits
1230                                    will be visible in the result */
1231
1232         /* division using radix 16, 7 nibbles in the result */
1233         for (i = 0; i < 7; i++) {
1234                 Q1 = (Q1 << 4) | R0 / D;
1235                 R0 = (R0 % D) << 4;
1236         }
1237         /* rounding */
1238         if ((R0 >> 3) >= D)
1239                 Q1++;
1240
1241         return Q1;
1242 }
1243
1244 /**
1245 * \fn u32 log1_times100( u32 x)
1246 * \brief Compute: 100*log10(x)
1247 * \param x 32 bits
1248 * \return 100*log10(x)
1249 *
1250 * 100*log10(x)
1251 * = 100*(log2(x)/log2(10)))
1252 * = (100*(2^15)*log2(x))/((2^15)*log2(10))
1253 * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1254 * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1255 * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1256 *
1257 * where y = 2^k and 1<= (x/y) < 2
1258 */
1259
1260 static u32 log1_times100(u32 x)
1261 {
1262         static const u8 scale = 15;
1263         static const u8 index_width = 5;
1264         /*
1265            log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1266            0 <= n < ((1<<INDEXWIDTH)+1)
1267          */
1268
1269         static const u32 log2lut[] = {
1270                 0,              /* 0.000000 */
1271                 290941,         /* 290941.300628 */
1272                 573196,         /* 573196.476418 */
1273                 847269,         /* 847269.179851 */
1274                 1113620,        /* 1113620.489452 */
1275                 1372674,        /* 1372673.576986 */
1276                 1624818,        /* 1624817.752104 */
1277                 1870412,        /* 1870411.981536 */
1278                 2109788,        /* 2109787.962654 */
1279                 2343253,        /* 2343252.817465 */
1280                 2571091,        /* 2571091.461923 */
1281                 2793569,        /* 2793568.696416 */
1282                 3010931,        /* 3010931.055901 */
1283                 3223408,        /* 3223408.452106 */
1284                 3431216,        /* 3431215.635215 */
1285                 3634553,        /* 3634553.498355 */
1286                 3833610,        /* 3833610.244726 */
1287                 4028562,        /* 4028562.434393 */
1288                 4219576,        /* 4219575.925308 */
1289                 4406807,        /* 4406806.721144 */
1290                 4590402,        /* 4590401.736809 */
1291                 4770499,        /* 4770499.491025 */
1292                 4947231,        /* 4947230.734179 */
1293                 5120719,        /* 5120719.018555 */
1294                 5291081,        /* 5291081.217197 */
1295                 5458428,        /* 5458427.996830 */
1296                 5622864,        /* 5622864.249668 */
1297                 5784489,        /* 5784489.488298 */
1298                 5943398,        /* 5943398.207380 */
1299                 6099680,        /* 6099680.215452 */
1300                 6253421,        /* 6253420.939751 */
1301                 6404702,        /* 6404701.706649 */
1302                 6553600,        /* 6553600.000000 */
1303         };
1304
1305         u8 i = 0;
1306         u32 y = 0;
1307         u32 d = 0;
1308         u32 k = 0;
1309         u32 r = 0;
1310
1311         if (x == 0)
1312                 return 0;
1313
1314         /* Scale x (normalize) */
1315         /* computing y in log(x/y) = log(x) - log(y) */
1316         if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
1317                 for (k = scale; k > 0; k--) {
1318                         if (x & (((u32) 1) << scale))
1319                                 break;
1320                         x <<= 1;
1321                 }
1322         } else {
1323                 for (k = scale; k < 31; k++) {
1324                         if ((x & (((u32) (-1)) << (scale + 1))) == 0)
1325                                 break;
1326                         x >>= 1;
1327                 }
1328         }
1329         /*
1330            Now x has binary point between bit[scale] and bit[scale-1]
1331            and 1.0 <= x < 2.0 */
1332
1333         /* correction for divison: log(x) = log(x/y)+log(y) */
1334         y = k * ((((u32) 1) << scale) * 200);
1335
1336         /* remove integer part */
1337         x &= ((((u32) 1) << scale) - 1);
1338         /* get index */
1339         i = (u8) (x >> (scale - index_width));
1340         /* compute delta (x-a) */
1341         d = x & ((((u32) 1) << (scale - index_width)) - 1);
1342         /* compute log, multiplication ( d* (.. )) must be within range ! */
1343         y += log2lut[i] +
1344             ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
1345         /* Conver to log10() */
1346         y /= 108853;            /* (log2(10) << scale) */
1347         r = (y >> 1);
1348         /* rounding */
1349         if (y & ((u32)1))
1350                 r++;
1351
1352         return r;
1353
1354 }
1355
1356 /**
1357 * \fn u32 frac_times1e6( u16 N, u32 D)
1358 * \brief Compute: (N/D) * 1000000.
1359 * \param N nominator 16-bits.
1360 * \param D denominator 32-bits.
1361 * \return u32
1362 * \retval ((N/D) * 1000000), 32 bits
1363 *
1364 * No check on D=0!
1365 */
1366 static u32 frac_times1e6(u32 N, u32 D)
1367 {
1368         u32 remainder = 0;
1369         u32 frac = 0;
1370
1371         /*
1372            frac = (N * 1000000) / D
1373            To let it fit in a 32 bits computation:
1374            frac = (N * (1000000 >> 4)) / (D >> 4)
1375            This would result in a problem in case D < 16 (div by 0).
1376            So we do it more elaborate as shown below.
1377          */
1378         frac = (((u32) N) * (1000000 >> 4)) / D;
1379         frac <<= 4;
1380         remainder = (((u32) N) * (1000000 >> 4)) % D;
1381         remainder <<= 4;
1382         frac += remainder / D;
1383         remainder = remainder % D;
1384         if ((remainder * 2) > D)
1385                 frac++;
1386
1387         return frac;
1388 }
1389
1390 /*============================================================================*/
1391
1392 /**
1393 * \brief Compute: 100 * 10^( gd_b / 200 ).
1394 * \param  u32   gd_b      Gain in 0.1dB
1395 * \return u32            Gainfactor in 0.01 resolution
1396 *
1397 */
1398 static u32 d_b2lin_times100(u32 gd_b)
1399 {
1400         u32 result = 0;
1401         u32 nr6d_b_steps = 0;
1402         u32 remainder = 0;
1403         u32 remainder_fac = 0;
1404
1405         /* start with factors 2 (6.02dB) */
1406         nr6d_b_steps = gd_b * 1000UL / 60206UL;
1407         if (nr6d_b_steps > 17) {
1408                 /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
1409                 return MAX_U32;
1410         }
1411         result = (1 << nr6d_b_steps);
1412
1413         /* calculate remaining factor,
1414            poly approximation of 10^(gd_b/200):
1415
1416            y = 1E-04x2 + 0.0106x + 1.0026
1417
1418            max deviation < 0.005 for range x = [0 ... 60]
1419          */
1420         remainder = ((gd_b * 1000UL) % 60206UL) / 1000UL;
1421         /* using 1e-4 for poly calculation  */
1422         remainder_fac = 1 * remainder * remainder;
1423         remainder_fac += 106 * remainder;
1424         remainder_fac += 10026;
1425
1426         /* multiply by remaining factor */
1427         result *= remainder_fac;
1428
1429         /* conversion from 1e-4 to 1e-2 */
1430         return (result + 50) / 100;
1431 }
1432
1433 #ifndef DRXJ_DIGITAL_ONLY
1434 #define FRAC_FLOOR    0
1435 #define FRAC_CEIL     1
1436 #define FRAC_ROUND    2
1437 /**
1438 * \fn u32 frac( u32 N, u32 D, u16 RC )
1439 * \brief Compute: N/D.
1440 * \param N nominator 32-bits.
1441 * \param D denominator 32-bits.
1442 * \param RC-result correction: 0-floor; 1-ceil; 2-round
1443 * \return u32
1444 * \retval N/D, 32 bits
1445 *
1446 * If D=0 returns 0
1447 */
1448 static u32 frac(u32 N, u32 D, u16 RC)
1449 {
1450         u32 remainder = 0;
1451         u32 frac = 0;
1452         u16 bit_cnt = 32;
1453
1454         if (D == 0) {
1455                 frac = 0;
1456                 remainder = 0;
1457
1458                 return frac;
1459         }
1460
1461         if (D > N) {
1462                 frac = 0;
1463                 remainder = N;
1464         } else {
1465                 remainder = 0;
1466                 frac = N;
1467                 while (bit_cnt-- > 0) {
1468                         remainder <<= 1;
1469                         remainder |= ((frac & 0x80000000) >> 31);
1470                         frac <<= 1;
1471                         if (remainder < D) {
1472                                 frac &= 0xFFFFFFFE;
1473                         } else {
1474                                 remainder -= D;
1475                                 frac |= 0x1;
1476                         }
1477                 }
1478
1479                 /* result correction if needed */
1480                 if ((RC == FRAC_CEIL) && (remainder != 0)) {
1481                         /* ceil the result */
1482                         /*(remainder is not zero -> value behind decimal point exists) */
1483                         frac++;
1484                 }
1485                 if ((RC == FRAC_ROUND) && (remainder >= D >> 1)) {
1486                         /* remainder is bigger from D/2 -> round the result */
1487                         frac++;
1488                 }
1489         }
1490
1491         return frac;
1492 }
1493 #endif
1494
1495 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1496 /*============================================================================*/
1497
1498 /**
1499 * \fn u16 u_code_read16( u8 *addr)
1500 * \brief Read a 16 bits word, expect big endian data.
1501 * \return u16 The data read.
1502 */
1503 static u16 u_code_read16(u8 *addr)
1504 {
1505         /* Works fo any host processor */
1506
1507         u16 word = 0;
1508
1509         word = ((u16) addr[0]);
1510         word <<= 8;
1511         word |= ((u16) addr[1]);
1512
1513         return word;
1514 }
1515
1516 /*============================================================================*/
1517
1518 /**
1519 * \fn u32 u_code_read32( u8 *addr)
1520 * \brief Read a 32 bits word, expect big endian data.
1521 * \return u32 The data read.
1522 */
1523 static u32 u_code_read32(u8 *addr)
1524 {
1525         /* Works fo any host processor */
1526
1527         u32 word = 0;
1528
1529         word = ((u16) addr[0]);
1530         word <<= 8;
1531         word |= ((u16) addr[1]);
1532         word <<= 8;
1533         word |= ((u16) addr[2]);
1534         word <<= 8;
1535         word |= ((u16) addr[3]);
1536
1537         return word;
1538 }
1539
1540 /*============================================================================*/
1541
1542 /**
1543 * \fn u16 u_code_compute_crc (u8 *block_data, u16 nr_words)
1544 * \brief Compute CRC of block of microcode data.
1545 * \param block_data Pointer to microcode data.
1546 * \param nr_words Size of microcode block (number of 16 bits words).
1547 * \return u16 The computed CRC residu.
1548 */
1549 static u16 u_code_compute_crc(u8 *block_data, u16 nr_words)
1550 {
1551         u16 i = 0;
1552         u16 j = 0;
1553         u32 crc_word = 0;
1554         u32 carry = 0;
1555
1556         while (i < nr_words) {
1557                 crc_word |= (u32) u_code_read16(block_data);
1558                 for (j = 0; j < 16; j++) {
1559                         crc_word <<= 1;
1560                         if (carry != 0)
1561                                 crc_word ^= 0x80050000UL;
1562                         carry = crc_word & 0x80000000UL;
1563                 }
1564                 i++;
1565                 block_data += (sizeof(u16));
1566         }
1567         return (u16)(crc_word >> 16);
1568 }
1569 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1570
1571 /**
1572 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1573 *        and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1574 *
1575 */
1576 static const u16 nicam_presc_table_val[43] = {
1577         1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1578         5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1579         18, 20, 23, 25, 28, 32, 36, 40, 45,
1580         51, 57, 64, 71, 80, 90, 101, 113, 127
1581 };
1582
1583 /*============================================================================*/
1584 /*==                        END HELPER FUNCTIONS                            ==*/
1585 /*============================================================================*/
1586
1587 /*============================================================================*/
1588 /*============================================================================*/
1589 /*==                      DRXJ DAP FUNCTIONS                                ==*/
1590 /*============================================================================*/
1591 /*============================================================================*/
1592
1593 /*
1594    This layer takes care of some device specific register access protocols:
1595    -conversion to short address format
1596    -access to audio block
1597    This layer is placed between the drx_dap_fasi and the rest of the drxj
1598    specific implementation. This layer can use address map knowledge whereas
1599    dap_fasi may not use memory map knowledge.
1600
1601    * For audio currently only 16 bits read and write register access is
1602      supported. More is not needed. RMW and 32 or 8 bit access on audio
1603      registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1604      single/multi master) will be ignored.
1605
1606    TODO: check ignoring single/multimaster is ok for AUD access ?
1607 */
1608
1609 #define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1610 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80     /* millisec */
1611 /*============================================================================*/
1612
1613 /**
1614 * \fn bool is_handled_by_aud_tr_if( u32 addr )
1615 * \brief Check if this address is handled by the audio token ring interface.
1616 * \param addr
1617 * \return bool
1618 * \retval true  Yes, handled by audio token ring interface
1619 * \retval false No, not handled by audio token ring interface
1620 *
1621 */
1622 static
1623 bool is_handled_by_aud_tr_if(u32 addr)
1624 {
1625         bool retval = false;
1626
1627         if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1628             (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1629             (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1630                 retval = true;
1631         }
1632
1633         return retval;
1634 }
1635
1636 /*============================================================================*/
1637
1638 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
1639                                       u32 addr,
1640                                       u16 datasize,
1641                                       u8 *data, u32 flags)
1642 {
1643         return drx_dap_fasi_funct_g.read_block_func(dev_addr,
1644                                                addr, datasize, data, flags);
1645 }
1646
1647 /*============================================================================*/
1648
1649 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
1650                                                 u32 waddr,
1651                                                 u32 raddr,
1652                                                 u8 wdata, u8 *rdata)
1653 {
1654         return drx_dap_fasi_funct_g.read_modify_write_reg8func(dev_addr,
1655                                                          waddr,
1656                                                          raddr, wdata, rdata);
1657 }
1658
1659 /*============================================================================*/
1660
1661 /**
1662 * \fn int drxj_dap_rm_write_reg16short
1663 * \brief Read modify write 16 bits audio register using short format only.
1664 * \param dev_addr
1665 * \param waddr    Address to write to
1666 * \param raddr    Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1667 * \param wdata    Data to write
1668 * \param rdata    Buffer for data to read
1669 * \return int
1670 * \retval 0 Succes
1671 * \retval -EIO Timeout, I2C error, illegal bank
1672 *
1673 * 16 bits register read modify write access using short addressing format only.
1674 * Requires knowledge of the registermap, thus device dependent.
1675 * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1676 *
1677 */
1678
1679 /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1680    See comments drxj_dap_read_modify_write_reg16 */
1681 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
1682 static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1683                                               u32 waddr,
1684                                               u32 raddr,
1685                                               u16 wdata, u16 *rdata)
1686 {
1687         int rc;
1688
1689         if (rdata == NULL)
1690                 return -EINVAL;
1691
1692         /* Set RMW flag */
1693         rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1694                                               SIO_HI_RA_RAM_S0_FLG_ACC__A,
1695                                               SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1696                                               0x0000);
1697         if (rc == 0) {
1698                 /* Write new data: triggers RMW */
1699                 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr, waddr, wdata,
1700                                                       0x0000);
1701         }
1702         if (rc == 0) {
1703                 /* Read old data */
1704                 rc = drx_dap_fasi_funct_g.read_reg16func(dev_addr, raddr, rdata,
1705                                                      0x0000);
1706         }
1707         if (rc == 0) {
1708                 /* Reset RMW flag */
1709                 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1710                                                       SIO_HI_RA_RAM_S0_FLG_ACC__A,
1711                                                       0, 0x0000);
1712         }
1713
1714         return rc;
1715 }
1716 #endif
1717
1718 /*============================================================================*/
1719
1720 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1721                                                  u32 waddr,
1722                                                  u32 raddr,
1723                                                  u16 wdata, u16 *rdata)
1724 {
1725         /* TODO: correct short/long addressing format decision,
1726            now long format has higher prio then short because short also
1727            needs virt bnks (not impl yet) for certain audio registers */
1728 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1729         return drx_dap_fasi_funct_g.read_modify_write_reg16func(dev_addr,
1730                                                           waddr,
1731                                                           raddr, wdata, rdata);
1732 #else
1733         return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
1734 #endif
1735 }
1736
1737 /*============================================================================*/
1738
1739 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
1740                                                  u32 waddr,
1741                                                  u32 raddr,
1742                                                  u32 wdata, u32 *rdata)
1743 {
1744         return drx_dap_fasi_funct_g.read_modify_write_reg32func(dev_addr,
1745                                                           waddr,
1746                                                           raddr, wdata, rdata);
1747 }
1748
1749 /*============================================================================*/
1750
1751 static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
1752                                      u32 addr,
1753                                      u8 *data, u32 flags)
1754 {
1755         return drx_dap_fasi_funct_g.read_reg8func(dev_addr, addr, data, flags);
1756 }
1757
1758 /*============================================================================*/
1759
1760 /**
1761 * \fn int drxj_dap_read_aud_reg16
1762 * \brief Read 16 bits audio register
1763 * \param dev_addr
1764 * \param addr
1765 * \param data
1766 * \return int
1767 * \retval 0 Succes
1768 * \retval -EIO Timeout, I2C error, illegal bank
1769 *
1770 * 16 bits register read access via audio token ring interface.
1771 *
1772 */
1773 static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1774                                          u32 addr, u16 *data)
1775 {
1776         u32 start_timer = 0;
1777         u32 current_timer = 0;
1778         u32 delta_timer = 0;
1779         u16 tr_status = 0;
1780         int stat = -EIO;
1781
1782         /* No read possible for bank 3, return with error */
1783         if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1784                 stat = -EINVAL;
1785         } else {
1786                 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1787
1788                 /* Force reset write bit */
1789                 addr &= (~write_bit);
1790
1791                 /* Set up read */
1792                 start_timer = drxbsp_hst_clock();
1793                 do {
1794                         /* RMW to aud TR IF until request is granted or timeout */
1795                         stat = drxj_dap_read_modify_write_reg16(dev_addr,
1796                                                              addr,
1797                                                              SIO_HI_RA_RAM_S0_RMWBUF__A,
1798                                                              0x0000, &tr_status);
1799
1800                         if (stat != 0)
1801                                 break;
1802
1803                         current_timer = drxbsp_hst_clock();
1804                         delta_timer = current_timer - start_timer;
1805                         if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1806                                 stat = -EIO;
1807                                 break;
1808                         }
1809
1810                 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1811                           AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1812                          ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1813                           AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1814         }                       /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1815
1816         /* Wait for read ready status or timeout */
1817         if (stat == 0) {
1818                 start_timer = drxbsp_hst_clock();
1819
1820                 while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1821                        AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1822                         stat = drxj_dap_read_reg16(dev_addr,
1823                                                   AUD_TOP_TR_CTR__A,
1824                                                   &tr_status, 0x0000);
1825                         if (stat != 0)
1826                                 break;
1827
1828                         current_timer = drxbsp_hst_clock();
1829                         delta_timer = current_timer - start_timer;
1830                         if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1831                                 stat = -EIO;
1832                                 break;
1833                         }
1834                 }               /* while ( ... ) */
1835         }
1836
1837         /* Read value */
1838         if (stat == 0)
1839                 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1840                                                      AUD_TOP_TR_RD_REG__A,
1841                                                      SIO_HI_RA_RAM_S0_RMWBUF__A,
1842                                                      0x0000, data);
1843         return stat;
1844 }
1845
1846 /*============================================================================*/
1847
1848 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1849                                       u32 addr,
1850                                       u16 *data, u32 flags)
1851 {
1852         int stat = -EIO;
1853
1854         /* Check param */
1855         if ((dev_addr == NULL) || (data == NULL))
1856                 return -EINVAL;
1857
1858         if (is_handled_by_aud_tr_if(addr))
1859                 stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
1860         else
1861                 stat = drx_dap_fasi_funct_g.read_reg16func(dev_addr,
1862                                                            addr, data, flags);
1863
1864         return stat;
1865 }
1866
1867 /*============================================================================*/
1868
1869 static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
1870                                       u32 addr,
1871                                       u32 *data, u32 flags)
1872 {
1873         return drx_dap_fasi_funct_g.read_reg32func(dev_addr, addr, data, flags);
1874 }
1875
1876 /*============================================================================*/
1877
1878 static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
1879                                        u32 addr,
1880                                        u16 datasize,
1881                                        u8 *data, u32 flags)
1882 {
1883         return drx_dap_fasi_funct_g.write_block_func(dev_addr,
1884                                                 addr, datasize, data, flags);
1885 }
1886
1887 /*============================================================================*/
1888
1889 static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
1890                                       u32 addr,
1891                                       u8 data, u32 flags)
1892 {
1893         return drx_dap_fasi_funct_g.write_reg8func(dev_addr, addr, data, flags);
1894 }
1895
1896 /*============================================================================*/
1897
1898 /**
1899 * \fn int drxj_dap_write_aud_reg16
1900 * \brief Write 16 bits audio register
1901 * \param dev_addr
1902 * \param addr
1903 * \param data
1904 * \return int
1905 * \retval 0 Succes
1906 * \retval -EIO Timeout, I2C error, illegal bank
1907 *
1908 * 16 bits register write access via audio token ring interface.
1909 *
1910 */
1911 static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
1912                                           u32 addr, u16 data)
1913 {
1914         int stat = -EIO;
1915
1916         /* No write possible for bank 2, return with error */
1917         if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
1918                 stat = -EINVAL;
1919         } else {
1920                 u32 start_timer = 0;
1921                 u32 current_timer = 0;
1922                 u32 delta_timer = 0;
1923                 u16 tr_status = 0;
1924                 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1925
1926                 /* Force write bit */
1927                 addr |= write_bit;
1928                 start_timer = drxbsp_hst_clock();
1929                 do {
1930                         /* RMW to aud TR IF until request is granted or timeout */
1931                         stat = drxj_dap_read_modify_write_reg16(dev_addr,
1932                                                              addr,
1933                                                              SIO_HI_RA_RAM_S0_RMWBUF__A,
1934                                                              data, &tr_status);
1935                         if (stat != 0)
1936                                 break;
1937
1938                         current_timer = drxbsp_hst_clock();
1939                         delta_timer = current_timer - start_timer;
1940                         if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1941                                 stat = -EIO;
1942                                 break;
1943                         }
1944
1945                 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1946                           AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1947                          ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1948                           AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1949
1950         }                       /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
1951
1952         return stat;
1953 }
1954
1955 /*============================================================================*/
1956
1957 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
1958                                        u32 addr,
1959                                        u16 data, u32 flags)
1960 {
1961         int stat = -EIO;
1962
1963         /* Check param */
1964         if (dev_addr == NULL)
1965                 return -EINVAL;
1966
1967         if (is_handled_by_aud_tr_if(addr))
1968                 stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
1969         else
1970                 stat = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1971                                                             addr, data, flags);
1972
1973         return stat;
1974 }
1975
1976 /*============================================================================*/
1977
1978 static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
1979                                        u32 addr,
1980                                        u32 data, u32 flags)
1981 {
1982         return drx_dap_fasi_funct_g.write_reg32func(dev_addr, addr, data, flags);
1983 }
1984
1985 /*============================================================================*/
1986
1987 /* Free data ram in SIO HI */
1988 #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
1989 #define SIO_HI_RA_RAM_USR_END__A   0x420060
1990
1991 #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
1992 #define DRXJ_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
1993 #define DRXJ_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
1994 #define DRXJ_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
1995
1996 /**
1997 * \fn int drxj_dap_atomic_read_write_block()
1998 * \brief Basic access routine for atomic read or write access
1999 * \param dev_addr  pointer to i2c dev address
2000 * \param addr     destination/source address
2001 * \param datasize size of data buffer in bytes
2002 * \param data     pointer to data buffer
2003 * \return int
2004 * \retval 0 Succes
2005 * \retval -EIO Timeout, I2C error, illegal bank
2006 *
2007 */
2008 static
2009 int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2010                                           u32 addr,
2011                                           u16 datasize,
2012                                           u8 *data, bool read_flag)
2013 {
2014         struct drxj_hi_cmd hi_cmd;
2015         int rc;
2016         u16 word;
2017         u16 dummy = 0;
2018         u16 i = 0;
2019
2020         /* Parameter check */
2021         if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
2022                 return -EINVAL;
2023
2024         /* Set up HI parameters to read or write n bytes */
2025         hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2026         hi_cmd.param1 =
2027             (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2028                      DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2029         hi_cmd.param2 =
2030             (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2031         hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2032         if (!read_flag)
2033                 hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2034         else
2035                 hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
2036         hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2037                                 DRXDAP_FASI_ADDR2BANK(addr));
2038         hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
2039
2040         if (!read_flag) {
2041                 /* write data to buffer */
2042                 for (i = 0; i < (datasize / 2); i++) {
2043
2044                         word = ((u16) data[2 * i]);
2045                         word += (((u16) data[(2 * i) + 1]) << 8);
2046                         drxj_dap_write_reg16(dev_addr,
2047                                              (DRXJ_HI_ATOMIC_BUF_START + i),
2048                                             word, 0);
2049                 }
2050         }
2051
2052         rc = hi_command(dev_addr, &hi_cmd, &dummy);
2053         if (rc != 0) {
2054                 pr_err("error %d\n", rc);
2055                 goto rw_error;
2056         }
2057
2058         if (read_flag) {
2059                 /* read data from buffer */
2060                 for (i = 0; i < (datasize / 2); i++) {
2061                         drxj_dap_read_reg16(dev_addr,
2062                                             (DRXJ_HI_ATOMIC_BUF_START + i),
2063                                            &word, 0);
2064                         data[2 * i] = (u8) (word & 0xFF);
2065                         data[(2 * i) + 1] = (u8) (word >> 8);
2066                 }
2067         }
2068
2069         return 0;
2070
2071 rw_error:
2072         return -EIO;
2073
2074 }
2075
2076 /*============================================================================*/
2077
2078 /**
2079 * \fn int drxj_dap_atomic_read_reg32()
2080 * \brief Atomic read of 32 bits words
2081 */
2082 static
2083 int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2084                                      u32 addr,
2085                                      u32 *data, u32 flags)
2086 {
2087         u8 buf[sizeof(*data)];
2088         int rc = -EIO;
2089         u32 word = 0;
2090
2091         if (!data)
2092                 return -EINVAL;
2093
2094         rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
2095                                               sizeof(*data), buf, true);
2096
2097         if (rc < 0)
2098                 return 0;
2099
2100         word = (u32) buf[3];
2101         word <<= 8;
2102         word |= (u32) buf[2];
2103         word <<= 8;
2104         word |= (u32) buf[1];
2105         word <<= 8;
2106         word |= (u32) buf[0];
2107
2108         *data = word;
2109
2110         return rc;
2111 }
2112
2113 /*============================================================================*/
2114
2115 /*============================================================================*/
2116 /*==                        END DRXJ DAP FUNCTIONS                          ==*/
2117 /*============================================================================*/
2118
2119 /*============================================================================*/
2120 /*============================================================================*/
2121 /*==                      HOST INTERFACE FUNCTIONS                          ==*/
2122 /*============================================================================*/
2123 /*============================================================================*/
2124
2125 /**
2126 * \fn int hi_cfg_command()
2127 * \brief Configure HI with settings stored in the demod structure.
2128 * \param demod Demodulator.
2129 * \return int.
2130 *
2131 * This routine was created because to much orthogonal settings have
2132 * been put into one HI API function (configure). Especially the I2C bridge
2133 * enable/disable should not need re-configuration of the HI.
2134 *
2135 */
2136 static int hi_cfg_command(const struct drx_demod_instance *demod)
2137 {
2138         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2139         struct drxj_hi_cmd hi_cmd;
2140         u16 result = 0;
2141         int rc;
2142
2143         ext_attr = (struct drxj_data *) demod->my_ext_attr;
2144
2145         hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2146         hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2147         hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2148         hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2149         hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2150         hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2151         hi_cmd.param6 = ext_attr->hi_cfg_transmit;
2152
2153         rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
2154         if (rc != 0) {
2155                 pr_err("error %d\n", rc);
2156                 goto rw_error;
2157         }
2158
2159         /* Reset power down flag (set one call only) */
2160         ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2161
2162         return 0;
2163
2164 rw_error:
2165         return -EIO;
2166 }
2167
2168 /**
2169 * \fn int hi_command()
2170 * \brief Configure HI with settings stored in the demod structure.
2171 * \param dev_addr I2C address.
2172 * \param cmd HI command.
2173 * \param result HI command result.
2174 * \return int.
2175 *
2176 * Sends command to HI
2177 *
2178 */
2179 static int
2180 hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
2181 {
2182         u16 wait_cmd = 0;
2183         u16 nr_retries = 0;
2184         bool powerdown_cmd = false;
2185         int rc;
2186
2187         /* Write parameters */
2188         switch (cmd->cmd) {
2189
2190         case SIO_HI_RA_RAM_CMD_CONFIG:
2191         case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2192                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
2193                 if (rc != 0) {
2194                         pr_err("error %d\n", rc);
2195                         goto rw_error;
2196                 }
2197                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
2198                 if (rc != 0) {
2199                         pr_err("error %d\n", rc);
2200                         goto rw_error;
2201                 }
2202                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
2203                 if (rc != 0) {
2204                         pr_err("error %d\n", rc);
2205                         goto rw_error;
2206                 }
2207                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
2208                 if (rc != 0) {
2209                         pr_err("error %d\n", rc);
2210                         goto rw_error;
2211                 }
2212                 /* fallthrough */
2213         case SIO_HI_RA_RAM_CMD_BRDCTRL:
2214                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
2215                 if (rc != 0) {
2216                         pr_err("error %d\n", rc);
2217                         goto rw_error;
2218                 }
2219                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
2220                 if (rc != 0) {
2221                         pr_err("error %d\n", rc);
2222                         goto rw_error;
2223                 }
2224                 /* fallthrough */
2225         case SIO_HI_RA_RAM_CMD_NULL:
2226                 /* No parameters */
2227                 break;
2228
2229         default:
2230                 return -EINVAL;
2231                 break;
2232         }
2233
2234         /* Write command */
2235         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
2236         if (rc != 0) {
2237                 pr_err("error %d\n", rc);
2238                 goto rw_error;
2239         }
2240
2241         if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
2242                 drxbsp_hst_sleep(1);
2243
2244         /* Detect power down to ommit reading result */
2245         powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2246                                   (((cmd->
2247                                      param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2248                                    == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2249         if (!powerdown_cmd) {
2250                 /* Wait until command rdy */
2251                 do {
2252                         nr_retries++;
2253                         if (nr_retries > DRXJ_MAX_RETRIES) {
2254                                 pr_err("timeout\n");
2255                                 goto rw_error;
2256                         }
2257
2258                         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
2259                         if (rc != 0) {
2260                                 pr_err("error %d\n", rc);
2261                                 goto rw_error;
2262                         }
2263                 } while (wait_cmd != 0);
2264
2265                 /* Read result */
2266                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
2267                 if (rc != 0) {
2268                         pr_err("error %d\n", rc);
2269                         goto rw_error;
2270                 }
2271
2272         }
2273         /* if ( powerdown_cmd == true ) */
2274         return 0;
2275 rw_error:
2276         return -EIO;
2277 }
2278
2279 /**
2280 * \fn int init_hi( const struct drx_demod_instance *demod )
2281 * \brief Initialise and configurate HI.
2282 * \param demod pointer to demod data.
2283 * \return int Return status.
2284 * \retval 0 Success.
2285 * \retval -EIO Failure.
2286 *
2287 * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2288 * Need to store configuration in driver because of the way I2C
2289 * bridging is controlled.
2290 *
2291 */
2292 static int init_hi(const struct drx_demod_instance *demod)
2293 {
2294         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2295         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2296         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2297         int rc;
2298
2299         ext_attr = (struct drxj_data *) demod->my_ext_attr;
2300         common_attr = (struct drx_common_attr *) demod->my_common_attr;
2301         dev_addr = demod->my_i2c_dev_addr;
2302
2303         /* PATCH for bug 5003, HI ucode v3.1.0 */
2304         rc = DRXJ_DAP.write_reg16func(dev_addr, 0x4301D7, 0x801, 0);
2305         if (rc != 0) {
2306                 pr_err("error %d\n", rc);
2307                 goto rw_error;
2308         }
2309
2310         /* Timing div, 250ns/Psys */
2311         /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2312         ext_attr->hi_cfg_timing_div =
2313             (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
2314         /* Clipping */
2315         if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
2316                 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2317         /* Bridge delay, uses oscilator clock */
2318         /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2319         /* SDA brdige delay */
2320         ext_attr->hi_cfg_bridge_delay =
2321             (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
2322             1000;
2323         /* Clipping */
2324         if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
2325                 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2326         /* SCL bridge delay, same as SDA for now */
2327         ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
2328                                       SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2329         /* Wakeup key, setting the read flag (as suggest in the documentation) does
2330            not always result into a working solution (barebones worked VI2C failed).
2331            Not setting the bit works in all cases . */
2332         ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
2333         /* port/bridge/power down ctrl */
2334         ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2335         /* transit mode time out delay and watch dog divider */
2336         ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
2337
2338         rc = hi_cfg_command(demod);
2339         if (rc != 0) {
2340                 pr_err("error %d\n", rc);
2341                 goto rw_error;
2342         }
2343
2344         return 0;
2345
2346 rw_error:
2347         return -EIO;
2348 }
2349
2350 /*============================================================================*/
2351 /*==                   END HOST INTERFACE FUNCTIONS                         ==*/
2352 /*============================================================================*/
2353
2354 /*============================================================================*/
2355 /*============================================================================*/
2356 /*==                        AUXILIARY FUNCTIONS                             ==*/
2357 /*============================================================================*/
2358 /*============================================================================*/
2359
2360 /**
2361 * \fn int get_device_capabilities()
2362 * \brief Get and store device capabilities.
2363 * \param demod  Pointer to demodulator instance.
2364 * \return int.
2365 * \return 0    Success
2366 * \retval -EIO Failure
2367 *
2368 * Depending on pulldowns on MDx pins the following internals are set:
2369 *  * common_attr->osc_clock_freq
2370 *  * ext_attr->has_lna
2371 *  * ext_attr->has_ntsc
2372 *  * ext_attr->has_btsc
2373 *  * ext_attr->has_oob
2374 *
2375 */
2376 static int get_device_capabilities(struct drx_demod_instance *demod)
2377 {
2378         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2379         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
2380         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2381         u16 sio_pdr_ohw_cfg = 0;
2382         u32 sio_top_jtagid_lo = 0;
2383         u16 bid = 0;
2384         int rc;
2385
2386         common_attr = (struct drx_common_attr *) demod->my_common_attr;
2387         ext_attr = (struct drxj_data *) demod->my_ext_attr;
2388         dev_addr = demod->my_i2c_dev_addr;
2389
2390         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2391         if (rc != 0) {
2392                 pr_err("error %d\n", rc);
2393                 goto rw_error;
2394         }
2395         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
2396         if (rc != 0) {
2397                 pr_err("error %d\n", rc);
2398                 goto rw_error;
2399         }
2400         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2401         if (rc != 0) {
2402                 pr_err("error %d\n", rc);
2403                 goto rw_error;
2404         }
2405
2406         switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2407         case 0:
2408                 /* ignore (bypass ?) */
2409                 break;
2410         case 1:
2411                 /* 27 MHz */
2412                 common_attr->osc_clock_freq = 27000;
2413                 break;
2414         case 2:
2415                 /* 20.25 MHz */
2416                 common_attr->osc_clock_freq = 20250;
2417                 break;
2418         case 3:
2419                 /* 4 MHz */
2420                 common_attr->osc_clock_freq = 4000;
2421                 break;
2422         default:
2423                 return -EIO;
2424         }
2425
2426         /*
2427            Determine device capabilities
2428            Based on pinning v47
2429          */
2430         rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
2431         if (rc != 0) {
2432                 pr_err("error %d\n", rc);
2433                 goto rw_error;
2434         }
2435         ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
2436
2437         switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
2438         case 0x31:
2439                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2440                 if (rc != 0) {
2441                         pr_err("error %d\n", rc);
2442                         goto rw_error;
2443                 }
2444                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
2445                 if (rc != 0) {
2446                         pr_err("error %d\n", rc);
2447                         goto rw_error;
2448                 }
2449                 bid = (bid >> 10) & 0xf;
2450                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2451                 if (rc != 0) {
2452                         pr_err("error %d\n", rc);
2453                         goto rw_error;
2454                 }
2455
2456                 ext_attr->has_lna = true;
2457                 ext_attr->has_ntsc = false;
2458                 ext_attr->has_btsc = false;
2459                 ext_attr->has_oob = false;
2460                 ext_attr->has_smatx = true;
2461                 ext_attr->has_smarx = false;
2462                 ext_attr->has_gpio = false;
2463                 ext_attr->has_irqn = false;
2464                 break;
2465         case 0x33:
2466                 ext_attr->has_lna = false;
2467                 ext_attr->has_ntsc = false;
2468                 ext_attr->has_btsc = false;
2469                 ext_attr->has_oob = false;
2470                 ext_attr->has_smatx = true;
2471                 ext_attr->has_smarx = false;
2472                 ext_attr->has_gpio = false;
2473                 ext_attr->has_irqn = false;
2474                 break;
2475         case 0x45:
2476                 ext_attr->has_lna = true;
2477                 ext_attr->has_ntsc = true;
2478                 ext_attr->has_btsc = false;
2479                 ext_attr->has_oob = false;
2480                 ext_attr->has_smatx = true;
2481                 ext_attr->has_smarx = true;
2482                 ext_attr->has_gpio = true;
2483                 ext_attr->has_irqn = false;
2484                 break;
2485         case 0x46:
2486                 ext_attr->has_lna = false;
2487                 ext_attr->has_ntsc = true;
2488                 ext_attr->has_btsc = false;
2489                 ext_attr->has_oob = false;
2490                 ext_attr->has_smatx = true;
2491                 ext_attr->has_smarx = true;
2492                 ext_attr->has_gpio = true;
2493                 ext_attr->has_irqn = false;
2494                 break;
2495         case 0x41:
2496                 ext_attr->has_lna = true;
2497                 ext_attr->has_ntsc = true;
2498                 ext_attr->has_btsc = true;
2499                 ext_attr->has_oob = false;
2500                 ext_attr->has_smatx = true;
2501                 ext_attr->has_smarx = true;
2502                 ext_attr->has_gpio = true;
2503                 ext_attr->has_irqn = false;
2504                 break;
2505         case 0x43:
2506                 ext_attr->has_lna = false;
2507                 ext_attr->has_ntsc = true;
2508                 ext_attr->has_btsc = true;
2509                 ext_attr->has_oob = false;
2510                 ext_attr->has_smatx = true;
2511                 ext_attr->has_smarx = true;
2512                 ext_attr->has_gpio = true;
2513                 ext_attr->has_irqn = false;
2514                 break;
2515         case 0x32:
2516                 ext_attr->has_lna = true;
2517                 ext_attr->has_ntsc = false;
2518                 ext_attr->has_btsc = false;
2519                 ext_attr->has_oob = true;
2520                 ext_attr->has_smatx = true;
2521                 ext_attr->has_smarx = true;
2522                 ext_attr->has_gpio = true;
2523                 ext_attr->has_irqn = true;
2524                 break;
2525         case 0x34:
2526                 ext_attr->has_lna = false;
2527                 ext_attr->has_ntsc = true;
2528                 ext_attr->has_btsc = true;
2529                 ext_attr->has_oob = true;
2530                 ext_attr->has_smatx = true;
2531                 ext_attr->has_smarx = true;
2532                 ext_attr->has_gpio = true;
2533                 ext_attr->has_irqn = true;
2534                 break;
2535         case 0x42:
2536                 ext_attr->has_lna = true;
2537                 ext_attr->has_ntsc = true;
2538                 ext_attr->has_btsc = true;
2539                 ext_attr->has_oob = true;
2540                 ext_attr->has_smatx = true;
2541                 ext_attr->has_smarx = true;
2542                 ext_attr->has_gpio = true;
2543                 ext_attr->has_irqn = true;
2544                 break;
2545         case 0x44:
2546                 ext_attr->has_lna = false;
2547                 ext_attr->has_ntsc = true;
2548                 ext_attr->has_btsc = true;
2549                 ext_attr->has_oob = true;
2550                 ext_attr->has_smatx = true;
2551                 ext_attr->has_smarx = true;
2552                 ext_attr->has_gpio = true;
2553                 ext_attr->has_irqn = true;
2554                 break;
2555         default:
2556                 /* Unknown device variant */
2557                 return -EIO;
2558                 break;
2559         }
2560
2561         return 0;
2562 rw_error:
2563         return -EIO;
2564 }
2565
2566 /**
2567 * \fn int power_up_device()
2568 * \brief Power up device.
2569 * \param demod  Pointer to demodulator instance.
2570 * \return int.
2571 * \return 0    Success
2572 * \retval -EIO Failure, I2C or max retries reached
2573 *
2574 */
2575
2576 #ifndef DRXJ_MAX_RETRIES_POWERUP
2577 #define DRXJ_MAX_RETRIES_POWERUP 10
2578 #endif
2579
2580 static int power_up_device(struct drx_demod_instance *demod)
2581 {
2582         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2583         u8 data = 0;
2584         u16 retry_count = 0;
2585         struct i2c_device_addr wake_up_addr;
2586
2587         dev_addr = demod->my_i2c_dev_addr;
2588         wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2589         wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2590         wake_up_addr.user_data = dev_addr->user_data;
2591         /*
2592          * I2C access may fail in this case: no ack
2593          * dummy write must be used to wake uop device, dummy read must be used to
2594          * reset HI state machine (avoiding actual writes)
2595          */
2596         do {
2597                 data = 0;
2598                 drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
2599                                       (struct i2c_device_addr *)(NULL), 0,
2600                                      (u8 *)(NULL));
2601                 drxbsp_hst_sleep(10);
2602                 retry_count++;
2603         } while ((drxbsp_i2c_write_read
2604                   ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
2605                    &data)
2606                   != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
2607
2608         /* Need some recovery time .... */
2609         drxbsp_hst_sleep(10);
2610
2611         if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
2612                 return -EIO;
2613
2614         return 0;
2615 }
2616
2617 /*----------------------------------------------------------------------------*/
2618 /* MPEG Output Configuration Functions - begin                                */
2619 /*----------------------------------------------------------------------------*/
2620 /**
2621 * \fn int ctrl_set_cfg_mpeg_output()
2622 * \brief Set MPEG output configuration of the device.
2623 * \param devmod  Pointer to demodulator instance.
2624 * \param cfg_data Pointer to mpeg output configuaration.
2625 * \return int.
2626 *
2627 *  Configure MPEG output parameters.
2628 *
2629 */
2630 static int
2631 ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
2632 {
2633         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2634         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2635         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2636         int rc;
2637         u16 fec_oc_reg_mode = 0;
2638         u16 fec_oc_reg_ipr_mode = 0;
2639         u16 fec_oc_reg_ipr_invert = 0;
2640         u32 max_bit_rate = 0;
2641         u32 rcn_rate = 0;
2642         u32 nr_bits = 0;
2643         u16 sio_pdr_md_cfg = 0;
2644         /* data mask for the output data byte */
2645         u16 invert_data_mask =
2646             FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2647             FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2648             FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2649             FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2650
2651         /* check arguments */
2652         if ((demod == NULL) || (cfg_data == NULL))
2653                 return -EINVAL;
2654
2655         dev_addr = demod->my_i2c_dev_addr;
2656         ext_attr = (struct drxj_data *) demod->my_ext_attr;
2657         common_attr = (struct drx_common_attr *) demod->my_common_attr;
2658
2659         if (cfg_data->enable_mpeg_output == true) {
2660                 /* quick and dirty patch to set MPEG incase current std is not
2661                    producing MPEG */
2662                 switch (ext_attr->standard) {
2663                 case DRX_STANDARD_8VSB:
2664                 case DRX_STANDARD_ITU_A:
2665                 case DRX_STANDARD_ITU_B:
2666                 case DRX_STANDARD_ITU_C:
2667                         break;
2668                 default:
2669                         /* not an MPEG producing std, just store MPEG cfg */
2670                         common_attr->mpeg_cfg.enable_mpeg_output =
2671                             cfg_data->enable_mpeg_output;
2672                         common_attr->mpeg_cfg.insert_rs_byte =
2673                             cfg_data->insert_rs_byte;
2674                         common_attr->mpeg_cfg.enable_parallel =
2675                             cfg_data->enable_parallel;
2676                         common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
2677                         common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
2678                         common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
2679                         common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
2680                         common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
2681                         common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
2682                         common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
2683                         return 0;
2684                 }
2685
2686                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
2687                 if (rc != 0) {
2688                         pr_err("error %d\n", rc);
2689                         goto rw_error;
2690                 }
2691                 switch (ext_attr->standard) {
2692                 case DRX_STANDARD_8VSB:
2693                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
2694                         if (rc != 0) {
2695                                 pr_err("error %d\n", rc);
2696                                 goto rw_error;
2697                         }       /* 2048 bytes fifo ram */
2698                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
2699                         if (rc != 0) {
2700                                 pr_err("error %d\n", rc);
2701                                 goto rw_error;
2702                         }
2703                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
2704                         if (rc != 0) {
2705                                 pr_err("error %d\n", rc);
2706                                 goto rw_error;
2707                         }
2708                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
2709                         if (rc != 0) {
2710                                 pr_err("error %d\n", rc);
2711                                 goto rw_error;
2712                         }
2713                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
2714                         if (rc != 0) {
2715                                 pr_err("error %d\n", rc);
2716                                 goto rw_error;
2717                         }
2718                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
2719                         if (rc != 0) {
2720                                 pr_err("error %d\n", rc);
2721                                 goto rw_error;
2722                         }
2723                         /* Low Water Mark for synchronization  */
2724                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
2725                         if (rc != 0) {
2726                                 pr_err("error %d\n", rc);
2727                                 goto rw_error;
2728                         }
2729                         /* High Water Mark for synchronization */
2730                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
2731                         if (rc != 0) {
2732                                 pr_err("error %d\n", rc);
2733                                 goto rw_error;
2734                         }
2735                         break;
2736                 case DRX_STANDARD_ITU_A:
2737                 case DRX_STANDARD_ITU_C:
2738                         switch (ext_attr->constellation) {
2739                         case DRX_CONSTELLATION_QAM256:
2740                                 nr_bits = 8;
2741                                 break;
2742                         case DRX_CONSTELLATION_QAM128:
2743                                 nr_bits = 7;
2744                                 break;
2745                         case DRX_CONSTELLATION_QAM64:
2746                                 nr_bits = 6;
2747                                 break;
2748                         case DRX_CONSTELLATION_QAM32:
2749                                 nr_bits = 5;
2750                                 break;
2751                         case DRX_CONSTELLATION_QAM16:
2752                                 nr_bits = 4;
2753                                 break;
2754                         default:
2755                                 return -EIO;
2756                         }       /* ext_attr->constellation */
2757                         /* max_bit_rate = symbol_rate * nr_bits * coef */
2758                         /* coef = 188/204                          */
2759                         max_bit_rate =
2760                             (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
2761                         /* pass through b/c Annex A/c need following settings */
2762                 case DRX_STANDARD_ITU_B:
2763                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
2764                         if (rc != 0) {
2765                                 pr_err("error %d\n", rc);
2766                                 goto rw_error;
2767                         }
2768                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
2769                         if (rc != 0) {
2770                                 pr_err("error %d\n", rc);
2771                                 goto rw_error;
2772                         }
2773                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
2774                         if (rc != 0) {
2775                                 pr_err("error %d\n", rc);
2776                                 goto rw_error;
2777                         }
2778                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
2779                         if (rc != 0) {
2780                                 pr_err("error %d\n", rc);
2781                                 goto rw_error;
2782                         }
2783                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
2784                         if (rc != 0) {
2785                                 pr_err("error %d\n", rc);
2786                                 goto rw_error;
2787                         }
2788                         if (cfg_data->static_clk == true) {
2789                                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
2790                                 if (rc != 0) {
2791                                         pr_err("error %d\n", rc);
2792                                         goto rw_error;
2793                                 }
2794                         } else {
2795                                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
2796                                 if (rc != 0) {
2797                                         pr_err("error %d\n", rc);
2798                                         goto rw_error;
2799                                 }
2800                         }
2801                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
2802                         if (rc != 0) {
2803                                 pr_err("error %d\n", rc);
2804                                 goto rw_error;
2805                         }
2806                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
2807                         if (rc != 0) {
2808                                 pr_err("error %d\n", rc);
2809                                 goto rw_error;
2810                         }
2811                         break;
2812                 default:
2813                         break;
2814                 }               /* swtich (standard) */
2815
2816                 /* Check insertion of the Reed-Solomon parity bytes */
2817                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
2818                 if (rc != 0) {
2819                         pr_err("error %d\n", rc);
2820                         goto rw_error;
2821                 }
2822                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
2823                 if (rc != 0) {
2824                         pr_err("error %d\n", rc);
2825                         goto rw_error;
2826                 }
2827                 if (cfg_data->insert_rs_byte == true) {
2828                         /* enable parity symbol forward */
2829                         fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
2830                         /* MVAL disable during parity bytes */
2831                         fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2832                         switch (ext_attr->standard) {
2833                         case DRX_STANDARD_8VSB:
2834                                 rcn_rate = 0x004854D3;
2835                                 break;
2836                         case DRX_STANDARD_ITU_B:
2837                                 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2838                                 switch (ext_attr->constellation) {
2839                                 case DRX_CONSTELLATION_QAM256:
2840                                         rcn_rate = 0x008945E7;
2841                                         break;
2842                                 case DRX_CONSTELLATION_QAM64:
2843                                         rcn_rate = 0x005F64D4;
2844                                         break;
2845                                 default:
2846                                         return -EIO;
2847                                 }
2848                                 break;
2849                         case DRX_STANDARD_ITU_A:
2850                         case DRX_STANDARD_ITU_C:
2851                                 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2852                                 rcn_rate =
2853                                     (frac28
2854                                      (max_bit_rate,
2855                                       (u32) (common_attr->sys_clock_freq / 8))) /
2856                                     188;
2857                                 break;
2858                         default:
2859                                 return -EIO;
2860                         }       /* ext_attr->standard */
2861                 } else {        /* insert_rs_byte == false */
2862
2863                         /* disable parity symbol forward */
2864                         fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2865                         /* MVAL enable during parity bytes */
2866                         fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2867                         switch (ext_attr->standard) {
2868                         case DRX_STANDARD_8VSB:
2869                                 rcn_rate = 0x0041605C;
2870                                 break;
2871                         case DRX_STANDARD_ITU_B:
2872                                 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2873                                 switch (ext_attr->constellation) {
2874                                 case DRX_CONSTELLATION_QAM256:
2875                                         rcn_rate = 0x0082D6A0;
2876                                         break;
2877                                 case DRX_CONSTELLATION_QAM64:
2878                                         rcn_rate = 0x005AEC1A;
2879                                         break;
2880                                 default:
2881                                         return -EIO;
2882                                 }
2883                                 break;
2884                         case DRX_STANDARD_ITU_A:
2885                         case DRX_STANDARD_ITU_C:
2886                                 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2887                                 rcn_rate =
2888                                     (frac28
2889                                      (max_bit_rate,
2890                                       (u32) (common_attr->sys_clock_freq / 8))) /
2891                                     204;
2892                                 break;
2893                         default:
2894                                 return -EIO;
2895                         }       /* ext_attr->standard */
2896                 }
2897
2898                 if (cfg_data->enable_parallel == true) {        /* MPEG data output is paralel -> clear ipr_mode[0] */
2899                         fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2900                 } else {        /* MPEG data output is serial -> set ipr_mode[0] */
2901                         fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
2902                 }
2903
2904                 /* Control slective inversion of output bits */
2905                 if (cfg_data->invert_data == true)
2906                         fec_oc_reg_ipr_invert |= invert_data_mask;
2907                 else
2908                         fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2909
2910                 if (cfg_data->invert_err == true)
2911                         fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2912                 else
2913                         fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2914
2915                 if (cfg_data->invert_str == true)
2916                         fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2917                 else
2918                         fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2919
2920                 if (cfg_data->invert_val == true)
2921                         fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2922                 else
2923                         fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2924
2925                 if (cfg_data->invert_clk == true)
2926                         fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
2927                 else
2928                         fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2929
2930                 if (cfg_data->static_clk == true) {     /* Static mode */
2931                         u32 dto_rate = 0;
2932                         u32 bit_rate = 0;
2933                         u16 fec_oc_dto_burst_len = 0;
2934                         u16 fec_oc_dto_period = 0;
2935
2936                         fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
2937
2938                         switch (ext_attr->standard) {
2939                         case DRX_STANDARD_8VSB:
2940                                 fec_oc_dto_period = 4;
2941                                 if (cfg_data->insert_rs_byte == true)
2942                                         fec_oc_dto_burst_len = 208;
2943                                 break;
2944                         case DRX_STANDARD_ITU_A:
2945                                 {
2946                                         u32 symbol_rate_th = 6400000;
2947                                         if (cfg_data->insert_rs_byte == true) {
2948                                                 fec_oc_dto_burst_len = 204;
2949                                                 symbol_rate_th = 5900000;
2950                                         }
2951                                         if (ext_attr->curr_symbol_rate >=
2952                                             symbol_rate_th) {
2953                                                 fec_oc_dto_period = 0;
2954                                         } else {
2955                                                 fec_oc_dto_period = 1;
2956                                         }
2957                                 }
2958                                 break;
2959                         case DRX_STANDARD_ITU_B:
2960                                 fec_oc_dto_period = 1;
2961                                 if (cfg_data->insert_rs_byte == true)
2962                                         fec_oc_dto_burst_len = 128;
2963                                 break;
2964                         case DRX_STANDARD_ITU_C:
2965                                 fec_oc_dto_period = 1;
2966                                 if (cfg_data->insert_rs_byte == true)
2967                                         fec_oc_dto_burst_len = 204;
2968                                 break;
2969                         default:
2970                                 return -EIO;
2971                         }
2972                         bit_rate =
2973                             common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
2974                                                                2);
2975                         dto_rate =
2976                             frac28(bit_rate, common_attr->sys_clock_freq * 1000);
2977                         dto_rate >>= 3;
2978                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
2979                         if (rc != 0) {
2980                                 pr_err("error %d\n", rc);
2981                                 goto rw_error;
2982                         }
2983                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_RATE_LO__A, (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), 0);
2984                         if (rc != 0) {
2985                                 pr_err("error %d\n", rc);
2986                                 goto rw_error;
2987                         }
2988                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M, 0);
2989                         if (rc != 0) {
2990                                 pr_err("error %d\n", rc);
2991                                 goto rw_error;
2992                         }
2993                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M, 0);
2994                         if (rc != 0) {
2995                                 pr_err("error %d\n", rc);
2996                                 goto rw_error;
2997                         }
2998                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
2999                         if (rc != 0) {
3000                                 pr_err("error %d\n", rc);
3001                                 goto rw_error;
3002                         }
3003                         if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3004                                 fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
3005                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
3006                         if (rc != 0) {
3007                                 pr_err("error %d\n", rc);
3008                                 goto rw_error;
3009                         }
3010                 } else {        /* Dynamic mode */
3011
3012                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
3013                         if (rc != 0) {
3014                                 pr_err("error %d\n", rc);
3015                                 goto rw_error;
3016                         }
3017                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
3018                         if (rc != 0) {
3019                                 pr_err("error %d\n", rc);
3020                                 goto rw_error;
3021                         }
3022                 }
3023
3024                 rc = DRXJ_DAP.write_reg32func(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
3025                 if (rc != 0) {
3026                         pr_err("error %d\n", rc);
3027                         goto rw_error;
3028                 }
3029
3030                 /* Write appropriate registers with requested configuration */
3031                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
3032                 if (rc != 0) {
3033                         pr_err("error %d\n", rc);
3034                         goto rw_error;
3035                 }
3036                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
3037                 if (rc != 0) {
3038                         pr_err("error %d\n", rc);
3039                         goto rw_error;
3040                 }
3041                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
3042                 if (rc != 0) {
3043                         pr_err("error %d\n", rc);
3044                         goto rw_error;
3045                 }
3046
3047                 /* enabling for both parallel and serial now */
3048                 /*  Write magic word to enable pdr reg write */
3049                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3050                 if (rc != 0) {
3051                         pr_err("error %d\n", rc);
3052                         goto rw_error;
3053                 }
3054                 /*  Set MPEG TS pads to outputmode */
3055                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
3056                 if (rc != 0) {
3057                         pr_err("error %d\n", rc);
3058                         goto rw_error;
3059                 }
3060                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
3061                 if (rc != 0) {
3062                         pr_err("error %d\n", rc);
3063                         goto rw_error;
3064                 }
3065                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MCLK_CFG__A, MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B | 0x03 << SIO_PDR_MCLK_CFG_MODE__B, 0);
3066                 if (rc != 0) {
3067                         pr_err("error %d\n", rc);
3068                         goto rw_error;
3069                 }
3070                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
3071                 if (rc != 0) {
3072                         pr_err("error %d\n", rc);
3073                         goto rw_error;
3074                 }
3075                 sio_pdr_md_cfg =
3076                     MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3077                     SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
3078                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3079                 if (rc != 0) {
3080                         pr_err("error %d\n", rc);
3081                         goto rw_error;
3082                 }
3083                 if (cfg_data->enable_parallel == true) {        /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
3084                         sio_pdr_md_cfg =
3085                             MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3086                             SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3087                             SIO_PDR_MD0_CFG_MODE__B;
3088                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3089                         if (rc != 0) {
3090                                 pr_err("error %d\n", rc);
3091                                 goto rw_error;
3092                         }
3093                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
3094                         if (rc != 0) {
3095                                 pr_err("error %d\n", rc);
3096                                 goto rw_error;
3097                         }
3098                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
3099                         if (rc != 0) {
3100                                 pr_err("error %d\n", rc);
3101                                 goto rw_error;
3102                         }
3103                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
3104                         if (rc != 0) {
3105                                 pr_err("error %d\n", rc);
3106                                 goto rw_error;
3107                         }
3108                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
3109                         if (rc != 0) {
3110                                 pr_err("error %d\n", rc);
3111                                 goto rw_error;
3112                         }
3113                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
3114                         if (rc != 0) {
3115                                 pr_err("error %d\n", rc);
3116                                 goto rw_error;
3117                         }
3118                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
3119                         if (rc != 0) {
3120                                 pr_err("error %d\n", rc);
3121                                 goto rw_error;
3122                         }
3123                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
3124                         if (rc != 0) {
3125                                 pr_err("error %d\n", rc);
3126                                 goto rw_error;
3127                         }
3128                 } else {        /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3129                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3130                         if (rc != 0) {
3131                                 pr_err("error %d\n", rc);
3132                                 goto rw_error;
3133                         }
3134                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3135                         if (rc != 0) {
3136                                 pr_err("error %d\n", rc);
3137                                 goto rw_error;
3138                         }
3139                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3140                         if (rc != 0) {
3141                                 pr_err("error %d\n", rc);
3142                                 goto rw_error;
3143                         }
3144                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3145                         if (rc != 0) {
3146                                 pr_err("error %d\n", rc);
3147                                 goto rw_error;
3148                         }
3149                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3150                         if (rc != 0) {
3151                                 pr_err("error %d\n", rc);
3152                                 goto rw_error;
3153                         }
3154                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3155                         if (rc != 0) {
3156                                 pr_err("error %d\n", rc);
3157                                 goto rw_error;
3158                         }
3159                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3160                         if (rc != 0) {
3161                                 pr_err("error %d\n", rc);
3162                                 goto rw_error;
3163                         }
3164                 }
3165                 /*  Enable Monitor Bus output over MPEG pads and ctl input */
3166                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3167                 if (rc != 0) {
3168                         pr_err("error %d\n", rc);
3169                         goto rw_error;
3170                 }
3171                 /*  Write nomagic word to enable pdr reg write */
3172                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3173                 if (rc != 0) {
3174                         pr_err("error %d\n", rc);
3175                         goto rw_error;
3176                 }
3177         } else {
3178                 /*  Write magic word to enable pdr reg write */
3179                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3180                 if (rc != 0) {
3181                         pr_err("error %d\n", rc);
3182                         goto rw_error;
3183                 }
3184                 /*  Set MPEG TS pads to inputmode */
3185                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
3186                 if (rc != 0) {
3187                         pr_err("error %d\n", rc);
3188                         goto rw_error;
3189                 }
3190                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
3191                 if (rc != 0) {
3192                         pr_err("error %d\n", rc);
3193                         goto rw_error;
3194                 }
3195                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
3196                 if (rc != 0) {
3197                         pr_err("error %d\n", rc);
3198                         goto rw_error;
3199                 }
3200                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
3201                 if (rc != 0) {
3202                         pr_err("error %d\n", rc);
3203                         goto rw_error;
3204                 }
3205                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
3206                 if (rc != 0) {
3207                         pr_err("error %d\n", rc);
3208                         goto rw_error;
3209                 }
3210                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3211                 if (rc != 0) {
3212                         pr_err("error %d\n", rc);
3213                         goto rw_error;
3214                 }
3215                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3216                 if (rc != 0) {
3217                         pr_err("error %d\n", rc);
3218                         goto rw_error;
3219                 }
3220                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3221                 if (rc != 0) {
3222                         pr_err("error %d\n", rc);
3223                         goto rw_error;
3224                 }
3225                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3226                 if (rc != 0) {
3227                         pr_err("error %d\n", rc);
3228                         goto rw_error;
3229                 }
3230                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3231                 if (rc != 0) {
3232                         pr_err("error %d\n", rc);
3233                         goto rw_error;
3234                 }
3235                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3236                 if (rc != 0) {
3237                         pr_err("error %d\n", rc);
3238                         goto rw_error;
3239                 }
3240                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3241                 if (rc != 0) {
3242                         pr_err("error %d\n", rc);
3243                         goto rw_error;
3244                 }
3245                 /* Enable Monitor Bus output over MPEG pads and ctl input */
3246                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3247                 if (rc != 0) {
3248                         pr_err("error %d\n", rc);
3249                         goto rw_error;
3250                 }
3251                 /* Write nomagic word to enable pdr reg write */
3252                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3253                 if (rc != 0) {
3254                         pr_err("error %d\n", rc);
3255                         goto rw_error;
3256                 }
3257         }
3258
3259         /* save values for restore after re-acquire */
3260         common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3261         common_attr->mpeg_cfg.insert_rs_byte = cfg_data->insert_rs_byte;
3262         common_attr->mpeg_cfg.enable_parallel = cfg_data->enable_parallel;
3263         common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
3264         common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
3265         common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
3266         common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
3267         common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
3268         common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
3269         common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
3270
3271         return 0;
3272 rw_error:
3273         return -EIO;
3274 }
3275
3276 /*----------------------------------------------------------------------------*/
3277
3278 /**
3279 * \fn int ctrl_get_cfg_mpeg_output()
3280 * \brief Get MPEG output configuration of the device.
3281 * \param devmod  Pointer to demodulator instance.
3282 * \param cfg_data Pointer to MPEG output configuaration struct.
3283 * \return int.
3284 *
3285 *  Retrieve MPEG output configuartion.
3286 *
3287 */
3288 static int
3289 ctrl_get_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
3290 {
3291         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3292         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
3293         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
3294         int rc;
3295         u32 rate_reg = 0;
3296         u32 data64hi = 0;
3297         u32 data64lo = 0;
3298
3299         if (cfg_data == NULL)
3300                 return -EINVAL;
3301
3302         dev_addr = demod->my_i2c_dev_addr;
3303         common_attr = demod->my_common_attr;
3304
3305         cfg_data->enable_mpeg_output = common_attr->mpeg_cfg.enable_mpeg_output;
3306         cfg_data->insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
3307         cfg_data->enable_parallel = common_attr->mpeg_cfg.enable_parallel;
3308         cfg_data->invert_data = common_attr->mpeg_cfg.invert_data;
3309         cfg_data->invert_err = common_attr->mpeg_cfg.invert_err;
3310         cfg_data->invert_str = common_attr->mpeg_cfg.invert_str;
3311         cfg_data->invert_val = common_attr->mpeg_cfg.invert_val;
3312         cfg_data->invert_clk = common_attr->mpeg_cfg.invert_clk;
3313         cfg_data->static_clk = common_attr->mpeg_cfg.static_clk;
3314         cfg_data->bitrate = 0;
3315
3316         rc = ctrl_lock_status(demod, &lock_status);
3317         if (rc != 0) {
3318                 pr_err("error %d\n", rc);
3319                 goto rw_error;
3320         }
3321         if ((lock_status == DRX_LOCKED)) {
3322                 rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_RCN_DYN_RATE_LO__A, &rate_reg, 0);
3323                 if (rc != 0) {
3324                         pr_err("error %d\n", rc);
3325                         goto rw_error;
3326                 }
3327                 /* Frcn_rate = rate_reg * Fsys / 2 ^ 25 */
3328                 mult32(rate_reg, common_attr->sys_clock_freq * 1000, &data64hi,
3329                        &data64lo);
3330                 cfg_data->bitrate = (data64hi << 7) | (data64lo >> 25);
3331         }
3332
3333         return 0;
3334 rw_error:
3335         return -EIO;
3336 }
3337
3338 /*----------------------------------------------------------------------------*/
3339 /* MPEG Output Configuration Functions - end                                  */
3340 /*----------------------------------------------------------------------------*/
3341
3342 /*----------------------------------------------------------------------------*/
3343 /* miscellaneous configuartions - begin                           */
3344 /*----------------------------------------------------------------------------*/
3345
3346 /**
3347 * \fn int set_mpegtei_handling()
3348 * \brief Activate MPEG TEI handling settings.
3349 * \param devmod  Pointer to demodulator instance.
3350 * \return int.
3351 *
3352 * This routine should be called during a set channel of QAM/VSB
3353 *
3354 */
3355 static int set_mpegtei_handling(struct drx_demod_instance *demod)
3356 {
3357         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3358         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3359         int rc;
3360         u16 fec_oc_dpr_mode = 0;
3361         u16 fec_oc_snc_mode = 0;
3362         u16 fec_oc_ems_mode = 0;
3363
3364         dev_addr = demod->my_i2c_dev_addr;
3365         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3366
3367         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
3368         if (rc != 0) {
3369                 pr_err("error %d\n", rc);
3370                 goto rw_error;
3371         }
3372         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
3373         if (rc != 0) {
3374                 pr_err("error %d\n", rc);
3375                 goto rw_error;
3376         }
3377         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
3378         if (rc != 0) {
3379                 pr_err("error %d\n", rc);
3380                 goto rw_error;
3381         }
3382
3383         /* reset to default, allow TEI bit to be changed */
3384         fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3385         fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3386                            FEC_OC_SNC_MODE_CORR_DISABLE__M));
3387         fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
3388
3389         if (ext_attr->disable_te_ihandling) {
3390                 /* do not change TEI bit */
3391                 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3392                 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3393                     ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3394                 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3395         }
3396
3397         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
3398         if (rc != 0) {
3399                 pr_err("error %d\n", rc);
3400                 goto rw_error;
3401         }
3402         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
3403         if (rc != 0) {
3404                 pr_err("error %d\n", rc);
3405                 goto rw_error;
3406         }
3407         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
3408         if (rc != 0) {
3409                 pr_err("error %d\n", rc);
3410                 goto rw_error;
3411         }
3412
3413         return 0;
3414 rw_error:
3415         return -EIO;
3416 }
3417
3418 /*----------------------------------------------------------------------------*/
3419 /**
3420 * \fn int bit_reverse_mpeg_output()
3421 * \brief Set MPEG output bit-endian settings.
3422 * \param devmod  Pointer to demodulator instance.
3423 * \return int.
3424 *
3425 * This routine should be called during a set channel of QAM/VSB
3426 *
3427 */
3428 static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
3429 {
3430         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3431         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3432         int rc;
3433         u16 fec_oc_ipr_mode = 0;
3434
3435         dev_addr = demod->my_i2c_dev_addr;
3436         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3437
3438         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
3439         if (rc != 0) {
3440                 pr_err("error %d\n", rc);
3441                 goto rw_error;
3442         }
3443
3444         /* reset to default (normal bit order) */
3445         fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3446
3447         if (ext_attr->bit_reverse_mpeg_outout)
3448                 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3449
3450         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
3451         if (rc != 0) {
3452                 pr_err("error %d\n", rc);
3453                 goto rw_error;
3454         }
3455
3456         return 0;
3457 rw_error:
3458         return -EIO;
3459 }
3460
3461 /*----------------------------------------------------------------------------*/
3462 /**
3463 * \fn int set_mpeg_output_clock_rate()
3464 * \brief Set MPEG output clock rate.
3465 * \param devmod  Pointer to demodulator instance.
3466 * \return int.
3467 *
3468 * This routine should be called during a set channel of QAM/VSB
3469 *
3470 */
3471 static int set_mpeg_output_clock_rate(struct drx_demod_instance *demod)
3472 {
3473         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3474         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3475         int rc;
3476
3477         dev_addr = demod->my_i2c_dev_addr;
3478         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3479
3480         if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3481                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_PERIOD__A, ext_attr->mpeg_output_clock_rate - 1, 0);
3482                 if (rc != 0) {
3483                         pr_err("error %d\n", rc);
3484                         goto rw_error;
3485                 }
3486         }
3487
3488         return 0;
3489 rw_error:
3490         return -EIO;
3491 }
3492
3493 /*----------------------------------------------------------------------------*/
3494 /**
3495 * \fn int set_mpeg_start_width()
3496 * \brief Set MPEG start width.
3497 * \param devmod  Pointer to demodulator instance.
3498 * \return int.
3499 *
3500 * This routine should be called during a set channel of QAM/VSB
3501 *
3502 */
3503 static int set_mpeg_start_width(struct drx_demod_instance *demod)
3504 {
3505         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3506         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3507         struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
3508         int rc;
3509         u16 fec_oc_comm_mb = 0;
3510
3511         dev_addr = demod->my_i2c_dev_addr;
3512         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3513         common_attr = demod->my_common_attr;
3514
3515         if ((common_attr->mpeg_cfg.static_clk == true)
3516             && (common_attr->mpeg_cfg.enable_parallel == false)) {
3517                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
3518                 if (rc != 0) {
3519                         pr_err("error %d\n", rc);
3520                         goto rw_error;
3521                 }
3522                 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3523                 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
3524                         fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
3525                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
3526                 if (rc != 0) {
3527                         pr_err("error %d\n", rc);
3528                         goto rw_error;
3529                 }
3530         }
3531
3532         return 0;
3533 rw_error:
3534         return -EIO;
3535 }
3536
3537 /*----------------------------------------------------------------------------*/
3538 /**
3539 * \fn int ctrl_set_cfg_mpeg_output_misc()
3540 * \brief Set miscellaneous configuartions
3541 * \param devmod  Pointer to demodulator instance.
3542 * \param cfg_data pDRXJCfgMisc_t
3543 * \return int.
3544 *
3545 *  This routine can be used to set configuartion options that are DRXJ
3546 *  specific and/or added to the requirements at a late stage.
3547 *
3548 */
3549 static int
3550 ctrl_set_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3551                               struct drxj_cfg_mpeg_output_misc *cfg_data)
3552 {
3553         struct drxj_data *ext_attr = NULL;
3554         int rc;
3555
3556         if (cfg_data == NULL)
3557                 return -EINVAL;
3558
3559         ext_attr = demod->my_ext_attr;
3560
3561         /*
3562            Set disable TEI bit handling flag.
3563            TEI must be left untouched by device in case of BER measurements using
3564            external equipment that is unable to ignore the TEI bit in the TS.
3565            Default will false (enable TEI bit handling).
3566            Reverse output bit order. Default is false (msb on MD7 (parallel) or out first (serial)).
3567            Set clock rate. Default is auto that is derived from symbol rate.
3568            The flags and values will also be used to set registers during a set channel.
3569          */
3570         ext_attr->disable_te_ihandling = cfg_data->disable_tei_handling;
3571         ext_attr->bit_reverse_mpeg_outout = cfg_data->bit_reverse_mpeg_outout;
3572         ext_attr->mpeg_output_clock_rate = cfg_data->mpeg_output_clock_rate;
3573         ext_attr->mpeg_start_width = cfg_data->mpeg_start_width;
3574         /* Don't care what the active standard is, activate setting immediatly */
3575         rc = set_mpegtei_handling(demod);
3576         if (rc != 0) {
3577                 pr_err("error %d\n", rc);
3578                 goto rw_error;
3579         }
3580         rc = bit_reverse_mpeg_output(demod);
3581         if (rc != 0) {
3582                 pr_err("error %d\n", rc);
3583                 goto rw_error;
3584         }
3585         rc = set_mpeg_output_clock_rate(demod);
3586         if (rc != 0) {
3587                 pr_err("error %d\n", rc);
3588                 goto rw_error;
3589         }
3590         rc = set_mpeg_start_width(demod);
3591         if (rc != 0) {
3592                 pr_err("error %d\n", rc);
3593                 goto rw_error;
3594         }
3595
3596         return 0;
3597 rw_error:
3598         return -EIO;
3599 }
3600
3601 /*----------------------------------------------------------------------------*/
3602
3603 /**
3604 * \fn int ctrl_get_cfg_mpeg_output_misc()
3605 * \brief Get miscellaneous configuartions.
3606 * \param devmod  Pointer to demodulator instance.
3607 * \param cfg_data Pointer to DRXJCfgMisc_t.
3608 * \return int.
3609 *
3610 *  This routine can be used to retreive the current setting of the configuartion
3611 *  options that are DRXJ specific and/or added to the requirements at a
3612 *  late stage.
3613 *
3614 */
3615 static int
3616 ctrl_get_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3617                               struct drxj_cfg_mpeg_output_misc *cfg_data)
3618 {
3619         struct drxj_data *ext_attr = NULL;
3620         int rc;
3621         u16 data = 0;
3622
3623         if (cfg_data == NULL)
3624                 return -EINVAL;
3625
3626         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3627         cfg_data->disable_tei_handling = ext_attr->disable_te_ihandling;
3628         cfg_data->bit_reverse_mpeg_outout = ext_attr->bit_reverse_mpeg_outout;
3629         cfg_data->mpeg_start_width = ext_attr->mpeg_start_width;
3630         if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3631                 cfg_data->mpeg_output_clock_rate = ext_attr->mpeg_output_clock_rate;
3632         } else {
3633                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, FEC_OC_DTO_PERIOD__A, &data, 0);
3634                 if (rc != 0) {
3635                         pr_err("error %d\n", rc);
3636                         goto rw_error;
3637                 }
3638                 cfg_data->mpeg_output_clock_rate =
3639                     (enum drxj_mpeg_output_clock_rate) (data + 1);
3640         }
3641
3642         return 0;
3643 rw_error:
3644         return -EIO;
3645 }
3646
3647 /*----------------------------------------------------------------------------*/
3648
3649 /**
3650 * \fn int ctrl_get_cfg_hw_cfg()
3651 * \brief Get HW configuartions.
3652 * \param devmod  Pointer to demodulator instance.
3653 * \param cfg_data Pointer to Bool.
3654 * \return int.
3655 *
3656 *  This routine can be used to retreive the current setting of the configuartion
3657 *  options that are DRXJ specific and/or added to the requirements at a
3658 *  late stage.
3659 *
3660 */
3661 static int
3662 ctrl_get_cfg_hw_cfg(struct drx_demod_instance *demod, struct drxj_cfg_hw_cfg *cfg_data)
3663 {
3664         int rc;
3665         u16 data = 0;
3666
3667         if (cfg_data == NULL)
3668                 return -EINVAL;
3669
3670         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3671         if (rc != 0) {
3672                 pr_err("error %d\n", rc);
3673                 goto rw_error;
3674         }
3675         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_OHW_CFG__A, &data, 0);
3676         if (rc != 0) {
3677                 pr_err("error %d\n", rc);
3678                 goto rw_error;
3679         }
3680         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3681         if (rc != 0) {
3682                 pr_err("error %d\n", rc);
3683                 goto rw_error;
3684         }
3685
3686         cfg_data->i2c_speed = (enum drxji2c_speed) ((data >> 6) & 0x1);
3687         cfg_data->xtal_freq = (enum drxj_xtal_freq) (data & 0x3);
3688
3689         return 0;
3690 rw_error:
3691         return -EIO;
3692 }
3693
3694 /*----------------------------------------------------------------------------*/
3695 /* miscellaneous configuartions - end                             */
3696 /*----------------------------------------------------------------------------*/
3697
3698 /*----------------------------------------------------------------------------*/
3699 /* UIO Configuration Functions - begin                                        */
3700 /*----------------------------------------------------------------------------*/
3701 /**
3702 * \fn int ctrl_set_uio_cfg()
3703 * \brief Configure modus oprandi UIO.
3704 * \param demod Pointer to demodulator instance.
3705 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3706 * \return int.
3707 */
3708 static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3709 {
3710         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3711         int rc;
3712
3713         if ((uio_cfg == NULL) || (demod == NULL))
3714                 return -EINVAL;
3715
3716         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3717
3718         /*  Write magic word to enable pdr reg write               */
3719         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3720         if (rc != 0) {
3721                 pr_err("error %d\n", rc);
3722                 goto rw_error;
3723         }
3724         switch (uio_cfg->uio) {
3725       /*====================================================================*/
3726         case DRX_UIO1:
3727                 /* DRX_UIO1: SMA_TX UIO-1 */
3728                 if (!ext_attr->has_smatx)
3729                         return -EIO;
3730                 switch (uio_cfg->mode) {
3731                 case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
3732                 case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
3733                 case DRX_UIO_MODE_READWRITE:
3734                         ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3735                         break;
3736                 case DRX_UIO_MODE_DISABLE:
3737                         ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3738                         /* pad configuration register is set 0 - input mode */
3739                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
3740                         if (rc != 0) {
3741                                 pr_err("error %d\n", rc);
3742                                 goto rw_error;
3743                         }
3744                         break;
3745                 default:
3746                         return -EINVAL;
3747                 }               /* switch ( uio_cfg->mode ) */
3748                 break;
3749       /*====================================================================*/
3750         case DRX_UIO2:
3751                 /* DRX_UIO2: SMA_RX UIO-2 */
3752                 if (!ext_attr->has_smarx)
3753                         return -EIO;
3754                 switch (uio_cfg->mode) {
3755                 case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
3756                 case DRX_UIO_MODE_READWRITE:
3757                         ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3758                         break;
3759                 case DRX_UIO_MODE_DISABLE:
3760                         ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3761                         /* pad configuration register is set 0 - input mode */
3762                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
3763                         if (rc != 0) {
3764                                 pr_err("error %d\n", rc);
3765                                 goto rw_error;
3766                         }
3767                         break;
3768                 default:
3769                         return -EINVAL;
3770                         break;
3771                 }               /* switch ( uio_cfg->mode ) */
3772                 break;
3773       /*====================================================================*/
3774         case DRX_UIO3:
3775                 /* DRX_UIO3: GPIO UIO-3 */
3776                 if (!ext_attr->has_gpio)
3777                         return -EIO;
3778                 switch (uio_cfg->mode) {
3779                 case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
3780                 case DRX_UIO_MODE_READWRITE:
3781                         ext_attr->uio_gpio_mode = uio_cfg->mode;
3782                         break;
3783                 case DRX_UIO_MODE_DISABLE:
3784                         ext_attr->uio_gpio_mode = uio_cfg->mode;
3785                         /* pad configuration register is set 0 - input mode */
3786                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
3787                         if (rc != 0) {
3788                                 pr_err("error %d\n", rc);
3789                                 goto rw_error;
3790                         }
3791                         break;
3792                 default:
3793                         return -EINVAL;
3794                         break;
3795                 }               /* switch ( uio_cfg->mode ) */
3796                 break;
3797       /*====================================================================*/
3798         case DRX_UIO4:
3799                 /* DRX_UIO4: IRQN UIO-4 */
3800                 if (!ext_attr->has_irqn)
3801                         return -EIO;
3802                 switch (uio_cfg->mode) {
3803                 case DRX_UIO_MODE_READWRITE:
3804                         ext_attr->uio_irqn_mode = uio_cfg->mode;
3805                         break;
3806                 case DRX_UIO_MODE_DISABLE:
3807                         /* pad configuration register is set 0 - input mode */
3808                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
3809                         if (rc != 0) {
3810                                 pr_err("error %d\n", rc);
3811                                 goto rw_error;
3812                         }
3813                         ext_attr->uio_irqn_mode = uio_cfg->mode;
3814                         break;
3815                 case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
3816                 default:
3817                         return -EINVAL;
3818                         break;
3819                 }               /* switch ( uio_cfg->mode ) */
3820                 break;
3821       /*====================================================================*/
3822         default:
3823                 return -EINVAL;
3824         }                       /* switch ( uio_cfg->uio ) */
3825
3826         /*  Write magic word to disable pdr reg write               */
3827         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3828         if (rc != 0) {
3829                 pr_err("error %d\n", rc);
3830                 goto rw_error;
3831         }
3832
3833         return 0;
3834 rw_error:
3835         return -EIO;
3836 }
3837
3838 /*============================================================================*/
3839 /**
3840 * \fn int ctrl_getuio_cfg()
3841 * \brief Get modus oprandi UIO.
3842 * \param demod Pointer to demodulator instance.
3843 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3844 * \return int.
3845 */
3846 static int ctrl_getuio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3847 {
3848
3849         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
3850         enum drxuio_mode *uio_mode[4] = { NULL };
3851         bool *uio_available[4] = { NULL };
3852
3853         ext_attr = demod->my_ext_attr;
3854
3855         uio_mode[DRX_UIO1] = &ext_attr->uio_sma_tx_mode;
3856         uio_mode[DRX_UIO2] = &ext_attr->uio_sma_rx_mode;
3857         uio_mode[DRX_UIO3] = &ext_attr->uio_gpio_mode;
3858         uio_mode[DRX_UIO4] = &ext_attr->uio_irqn_mode;
3859
3860         uio_available[DRX_UIO1] = &ext_attr->has_smatx;
3861         uio_available[DRX_UIO2] = &ext_attr->has_smarx;
3862         uio_available[DRX_UIO3] = &ext_attr->has_gpio;
3863         uio_available[DRX_UIO4] = &ext_attr->has_irqn;
3864
3865         if (uio_cfg == NULL)
3866                 return -EINVAL;
3867
3868         if ((uio_cfg->uio > DRX_UIO4) || (uio_cfg->uio < DRX_UIO1))
3869                 return -EINVAL;
3870
3871         if (!*uio_available[uio_cfg->uio])
3872                 return -EIO;
3873
3874         uio_cfg->mode = *uio_mode[uio_cfg->uio];
3875
3876         return 0;
3877 }
3878
3879 /**
3880 * \fn int ctrl_uio_write()
3881 * \brief Write to a UIO.
3882 * \param demod Pointer to demodulator instance.
3883 * \param uio_data Pointer to data container for a certain UIO.
3884 * \return int.
3885 */
3886 static int
3887 ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
3888 {
3889         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3890         int rc;
3891         u16 pin_cfg_value = 0;
3892         u16 value = 0;
3893
3894         if ((uio_data == NULL) || (demod == NULL))
3895                 return -EINVAL;
3896
3897         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3898
3899         /*  Write magic word to enable pdr reg write               */
3900         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3901         if (rc != 0) {
3902                 pr_err("error %d\n", rc);
3903                 goto rw_error;
3904         }
3905         switch (uio_data->uio) {
3906       /*====================================================================*/
3907         case DRX_UIO1:
3908                 /* DRX_UIO1: SMA_TX UIO-1 */
3909                 if (!ext_attr->has_smatx)
3910                         return -EIO;
3911                 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3912                     && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3913                         return -EIO;
3914                 }
3915                 pin_cfg_value = 0;
3916                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3917                 pin_cfg_value |= 0x0113;
3918                 /* io_pad_cfg_mode output mode is drive always */
3919                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3920
3921                 /* write to io pad configuration register - output mode */
3922                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
3923                 if (rc != 0) {
3924                         pr_err("error %d\n", rc);
3925                         goto rw_error;
3926                 }
3927
3928                 /* use corresponding bit in io data output registar */
3929                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3930                 if (rc != 0) {
3931                         pr_err("error %d\n", rc);
3932                         goto rw_error;
3933                 }
3934                 if (!uio_data->value)
3935                         value &= 0x7FFF;        /* write zero to 15th bit - 1st UIO */
3936                 else
3937                         value |= 0x8000;        /* write one to 15th bit - 1st UIO */
3938
3939                 /* write back to io data output register */
3940                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3941                 if (rc != 0) {
3942                         pr_err("error %d\n", rc);
3943                         goto rw_error;
3944                 }
3945                 break;
3946    /*======================================================================*/
3947         case DRX_UIO2:
3948                 /* DRX_UIO2: SMA_RX UIO-2 */
3949                 if (!ext_attr->has_smarx)
3950                         return -EIO;
3951                 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
3952                         return -EIO;
3953
3954                 pin_cfg_value = 0;
3955                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3956                 pin_cfg_value |= 0x0113;
3957                 /* io_pad_cfg_mode output mode is drive always */
3958                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3959
3960                 /* write to io pad configuration register - output mode */
3961                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
3962                 if (rc != 0) {
3963                         pr_err("error %d\n", rc);
3964                         goto rw_error;
3965                 }
3966
3967                 /* use corresponding bit in io data output registar */
3968                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3969                 if (rc != 0) {
3970                         pr_err("error %d\n", rc);
3971                         goto rw_error;
3972                 }
3973                 if (!uio_data->value)
3974                         value &= 0xBFFF;        /* write zero to 14th bit - 2nd UIO */
3975                 else
3976                         value |= 0x4000;        /* write one to 14th bit - 2nd UIO */
3977
3978                 /* write back to io data output register */
3979                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3980                 if (rc != 0) {
3981                         pr_err("error %d\n", rc);
3982                         goto rw_error;
3983                 }
3984                 break;
3985    /*====================================================================*/
3986         case DRX_UIO3:
3987                 /* DRX_UIO3: ASEL UIO-3 */
3988                 if (!ext_attr->has_gpio)
3989                         return -EIO;
3990                 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
3991                         return -EIO;
3992
3993                 pin_cfg_value = 0;
3994                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3995                 pin_cfg_value |= 0x0113;
3996                 /* io_pad_cfg_mode output mode is drive always */
3997                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3998
3999                 /* write to io pad configuration register - output mode */
4000                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
4001                 if (rc != 0) {
4002                         pr_err("error %d\n", rc);
4003                         goto rw_error;
4004                 }
4005
4006                 /* use corresponding bit in io data output registar */
4007                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
4008                 if (rc != 0) {
4009                         pr_err("error %d\n", rc);
4010                         goto rw_error;
4011                 }
4012                 if (!uio_data->value)
4013                         value &= 0xFFFB;        /* write zero to 2nd bit - 3rd UIO */
4014                 else
4015                         value |= 0x0004;        /* write one to 2nd bit - 3rd UIO */
4016
4017                 /* write back to io data output register */
4018                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
4019                 if (rc != 0) {
4020                         pr_err("error %d\n", rc);
4021                         goto rw_error;
4022                 }
4023                 break;
4024    /*=====================================================================*/
4025         case DRX_UIO4:
4026                 /* DRX_UIO4: IRQN UIO-4 */
4027                 if (!ext_attr->has_irqn)
4028                         return -EIO;
4029
4030                 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
4031                         return -EIO;
4032
4033                 pin_cfg_value = 0;
4034                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4035                 pin_cfg_value |= 0x0113;
4036                 /* io_pad_cfg_mode output mode is drive always */
4037                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4038
4039                 /* write to io pad configuration register - output mode */
4040                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
4041                 if (rc != 0) {
4042                         pr_err("error %d\n", rc);
4043                         goto rw_error;
4044                 }
4045
4046                 /* use corresponding bit in io data output registar */
4047                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
4048                 if (rc != 0) {
4049                         pr_err("error %d\n", rc);
4050                         goto rw_error;
4051                 }
4052                 if (uio_data->value == false)
4053                         value &= 0xEFFF;        /* write zero to 12th bit - 4th UIO */
4054                 else
4055                         value |= 0x1000;        /* write one to 12th bit - 4th UIO */
4056
4057                 /* write back to io data output register */
4058                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
4059                 if (rc != 0) {
4060                         pr_err("error %d\n", rc);
4061                         goto rw_error;
4062                 }
4063                 break;
4064       /*=====================================================================*/
4065         default:
4066                 return -EINVAL;
4067         }                       /* switch ( uio_data->uio ) */
4068
4069         /*  Write magic word to disable pdr reg write               */
4070         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4071         if (rc != 0) {
4072                 pr_err("error %d\n", rc);
4073                 goto rw_error;
4074         }
4075
4076         return 0;
4077 rw_error:
4078         return -EIO;
4079 }
4080
4081 /**
4082 *\fn int ctrl_uio_read
4083 *\brief Read from a UIO.
4084 * \param demod Pointer to demodulator instance.
4085 * \param uio_data Pointer to data container for a certain UIO.
4086 * \return int.
4087 */
4088 static int ctrl_uio_read(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
4089 {
4090         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
4091         int rc;
4092         u16 pin_cfg_value = 0;
4093         u16 value = 0;
4094
4095         if ((uio_data == NULL) || (demod == NULL))
4096                 return -EINVAL;
4097
4098         ext_attr = (struct drxj_data *) demod->my_ext_attr;
4099
4100         /*  Write magic word to enable pdr reg write               */
4101         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4102         if (rc != 0) {
4103                 pr_err("error %d\n", rc);
4104                 goto rw_error;
4105         }
4106         switch (uio_data->uio) {
4107       /*====================================================================*/
4108         case DRX_UIO1:
4109                 /* DRX_UIO1: SMA_TX UIO-1 */
4110                 if (!ext_attr->has_smatx)
4111                         return -EIO;
4112
4113                 if (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
4114                         return -EIO;
4115
4116                 pin_cfg_value = 0;
4117                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4118                 pin_cfg_value |= 0x0110;
4119                 /* io_pad_cfg_mode output mode is drive always */
4120                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4121
4122                 /* write to io pad configuration register - input mode */
4123                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
4124                 if (rc != 0) {
4125                         pr_err("error %d\n", rc);
4126                         goto rw_error;
4127                 }
4128
4129                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4130                 if (rc != 0) {
4131                         pr_err("error %d\n", rc);
4132                         goto rw_error;
4133                 }
4134                 if ((value & 0x8000) != 0) {    /* check 15th bit - 1st UIO */
4135                         uio_data->value = true;
4136                 } else {
4137                         uio_data->value = false;
4138                 }
4139                 break;
4140    /*======================================================================*/
4141         case DRX_UIO2:
4142                 /* DRX_UIO2: SMA_RX UIO-2 */
4143                 if (!ext_attr->has_smarx)
4144                         return -EIO;
4145
4146                 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
4147                         return -EIO;
4148
4149                 pin_cfg_value = 0;
4150                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4151                 pin_cfg_value |= 0x0110;
4152                 /* io_pad_cfg_mode output mode is drive always */
4153                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4154
4155                 /* write to io pad configuration register - input mode */
4156                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
4157                 if (rc != 0) {
4158                         pr_err("error %d\n", rc);
4159                         goto rw_error;
4160                 }
4161
4162                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4163                 if (rc != 0) {
4164                         pr_err("error %d\n", rc);
4165                         goto rw_error;
4166                 }
4167
4168                 if ((value & 0x4000) != 0)      /* check 14th bit - 2nd UIO */
4169                         uio_data->value = true;
4170                 else
4171                         uio_data->value = false;
4172
4173                 break;
4174    /*=====================================================================*/
4175         case DRX_UIO3:
4176                 /* DRX_UIO3: GPIO UIO-3 */
4177                 if (!ext_attr->has_gpio)
4178                         return -EIO;
4179
4180                 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
4181                         return -EIO;
4182
4183                 pin_cfg_value = 0;
4184                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4185                 pin_cfg_value |= 0x0110;
4186                 /* io_pad_cfg_mode output mode is drive always */
4187                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4188
4189                 /* write to io pad configuration register - input mode */
4190                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
4191                 if (rc != 0) {
4192                         pr_err("error %d\n", rc);
4193                         goto rw_error;
4194                 }
4195
4196                 /* read io input data registar */
4197                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_HI__A, &value, 0);
4198                 if (rc != 0) {
4199                         pr_err("error %d\n", rc);
4200                         goto rw_error;
4201                 }
4202                 if ((value & 0x0004) != 0) {    /* check 2nd bit - 3rd UIO */
4203                         uio_data->value = true;
4204                 } else {
4205                         uio_data->value = false;
4206                 }
4207                 break;
4208    /*=====================================================================*/
4209         case DRX_UIO4:
4210                 /* DRX_UIO4: IRQN UIO-4 */
4211                 if (!ext_attr->has_irqn)
4212                         return -EIO;
4213
4214                 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
4215                         return -EIO;
4216
4217                 pin_cfg_value = 0;
4218                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4219                 pin_cfg_value |= 0x0110;
4220                 /* io_pad_cfg_mode output mode is drive always */
4221                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4222
4223                 /* write to io pad configuration register - input mode */
4224                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
4225                 if (rc != 0) {
4226                         pr_err("error %d\n", rc);
4227                         goto rw_error;
4228                 }
4229
4230                 /* read io input data registar */
4231                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4232                 if (rc != 0) {
4233                         pr_err("error %d\n", rc);
4234                         goto rw_error;
4235                 }
4236                 if ((value & 0x1000) != 0)      /* check 12th bit - 4th UIO */
4237                         uio_data->value = true;
4238                 else
4239                         uio_data->value = false;
4240
4241                 break;
4242       /*====================================================================*/
4243         default:
4244                 return -EINVAL;
4245         }                       /* switch ( uio_data->uio ) */
4246
4247         /*  Write magic word to disable pdr reg write               */
4248         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4249         if (rc != 0) {
4250                 pr_err("error %d\n", rc);
4251                 goto rw_error;
4252         }
4253
4254         return 0;
4255 rw_error:
4256         return -EIO;
4257 }
4258
4259 /*---------------------------------------------------------------------------*/
4260 /* UIO Configuration Functions - end                                         */
4261 /*---------------------------------------------------------------------------*/
4262
4263 /*----------------------------------------------------------------------------*/
4264 /* I2C Bridge Functions - begin                                               */
4265 /*----------------------------------------------------------------------------*/
4266 /**
4267 * \fn int ctrl_i2c_bridge()
4268 * \brief Open or close the I2C switch to tuner.
4269 * \param demod Pointer to demodulator instance.
4270 * \param bridge_closed Pointer to bool indication if bridge is closed not.
4271 * \return int.
4272
4273 */
4274 static int
4275 ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
4276 {
4277         struct drxj_hi_cmd hi_cmd;
4278         u16 result = 0;
4279
4280         /* check arguments */
4281         if (bridge_closed == NULL)
4282                 return -EINVAL;
4283
4284         hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
4285         hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
4286         if (*bridge_closed)
4287                 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
4288         else
4289                 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
4290
4291         return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
4292 }
4293
4294 /*----------------------------------------------------------------------------*/
4295 /* I2C Bridge Functions - end                                                 */
4296 /*----------------------------------------------------------------------------*/
4297
4298 /*----------------------------------------------------------------------------*/
4299 /* Smart antenna Functions - begin                                            */
4300 /*----------------------------------------------------------------------------*/
4301 /**
4302 * \fn int smart_ant_init()
4303 * \brief Initialize Smart Antenna.
4304 * \param pointer to struct drx_demod_instance.
4305 * \return int.
4306 *
4307 */
4308 static int smart_ant_init(struct drx_demod_instance *demod)
4309 {
4310         struct drxj_data *ext_attr = NULL;
4311         struct i2c_device_addr *dev_addr = NULL;
4312         struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
4313         int rc;
4314         u16 data = 0;
4315
4316         dev_addr = demod->my_i2c_dev_addr;
4317         ext_attr = (struct drxj_data *) demod->my_ext_attr;
4318
4319         /*  Write magic word to enable pdr reg write               */
4320         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4321         if (rc != 0) {
4322                 pr_err("error %d\n", rc);
4323                 goto rw_error;
4324         }
4325         /* init smart antenna */
4326         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
4327         if (rc != 0) {
4328                 pr_err("error %d\n", rc);
4329                 goto rw_error;
4330         }
4331         if (ext_attr->smart_ant_inverted) {
4332                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_COMMAND__A, (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
4333                 if (rc != 0) {
4334                         pr_err("error %d\n", rc);
4335                         goto rw_error;
4336                 }
4337         } else {
4338                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_COMMAND__A, (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
4339                 if (rc != 0) {
4340                         pr_err("error %d\n", rc);
4341                         goto rw_error;
4342                 }
4343         }
4344
4345         /* config SMA_TX pin to smart antenna mode */
4346         rc = ctrl_set_uio_cfg(demod, &uio_cfg);
4347         if (rc != 0) {
4348                 pr_err("error %d\n", rc);
4349                 goto rw_error;
4350         }
4351         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
4352         if (rc != 0) {
4353                 pr_err("error %d\n", rc);
4354                 goto rw_error;
4355         }
4356         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
4357         if (rc != 0) {
4358                 pr_err("error %d\n", rc);
4359                 goto rw_error;
4360         }
4361
4362         /*  Write magic word to disable pdr reg write               */
4363         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4364         if (rc != 0) {
4365                 pr_err("error %d\n", rc);
4366                 goto rw_error;
4367         }
4368
4369         return 0;
4370 rw_error:
4371         return -EIO;
4372 }
4373
4374 /**
4375 * \fn int ctrl_set_cfg_smart_ant()
4376 * \brief Set Smart Antenna.
4377 * \param pointer to struct drxj_cfg_smart_ant.
4378 * \return int.
4379 *
4380 */
4381 static int
4382 ctrl_set_cfg_smart_ant(struct drx_demod_instance *demod, struct drxj_cfg_smart_ant *smart_ant)
4383 {
4384         struct drxj_data *ext_attr = NULL;
4385         struct i2c_device_addr *dev_addr = NULL;
4386         int rc;
4387         u32 start_time = 0;
4388         u16 data = 0;
4389         static bool bit_inverted;
4390
4391         dev_addr = demod->my_i2c_dev_addr;
4392         ext_attr = (struct drxj_data *) demod->my_ext_attr;
4393
4394         /* check arguments */
4395         if (smart_ant == NULL)
4396                 return -EINVAL;
4397
4398         if (bit_inverted != ext_attr->smart_ant_inverted
4399             || ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SMA) {
4400                 rc = smart_ant_init(demod);
4401                 if (rc != 0) {
4402                         pr_err("error %d\n", rc);
4403                         goto rw_error;
4404                 }
4405                 bit_inverted = ext_attr->smart_ant_inverted;
4406         }
4407
4408         /*  Write magic word to enable pdr reg write               */
4409         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4410         if (rc != 0) {
4411                 pr_err("error %d\n", rc);
4412                 goto rw_error;
4413         }
4414
4415         switch (smart_ant->io) {
4416         case DRXJ_SMT_ANT_OUTPUT:
4417                 /* enable Tx if Mode B (input) is supported */
4418                 /*
4419                    RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4420                    WR16( dev_addr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
4421                  */
4422                 start_time = drxbsp_hst_clock();
4423                 do {
4424                         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_SA_TX_STATUS__A, &data, 0);
4425                         if (rc != 0) {
4426                                 pr_err("error %d\n", rc);
4427                                 goto rw_error;
4428                         }
4429                 } while ((data & SIO_SA_TX_STATUS_BUSY__M) && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
4430
4431                 if (data & SIO_SA_TX_STATUS_BUSY__M)
4432                         return -EIO;
4433
4434                 /* write to smart antenna configuration register */
4435                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA0__A, 0x9200 | ((smart_ant->ctrl_data & 0x0001) << 8) | ((smart_ant->ctrl_data & 0x0002) << 10) | ((smart_ant->ctrl_data & 0x0004) << 12), 0);
4436                 if (rc != 0) {
4437                         pr_err("error %d\n", rc);
4438                         goto rw_error;
4439                 }
4440                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA1__A, 0x4924 | ((smart_ant->ctrl_data & 0x0008) >> 2) | ((smart_ant->ctrl_data & 0x0010)) | ((smart_ant->ctrl_data & 0x0020) << 2) | ((smart_ant->ctrl_data & 0x0040) << 4) | ((smart_ant->ctrl_data & 0x0080) << 6), 0);
4441                 if (rc != 0) {
4442                         pr_err("error %d\n", rc);
4443                         goto rw_error;
4444                 }
4445                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA2__A, 0x2492 | ((smart_ant->ctrl_data & 0x0100) >> 8) | ((smart_ant->ctrl_data & 0x0200) >> 6) | ((smart_ant->ctrl_data & 0x0400) >> 4) | ((smart_ant->ctrl_data & 0x0800) >> 2) | ((smart_ant->ctrl_data & 0x1000)) | ((smart_ant->ctrl_data & 0x2000) << 2), 0);
4446                 if (rc != 0) {
4447                         pr_err("error %d\n", rc);
4448                         goto rw_error;
4449                 }
4450                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA3__A, 0xff8d, 0);
4451                 if (rc != 0) {
4452                         pr_err("error %d\n", rc);
4453                         goto rw_error;
4454                 }
4455
4456                 /* trigger the sending */
4457                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_LENGTH__A, 56, 0);
4458                 if (rc != 0) {
4459                         pr_err("error %d\n", rc);
4460                         goto rw_error;
4461                 }
4462
4463                 break;
4464         case DRXJ_SMT_ANT_INPUT:
4465                 /* disable Tx if Mode B (input) is supported */
4466                 /*
4467                    RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4468                    WR16( dev_addr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
4469                  */
4470         default:
4471                 return -EINVAL;
4472         }
4473         /*  Write magic word to enable pdr reg write               */
4474         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4475         if (rc != 0) {
4476                 pr_err("error %d\n", rc);
4477                 goto rw_error;
4478         }
4479
4480         return 0;
4481 rw_error:
4482         return -EIO;
4483 }
4484
4485 static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
4486 {
4487         int rc;
4488         u32 start_time = 0;
4489         u16 cur_cmd = 0;
4490
4491         /* Check param */
4492         if (cmd == NULL)
4493                 return -EINVAL;
4494
4495         /* Wait until SCU command interface is ready to receive command */
4496         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4497         if (rc != 0) {
4498                 pr_err("error %d\n", rc);
4499                 goto rw_error;
4500         }
4501         if (cur_cmd != DRX_SCU_READY)
4502                 return -EIO;
4503
4504         switch (cmd->parameter_len) {
4505         case 5:
4506                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
4507                 if (rc != 0) {
4508                         pr_err("error %d\n", rc);
4509                         goto rw_error;
4510                 }       /* fallthrough */
4511         case 4:
4512                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
4513                 if (rc != 0) {
4514                         pr_err("error %d\n", rc);
4515                         goto rw_error;
4516                 }       /* fallthrough */
4517         case 3:
4518                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
4519                 if (rc != 0) {
4520                         pr_err("error %d\n", rc);
4521                         goto rw_error;
4522                 }       /* fallthrough */
4523         case 2:
4524                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
4525                 if (rc != 0) {
4526                         pr_err("error %d\n", rc);
4527                         goto rw_error;
4528                 }       /* fallthrough */
4529         case 1:
4530                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
4531                 if (rc != 0) {
4532                         pr_err("error %d\n", rc);
4533                         goto rw_error;
4534                 }       /* fallthrough */
4535         case 0:
4536                 /* do nothing */
4537                 break;
4538         default:
4539                 /* this number of parameters is not supported */
4540                 return -EIO;
4541         }
4542         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
4543         if (rc != 0) {
4544                 pr_err("error %d\n", rc);
4545                 goto rw_error;
4546         }
4547
4548         /* Wait until SCU has processed command */
4549         start_time = drxbsp_hst_clock();
4550         do {
4551                 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4552                 if (rc != 0) {
4553                         pr_err("error %d\n", rc);
4554                         goto rw_error;
4555                 }
4556         } while (!(cur_cmd == DRX_SCU_READY)
4557                  && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
4558
4559         if (cur_cmd != DRX_SCU_READY)
4560                 return -EIO;
4561
4562         /* read results */
4563         if ((cmd->result_len > 0) && (cmd->result != NULL)) {
4564                 s16 err;
4565
4566                 switch (cmd->result_len) {
4567                 case 4:
4568                         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
4569                         if (rc != 0) {
4570                                 pr_err("error %d\n", rc);
4571                                 goto rw_error;
4572                         }       /* fallthrough */
4573                 case 3:
4574                         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
4575                         if (rc != 0) {
4576                                 pr_err("error %d\n", rc);
4577                                 goto rw_error;
4578                         }       /* fallthrough */
4579                 case 2:
4580                         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
4581                         if (rc != 0) {
4582                                 pr_err("error %d\n", rc);
4583                                 goto rw_error;
4584                         }       /* fallthrough */
4585                 case 1:
4586                         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
4587                         if (rc != 0) {
4588                                 pr_err("error %d\n", rc);
4589                                 goto rw_error;
4590                         }       /* fallthrough */
4591                 case 0:
4592                         /* do nothing */
4593                         break;
4594                 default:
4595                         /* this number of parameters is not supported */
4596                         return -EIO;
4597                 }
4598
4599                 /* Check if an error was reported by SCU */
4600                 err = cmd->result[0];
4601
4602                 /* check a few fixed error codes */
4603                 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4604                     || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4605                     || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4606                     || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
4607                     ) {
4608                         return -EINVAL;
4609                 }
4610                 /* here it is assumed that negative means error, and positive no error */
4611                 else if (err < 0)
4612                         return -EIO;
4613                 else
4614                         return 0;
4615         }
4616
4617         return 0;
4618
4619 rw_error:
4620         return -EIO;
4621 }
4622
4623 /**
4624 * \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4625 * \brief Basic access routine for SCU atomic read or write access
4626 * \param dev_addr  pointer to i2c dev address
4627 * \param addr     destination/source address
4628 * \param datasize size of data buffer in bytes
4629 * \param data     pointer to data buffer
4630 * \return int
4631 * \retval 0 Succes
4632 * \retval -EIO Timeout, I2C error, illegal bank
4633 *
4634 */
4635 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4636 static
4637 int drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr *dev_addr, u32 addr, u16 datasize,      /* max 30 bytes because the limit of SCU parameter */
4638                                               u8 *data, bool read_flag)
4639 {
4640         struct drxjscu_cmd scu_cmd;
4641         int rc;
4642         u16 set_param_parameters[15];
4643         u16 cmd_result[15];
4644
4645         /* Parameter check */
4646         if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
4647                 return -EINVAL;
4648
4649         set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4650         if (read_flag) {                /* read */
4651                 set_param_parameters[0] = ((~(0x0080)) & datasize);
4652                 scu_cmd.parameter_len = 2;
4653                 scu_cmd.result_len = datasize / 2 + 2;
4654         } else {
4655                 int i = 0;
4656
4657                 set_param_parameters[0] = 0x0080 | datasize;
4658                 for (i = 0; i < (datasize / 2); i++) {
4659                         set_param_parameters[i + 2] =
4660                             (data[2 * i] | (data[(2 * i) + 1] << 8));
4661                 }
4662                 scu_cmd.parameter_len = datasize / 2 + 2;
4663                 scu_cmd.result_len = 1;
4664         }
4665
4666         scu_cmd.command =
4667             SCU_RAM_COMMAND_STANDARD_TOP |
4668             SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4669         scu_cmd.result = cmd_result;
4670         scu_cmd.parameter = set_param_parameters;
4671         rc = scu_command(dev_addr, &scu_cmd);
4672         if (rc != 0) {
4673                 pr_err("error %d\n", rc);
4674                 goto rw_error;
4675         }
4676
4677         if (read_flag) {
4678                 int i = 0;
4679                 /* read data from buffer */
4680                 for (i = 0; i < (datasize / 2); i++) {
4681                         data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4682                         data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
4683                 }
4684         }
4685
4686         return 0;
4687
4688 rw_error:
4689         return -EIO;
4690
4691 }
4692
4693 /*============================================================================*/
4694
4695 /**
4696 * \fn int DRXJ_DAP_AtomicReadReg16()
4697 * \brief Atomic read of 16 bits words
4698 */
4699 static
4700 int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4701                                          u32 addr,
4702                                          u16 *data, u32 flags)
4703 {
4704         u8 buf[2];
4705         int rc = -EIO;
4706         u16 word = 0;
4707
4708         if (!data)
4709                 return -EINVAL;
4710
4711         rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
4712         if (rc < 0)
4713                 return rc;
4714
4715         word = (u16) (buf[0] + (buf[1] << 8));
4716
4717         *data = word;
4718
4719         return rc;
4720 }
4721
4722 /*============================================================================*/
4723 /**
4724 * \fn int drxj_dap_scu_atomic_write_reg16()
4725 * \brief Atomic read of 16 bits words
4726 */
4727 static
4728 int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4729                                           u32 addr,
4730                                           u16 data, u32 flags)
4731 {
4732         u8 buf[2];
4733         int rc = -EIO;
4734
4735         buf[0] = (u8) (data & 0xff);
4736         buf[1] = (u8) ((data >> 8) & 0xff);
4737
4738         rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
4739
4740         return rc;
4741 }
4742
4743 static int
4744 ctrl_i2c_write_read(struct drx_demod_instance *demod, struct drxi2c_data *i2c_data)
4745 {
4746         return -ENOTSUPP;
4747 }
4748
4749 /* -------------------------------------------------------------------------- */
4750 /**
4751 * \brief Measure result of ADC synchronisation
4752 * \param demod demod instance
4753 * \param count (returned) count
4754 * \return int.
4755 * \retval 0    Success
4756 * \retval -EIO Failure: I2C error
4757 *
4758 */
4759 static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
4760 {
4761         struct i2c_device_addr *dev_addr = NULL;
4762         int rc;
4763         u16 data = 0;
4764
4765         dev_addr = demod->my_i2c_dev_addr;
4766
4767         /* Start measurement */
4768         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
4769         if (rc != 0) {
4770                 pr_err("error %d\n", rc);
4771                 goto rw_error;
4772         }
4773         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
4774         if (rc != 0) {
4775                 pr_err("error %d\n", rc);
4776                 goto rw_error;
4777         }
4778
4779         /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4780         rc = drxbsp_hst_sleep(1);
4781         if (rc != 0) {
4782                 pr_err("error %d\n", rc);
4783                 goto rw_error;
4784         }
4785
4786         *count = 0;
4787         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE0__A, &data, 0);
4788         if (rc != 0) {
4789                 pr_err("error %d\n", rc);
4790                 goto rw_error;
4791         }
4792         if (data == 127)
4793                 *count = *count + 1;
4794         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE1__A, &data, 0);
4795         if (rc != 0) {
4796                 pr_err("error %d\n", rc);
4797                 goto rw_error;
4798         }
4799         if (data == 127)
4800                 *count = *count + 1;
4801         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE2__A, &data, 0);
4802         if (rc != 0) {
4803                 pr_err("error %d\n", rc);
4804                 goto rw_error;
4805         }
4806         if (data == 127)
4807                 *count = *count + 1;
4808
4809         return 0;
4810 rw_error:
4811         return -EIO;
4812 }
4813
4814 /**
4815 * \brief Synchronize analog and digital clock domains
4816 * \param demod demod instance
4817 * \return int.
4818 * \retval 0    Success
4819 * \retval -EIO Failure: I2C error or failure to synchronize
4820 *
4821 * An IQM reset will also reset the results of this synchronization.
4822 * After an IQM reset this routine needs to be called again.
4823 *
4824 */
4825
4826 static int adc_synchronization(struct drx_demod_instance *demod)
4827 {
4828         struct i2c_device_addr *dev_addr = NULL;
4829         int rc;
4830         u16 count = 0;
4831
4832         dev_addr = demod->my_i2c_dev_addr;
4833
4834         rc = adc_sync_measurement(demod, &count);
4835         if (rc != 0) {
4836                 pr_err("error %d\n", rc);
4837                 goto rw_error;
4838         }
4839
4840         if (count == 1) {
4841                 /* Try sampling on a diffrent edge */
4842                 u16 clk_neg = 0;
4843
4844                 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
4845                 if (rc != 0) {
4846                         pr_err("error %d\n", rc);
4847                         goto rw_error;
4848                 }
4849
4850                 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4851                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
4852                 if (rc != 0) {
4853                         pr_err("error %d\n", rc);
4854                         goto rw_error;
4855                 }
4856
4857                 rc = adc_sync_measurement(demod, &count);
4858                 if (rc != 0) {
4859                         pr_err("error %d\n", rc);
4860                         goto rw_error;
4861                 }
4862         }
4863
4864         /* TODO: implement fallback scenarios */
4865         if (count < 2)
4866                 return -EIO;
4867
4868         return 0;
4869 rw_error:
4870         return -EIO;
4871 }
4872
4873 /**
4874 * \brief Configure IQM AF registers
4875 * \param demod instance of demodulator.
4876 * \param active
4877 * \return int.
4878 */
4879 static int iqm_set_af(struct drx_demod_instance *demod, bool active)
4880 {
4881         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
4882         int rc;
4883         u16 data = 0;
4884
4885         /* Configure IQM */
4886         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
4887         if (rc != 0) {
4888                 pr_err("error %d\n", rc);
4889                 goto rw_error;
4890         }
4891         if (!active)
4892                 data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE));
4893         else
4894                 data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
4895         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
4896         if (rc != 0) {
4897                 pr_err("error %d\n", rc);
4898                 goto rw_error;
4899         }
4900
4901         return 0;
4902 rw_error:
4903         return -EIO;
4904 }
4905
4906 /* -------------------------------------------------------------------------- */
4907 static int
4908 ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg);
4909
4910 /**
4911 * \brief set configuration of pin-safe mode
4912 * \param demod instance of demodulator.
4913 * \param enable boolean; true: activate pin-safe mode, false: de-activate p.s.m.
4914 * \return int.
4915 */
4916 static int
4917 ctrl_set_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enable)
4918 {
4919         struct drxj_data *ext_attr = NULL;
4920         struct i2c_device_addr *dev_addr = NULL;
4921         int rc;
4922
4923         if (enable == NULL)
4924                 return -EINVAL;
4925
4926         dev_addr = demod->my_i2c_dev_addr;
4927         ext_attr = (struct drxj_data *) demod->my_ext_attr;
4928
4929         /*  Write magic word to enable pdr reg write  */
4930         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4931         if (rc != 0) {
4932                 pr_err("error %d\n", rc);
4933                 goto rw_error;
4934         }
4935
4936         if (*enable) {
4937                 bool bridge_enabled = false;
4938
4939                 /* MPEG pins to input */
4940                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4941                 if (rc != 0) {
4942                         pr_err("error %d\n", rc);
4943                         goto rw_error;
4944                 }
4945                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4946                 if (rc != 0) {
4947                         pr_err("error %d\n", rc);
4948                         goto rw_error;
4949                 }
4950                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MCLK_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4951                 if (rc != 0) {
4952                         pr_err("error %d\n", rc);
4953                         goto rw_error;
4954                 }
4955                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4956                 if (rc != 0) {
4957                         pr_err("error %d\n", rc);
4958                         goto rw_error;
4959                 }
4960                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4961                 if (rc != 0) {
4962                         pr_err("error %d\n", rc);
4963                         goto rw_error;
4964                 }
4965                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4966                 if (rc != 0) {
4967                         pr_err("error %d\n", rc);
4968                         goto rw_error;
4969                 }
4970                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4971                 if (rc != 0) {
4972                         pr_err("error %d\n", rc);
4973                         goto rw_error;
4974                 }
4975                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4976                 if (rc != 0) {
4977                         pr_err("error %d\n", rc);
4978                         goto rw_error;
4979                 }
4980                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4981                 if (rc != 0) {
4982                         pr_err("error %d\n", rc);
4983                         goto rw_error;
4984                 }
4985                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4986                 if (rc != 0) {
4987                         pr_err("error %d\n", rc);
4988                         goto rw_error;
4989                 }
4990                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4991                 if (rc != 0) {
4992                         pr_err("error %d\n", rc);
4993                         goto rw_error;
4994                 }
4995                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4996                 if (rc != 0) {
4997                         pr_err("error %d\n", rc);
4998                         goto rw_error;
4999                 }
5000
5001                 /* PD_I2C_SDA2 Bridge off, Port2 Inactive
5002                    PD_I2C_SCL2 Bridge off, Port2 Inactive */
5003                 rc = ctrl_i2c_bridge(demod, &bridge_enabled);
5004                 if (rc != 0) {
5005                         pr_err("error %d\n", rc);
5006                         goto rw_error;
5007                 }
5008                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5009                 if (rc != 0) {
5010                         pr_err("error %d\n", rc);
5011                         goto rw_error;
5012                 }
5013                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5014                 if (rc != 0) {
5015                         pr_err("error %d\n", rc);
5016                         goto rw_error;
5017                 }
5018
5019                 /*  PD_GPIO     Store and set to input
5020                    PD_VSYNC    Store and set to input
5021                    PD_SMA_RX   Store and set to input
5022                    PD_SMA_TX   Store and set to input */
5023                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, &ext_attr->pdr_safe_restore_val_gpio, 0);
5024                 if (rc != 0) {
5025                         pr_err("error %d\n", rc);
5026                         goto rw_error;
5027                 }
5028                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, &ext_attr->pdr_safe_restore_val_v_sync, 0);
5029                 if (rc != 0) {
5030                         pr_err("error %d\n", rc);
5031                         goto rw_error;
5032                 }
5033                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_rx, 0);
5034                 if (rc != 0) {
5035                         pr_err("error %d\n", rc);
5036                         goto rw_error;
5037                 }
5038                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_tx, 0);
5039                 if (rc != 0) {
5040                         pr_err("error %d\n", rc);
5041                         goto rw_error;
5042                 }
5043                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5044                 if (rc != 0) {
5045                         pr_err("error %d\n", rc);
5046                         goto rw_error;
5047                 }
5048                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5049                 if (rc != 0) {
5050                         pr_err("error %d\n", rc);
5051                         goto rw_error;
5052                 }
5053                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5054                 if (rc != 0) {
5055                         pr_err("error %d\n", rc);
5056                         goto rw_error;
5057                 }
5058                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5059                 if (rc != 0) {
5060                         pr_err("error %d\n", rc);
5061                         goto rw_error;
5062                 }
5063
5064                 /*  PD_RF_AGC   Analog DAC outputs, cannot be set to input or tristate!
5065                    PD_IF_AGC   Analog DAC outputs, cannot be set to input or tristate! */
5066                 rc = iqm_set_af(demod, false);
5067                 if (rc != 0) {
5068                         pr_err("error %d\n", rc);
5069                         goto rw_error;
5070                 }
5071
5072                 /*  PD_CVBS     Analog DAC output, standby mode
5073                    PD_SIF      Analog DAC output, standby mode */
5074                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
5075                 if (rc != 0) {
5076                         pr_err("error %d\n", rc);
5077                         goto rw_error;
5078                 }
5079
5080                 /*  PD_I2S_CL   Input
5081                    PD_I2S_DA   Input
5082                    PD_I2S_WS   Input */
5083                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5084                 if (rc != 0) {
5085                         pr_err("error %d\n", rc);
5086                         goto rw_error;
5087                 }
5088                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5089                 if (rc != 0) {
5090                         pr_err("error %d\n", rc);
5091                         goto rw_error;
5092                 }
5093                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_WS_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5094                 if (rc != 0) {
5095                         pr_err("error %d\n", rc);
5096                         goto rw_error;
5097                 }
5098         } else {
5099                 /* No need to restore MPEG pins;
5100                    is done in SetStandard/SetChannel */
5101
5102                 /* PD_I2C_SDA2 Port2 active
5103                    PD_I2C_SCL2 Port2 active */
5104                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, SIO_PDR_I2C_SDA2_CFG__PRE, 0);
5105                 if (rc != 0) {
5106                         pr_err("error %d\n", rc);
5107                         goto rw_error;
5108                 }
5109                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, SIO_PDR_I2C_SCL2_CFG__PRE, 0);
5110                 if (rc != 0) {
5111                         pr_err("error %d\n", rc);
5112                         goto rw_error;
5113                 }
5114
5115                 /*  PD_GPIO     Restore
5116                    PD_VSYNC    Restore
5117                    PD_SMA_RX   Restore
5118                    PD_SMA_TX   Restore */
5119                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, ext_attr->pdr_safe_restore_val_gpio, 0);
5120                 if (rc != 0) {
5121                         pr_err("error %d\n", rc);
5122                         goto rw_error;
5123                 }
5124                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, ext_attr->pdr_safe_restore_val_v_sync, 0);
5125                 if (rc != 0) {
5126                         pr_err("error %d\n", rc);
5127                         goto rw_error;
5128                 }
5129                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, ext_attr->pdr_safe_restore_val_sma_rx, 0);
5130                 if (rc != 0) {
5131                         pr_err("error %d\n", rc);
5132                         goto rw_error;
5133                 }
5134                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, ext_attr->pdr_safe_restore_val_sma_tx, 0);
5135                 if (rc != 0) {
5136                         pr_err("error %d\n", rc);
5137                         goto rw_error;
5138                 }
5139
5140                 /*  PD_RF_AGC, PD_IF_AGC
5141                    No need to restore; will be restored in SetStandard/SetChannel */
5142
5143                 /*  PD_CVBS, PD_SIF
5144                    No need to restore; will be restored in SetStandard/SetChannel */
5145
5146                 /*  PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
5147                    Should be restored via DRX_CTRL_SET_AUD */
5148         }
5149
5150         /*  Write magic word to disable pdr reg write */
5151         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
5152         if (rc != 0) {
5153                 pr_err("error %d\n", rc);
5154                 goto rw_error;
5155         }
5156         ext_attr->pdr_safe_mode = *enable;
5157
5158         return 0;
5159
5160 rw_error:
5161         return -EIO;
5162 }
5163
5164 /* -------------------------------------------------------------------------- */
5165
5166 /**
5167 * \brief get configuration of pin-safe mode
5168 * \param demod instance of demodulator.
5169 * \param enable boolean indicating whether pin-safe mode is active
5170 * \return int.
5171 */
5172 static int
5173 ctrl_get_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enabled)
5174 {
5175         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
5176
5177         if (enabled == NULL)
5178                 return -EINVAL;
5179
5180         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5181         *enabled = ext_attr->pdr_safe_mode;
5182
5183         return 0;
5184 }
5185
5186 /**
5187 * \brief Verifies whether microcode can be loaded.
5188 * \param demod Demodulator instance.
5189 * \return int.
5190 */
5191 static int ctrl_validate_u_code(struct drx_demod_instance *demod)
5192 {
5193         u32 mc_dev, mc_patch;
5194         u16 ver_type;
5195
5196         /* Check device.
5197          *  Disallow microcode if:
5198          *   - MC has version record AND
5199          *   - device ID in version record is not 0 AND
5200          *   - product ID in version record's device ID does not
5201          *     match DRXJ1 product IDs - 0x393 or 0x394
5202          */
5203         ver_type = DRX_ATTR_MCRECORD(demod).aux_type;
5204         mc_dev = DRX_ATTR_MCRECORD(demod).mc_dev_type;
5205         mc_patch = DRX_ATTR_MCRECORD(demod).mc_base_version;
5206
5207         if (DRX_ISMCVERTYPE(ver_type)) {
5208                 if ((mc_dev != 0) &&
5209                     (((mc_dev >> 16) & 0xFFF) != 0x393) &&
5210                     (((mc_dev >> 16) & 0xFFF) != 0x394)) {
5211                         /* Microcode is marked for another device - error */
5212                         return -EINVAL;
5213                 } else if (mc_patch != 0) {
5214                         /* Patch not allowed because there is no ROM */
5215                         return -EINVAL;
5216                 }
5217         }
5218
5219         /* Everything else: OK */
5220         return 0;
5221 }
5222
5223 /*============================================================================*/
5224 /*==                      END AUXILIARY FUNCTIONS                           ==*/
5225 /*============================================================================*/
5226
5227 /*============================================================================*/
5228 /*============================================================================*/
5229 /*==                8VSB & QAM COMMON DATAPATH FUNCTIONS                    ==*/
5230 /*============================================================================*/
5231 /*============================================================================*/
5232 /**
5233 * \fn int init_agc ()
5234 * \brief Initialize AGC for all standards.
5235 * \param demod instance of demodulator.
5236 * \param channel pointer to channel data.
5237 * \return int.
5238 */
5239 static int init_agc(struct drx_demod_instance *demod)
5240 {
5241         struct i2c_device_addr *dev_addr = NULL;
5242         struct drx_common_attr *common_attr = NULL;
5243         struct drxj_data *ext_attr = NULL;
5244         struct drxj_cfg_agc *p_agc_rf_settings = NULL;
5245         struct drxj_cfg_agc *p_agc_if_settings = NULL;
5246         int rc;
5247         u16 ingain_tgt_max = 0;
5248         u16 clp_dir_to = 0;
5249         u16 sns_sum_max = 0;
5250         u16 clp_sum_max = 0;
5251         u16 sns_dir_to = 0;
5252         u16 ki_innergain_min = 0;
5253         u16 agc_ki = 0;
5254         u16 ki_max = 0;
5255         u16 if_iaccu_hi_tgt_min = 0;
5256         u16 data = 0;
5257         u16 agc_ki_dgain = 0;
5258         u16 ki_min = 0;
5259         u16 clp_ctrl_mode = 0;
5260         u16 agc_rf = 0;
5261         u16 agc_if = 0;
5262
5263         dev_addr = demod->my_i2c_dev_addr;
5264         common_attr = (struct drx_common_attr *) demod->my_common_attr;
5265         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5266
5267         switch (ext_attr->standard) {
5268         case DRX_STANDARD_8VSB:
5269                 clp_sum_max = 1023;
5270                 clp_dir_to = (u16) (-9);
5271                 sns_sum_max = 1023;
5272                 sns_dir_to = (u16) (-9);
5273                 ki_innergain_min = (u16) (-32768);
5274                 ki_max = 0x032C;
5275                 agc_ki_dgain = 0xC;
5276                 if_iaccu_hi_tgt_min = 2047;
5277                 ki_min = 0x0117;
5278                 ingain_tgt_max = 16383;
5279                 clp_ctrl_mode = 0;
5280                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
5281                 if (rc != 0) {
5282                         pr_err("error %d\n", rc);
5283                         goto rw_error;
5284                 }
5285                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
5286                 if (rc != 0) {
5287                         pr_err("error %d\n", rc);
5288                         goto rw_error;
5289                 }
5290                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
5291                 if (rc != 0) {
5292                         pr_err("error %d\n", rc);
5293                         goto rw_error;
5294                 }
5295                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
5296                 if (rc != 0) {
5297                         pr_err("error %d\n", rc);
5298                         goto rw_error;
5299                 }
5300                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
5301                 if (rc != 0) {
5302                         pr_err("error %d\n", rc);
5303                         goto rw_error;
5304                 }
5305                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
5306                 if (rc != 0) {
5307                         pr_err("error %d\n", rc);
5308                         goto rw_error;
5309                 }
5310                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
5311                 if (rc != 0) {
5312                         pr_err("error %d\n", rc);
5313                         goto rw_error;
5314                 }
5315                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
5316                 if (rc != 0) {
5317                         pr_err("error %d\n", rc);
5318                         goto rw_error;
5319                 }
5320                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
5321                 if (rc != 0) {
5322                         pr_err("error %d\n", rc);
5323                         goto rw_error;
5324                 }
5325                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
5326                 if (rc != 0) {
5327                         pr_err("error %d\n", rc);
5328                         goto rw_error;
5329                 }
5330                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
5331                 if (rc != 0) {
5332                         pr_err("error %d\n", rc);
5333                         goto rw_error;
5334                 }
5335                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
5336                 if (rc != 0) {
5337                         pr_err("error %d\n", rc);
5338                         goto rw_error;
5339                 }
5340                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
5341                 if (rc != 0) {
5342                         pr_err("error %d\n", rc);
5343                         goto rw_error;
5344                 }
5345                 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
5346                 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
5347                 break;
5348 #ifndef DRXJ_VSB_ONLY
5349         case DRX_STANDARD_ITU_A:
5350         case DRX_STANDARD_ITU_C:
5351         case DRX_STANDARD_ITU_B:
5352                 ingain_tgt_max = 5119;
5353                 clp_sum_max = 1023;
5354                 clp_dir_to = (u16) (-5);
5355                 sns_sum_max = 127;
5356                 sns_dir_to = (u16) (-3);
5357                 ki_innergain_min = 0;
5358                 ki_max = 0x0657;
5359                 if_iaccu_hi_tgt_min = 2047;
5360                 agc_ki_dgain = 0x7;
5361                 ki_min = 0x0117;
5362                 clp_ctrl_mode = 0;
5363                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
5364                 if (rc != 0) {
5365                         pr_err("error %d\n", rc);
5366                         goto rw_error;
5367                 }
5368                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
5369                 if (rc != 0) {
5370                         pr_err("error %d\n", rc);
5371                         goto rw_error;
5372                 }
5373                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
5374                 if (rc != 0) {
5375                         pr_err("error %d\n", rc);
5376                         goto rw_error;
5377                 }
5378                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
5379                 if (rc != 0) {
5380                         pr_err("error %d\n", rc);
5381                         goto rw_error;
5382                 }
5383                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
5384                 if (rc != 0) {
5385                         pr_err("error %d\n", rc);
5386                         goto rw_error;
5387                 }
5388                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
5389                 if (rc != 0) {
5390                         pr_err("error %d\n", rc);
5391                         goto rw_error;
5392                 }
5393                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
5394                 if (rc != 0) {
5395                         pr_err("error %d\n", rc);
5396                         goto rw_error;
5397                 }
5398                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
5399                 if (rc != 0) {
5400                         pr_err("error %d\n", rc);
5401                         goto rw_error;
5402                 }
5403                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
5404                 if (rc != 0) {
5405                         pr_err("error %d\n", rc);
5406                         goto rw_error;
5407                 }
5408                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
5409                 if (rc != 0) {
5410                         pr_err("error %d\n", rc);
5411                         goto rw_error;
5412                 }
5413                 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
5414                 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
5415                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5416                 if (rc != 0) {
5417                         pr_err("error %d\n", rc);
5418                         goto rw_error;
5419                 }
5420
5421                 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
5422                 if (rc != 0) {
5423                         pr_err("error %d\n", rc);
5424                         goto rw_error;
5425                 }
5426                 agc_ki &= 0xf000;
5427                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
5428                 if (rc != 0) {
5429                         pr_err("error %d\n", rc);
5430                         goto rw_error;
5431                 }
5432                 break;
5433 #endif
5434 #ifndef DRXJ_DIGITAL_ONLY
5435         case DRX_STANDARD_FM:
5436                 clp_sum_max = 1023;
5437                 sns_sum_max = 1023;
5438                 ki_innergain_min = (u16) (-32768);
5439                 if_iaccu_hi_tgt_min = 2047;
5440                 agc_ki_dgain = 0x7;
5441                 ki_min = 0x0225;
5442                 ki_max = 0x0547;
5443                 clp_dir_to = (u16) (-9);
5444                 sns_dir_to = (u16) (-9);
5445                 ingain_tgt_max = 9000;
5446                 clp_ctrl_mode = 1;
5447                 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5448                 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5449                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5450                 if (rc != 0) {
5451                         pr_err("error %d\n", rc);
5452                         goto rw_error;
5453                 }
5454                 break;
5455         case DRX_STANDARD_NTSC:
5456         case DRX_STANDARD_PAL_SECAM_BG:
5457         case DRX_STANDARD_PAL_SECAM_DK:
5458         case DRX_STANDARD_PAL_SECAM_I:
5459                 clp_sum_max = 1023;
5460                 sns_sum_max = 1023;
5461                 ki_innergain_min = (u16) (-32768);
5462                 if_iaccu_hi_tgt_min = 2047;
5463                 agc_ki_dgain = 0x7;
5464                 ki_min = 0x0225;
5465                 ki_max = 0x0547;
5466                 clp_dir_to = (u16) (-9);
5467                 ingain_tgt_max = 9000;
5468                 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5469                 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5470                 sns_dir_to = (u16) (-9);
5471                 clp_ctrl_mode = 1;
5472                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5473                 if (rc != 0) {
5474                         pr_err("error %d\n", rc);
5475                         goto rw_error;
5476                 }
5477                 break;
5478         case DRX_STANDARD_PAL_SECAM_L:
5479         case DRX_STANDARD_PAL_SECAM_LP:
5480                 clp_sum_max = 1023;
5481                 sns_sum_max = 1023;
5482                 ki_innergain_min = (u16) (-32768);
5483                 if_iaccu_hi_tgt_min = 2047;
5484                 agc_ki_dgain = 0x7;
5485                 ki_min = 0x0225;
5486                 ki_max = 0x0547;
5487                 clp_dir_to = (u16) (-9);
5488                 sns_dir_to = (u16) (-9);
5489                 ingain_tgt_max = 9000;
5490                 clp_ctrl_mode = 1;
5491                 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5492                 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5493                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5494                 if (rc != 0) {
5495                         pr_err("error %d\n", rc);
5496                         goto rw_error;
5497                 }
5498                 break;
5499 #endif
5500         default:
5501                 return -EINVAL;
5502         }
5503
5504         /* for new AGC interface */
5505         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
5506         if (rc != 0) {
5507                 pr_err("error %d\n", rc);
5508                 goto rw_error;
5509         }
5510         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
5511         if (rc != 0) {
5512                 pr_err("error %d\n", rc);
5513                 goto rw_error;
5514         }       /* Gain fed from inner to outer AGC */
5515         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
5516         if (rc != 0) {
5517                 pr_err("error %d\n", rc);
5518                 goto rw_error;
5519         }
5520         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
5521         if (rc != 0) {
5522                 pr_err("error %d\n", rc);
5523                 goto rw_error;
5524         }
5525         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
5526         if (rc != 0) {
5527                 pr_err("error %d\n", rc);
5528                 goto rw_error;
5529         }       /* set to p_agc_settings->top before */
5530         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
5531         if (rc != 0) {
5532                 pr_err("error %d\n", rc);
5533                 goto rw_error;
5534         }
5535         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
5536         if (rc != 0) {
5537                 pr_err("error %d\n", rc);
5538                 goto rw_error;
5539         }
5540         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
5541         if (rc != 0) {
5542                 pr_err("error %d\n", rc);
5543                 goto rw_error;
5544         }
5545         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
5546         if (rc != 0) {
5547                 pr_err("error %d\n", rc);
5548                 goto rw_error;
5549         }
5550         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
5551         if (rc != 0) {
5552                 pr_err("error %d\n", rc);
5553                 goto rw_error;
5554         }
5555         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
5556         if (rc != 0) {
5557                 pr_err("error %d\n", rc);
5558                 goto rw_error;
5559         }
5560         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
5561         if (rc != 0) {
5562                 pr_err("error %d\n", rc);
5563                 goto rw_error;
5564         }
5565         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
5566         if (rc != 0) {
5567                 pr_err("error %d\n", rc);
5568                 goto rw_error;
5569         }
5570         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
5571         if (rc != 0) {
5572                 pr_err("error %d\n", rc);
5573                 goto rw_error;
5574         }
5575         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
5576         if (rc != 0) {
5577                 pr_err("error %d\n", rc);
5578                 goto rw_error;
5579         }
5580         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
5581         if (rc != 0) {
5582                 pr_err("error %d\n", rc);
5583                 goto rw_error;
5584         }
5585         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
5586         if (rc != 0) {
5587                 pr_err("error %d\n", rc);
5588                 goto rw_error;
5589         }
5590         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
5591         if (rc != 0) {
5592                 pr_err("error %d\n", rc);
5593                 goto rw_error;
5594         }
5595         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
5596         if (rc != 0) {
5597                 pr_err("error %d\n", rc);
5598                 goto rw_error;
5599         }
5600         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
5601         if (rc != 0) {
5602                 pr_err("error %d\n", rc);
5603                 goto rw_error;
5604         }
5605         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
5606         if (rc != 0) {
5607                 pr_err("error %d\n", rc);
5608                 goto rw_error;
5609         }
5610         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
5611         if (rc != 0) {
5612                 pr_err("error %d\n", rc);
5613                 goto rw_error;
5614         }
5615         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
5616         if (rc != 0) {
5617                 pr_err("error %d\n", rc);
5618                 goto rw_error;
5619         }
5620         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
5621         if (rc != 0) {
5622                 pr_err("error %d\n", rc);
5623                 goto rw_error;
5624         }
5625         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
5626         if (rc != 0) {
5627                 pr_err("error %d\n", rc);
5628                 goto rw_error;
5629         }
5630         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
5631         if (rc != 0) {
5632                 pr_err("error %d\n", rc);
5633                 goto rw_error;
5634         }
5635
5636         agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
5637         if (common_attr->tuner_rf_agc_pol == true)
5638                 agc_rf = 0x87ff - agc_rf;
5639
5640         agc_if = 0x800;
5641         if (common_attr->tuner_if_agc_pol == true)
5642                 agc_rf = 0x87ff - agc_rf;
5643
5644         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
5645         if (rc != 0) {
5646                 pr_err("error %d\n", rc);
5647                 goto rw_error;
5648         }
5649         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
5650         if (rc != 0) {
5651                 pr_err("error %d\n", rc);
5652                 goto rw_error;
5653         }
5654
5655         /* Set/restore Ki DGAIN factor */
5656         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5657         if (rc != 0) {
5658                 pr_err("error %d\n", rc);
5659                 goto rw_error;
5660         }
5661         data &= ~SCU_RAM_AGC_KI_DGAIN__M;
5662         data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
5663         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5664         if (rc != 0) {
5665                 pr_err("error %d\n", rc);
5666                 goto rw_error;
5667         }
5668
5669         return 0;
5670 rw_error:
5671         return -EIO;
5672 }
5673
5674 /**
5675 * \fn int set_frequency ()
5676 * \brief Set frequency shift.
5677 * \param demod instance of demodulator.
5678 * \param channel pointer to channel data.
5679 * \param tuner_freq_offset residual frequency from tuner.
5680 * \return int.
5681 */
5682 static int
5683 set_frequency(struct drx_demod_instance *demod,
5684               struct drx_channel *channel, s32 tuner_freq_offset)
5685 {
5686         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5687         struct drxj_data *ext_attr = demod->my_ext_attr;
5688         int rc;
5689         s32 sampling_frequency = 0;
5690         s32 frequency_shift = 0;
5691         s32 if_freq_actual = 0;
5692         s32 rf_freq_residual = -1 * tuner_freq_offset;
5693         s32 adc_freq = 0;
5694         s32 intermediate_freq = 0;
5695         u32 iqm_fs_rate_ofs = 0;
5696         bool adc_flip = true;
5697         bool select_pos_image = false;
5698         bool rf_mirror;
5699         bool tuner_mirror;
5700         bool image_to_select = true;
5701         s32 fm_frequency_shift = 0;
5702
5703         rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
5704         tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
5705         /*
5706            Program frequency shifter
5707            No need to account for mirroring on RF
5708          */
5709         switch (ext_attr->standard) {
5710         case DRX_STANDARD_ITU_A:        /* fallthrough */
5711         case DRX_STANDARD_ITU_C:        /* fallthrough */
5712         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
5713         case DRX_STANDARD_8VSB:
5714                 select_pos_image = true;
5715                 break;
5716         case DRX_STANDARD_FM:
5717                 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
5718                    Sound carrier is already 3Mhz above centre frequency due
5719                    to tuner setting so now add an extra shift of 1MHz... */
5720                 fm_frequency_shift = 1000;
5721         case DRX_STANDARD_ITU_B:        /* fallthrough */
5722         case DRX_STANDARD_NTSC: /* fallthrough */
5723         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
5724         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
5725         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
5726         case DRX_STANDARD_PAL_SECAM_L:
5727                 select_pos_image = false;
5728                 break;
5729         default:
5730                 return -EINVAL;
5731         }
5732         intermediate_freq = demod->my_common_attr->intermediate_freq;
5733         sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
5734         if (tuner_mirror)
5735                 if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
5736         else
5737                 if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
5738         if (if_freq_actual > sampling_frequency / 2) {
5739                 /* adc mirrors */
5740                 adc_freq = sampling_frequency - if_freq_actual;
5741                 adc_flip = true;
5742         } else {
5743                 /* adc doesn't mirror */
5744                 adc_freq = if_freq_actual;
5745                 adc_flip = false;
5746         }
5747
5748         frequency_shift = adc_freq;
5749         image_to_select =
5750             (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
5751         iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
5752
5753         if (image_to_select)
5754                 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
5755
5756         /* Program frequency shifter with tuner offset compensation */
5757         /* frequency_shift += tuner_freq_offset; TODO */
5758         rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
5759         if (rc != 0) {
5760                 pr_err("error %d\n", rc);
5761                 goto rw_error;
5762         }
5763         ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
5764         ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
5765
5766         return 0;
5767 rw_error:
5768         return -EIO;
5769 }
5770
5771 /**
5772 * \fn int get_sig_strength()
5773 * \brief Retrieve signal strength for VSB and QAM.
5774 * \param demod Pointer to demod instance
5775 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
5776 * \return int.
5777 * \retval 0 sig_strength contains valid data.
5778 * \retval -EINVAL sig_strength is NULL.
5779 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5780 */
5781 #define DRXJ_AGC_TOP    0x2800
5782 #define DRXJ_AGC_SNS    0x1600
5783 #define DRXJ_RFAGC_MAX  0x3fff
5784 #define DRXJ_RFAGC_MIN  0x800
5785
5786 static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
5787 {
5788         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5789         int rc;
5790         u16 rf_gain = 0;
5791         u16 if_gain = 0;
5792         u16 if_agc_sns = 0;
5793         u16 if_agc_top = 0;
5794         u16 rf_agc_max = 0;
5795         u16 rf_agc_min = 0;
5796
5797         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
5798         if (rc != 0) {
5799                 pr_err("error %d\n", rc);
5800                 goto rw_error;
5801         }
5802         if_gain &= IQM_AF_AGC_IF__M;
5803         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
5804         if (rc != 0) {
5805                 pr_err("error %d\n", rc);
5806                 goto rw_error;
5807         }
5808         rf_gain &= IQM_AF_AGC_RF__M;
5809
5810         if_agc_sns = DRXJ_AGC_SNS;
5811         if_agc_top = DRXJ_AGC_TOP;
5812         rf_agc_max = DRXJ_RFAGC_MAX;
5813         rf_agc_min = DRXJ_RFAGC_MIN;
5814
5815         if (if_gain > if_agc_top) {
5816                 if (rf_gain > rf_agc_max)
5817                         *sig_strength = 100;
5818                 else if (rf_gain > rf_agc_min) {
5819                         if (rf_agc_max == rf_agc_min) {
5820                                 pr_err("error: rf_agc_max == rf_agc_min\n");
5821                                 return -EIO;
5822                         }
5823                         *sig_strength =
5824                             75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
5825                                                              rf_agc_min);
5826                 } else
5827                         *sig_strength = 75;
5828         } else if (if_gain > if_agc_sns) {
5829                 if (if_agc_top == if_agc_sns) {
5830                         pr_err("error: if_agc_top == if_agc_sns\n");
5831                         return -EIO;
5832                 }
5833                 *sig_strength =
5834                     20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
5835         } else {
5836                 if (!if_agc_sns) {
5837                         pr_err("error: if_agc_sns is zero!\n");
5838                         return -EIO;
5839                 }
5840                 *sig_strength = (20 * if_gain / if_agc_sns);
5841         }
5842
5843         return 0;
5844 rw_error:
5845         return -EIO;
5846 }
5847
5848 /**
5849 * \fn int get_acc_pkt_err()
5850 * \brief Retrieve signal strength for VSB and QAM.
5851 * \param demod Pointer to demod instance
5852 * \param packet_err Pointer to packet error
5853 * \return int.
5854 * \retval 0 sig_strength contains valid data.
5855 * \retval -EINVAL sig_strength is NULL.
5856 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5857 */
5858 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5859 static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
5860 {
5861         int rc;
5862         static u16 pkt_err;
5863         static u16 last_pkt_err;
5864         u16 data = 0;
5865         struct drxj_data *ext_attr = NULL;
5866         struct i2c_device_addr *dev_addr = NULL;
5867
5868         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5869         dev_addr = demod->my_i2c_dev_addr;
5870
5871         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
5872         if (rc != 0) {
5873                 pr_err("error %d\n", rc);
5874                 goto rw_error;
5875         }
5876         if (ext_attr->reset_pkt_err_acc) {
5877                 last_pkt_err = data;
5878                 pkt_err = 0;
5879                 ext_attr->reset_pkt_err_acc = false;
5880         }
5881
5882         if (data < last_pkt_err) {
5883                 pkt_err += 0xffff - last_pkt_err;
5884                 pkt_err += data;
5885         } else {
5886                 pkt_err += (data - last_pkt_err);
5887         }
5888         *packet_err = pkt_err;
5889         last_pkt_err = data;
5890
5891         return 0;
5892 rw_error:
5893         return -EIO;
5894 }
5895 #endif
5896
5897 /**
5898 * \fn int ResetAccPktErr()
5899 * \brief Reset Accumulating packet error count.
5900 * \param demod Pointer to demod instance
5901 * \return int.
5902 * \retval 0.
5903 * \retval -EIO Erroneous data.
5904 */
5905 static int ctrl_set_cfg_reset_pkt_err(struct drx_demod_instance *demod)
5906 {
5907 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5908         struct drxj_data *ext_attr = NULL;
5909         int rc;
5910         u16 packet_error = 0;
5911
5912         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5913         ext_attr->reset_pkt_err_acc = true;
5914         /* call to reset counter */
5915         rc = get_acc_pkt_err(demod, &packet_error);
5916         if (rc != 0) {
5917                 pr_err("error %d\n", rc);
5918                 goto rw_error;
5919         }
5920
5921         return 0;
5922 rw_error:
5923 #endif
5924         return -EIO;
5925 }
5926
5927 /**
5928 * \fn static short get_str_freq_offset()
5929 * \brief Get symbol rate offset in QAM & 8VSB mode
5930 * \return Error code
5931 */
5932 static int get_str_freq_offset(struct drx_demod_instance *demod, s32 *str_freq)
5933 {
5934         int rc;
5935         u32 symbol_frequency_ratio = 0;
5936         u32 symbol_nom_frequency_ratio = 0;
5937
5938         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5939         struct drxj_data *ext_attr = demod->my_ext_attr;
5940
5941         rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &symbol_frequency_ratio, 0);
5942         if (rc != 0) {
5943                 pr_err("error %d\n", rc);
5944                 goto rw_error;
5945         }
5946         symbol_nom_frequency_ratio = ext_attr->iqm_rc_rate_ofs;
5947
5948         if (symbol_frequency_ratio > symbol_nom_frequency_ratio)
5949                 *str_freq =
5950                     -1 *
5951                     frac_times1e6((symbol_frequency_ratio -
5952                                   symbol_nom_frequency_ratio),
5953                                  (symbol_frequency_ratio + (1 << 23)));
5954         else
5955                 *str_freq =
5956                     frac_times1e6((symbol_nom_frequency_ratio -
5957                                   symbol_frequency_ratio),
5958                                  (symbol_frequency_ratio + (1 << 23)));
5959
5960         return 0;
5961 rw_error:
5962         return -EIO;
5963 }
5964
5965 /**
5966 * \fn static short get_ctl_freq_offset
5967 * \brief Get the value of ctl_freq in QAM & ATSC mode
5968 * \return Error code
5969 */
5970 static int get_ctl_freq_offset(struct drx_demod_instance *demod, s32 *ctl_freq)
5971 {
5972         s32 sampling_frequency = 0;
5973         s32 current_frequency = 0;
5974         s32 nominal_frequency = 0;
5975         s32 carrier_frequency_shift = 0;
5976         s32 sign = 1;
5977         u32 data64hi = 0;
5978         u32 data64lo = 0;
5979         struct drxj_data *ext_attr = NULL;
5980         struct drx_common_attr *common_attr = NULL;
5981         struct i2c_device_addr *dev_addr = NULL;
5982         int rc;
5983
5984         dev_addr = demod->my_i2c_dev_addr;
5985         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5986         common_attr = (struct drx_common_attr *) demod->my_common_attr;
5987
5988         sampling_frequency = common_attr->sys_clock_freq / 3;
5989
5990         /* both registers are sign extended */
5991         nominal_frequency = ext_attr->iqm_fs_rate_ofs;
5992         rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, (u32 *)&current_frequency, 0);
5993         if (rc != 0) {
5994                 pr_err("error %d\n", rc);
5995                 goto rw_error;
5996         }
5997
5998         if (ext_attr->pos_image) {
5999                 /* negative image */
6000                 carrier_frequency_shift = nominal_frequency - current_frequency;
6001         } else {
6002                 /* positive image */
6003                 carrier_frequency_shift = current_frequency - nominal_frequency;
6004         }
6005
6006         /* carrier Frequency Shift In Hz */
6007         if (carrier_frequency_shift < 0) {
6008                 sign = -1;
6009                 carrier_frequency_shift *= sign;
6010         }
6011
6012         /* *ctl_freq = carrier_frequency_shift * 50.625e6 / (1 << 28); */
6013         mult32(carrier_frequency_shift, sampling_frequency, &data64hi, &data64lo);
6014         *ctl_freq =
6015             (s32) ((((data64lo >> 28) & 0xf) | (data64hi << 4)) * sign);
6016
6017         return 0;
6018 rw_error:
6019         return -EIO;
6020 }
6021
6022 /*============================================================================*/
6023
6024 /**
6025 * \fn int set_agc_rf ()
6026 * \brief Configure RF AGC
6027 * \param demod instance of demodulator.
6028 * \param agc_settings AGC configuration structure
6029 * \return int.
6030 */
6031 static int
6032 set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
6033 {
6034         struct i2c_device_addr *dev_addr = NULL;
6035         struct drxj_data *ext_attr = NULL;
6036         struct drxj_cfg_agc *p_agc_settings = NULL;
6037         struct drx_common_attr *common_attr = NULL;
6038         int rc;
6039         drx_write_reg16func_t scu_wr16 = NULL;
6040         drx_read_reg16func_t scu_rr16 = NULL;
6041
6042         common_attr = (struct drx_common_attr *) demod->my_common_attr;
6043         dev_addr = demod->my_i2c_dev_addr;
6044         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6045
6046         if (atomic) {
6047                 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
6048                 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
6049         } else {
6050                 scu_rr16 = DRXJ_DAP.read_reg16func;
6051                 scu_wr16 = DRXJ_DAP.write_reg16func;
6052         }
6053
6054         /* Configure AGC only if standard is currently active */
6055         if ((ext_attr->standard == agc_settings->standard) ||
6056             (DRXJ_ISQAMSTD(ext_attr->standard) &&
6057              DRXJ_ISQAMSTD(agc_settings->standard)) ||
6058             (DRXJ_ISATVSTD(ext_attr->standard) &&
6059              DRXJ_ISATVSTD(agc_settings->standard))) {
6060                 u16 data = 0;
6061
6062                 switch (agc_settings->ctrl_mode) {
6063                 case DRX_AGC_CTRL_AUTO:
6064
6065                         /* Enable RF AGC DAC */
6066                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6067                         if (rc != 0) {
6068                                 pr_err("error %d\n", rc);
6069                                 goto rw_error;
6070                         }
6071                         data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
6072                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6073                         if (rc != 0) {
6074                                 pr_err("error %d\n", rc);
6075                                 goto rw_error;
6076                         }
6077
6078                         /* Enable SCU RF AGC loop */
6079                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6080                         if (rc != 0) {
6081                                 pr_err("error %d\n", rc);
6082                                 goto rw_error;
6083                         }
6084                         data &= ~SCU_RAM_AGC_KI_RF__M;
6085                         if (ext_attr->standard == DRX_STANDARD_8VSB)
6086                                 data |= (2 << SCU_RAM_AGC_KI_RF__B);
6087                         else if (DRXJ_ISQAMSTD(ext_attr->standard))
6088                                 data |= (5 << SCU_RAM_AGC_KI_RF__B);
6089                         else
6090                                 data |= (4 << SCU_RAM_AGC_KI_RF__B);
6091
6092                         if (common_attr->tuner_rf_agc_pol)
6093                                 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
6094                         else
6095                                 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
6096                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6097                         if (rc != 0) {
6098                                 pr_err("error %d\n", rc);
6099                                 goto rw_error;
6100                         }
6101
6102                         /* Set speed ( using complementary reduction value ) */
6103                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
6104                         if (rc != 0) {
6105                                 pr_err("error %d\n", rc);
6106                                 goto rw_error;
6107                         }
6108                         data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
6109                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_RAGC_RED__B) & SCU_RAM_AGC_KI_RED_RAGC_RED__M) | data, 0);
6110                         if (rc != 0) {
6111                                 pr_err("error %d\n", rc);
6112                                 goto rw_error;
6113                         }
6114
6115                         if (agc_settings->standard == DRX_STANDARD_8VSB)
6116                                 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
6117                         else if (DRXJ_ISQAMSTD(agc_settings->standard))
6118                                 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
6119                         else if (DRXJ_ISATVSTD(agc_settings->standard))
6120                                 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
6121                         else
6122                                 return -EINVAL;
6123
6124                         /* Set TOP, only if IF-AGC is in AUTO mode */
6125                         if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
6126                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
6127                                 if (rc != 0) {
6128                                         pr_err("error %d\n", rc);
6129                                         goto rw_error;
6130                                 }
6131                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
6132                                 if (rc != 0) {
6133                                         pr_err("error %d\n", rc);
6134                                         goto rw_error;
6135                                 }
6136                         }
6137
6138                         /* Cut-Off current */
6139                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
6140                         if (rc != 0) {
6141                                 pr_err("error %d\n", rc);
6142                                 goto rw_error;
6143                         }
6144                         break;
6145                 case DRX_AGC_CTRL_USER:
6146
6147                         /* Enable RF AGC DAC */
6148                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6149                         if (rc != 0) {
6150                                 pr_err("error %d\n", rc);
6151                                 goto rw_error;
6152                         }
6153                         data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
6154                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6155                         if (rc != 0) {
6156                                 pr_err("error %d\n", rc);
6157                                 goto rw_error;
6158                         }
6159
6160                         /* Disable SCU RF AGC loop */
6161                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6162                         if (rc != 0) {
6163                                 pr_err("error %d\n", rc);
6164                                 goto rw_error;
6165                         }
6166                         data &= ~SCU_RAM_AGC_KI_RF__M;
6167                         if (common_attr->tuner_rf_agc_pol)
6168                                 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
6169                         else
6170                                 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
6171                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6172                         if (rc != 0) {
6173                                 pr_err("error %d\n", rc);
6174                                 goto rw_error;
6175                         }
6176
6177                         /* Write value to output pin */
6178                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
6179                         if (rc != 0) {
6180                                 pr_err("error %d\n", rc);
6181                                 goto rw_error;
6182                         }
6183                         break;
6184                 case DRX_AGC_CTRL_OFF:
6185
6186                         /* Disable RF AGC DAC */
6187                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6188                         if (rc != 0) {
6189                                 pr_err("error %d\n", rc);
6190                                 goto rw_error;
6191                         }
6192                         data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
6193                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6194                         if (rc != 0) {
6195                                 pr_err("error %d\n", rc);
6196                                 goto rw_error;
6197                         }
6198
6199                         /* Disable SCU RF AGC loop */
6200                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6201                         if (rc != 0) {
6202                                 pr_err("error %d\n", rc);
6203                                 goto rw_error;
6204                         }
6205                         data &= ~SCU_RAM_AGC_KI_RF__M;
6206                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6207                         if (rc != 0) {
6208                                 pr_err("error %d\n", rc);
6209                                 goto rw_error;
6210                         }
6211                         break;
6212                 default:
6213                         return -EINVAL;
6214                 }               /* switch ( agcsettings->ctrl_mode ) */
6215         }
6216
6217         /* Store rf agc settings */
6218         switch (agc_settings->standard) {
6219         case DRX_STANDARD_8VSB:
6220                 ext_attr->vsb_rf_agc_cfg = *agc_settings;
6221                 break;
6222 #ifndef DRXJ_VSB_ONLY
6223         case DRX_STANDARD_ITU_A:
6224         case DRX_STANDARD_ITU_B:
6225         case DRX_STANDARD_ITU_C:
6226                 ext_attr->qam_rf_agc_cfg = *agc_settings;
6227                 break;
6228 #endif
6229 #ifndef DRXJ_DIGITAL_ONLY
6230         case DRX_STANDARD_PAL_SECAM_BG:
6231         case DRX_STANDARD_PAL_SECAM_DK:
6232         case DRX_STANDARD_PAL_SECAM_I:
6233         case DRX_STANDARD_PAL_SECAM_L:
6234         case DRX_STANDARD_PAL_SECAM_LP:
6235         case DRX_STANDARD_NTSC:
6236         case DRX_STANDARD_FM:
6237                 ext_attr->atv_rf_agc_cfg = *agc_settings;
6238                 break;
6239 #endif
6240         default:
6241                 return -EIO;
6242         }
6243
6244         return 0;
6245 rw_error:
6246         return -EIO;
6247 }
6248
6249 /**
6250 * \fn int get_agc_rf ()
6251 * \brief get configuration of RF AGC
6252 * \param demod instance of demodulator.
6253 * \param agc_settings AGC configuration structure
6254 * \return int.
6255 */
6256 static int
6257 get_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6258 {
6259         struct i2c_device_addr *dev_addr = NULL;
6260         struct drxj_data *ext_attr = NULL;
6261         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6262         int rc;
6263
6264         dev_addr = demod->my_i2c_dev_addr;
6265         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6266
6267         /* Return stored AGC settings */
6268         standard = agc_settings->standard;
6269         switch (agc_settings->standard) {
6270         case DRX_STANDARD_8VSB:
6271                 *agc_settings = ext_attr->vsb_rf_agc_cfg;
6272                 break;
6273 #ifndef DRXJ_VSB_ONLY
6274         case DRX_STANDARD_ITU_A:
6275         case DRX_STANDARD_ITU_B:
6276         case DRX_STANDARD_ITU_C:
6277                 *agc_settings = ext_attr->qam_rf_agc_cfg;
6278                 break;
6279 #endif
6280 #ifndef DRXJ_DIGITAL_ONLY
6281         case DRX_STANDARD_PAL_SECAM_BG:
6282         case DRX_STANDARD_PAL_SECAM_DK:
6283         case DRX_STANDARD_PAL_SECAM_I:
6284         case DRX_STANDARD_PAL_SECAM_L:
6285         case DRX_STANDARD_PAL_SECAM_LP:
6286         case DRX_STANDARD_NTSC:
6287         case DRX_STANDARD_FM:
6288                 *agc_settings = ext_attr->atv_rf_agc_cfg;
6289                 break;
6290 #endif
6291         default:
6292                 return -EIO;
6293         }
6294         agc_settings->standard = standard;
6295
6296         /* Get AGC output only if standard is currently active. */
6297         if ((ext_attr->standard == agc_settings->standard) ||
6298             (DRXJ_ISQAMSTD(ext_attr->standard) &&
6299              DRXJ_ISQAMSTD(agc_settings->standard)) ||
6300             (DRXJ_ISATVSTD(ext_attr->standard) &&
6301              DRXJ_ISATVSTD(agc_settings->standard))) {
6302                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, &(agc_settings->output_level), 0);
6303                 if (rc != 0) {
6304                         pr_err("error %d\n", rc);
6305                         goto rw_error;
6306                 }
6307         }
6308
6309         return 0;
6310 rw_error:
6311         return -EIO;
6312 }
6313
6314 /**
6315 * \fn int set_agc_if ()
6316 * \brief Configure If AGC
6317 * \param demod instance of demodulator.
6318 * \param agc_settings AGC configuration structure
6319 * \return int.
6320 */
6321 static int
6322 set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
6323 {
6324         struct i2c_device_addr *dev_addr = NULL;
6325         struct drxj_data *ext_attr = NULL;
6326         struct drxj_cfg_agc *p_agc_settings = NULL;
6327         struct drx_common_attr *common_attr = NULL;
6328         drx_write_reg16func_t scu_wr16 = NULL;
6329         drx_read_reg16func_t scu_rr16 = NULL;
6330         int rc;
6331
6332         common_attr = (struct drx_common_attr *) demod->my_common_attr;
6333         dev_addr = demod->my_i2c_dev_addr;
6334         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6335
6336         if (atomic) {
6337                 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
6338                 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
6339         } else {
6340                 scu_rr16 = DRXJ_DAP.read_reg16func;
6341                 scu_wr16 = DRXJ_DAP.write_reg16func;
6342         }
6343
6344         /* Configure AGC only if standard is currently active */
6345         if ((ext_attr->standard == agc_settings->standard) ||
6346             (DRXJ_ISQAMSTD(ext_attr->standard) &&
6347              DRXJ_ISQAMSTD(agc_settings->standard)) ||
6348             (DRXJ_ISATVSTD(ext_attr->standard) &&
6349              DRXJ_ISATVSTD(agc_settings->standard))) {
6350                 u16 data = 0;
6351
6352                 switch (agc_settings->ctrl_mode) {
6353                 case DRX_AGC_CTRL_AUTO:
6354                         /* Enable IF AGC DAC */
6355                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6356                         if (rc != 0) {
6357                                 pr_err("error %d\n", rc);
6358                                 goto rw_error;
6359                         }
6360                         data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
6361                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6362                         if (rc != 0) {
6363                                 pr_err("error %d\n", rc);
6364                                 goto rw_error;
6365                         }
6366
6367                         /* Enable SCU IF AGC loop */
6368                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6369                         if (rc != 0) {
6370                                 pr_err("error %d\n", rc);
6371                                 goto rw_error;
6372                         }
6373                         data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6374                         data &= ~SCU_RAM_AGC_KI_IF__M;
6375                         if (ext_attr->standard == DRX_STANDARD_8VSB)
6376                                 data |= (3 << SCU_RAM_AGC_KI_IF__B);
6377                         else if (DRXJ_ISQAMSTD(ext_attr->standard))
6378                                 data |= (6 << SCU_RAM_AGC_KI_IF__B);
6379                         else
6380                                 data |= (5 << SCU_RAM_AGC_KI_IF__B);
6381
6382                         if (common_attr->tuner_if_agc_pol)
6383                                 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
6384                         else
6385                                 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
6386                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6387                         if (rc != 0) {
6388                                 pr_err("error %d\n", rc);
6389                                 goto rw_error;
6390                         }
6391
6392                         /* Set speed (using complementary reduction value) */
6393                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
6394                         if (rc != 0) {
6395                                 pr_err("error %d\n", rc);
6396                                 goto rw_error;
6397                         }
6398                         data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
6399                         rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_KI_RED__A, (~(agc_settings->speed << SCU_RAM_AGC_KI_RED_IAGC_RED__B) & SCU_RAM_AGC_KI_RED_IAGC_RED__M) | data, 0);
6400                         if (rc != 0) {
6401                                 pr_err("error %d\n", rc);
6402                                 goto rw_error;
6403                         }
6404
6405                         if (agc_settings->standard == DRX_STANDARD_8VSB)
6406                                 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
6407                         else if (DRXJ_ISQAMSTD(agc_settings->standard))
6408                                 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
6409                         else if (DRXJ_ISATVSTD(agc_settings->standard))
6410                                 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
6411                         else
6412                                 return -EINVAL;
6413
6414                         /* Restore TOP */
6415                         if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
6416                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
6417                                 if (rc != 0) {
6418                                         pr_err("error %d\n", rc);
6419                                         goto rw_error;
6420                                 }
6421                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
6422                                 if (rc != 0) {
6423                                         pr_err("error %d\n", rc);
6424                                         goto rw_error;
6425                                 }
6426                         } else {
6427                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
6428                                 if (rc != 0) {
6429                                         pr_err("error %d\n", rc);
6430                                         goto rw_error;
6431                                 }
6432                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
6433                                 if (rc != 0) {
6434                                         pr_err("error %d\n", rc);
6435                                         goto rw_error;
6436                                 }
6437                         }
6438                         break;
6439
6440                 case DRX_AGC_CTRL_USER:
6441
6442                         /* Enable IF AGC DAC */
6443                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6444                         if (rc != 0) {
6445                                 pr_err("error %d\n", rc);
6446                                 goto rw_error;
6447                         }
6448                         data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
6449                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6450                         if (rc != 0) {
6451                                 pr_err("error %d\n", rc);
6452                                 goto rw_error;
6453                         }
6454
6455                         /* Disable SCU IF AGC loop */
6456                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6457                         if (rc != 0) {
6458                                 pr_err("error %d\n", rc);
6459                                 goto rw_error;
6460                         }
6461                         data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6462                         data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6463                         if (common_attr->tuner_if_agc_pol)
6464                                 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
6465                         else
6466                                 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
6467                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6468                         if (rc != 0) {
6469                                 pr_err("error %d\n", rc);
6470                                 goto rw_error;
6471                         }
6472
6473                         /* Write value to output pin */
6474                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
6475                         if (rc != 0) {
6476                                 pr_err("error %d\n", rc);
6477                                 goto rw_error;
6478                         }
6479                         break;
6480
6481                 case DRX_AGC_CTRL_OFF:
6482
6483                         /* Disable If AGC DAC */
6484                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6485                         if (rc != 0) {
6486                                 pr_err("error %d\n", rc);
6487                                 goto rw_error;
6488                         }
6489                         data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
6490                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6491                         if (rc != 0) {
6492                                 pr_err("error %d\n", rc);
6493                                 goto rw_error;
6494                         }
6495
6496                         /* Disable SCU IF AGC loop */
6497                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6498                         if (rc != 0) {
6499                                 pr_err("error %d\n", rc);
6500                                 goto rw_error;
6501                         }
6502                         data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6503                         data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6504                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6505                         if (rc != 0) {
6506                                 pr_err("error %d\n", rc);
6507                                 goto rw_error;
6508                         }
6509                         break;
6510                 default:
6511                         return -EINVAL;
6512                 }               /* switch ( agcsettings->ctrl_mode ) */
6513
6514                 /* always set the top to support configurations without if-loop */
6515                 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
6516                 if (rc != 0) {
6517                         pr_err("error %d\n", rc);
6518                         goto rw_error;
6519                 }
6520         }
6521
6522         /* Store if agc settings */
6523         switch (agc_settings->standard) {
6524         case DRX_STANDARD_8VSB:
6525                 ext_attr->vsb_if_agc_cfg = *agc_settings;
6526                 break;
6527 #ifndef DRXJ_VSB_ONLY
6528         case DRX_STANDARD_ITU_A:
6529         case DRX_STANDARD_ITU_B:
6530         case DRX_STANDARD_ITU_C:
6531                 ext_attr->qam_if_agc_cfg = *agc_settings;
6532                 break;
6533 #endif
6534 #ifndef DRXJ_DIGITAL_ONLY
6535         case DRX_STANDARD_PAL_SECAM_BG:
6536         case DRX_STANDARD_PAL_SECAM_DK:
6537         case DRX_STANDARD_PAL_SECAM_I:
6538         case DRX_STANDARD_PAL_SECAM_L:
6539         case DRX_STANDARD_PAL_SECAM_LP:
6540         case DRX_STANDARD_NTSC:
6541         case DRX_STANDARD_FM:
6542                 ext_attr->atv_if_agc_cfg = *agc_settings;
6543                 break;
6544 #endif
6545         default:
6546                 return -EIO;
6547         }
6548
6549         return 0;
6550 rw_error:
6551         return -EIO;
6552 }
6553
6554 /**
6555 * \fn int get_agc_if ()
6556 * \brief get configuration of If AGC
6557 * \param demod instance of demodulator.
6558 * \param agc_settings AGC configuration structure
6559 * \return int.
6560 */
6561 static int
6562 get_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6563 {
6564         struct i2c_device_addr *dev_addr = NULL;
6565         struct drxj_data *ext_attr = NULL;
6566         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6567         int rc;
6568
6569         dev_addr = demod->my_i2c_dev_addr;
6570         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6571
6572         /* Return stored ATV AGC settings */
6573         standard = agc_settings->standard;
6574         switch (agc_settings->standard) {
6575         case DRX_STANDARD_8VSB:
6576                 *agc_settings = ext_attr->vsb_if_agc_cfg;
6577                 break;
6578 #ifndef DRXJ_VSB_ONLY
6579         case DRX_STANDARD_ITU_A:
6580         case DRX_STANDARD_ITU_B:
6581         case DRX_STANDARD_ITU_C:
6582                 *agc_settings = ext_attr->qam_if_agc_cfg;
6583                 break;
6584 #endif
6585 #ifndef DRXJ_DIGITAL_ONLY
6586         case DRX_STANDARD_PAL_SECAM_BG:
6587         case DRX_STANDARD_PAL_SECAM_DK:
6588         case DRX_STANDARD_PAL_SECAM_I:
6589         case DRX_STANDARD_PAL_SECAM_L:
6590         case DRX_STANDARD_PAL_SECAM_LP:
6591         case DRX_STANDARD_NTSC:
6592         case DRX_STANDARD_FM:
6593                 *agc_settings = ext_attr->atv_if_agc_cfg;
6594                 break;
6595 #endif
6596         default:
6597                 return -EIO;
6598         }
6599         agc_settings->standard = standard;
6600
6601         /* Get AGC output only if standard is currently active */
6602         if ((ext_attr->standard == agc_settings->standard) ||
6603             (DRXJ_ISQAMSTD(ext_attr->standard) &&
6604              DRXJ_ISQAMSTD(agc_settings->standard)) ||
6605             (DRXJ_ISATVSTD(ext_attr->standard) &&
6606              DRXJ_ISATVSTD(agc_settings->standard))) {
6607                 /* read output level */
6608                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, &(agc_settings->output_level), 0);
6609                 if (rc != 0) {
6610                         pr_err("error %d\n", rc);
6611                         goto rw_error;
6612                 }
6613         }
6614
6615         return 0;
6616 rw_error:
6617         return -EIO;
6618 }
6619
6620 /**
6621 * \fn int set_iqm_af ()
6622 * \brief Configure IQM AF registers
6623 * \param demod instance of demodulator.
6624 * \param active
6625 * \return int.
6626 */
6627 static int set_iqm_af(struct drx_demod_instance *demod, bool active)
6628 {
6629         u16 data = 0;
6630         struct i2c_device_addr *dev_addr = NULL;
6631         int rc;
6632
6633         dev_addr = demod->my_i2c_dev_addr;
6634
6635         /* Configure IQM */
6636         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6637         if (rc != 0) {
6638                 pr_err("error %d\n", rc);
6639                 goto rw_error;
6640         }
6641         if (!active)
6642                 data &= ((~IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_PD_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE) & (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE));
6643         else
6644                 data |= (IQM_AF_STDBY_STDBY_ADC_A2_ACTIVE | IQM_AF_STDBY_STDBY_AMP_A2_ACTIVE | IQM_AF_STDBY_STDBY_PD_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE | IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
6645         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6646         if (rc != 0) {
6647                 pr_err("error %d\n", rc);
6648                 goto rw_error;
6649         }
6650
6651         return 0;
6652 rw_error:
6653         return -EIO;
6654 }
6655
6656 /*============================================================================*/
6657 /*==              END 8VSB & QAM COMMON DATAPATH FUNCTIONS                  ==*/
6658 /*============================================================================*/
6659
6660 /*============================================================================*/
6661 /*============================================================================*/
6662 /*==                       8VSB DATAPATH FUNCTIONS                          ==*/
6663 /*============================================================================*/
6664 /*============================================================================*/
6665
6666 /**
6667 * \fn int power_down_vsb ()
6668 * \brief Powr down QAM related blocks.
6669 * \param demod instance of demodulator.
6670 * \param channel pointer to channel data.
6671 * \return int.
6672 */
6673 static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
6674 {
6675         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6676         struct drxjscu_cmd cmd_scu = { /* command     */ 0,
6677                 /* parameter_len */ 0,
6678                 /* result_len    */ 0,
6679                 /* *parameter   */ NULL,
6680                 /* *result      */ NULL
6681         };
6682         struct drx_cfg_mpeg_output cfg_mpeg_output;
6683         int rc;
6684         u16 cmd_result = 0;
6685
6686         /*
6687            STOP demodulator
6688            reset of FEC and VSB HW
6689          */
6690         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
6691             SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6692         cmd_scu.parameter_len = 0;
6693         cmd_scu.result_len = 1;
6694         cmd_scu.parameter = NULL;
6695         cmd_scu.result = &cmd_result;
6696         rc = scu_command(dev_addr, &cmd_scu);
6697         if (rc != 0) {
6698                 pr_err("error %d\n", rc);
6699                 goto rw_error;
6700         }
6701
6702         /* stop all comm_exec */
6703         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
6704         if (rc != 0) {
6705                 pr_err("error %d\n", rc);
6706                 goto rw_error;
6707         }
6708         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
6709         if (rc != 0) {
6710                 pr_err("error %d\n", rc);
6711                 goto rw_error;
6712         }
6713         if (primary) {
6714                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
6715                 if (rc != 0) {
6716                         pr_err("error %d\n", rc);
6717                         goto rw_error;
6718                 }
6719                 rc = set_iqm_af(demod, false);
6720                 if (rc != 0) {
6721                         pr_err("error %d\n", rc);
6722                         goto rw_error;
6723                 }
6724         } else {
6725                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
6726                 if (rc != 0) {
6727                         pr_err("error %d\n", rc);
6728                         goto rw_error;
6729                 }
6730                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
6731                 if (rc != 0) {
6732                         pr_err("error %d\n", rc);
6733                         goto rw_error;
6734                 }
6735                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
6736                 if (rc != 0) {
6737                         pr_err("error %d\n", rc);
6738                         goto rw_error;
6739                 }
6740                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
6741                 if (rc != 0) {
6742                         pr_err("error %d\n", rc);
6743                         goto rw_error;
6744                 }
6745                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
6746                 if (rc != 0) {
6747                         pr_err("error %d\n", rc);
6748                         goto rw_error;
6749                 }
6750         }
6751
6752         cfg_mpeg_output.enable_mpeg_output = false;
6753         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6754         if (rc != 0) {
6755                 pr_err("error %d\n", rc);
6756                 goto rw_error;
6757         }
6758
6759         return 0;
6760 rw_error:
6761         return -EIO;
6762 }
6763
6764 /**
6765 * \fn int set_vsb_leak_n_gain ()
6766 * \brief Set ATSC demod.
6767 * \param demod instance of demodulator.
6768 * \return int.
6769 */
6770 static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
6771 {
6772         struct i2c_device_addr *dev_addr = NULL;
6773         int rc;
6774
6775         const u8 vsb_ffe_leak_gain_ram0[] = {
6776                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO1  */
6777                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO2  */
6778                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO3  */
6779                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO4  */
6780                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO5  */
6781                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO6  */
6782                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO7  */
6783                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO8  */
6784                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO9  */
6785                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO10  */
6786                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO11 */
6787                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO12 */
6788                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO1 */
6789                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO2 */
6790                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO3 */
6791                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO4 */
6792                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO5 */
6793                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO6 */
6794                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO7 */
6795                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO8 */
6796                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO9 */
6797                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO10 */
6798                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO11 */
6799                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO12 */
6800                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO1 */
6801                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO2 */
6802                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO3 */
6803                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO4 */
6804                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO5 */
6805                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO6 */
6806                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO7 */
6807                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO8 */
6808                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO9 */
6809                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO10 */
6810                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO11 */
6811                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO12 */
6812                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO1 */
6813                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO2 */
6814                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO3 */
6815                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO4 */
6816                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO5 */
6817                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO6 */
6818                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO7 */
6819                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO8 */
6820                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO9 */
6821                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO10 */
6822                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO11 */
6823                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO12 */
6824                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO1 */
6825                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO2 */
6826                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO3 */
6827                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO4 */
6828                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO5 */
6829                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO6 */
6830                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO7 */
6831                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO8 */
6832                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO9 */
6833                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO10 */
6834                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO11 */
6835                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO12 */
6836                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO1 */
6837                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO2 */
6838                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO3 */
6839                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO4 */
6840                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO5 */
6841                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO6 */
6842                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO7 */
6843                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO8 */
6844                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO9 */
6845                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO10 */
6846                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO11 */
6847                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO12 */
6848                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO1 */
6849                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO2 */
6850                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO3 */
6851                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO4 */
6852                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO5 */
6853                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO6 */
6854                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO7 */
6855                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO8 */
6856                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO9 */
6857                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO10 */
6858                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO11 */
6859                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO12 */
6860                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO1 */
6861                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO2 */
6862                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO3 */
6863                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO4 */
6864                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO5 */
6865                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO6 */
6866                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO7 */
6867                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO8 */
6868                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO9 */
6869                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO10 */
6870                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO11 */
6871                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO12 */
6872                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO1 */
6873                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO2 */
6874                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO3 */
6875                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO4 */
6876                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO5 */
6877                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO6 */
6878                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO7 */
6879                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO8 */
6880                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO9 */
6881                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO10 */
6882                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO11 */
6883                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO12 */
6884                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN1 */
6885                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN2 */
6886                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN3 */
6887                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN4 */
6888                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN5 */
6889                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN6 */
6890                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN7 */
6891                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN8 */
6892                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN9 */
6893                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN10 */
6894                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN11 */
6895                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN12 */
6896                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN1 */
6897                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN2 */
6898                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN3 */
6899                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN4 */
6900                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN5 */
6901                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN6 */
6902                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN7 */
6903                 DRXJ_16TO8(0x1010)      /* FIRRCA1GAIN8 */
6904         };
6905
6906         const u8 vsb_ffe_leak_gain_ram1[] = {
6907                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN9 */
6908                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN10 */
6909                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN11 */
6910                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN12 */
6911                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN1 */
6912                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN2 */
6913                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN3 */
6914                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN4 */
6915                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN5 */
6916                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN6 */
6917                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN7 */
6918                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN8 */
6919                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN9 */
6920                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN10 */
6921                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN11 */
6922                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN12 */
6923                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN1 */
6924                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN2 */
6925                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN3 */
6926                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN4 */
6927                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN5 */
6928                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN6 */
6929                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN7 */
6930                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN8 */
6931                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN9 */
6932                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN10 */
6933                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN11 */
6934                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN12 */
6935                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN1 */
6936                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN2 */
6937                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN3 */
6938                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN4 */
6939                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN5 */
6940                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN6 */
6941                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN7 */
6942                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN8 */
6943                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN9 */
6944                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN10 */
6945                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN11 */
6946                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN12 */
6947                 DRXJ_16TO8(0x001f),     /* DFETRAINLKRATIO */
6948                 DRXJ_16TO8(0x01ff),     /* DFERCA1TRAINLKRATIO */
6949                 DRXJ_16TO8(0x01ff),     /* DFERCA1DATALKRATIO */
6950                 DRXJ_16TO8(0x004f),     /* DFERCA2TRAINLKRATIO */
6951                 DRXJ_16TO8(0x004f),     /* DFERCA2DATALKRATIO */
6952                 DRXJ_16TO8(0x01ff),     /* DFEDDM1TRAINLKRATIO */
6953                 DRXJ_16TO8(0x01ff),     /* DFEDDM1DATALKRATIO */
6954                 DRXJ_16TO8(0x0352),     /* DFEDDM2TRAINLKRATIO */
6955                 DRXJ_16TO8(0x0352),     /* DFEDDM2DATALKRATIO */
6956                 DRXJ_16TO8(0x0000),     /* DFETRAINGAIN */
6957                 DRXJ_16TO8(0x2020),     /* DFERCA1GAIN */
6958                 DRXJ_16TO8(0x1010),     /* DFERCA2GAIN */
6959                 DRXJ_16TO8(0x1818),     /* DFEDDM1GAIN */
6960                 DRXJ_16TO8(0x1212)      /* DFEDDM2GAIN */
6961         };
6962
6963         dev_addr = demod->my_i2c_dev_addr;
6964         rc = DRXJ_DAP.write_block_func(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, sizeof(vsb_ffe_leak_gain_ram0), ((u8 *)vsb_ffe_leak_gain_ram0), 0);
6965         if (rc != 0) {
6966                 pr_err("error %d\n", rc);
6967                 goto rw_error;
6968         }
6969         rc = DRXJ_DAP.write_block_func(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, sizeof(vsb_ffe_leak_gain_ram1), ((u8 *)vsb_ffe_leak_gain_ram1), 0);
6970         if (rc != 0) {
6971                 pr_err("error %d\n", rc);
6972                 goto rw_error;
6973         }
6974
6975         return 0;
6976 rw_error:
6977         return -EIO;
6978 }
6979
6980 /**
6981 * \fn int set_vsb()
6982 * \brief Set 8VSB demod.
6983 * \param demod instance of demodulator.
6984 * \return int.
6985 *
6986 */
6987 static int set_vsb(struct drx_demod_instance *demod)
6988 {
6989         struct i2c_device_addr *dev_addr = NULL;
6990         int rc;
6991         struct drx_common_attr *common_attr = NULL;
6992         struct drxjscu_cmd cmd_scu;
6993         struct drxj_data *ext_attr = NULL;
6994         u16 cmd_result = 0;
6995         u16 cmd_param = 0;
6996         const u8 vsb_taps_re[] = {
6997                 DRXJ_16TO8(-2), /* re0  */
6998                 DRXJ_16TO8(4),  /* re1  */
6999                 DRXJ_16TO8(1),  /* re2  */
7000                 DRXJ_16TO8(-4), /* re3  */
7001                 DRXJ_16TO8(1),  /* re4  */
7002                 DRXJ_16TO8(4),  /* re5  */
7003                 DRXJ_16TO8(-3), /* re6  */
7004                 DRXJ_16TO8(-3), /* re7  */
7005                 DRXJ_16TO8(6),  /* re8  */
7006                 DRXJ_16TO8(1),  /* re9  */
7007                 DRXJ_16TO8(-9), /* re10 */
7008                 DRXJ_16TO8(3),  /* re11 */
7009                 DRXJ_16TO8(12), /* re12 */
7010                 DRXJ_16TO8(-9), /* re13 */
7011                 DRXJ_16TO8(-15),        /* re14 */
7012                 DRXJ_16TO8(17), /* re15 */
7013                 DRXJ_16TO8(19), /* re16 */
7014                 DRXJ_16TO8(-29),        /* re17 */
7015                 DRXJ_16TO8(-22),        /* re18 */
7016                 DRXJ_16TO8(45), /* re19 */
7017                 DRXJ_16TO8(25), /* re20 */
7018                 DRXJ_16TO8(-70),        /* re21 */
7019                 DRXJ_16TO8(-28),        /* re22 */
7020                 DRXJ_16TO8(111),        /* re23 */
7021                 DRXJ_16TO8(30), /* re24 */
7022                 DRXJ_16TO8(-201),       /* re25 */
7023                 DRXJ_16TO8(-31),        /* re26 */
7024                 DRXJ_16TO8(629) /* re27 */
7025         };
7026
7027         dev_addr = demod->my_i2c_dev_addr;
7028         common_attr = (struct drx_common_attr *) demod->my_common_attr;
7029         ext_attr = (struct drxj_data *) demod->my_ext_attr;
7030
7031         /* stop all comm_exec */
7032         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
7033         if (rc != 0) {
7034                 pr_err("error %d\n", rc);
7035                 goto rw_error;
7036         }
7037         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
7038         if (rc != 0) {
7039                 pr_err("error %d\n", rc);
7040                 goto rw_error;
7041         }
7042         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
7043         if (rc != 0) {
7044                 pr_err("error %d\n", rc);
7045                 goto rw_error;
7046         }
7047         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
7048         if (rc != 0) {
7049                 pr_err("error %d\n", rc);
7050                 goto rw_error;
7051         }
7052         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
7053         if (rc != 0) {
7054                 pr_err("error %d\n", rc);
7055                 goto rw_error;
7056         }
7057         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
7058         if (rc != 0) {
7059                 pr_err("error %d\n", rc);
7060                 goto rw_error;
7061         }
7062         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
7063         if (rc != 0) {
7064                 pr_err("error %d\n", rc);
7065                 goto rw_error;
7066         }
7067
7068         /* reset demodulator */
7069         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7070             | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
7071         cmd_scu.parameter_len = 0;
7072         cmd_scu.result_len = 1;
7073         cmd_scu.parameter = NULL;
7074         cmd_scu.result = &cmd_result;
7075         rc = scu_command(dev_addr, &cmd_scu);
7076         if (rc != 0) {
7077                 pr_err("error %d\n", rc);
7078                 goto rw_error;
7079         }
7080
7081         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
7082         if (rc != 0) {
7083                 pr_err("error %d\n", rc);
7084                 goto rw_error;
7085         }
7086         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
7087         if (rc != 0) {
7088                 pr_err("error %d\n", rc);
7089                 goto rw_error;
7090         }
7091         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
7092         if (rc != 0) {
7093                 pr_err("error %d\n", rc);
7094                 goto rw_error;
7095         }
7096         ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
7097         rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
7098         if (rc != 0) {
7099                 pr_err("error %d\n", rc);
7100                 goto rw_error;
7101         }
7102         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
7103         if (rc != 0) {
7104                 pr_err("error %d\n", rc);
7105                 goto rw_error;
7106         }
7107         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
7108         if (rc != 0) {
7109                 pr_err("error %d\n", rc);
7110                 goto rw_error;
7111         }
7112
7113         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
7114         if (rc != 0) {
7115                 pr_err("error %d\n", rc);
7116                 goto rw_error;
7117         }
7118         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, 28, 0);
7119         if (rc != 0) {
7120                 pr_err("error %d\n", rc);
7121                 goto rw_error;
7122         }
7123         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
7124         if (rc != 0) {
7125                 pr_err("error %d\n", rc);
7126                 goto rw_error;
7127         }
7128         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
7129         if (rc != 0) {
7130                 pr_err("error %d\n", rc);
7131                 goto rw_error;
7132         }
7133         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
7134         if (rc != 0) {
7135                 pr_err("error %d\n", rc);
7136                 goto rw_error;
7137         }
7138         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
7139         if (rc != 0) {
7140                 pr_err("error %d\n", rc);
7141                 goto rw_error;
7142         }
7143         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE__A, 1393, 0);
7144         if (rc != 0) {
7145                 pr_err("error %d\n", rc);
7146                 goto rw_error;
7147         }
7148         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
7149         if (rc != 0) {
7150                 pr_err("error %d\n", rc);
7151                 goto rw_error;
7152         }
7153         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
7154         if (rc != 0) {
7155                 pr_err("error %d\n", rc);
7156                 goto rw_error;
7157         }
7158
7159         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
7160         if (rc != 0) {
7161                 pr_err("error %d\n", rc);
7162                 goto rw_error;
7163         }
7164         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
7165         if (rc != 0) {
7166                 pr_err("error %d\n", rc);
7167                 goto rw_error;
7168         }
7169
7170         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
7171         if (rc != 0) {
7172                 pr_err("error %d\n", rc);
7173                 goto rw_error;
7174         }       /* set higher threshold */
7175         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
7176         if (rc != 0) {
7177                 pr_err("error %d\n", rc);
7178                 goto rw_error;
7179         }       /* burst detection on   */
7180         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
7181         if (rc != 0) {
7182                 pr_err("error %d\n", rc);
7183                 goto rw_error;
7184         }       /* drop thresholds by 1 dB */
7185         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
7186         if (rc != 0) {
7187                 pr_err("error %d\n", rc);
7188                 goto rw_error;
7189         }       /* drop thresholds by 2 dB */
7190         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
7191         if (rc != 0) {
7192                 pr_err("error %d\n", rc);
7193                 goto rw_error;
7194         }       /* cma on               */
7195         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
7196         if (rc != 0) {
7197                 pr_err("error %d\n", rc);
7198                 goto rw_error;
7199         }       /* GPIO               */
7200
7201         /* Initialize the FEC Subsystem */
7202         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
7203         if (rc != 0) {
7204                 pr_err("error %d\n", rc);
7205                 goto rw_error;
7206         }
7207         {
7208                 u16 fec_oc_snc_mode = 0;
7209                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
7210                 if (rc != 0) {
7211                         pr_err("error %d\n", rc);
7212                         goto rw_error;
7213                 }
7214                 /* output data even when not locked */
7215                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
7216                 if (rc != 0) {
7217                         pr_err("error %d\n", rc);
7218                         goto rw_error;
7219                 }
7220         }
7221
7222         /* set clip */
7223         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
7224         if (rc != 0) {
7225                 pr_err("error %d\n", rc);
7226                 goto rw_error;
7227         }
7228         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
7229         if (rc != 0) {
7230                 pr_err("error %d\n", rc);
7231                 goto rw_error;
7232         }
7233         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
7234         if (rc != 0) {
7235                 pr_err("error %d\n", rc);
7236                 goto rw_error;
7237         }
7238         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
7239         if (rc != 0) {
7240                 pr_err("error %d\n", rc);
7241                 goto rw_error;
7242         }
7243         /* no transparent, no A&C framing; parity is set in mpegoutput */
7244         {
7245                 u16 fec_oc_reg_mode = 0;
7246                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
7247                 if (rc != 0) {
7248                         pr_err("error %d\n", rc);
7249                         goto rw_error;
7250                 }
7251                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode & (~(FEC_OC_MODE_TRANSPARENT__M | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)), 0);
7252                 if (rc != 0) {
7253                         pr_err("error %d\n", rc);
7254                         goto rw_error;
7255                 }
7256         }
7257
7258         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
7259         if (rc != 0) {
7260                 pr_err("error %d\n", rc);
7261                 goto rw_error;
7262         }       /* timeout counter for restarting */
7263         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
7264         if (rc != 0) {
7265                 pr_err("error %d\n", rc);
7266                 goto rw_error;
7267         }
7268         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MODE__A, 0, 0);
7269         if (rc != 0) {
7270                 pr_err("error %d\n", rc);
7271                 goto rw_error;
7272         }       /* bypass disabled */
7273         /* initialize RS packet error measurement parameters */
7274         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
7275         if (rc != 0) {
7276                 pr_err("error %d\n", rc);
7277                 goto rw_error;
7278         }
7279         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
7280         if (rc != 0) {
7281                 pr_err("error %d\n", rc);
7282                 goto rw_error;
7283         }
7284
7285         /* init measurement period of MER/SER */
7286         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
7287         if (rc != 0) {
7288                 pr_err("error %d\n", rc);
7289                 goto rw_error;
7290         }
7291         rc = DRXJ_DAP.write_reg32func(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
7292         if (rc != 0) {
7293                 pr_err("error %d\n", rc);
7294                 goto rw_error;
7295         }
7296         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
7297         if (rc != 0) {
7298                 pr_err("error %d\n", rc);
7299                 goto rw_error;
7300         }
7301         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
7302         if (rc != 0) {
7303                 pr_err("error %d\n", rc);
7304                 goto rw_error;
7305         }
7306
7307         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
7308         if (rc != 0) {
7309                 pr_err("error %d\n", rc);
7310                 goto rw_error;
7311         }
7312         /* B-Input to ADC, PGA+filter in standby */
7313         if (!ext_attr->has_lna) {
7314                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
7315                 if (rc != 0) {
7316                         pr_err("error %d\n", rc);
7317                         goto rw_error;
7318                 }
7319         }
7320
7321         /* turn on IQMAF. It has to be in front of setAgc**() */
7322         rc = set_iqm_af(demod, true);
7323         if (rc != 0) {
7324                 pr_err("error %d\n", rc);
7325                 goto rw_error;
7326         }
7327         rc = adc_synchronization(demod);
7328         if (rc != 0) {
7329                 pr_err("error %d\n", rc);
7330                 goto rw_error;
7331         }
7332
7333         rc = init_agc(demod);
7334         if (rc != 0) {
7335                 pr_err("error %d\n", rc);
7336                 goto rw_error;
7337         }
7338         rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
7339         if (rc != 0) {
7340                 pr_err("error %d\n", rc);
7341                 goto rw_error;
7342         }
7343         rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
7344         if (rc != 0) {
7345                 pr_err("error %d\n", rc);
7346                 goto rw_error;
7347         }
7348         {
7349                 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
7350                    of only the gain */
7351                 struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
7352
7353                 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
7354                 rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
7355                 if (rc != 0) {
7356                         pr_err("error %d\n", rc);
7357                         goto rw_error;
7358                 }
7359         }
7360         rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
7361         if (rc != 0) {
7362                 pr_err("error %d\n", rc);
7363                 goto rw_error;
7364         }
7365
7366         /* Mpeg output has to be in front of FEC active */
7367         rc = set_mpegtei_handling(demod);
7368         if (rc != 0) {
7369                 pr_err("error %d\n", rc);
7370                 goto rw_error;
7371         }
7372         rc = bit_reverse_mpeg_output(demod);
7373         if (rc != 0) {
7374                 pr_err("error %d\n", rc);
7375                 goto rw_error;
7376         }
7377         rc = set_mpeg_start_width(demod);
7378         if (rc != 0) {
7379                 pr_err("error %d\n", rc);
7380                 goto rw_error;
7381         }
7382         {
7383                 /* TODO: move to set_standard after hardware reset value problem is solved */
7384                 /* Configure initial MPEG output */
7385                 struct drx_cfg_mpeg_output cfg_mpeg_output;
7386                 cfg_mpeg_output.enable_mpeg_output = true;
7387                 cfg_mpeg_output.insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
7388                 cfg_mpeg_output.enable_parallel =
7389                     common_attr->mpeg_cfg.enable_parallel;
7390                 cfg_mpeg_output.invert_data = common_attr->mpeg_cfg.invert_data;
7391                 cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
7392                 cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
7393                 cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
7394                 cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
7395                 cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
7396                 cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
7397                 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
7398                 if (rc != 0) {
7399                         pr_err("error %d\n", rc);
7400                         goto rw_error;
7401                 }
7402         }
7403
7404         /* TBD: what parameters should be set */
7405         cmd_param = 0x00;       /* Default mode AGC on, etc */
7406         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7407             | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
7408         cmd_scu.parameter_len = 1;
7409         cmd_scu.result_len = 1;
7410         cmd_scu.parameter = &cmd_param;
7411         cmd_scu.result = &cmd_result;
7412         rc = scu_command(dev_addr, &cmd_scu);
7413         if (rc != 0) {
7414                 pr_err("error %d\n", rc);
7415                 goto rw_error;
7416         }
7417
7418         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
7419         if (rc != 0) {
7420                 pr_err("error %d\n", rc);
7421                 goto rw_error;
7422         }
7423         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
7424         if (rc != 0) {
7425                 pr_err("error %d\n", rc);
7426                 goto rw_error;
7427         }
7428         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
7429         if (rc != 0) {
7430                 pr_err("error %d\n", rc);
7431                 goto rw_error;
7432         }
7433         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
7434         if (rc != 0) {
7435                 pr_err("error %d\n", rc);
7436                 goto rw_error;
7437         }
7438         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
7439         if (rc != 0) {
7440                 pr_err("error %d\n", rc);
7441                 goto rw_error;
7442         }
7443         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
7444         if (rc != 0) {
7445                 pr_err("error %d\n", rc);
7446                 goto rw_error;
7447         }
7448         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
7449         if (rc != 0) {
7450                 pr_err("error %d\n", rc);
7451                 goto rw_error;
7452         }
7453         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
7454         if (rc != 0) {
7455                 pr_err("error %d\n", rc);
7456                 goto rw_error;
7457         }
7458
7459         /* start demodulator */
7460         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7461             | SCU_RAM_COMMAND_CMD_DEMOD_START;
7462         cmd_scu.parameter_len = 0;
7463         cmd_scu.result_len = 1;
7464         cmd_scu.parameter = NULL;
7465         cmd_scu.result = &cmd_result;
7466         rc = scu_command(dev_addr, &cmd_scu);
7467         if (rc != 0) {
7468                 pr_err("error %d\n", rc);
7469                 goto rw_error;
7470         }
7471
7472         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
7473         if (rc != 0) {
7474                 pr_err("error %d\n", rc);
7475                 goto rw_error;
7476         }
7477         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
7478         if (rc != 0) {
7479                 pr_err("error %d\n", rc);
7480                 goto rw_error;
7481         }
7482         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
7483         if (rc != 0) {
7484                 pr_err("error %d\n", rc);
7485                 goto rw_error;
7486         }
7487
7488         return 0;
7489 rw_error:
7490         return -EIO;
7491 }
7492
7493 /**
7494 * \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
7495 * \brief Get the values of packet error in 8VSB mode
7496 * \return Error code
7497 */
7498 static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *pck_errs)
7499 {
7500         int rc;
7501         u16 data = 0;
7502         u16 period = 0;
7503         u16 prescale = 0;
7504         u16 packet_errors_mant = 0;
7505         u16 packet_errors_exp = 0;
7506
7507         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
7508         if (rc != 0) {
7509                 pr_err("error %d\n", rc);
7510                 goto rw_error;
7511         }
7512         packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
7513         packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
7514             >> FEC_RS_NR_FAILURES_EXP__B;
7515         period = FEC_RS_MEASUREMENT_PERIOD;
7516         prescale = FEC_RS_MEASUREMENT_PRESCALE;
7517         /* packet error rate = (error packet number) per second */
7518         /* 77.3 us is time for per packet */
7519         if (period * prescale == 0) {
7520                 pr_err("error: period and/or prescale is zero!\n");
7521                 return -EIO;
7522         }
7523         *pck_errs =
7524             (u16) frac_times1e6(packet_errors_mant * (1 << packet_errors_exp),
7525                                  (period * prescale * 77));
7526
7527         return 0;
7528 rw_error:
7529         return -EIO;
7530 }
7531
7532 /**
7533 * \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
7534 * \brief Get the values of ber in VSB mode
7535 * \return Error code
7536 */
7537 static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7538 {
7539         int rc;
7540         u16 data = 0;
7541         u16 period = 0;
7542         u16 prescale = 0;
7543         u16 bit_errors_mant = 0;
7544         u16 bit_errors_exp = 0;
7545
7546         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
7547         if (rc != 0) {
7548                 pr_err("error %d\n", rc);
7549                 goto rw_error;
7550         }
7551         period = FEC_RS_MEASUREMENT_PERIOD;
7552         prescale = FEC_RS_MEASUREMENT_PRESCALE;
7553
7554         bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
7555         bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
7556             >> FEC_RS_NR_BIT_ERRORS_EXP__B;
7557
7558         if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
7559                 *ber = 26570;
7560         else {
7561                 if (period * prescale == 0) {
7562                         pr_err("error: period and/or prescale is zero!\n");
7563                         return -EIO;
7564                 }
7565                 *ber =
7566                     frac_times1e6(bit_errors_mant <<
7567                                  ((bit_errors_exp >
7568                                    2) ? (bit_errors_exp - 3) : bit_errors_exp),
7569                                  period * prescale * 207 *
7570                                  ((bit_errors_exp > 2) ? 1 : 8));
7571         }
7572
7573         return 0;
7574 rw_error:
7575         return -EIO;
7576 }
7577
7578 /**
7579 * \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7580 * \brief Get the values of ber in VSB mode
7581 * \return Error code
7582 */
7583 static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7584 {
7585         u16 data = 0;
7586         int rc;
7587
7588         rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
7589         if (rc != 0) {
7590                 pr_err("error %d\n", rc);
7591                 goto rw_error;
7592         }
7593         *ber =
7594             frac_times1e6(data,
7595                          VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT);
7596
7597         return 0;
7598 rw_error:
7599         return -EIO;
7600 }
7601
7602 /**
7603 * \fn static short get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ber)
7604 * \brief Get the values of ber in VSB mode
7605 * \return Error code
7606 */
7607 static int get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ser)
7608 {
7609         int rc;
7610         u16 data = 0;
7611         u16 period = 0;
7612         u16 prescale = 0;
7613         u16 symb_errors_mant = 0;
7614         u16 symb_errors_exp = 0;
7615
7616         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &data, 0);
7617         if (rc != 0) {
7618                 pr_err("error %d\n", rc);
7619                 goto rw_error;
7620         }
7621         period = FEC_RS_MEASUREMENT_PERIOD;
7622         prescale = FEC_RS_MEASUREMENT_PRESCALE;
7623
7624         symb_errors_mant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M;
7625         symb_errors_exp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M)
7626             >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B;
7627
7628         if (period * prescale == 0) {
7629                 pr_err("error: period and/or prescale is zero!\n");
7630                 return -EIO;
7631         }
7632         *ser = (u32) frac_times1e6((symb_errors_mant << symb_errors_exp) * 1000,
7633                                     (period * prescale * 77318));
7634
7635         return 0;
7636 rw_error:
7637         return -EIO;
7638 }
7639
7640 /**
7641 * \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7642 * \brief Get the values of MER
7643 * \return Error code
7644 */
7645 static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7646 {
7647         int rc;
7648         u16 data_hi = 0;
7649
7650         rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
7651         if (rc != 0) {
7652                 pr_err("error %d\n", rc);
7653                 goto rw_error;
7654         }
7655         *mer =
7656             (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
7657
7658         return 0;
7659 rw_error:
7660         return -EIO;
7661 }
7662
7663 /*============================================================================*/
7664 /**
7665 * \fn int ctrl_get_vsb_constel()
7666 * \brief Retreive a VSB constellation point via I2C.
7667 * \param demod Pointer to demodulator instance.
7668 * \param complex_nr Pointer to the structure in which to store the
7669                    constellation point.
7670 * \return int.
7671 */
7672 static int
7673 ctrl_get_vsb_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
7674 {
7675         struct i2c_device_addr *dev_addr = NULL;
7676         int rc;
7677                                        /**< device address                    */
7678         u16 vsb_top_comm_mb = 0;               /**< VSB SL MB configuration           */
7679         u16 vsb_top_comm_mb_init = 0;    /**< VSB SL MB intial configuration    */
7680         u16 re = 0;                    /**< constellation Re part             */
7681         u32 data = 0;
7682
7683         /* read device info */
7684         dev_addr = demod->my_i2c_dev_addr;
7685
7686         /* TODO: */
7687         /* Monitor bus grabbing is an open external interface issue  */
7688         /* Needs to be checked when external interface PG is updated */
7689
7690         /* Configure MB (Monitor bus) */
7691         rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_COMM_MB__A, &vsb_top_comm_mb_init, 0);
7692         if (rc != 0) {
7693                 pr_err("error %d\n", rc);
7694                 goto rw_error;
7695         }
7696         /* set observe flag & MB mux */
7697         vsb_top_comm_mb = (vsb_top_comm_mb_init |
7698                         VSB_TOP_COMM_MB_OBS_OBS_ON |
7699                         VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2);
7700         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb, 0);
7701         if (rc != 0) {
7702                 pr_err("error %d\n", rc);
7703                 goto rw_error;
7704         }
7705
7706         /* Enable MB grabber in the FEC OC */
7707         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M, 0);
7708         if (rc != 0) {
7709                 pr_err("error %d\n", rc);
7710                 goto rw_error;
7711         }
7712
7713         /* Disable MB grabber in the FEC OC */
7714         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, 0x0, 0);
7715         if (rc != 0) {
7716                 pr_err("error %d\n", rc);
7717                 goto rw_error;
7718         }
7719
7720         /* read data */
7721         rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_OCR_GRAB_RD1__A, &data, 0);
7722         if (rc != 0) {
7723                 pr_err("error %d\n", rc);
7724                 goto rw_error;
7725         }
7726         re = (u16) (((data >> 10) & 0x300) | ((data >> 2) & 0xff));
7727         if (re & 0x0200)
7728                 re |= 0xfc00;
7729         complex_nr->re = re;
7730         complex_nr->im = 0;
7731
7732         /* Restore MB (Monitor bus) */
7733         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb_init, 0);
7734         if (rc != 0) {
7735                 pr_err("error %d\n", rc);
7736                 goto rw_error;
7737         }
7738
7739         return 0;
7740 rw_error:
7741         return -EIO;
7742 }
7743
7744 /*============================================================================*/
7745 /*==                     END 8VSB DATAPATH FUNCTIONS                        ==*/
7746 /*============================================================================*/
7747
7748 /*============================================================================*/
7749 /*============================================================================*/
7750 /*==                       QAM DATAPATH FUNCTIONS                           ==*/
7751 /*============================================================================*/
7752 /*============================================================================*/
7753
7754 /**
7755 * \fn int power_down_qam ()
7756 * \brief Powr down QAM related blocks.
7757 * \param demod instance of demodulator.
7758 * \param channel pointer to channel data.
7759 * \return int.
7760 */
7761 static int power_down_qam(struct drx_demod_instance *demod, bool primary)
7762 {
7763         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
7764                 /* parameter_len */ 0,
7765                 /* result_len    */ 0,
7766                 /* *parameter   */ NULL,
7767                 /* *result      */ NULL
7768         };
7769         int rc;
7770         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7771         struct drx_cfg_mpeg_output cfg_mpeg_output;
7772         u16 cmd_result = 0;
7773
7774         /*
7775            STOP demodulator
7776            resets IQM, QAM and FEC HW blocks
7777          */
7778         /* stop all comm_exec */
7779         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
7780         if (rc != 0) {
7781                 pr_err("error %d\n", rc);
7782                 goto rw_error;
7783         }
7784         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
7785         if (rc != 0) {
7786                 pr_err("error %d\n", rc);
7787                 goto rw_error;
7788         }
7789
7790         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
7791             SCU_RAM_COMMAND_CMD_DEMOD_STOP;
7792         cmd_scu.parameter_len = 0;
7793         cmd_scu.result_len = 1;
7794         cmd_scu.parameter = NULL;
7795         cmd_scu.result = &cmd_result;
7796         rc = scu_command(dev_addr, &cmd_scu);
7797         if (rc != 0) {
7798                 pr_err("error %d\n", rc);
7799                 goto rw_error;
7800         }
7801
7802         if (primary) {
7803                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
7804                 if (rc != 0) {
7805                         pr_err("error %d\n", rc);
7806                         goto rw_error;
7807                 }
7808                 rc = set_iqm_af(demod, false);
7809                 if (rc != 0) {
7810                         pr_err("error %d\n", rc);
7811                         goto rw_error;
7812                 }
7813         } else {
7814                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
7815                 if (rc != 0) {
7816                         pr_err("error %d\n", rc);
7817                         goto rw_error;
7818                 }
7819                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
7820                 if (rc != 0) {
7821                         pr_err("error %d\n", rc);
7822                         goto rw_error;
7823                 }
7824                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
7825                 if (rc != 0) {
7826                         pr_err("error %d\n", rc);
7827                         goto rw_error;
7828                 }
7829                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
7830                 if (rc != 0) {
7831                         pr_err("error %d\n", rc);
7832                         goto rw_error;
7833                 }
7834                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
7835                 if (rc != 0) {
7836                         pr_err("error %d\n", rc);
7837                         goto rw_error;
7838                 }
7839         }
7840
7841         cfg_mpeg_output.enable_mpeg_output = false;
7842         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
7843         if (rc != 0) {
7844                 pr_err("error %d\n", rc);
7845                 goto rw_error;
7846         }
7847
7848         return 0;
7849 rw_error:
7850         return -EIO;
7851 }
7852
7853 /*============================================================================*/
7854
7855 /**
7856 * \fn int set_qam_measurement ()
7857 * \brief Setup of the QAM Measuremnt intervals for signal quality
7858 * \param demod instance of demod.
7859 * \param constellation current constellation.
7860 * \return int.
7861 *
7862 *  NOTE:
7863 *  Take into account that for certain settings the errorcounters can overflow.
7864 *  The implementation does not check this.
7865 *
7866 *  TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
7867 *  constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
7868 *  field ?
7869 *
7870 */
7871 #ifndef DRXJ_VSB_ONLY
7872 static int
7873 set_qam_measurement(struct drx_demod_instance *demod,
7874                     enum drx_modulation constellation, u32 symbol_rate)
7875 {
7876         struct i2c_device_addr *dev_addr = NULL;        /* device address for I2C writes */
7877         struct drxj_data *ext_attr = NULL;      /* Global data container for DRXJ specif data */
7878         int rc;
7879         u32 fec_bits_desired = 0;       /* BER accounting period */
7880         u16 fec_rs_plen = 0;    /* defines RS BER measurement period */
7881         u16 fec_rs_prescale = 0;        /* ReedSolomon Measurement Prescale */
7882         u32 fec_rs_period = 0;  /* Value for corresponding I2C register */
7883         u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
7884         u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
7885         u32 qam_vd_period = 0;  /* Value for corresponding I2C register */
7886         u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
7887         u16 fec_vd_plen = 0;    /* no of trellis symbols: VD SER measur period */
7888         u16 qam_vd_prescale = 0;        /* Viterbi Measurement Prescale */
7889
7890         dev_addr = demod->my_i2c_dev_addr;
7891         ext_attr = (struct drxj_data *) demod->my_ext_attr;
7892
7893         fec_bits_desired = ext_attr->fec_bits_desired;
7894         fec_rs_prescale = ext_attr->fec_rs_prescale;
7895
7896         switch (constellation) {
7897         case DRX_CONSTELLATION_QAM16:
7898                 fec_bits_desired = 4 * symbol_rate;
7899                 break;
7900         case DRX_CONSTELLATION_QAM32:
7901                 fec_bits_desired = 5 * symbol_rate;
7902                 break;
7903         case DRX_CONSTELLATION_QAM64:
7904                 fec_bits_desired = 6 * symbol_rate;
7905                 break;
7906         case DRX_CONSTELLATION_QAM128:
7907                 fec_bits_desired = 7 * symbol_rate;
7908                 break;
7909         case DRX_CONSTELLATION_QAM256:
7910                 fec_bits_desired = 8 * symbol_rate;
7911                 break;
7912         default:
7913                 return -EINVAL;
7914         }
7915
7916         /* Parameters for Reed-Solomon Decoder */
7917         /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
7918         /* rs_bit_cnt   = fecrs_period*fecrs_prescale*plen                  */
7919         /*     result is within 32 bit arithmetic ->                        */
7920         /*     no need for mult or frac functions                           */
7921
7922         /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
7923         switch (ext_attr->standard) {
7924         case DRX_STANDARD_ITU_A:
7925         case DRX_STANDARD_ITU_C:
7926                 fec_rs_plen = 204 * 8;
7927                 break;
7928         case DRX_STANDARD_ITU_B:
7929                 fec_rs_plen = 128 * 7;
7930                 break;
7931         default:
7932                 return -EINVAL;
7933         }
7934
7935         ext_attr->fec_rs_plen = fec_rs_plen;    /* for getSigQual */
7936         fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage   */
7937         if (fec_rs_bit_cnt == 0) {
7938                 pr_err("error: fec_rs_bit_cnt is zero!\n");
7939                 return -EIO;
7940         }
7941         fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1;  /* ceil */
7942         if (ext_attr->standard != DRX_STANDARD_ITU_B)
7943                 fec_oc_snc_fail_period = fec_rs_period;
7944
7945         /* limit to max 16 bit value (I2C register width) if needed */
7946         if (fec_rs_period > 0xFFFF)
7947                 fec_rs_period = 0xFFFF;
7948
7949         /* write corresponding registers */
7950         switch (ext_attr->standard) {
7951         case DRX_STANDARD_ITU_A:
7952         case DRX_STANDARD_ITU_C:
7953                 break;
7954         case DRX_STANDARD_ITU_B:
7955                 switch (constellation) {
7956                 case DRX_CONSTELLATION_QAM64:
7957                         fec_rs_period = 31581;
7958                         fec_oc_snc_fail_period = 17932;
7959                         break;
7960                 case DRX_CONSTELLATION_QAM256:
7961                         fec_rs_period = 45446;
7962                         fec_oc_snc_fail_period = 25805;
7963                         break;
7964                 default:
7965                         return -EINVAL;
7966                 }
7967                 break;
7968         default:
7969                 return -EINVAL;
7970         }
7971
7972         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
7973         if (rc != 0) {
7974                 pr_err("error %d\n", rc);
7975                 goto rw_error;
7976         }
7977         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
7978         if (rc != 0) {
7979                 pr_err("error %d\n", rc);
7980                 goto rw_error;
7981         }
7982         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
7983         if (rc != 0) {
7984                 pr_err("error %d\n", rc);
7985                 goto rw_error;
7986         }
7987         ext_attr->fec_rs_period = (u16) fec_rs_period;
7988         ext_attr->fec_rs_prescale = fec_rs_prescale;
7989         rc = DRXJ_DAP.write_reg32func(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
7990         if (rc != 0) {
7991                 pr_err("error %d\n", rc);
7992                 goto rw_error;
7993         }
7994         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
7995         if (rc != 0) {
7996                 pr_err("error %d\n", rc);
7997                 goto rw_error;
7998         }
7999         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
8000         if (rc != 0) {
8001                 pr_err("error %d\n", rc);
8002                 goto rw_error;
8003         }
8004
8005         if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8006                 /* Parameters for Viterbi Decoder */
8007                 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/                      */
8008                 /*                    (qamvd_prescale*plen*(qam_constellation+1))) */
8009                 /* vd_bit_cnt   = qamvd_period*qamvd_prescale*plen                 */
8010                 /*     result is within 32 bit arithmetic ->                       */
8011                 /*     no need for mult or frac functions                          */
8012
8013                 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
8014                 fec_vd_plen = ext_attr->fec_vd_plen;
8015                 qam_vd_prescale = ext_attr->qam_vd_prescale;
8016                 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
8017
8018                 switch (constellation) {
8019                 case DRX_CONSTELLATION_QAM64:
8020                         /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
8021                         qam_vd_period =
8022                             qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
8023                             * (QAM_TOP_CONSTELLATION_QAM64 + 1);
8024                         break;
8025                 case DRX_CONSTELLATION_QAM256:
8026                         /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
8027                         qam_vd_period =
8028                             qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
8029                             * (QAM_TOP_CONSTELLATION_QAM256 + 1);
8030                         break;
8031                 default:
8032                         return -EINVAL;
8033                 }
8034                 if (qam_vd_period == 0) {
8035                         pr_err("error: qam_vd_period is zero!\n");
8036                         return -EIO;
8037                 }
8038                 qam_vd_period = fec_bits_desired / qam_vd_period;
8039                 /* limit to max 16 bit value (I2C register width) if needed */
8040                 if (qam_vd_period > 0xFFFF)
8041                         qam_vd_period = 0xFFFF;
8042
8043                 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
8044                 qam_vd_bit_cnt *= qam_vd_period;
8045
8046                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
8047                 if (rc != 0) {
8048                         pr_err("error %d\n", rc);
8049                         goto rw_error;
8050                 }
8051                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
8052                 if (rc != 0) {
8053                         pr_err("error %d\n", rc);
8054                         goto rw_error;
8055                 }
8056                 ext_attr->qam_vd_period = (u16) qam_vd_period;
8057                 ext_attr->qam_vd_prescale = qam_vd_prescale;
8058         }
8059
8060         return 0;
8061 rw_error:
8062         return -EIO;
8063 }
8064
8065 /*============================================================================*/
8066
8067 /**
8068 * \fn int set_qam16 ()
8069 * \brief QAM16 specific setup
8070 * \param demod instance of demod.
8071 * \return int.
8072 */
8073 static int set_qam16(struct drx_demod_instance *demod)
8074 {
8075         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8076         int rc;
8077         const u8 qam_dq_qual_fun[] = {
8078                 DRXJ_16TO8(2),  /* fun0  */
8079                 DRXJ_16TO8(2),  /* fun1  */
8080                 DRXJ_16TO8(2),  /* fun2  */
8081                 DRXJ_16TO8(2),  /* fun3  */
8082                 DRXJ_16TO8(3),  /* fun4  */
8083                 DRXJ_16TO8(3),  /* fun5  */
8084         };
8085         const u8 qam_eq_cma_rad[] = {
8086                 DRXJ_16TO8(13517),      /* RAD0  */
8087                 DRXJ_16TO8(13517),      /* RAD1  */
8088                 DRXJ_16TO8(13517),      /* RAD2  */
8089                 DRXJ_16TO8(13517),      /* RAD3  */
8090                 DRXJ_16TO8(13517),      /* RAD4  */
8091                 DRXJ_16TO8(13517),      /* RAD5  */
8092         };
8093
8094         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8095         if (rc != 0) {
8096                 pr_err("error %d\n", rc);
8097                 goto rw_error;
8098         }
8099         rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
8100         if (rc != 0) {
8101                 pr_err("error %d\n", rc);
8102                 goto rw_error;
8103         }
8104
8105         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
8106         if (rc != 0) {
8107                 pr_err("error %d\n", rc);
8108                 goto rw_error;
8109         }
8110         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
8111         if (rc != 0) {
8112                 pr_err("error %d\n", rc);
8113                 goto rw_error;
8114         }
8115         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
8116         if (rc != 0) {
8117                 pr_err("error %d\n", rc);
8118                 goto rw_error;
8119         }
8120         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
8121         if (rc != 0) {
8122                 pr_err("error %d\n", rc);
8123                 goto rw_error;
8124         }
8125         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
8126         if (rc != 0) {
8127                 pr_err("error %d\n", rc);
8128                 goto rw_error;
8129         }
8130         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
8131         if (rc != 0) {
8132                 pr_err("error %d\n", rc);
8133                 goto rw_error;
8134         }
8135
8136         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8137         if (rc != 0) {
8138                 pr_err("error %d\n", rc);
8139                 goto rw_error;
8140         }
8141         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
8142         if (rc != 0) {
8143                 pr_err("error %d\n", rc);
8144                 goto rw_error;
8145         }
8146         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8147         if (rc != 0) {
8148                 pr_err("error %d\n", rc);
8149                 goto rw_error;
8150         }
8151
8152         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
8153         if (rc != 0) {
8154                 pr_err("error %d\n", rc);
8155                 goto rw_error;
8156         }
8157         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
8158         if (rc != 0) {
8159                 pr_err("error %d\n", rc);
8160                 goto rw_error;
8161         }
8162         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
8163         if (rc != 0) {
8164                 pr_err("error %d\n", rc);
8165                 goto rw_error;
8166         }
8167         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
8168         if (rc != 0) {
8169                 pr_err("error %d\n", rc);
8170                 goto rw_error;
8171         }
8172         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
8173         if (rc != 0) {
8174                 pr_err("error %d\n", rc);
8175                 goto rw_error;
8176         }
8177         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
8178         if (rc != 0) {
8179                 pr_err("error %d\n", rc);
8180                 goto rw_error;
8181         }
8182         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
8183         if (rc != 0) {
8184                 pr_err("error %d\n", rc);
8185                 goto rw_error;
8186         }
8187
8188         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8189         if (rc != 0) {
8190                 pr_err("error %d\n", rc);
8191                 goto rw_error;
8192         }
8193         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8194         if (rc != 0) {
8195                 pr_err("error %d\n", rc);
8196                 goto rw_error;
8197         }
8198         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8199         if (rc != 0) {
8200                 pr_err("error %d\n", rc);
8201                 goto rw_error;
8202         }
8203         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
8204         if (rc != 0) {
8205                 pr_err("error %d\n", rc);
8206                 goto rw_error;
8207         }
8208         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8209         if (rc != 0) {
8210                 pr_err("error %d\n", rc);
8211                 goto rw_error;
8212         }
8213         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8214         if (rc != 0) {
8215                 pr_err("error %d\n", rc);
8216                 goto rw_error;
8217         }
8218         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
8219         if (rc != 0) {
8220                 pr_err("error %d\n", rc);
8221                 goto rw_error;
8222         }
8223         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
8224         if (rc != 0) {
8225                 pr_err("error %d\n", rc);
8226                 goto rw_error;
8227         }
8228         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8229         if (rc != 0) {
8230                 pr_err("error %d\n", rc);
8231                 goto rw_error;
8232         }
8233         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8234         if (rc != 0) {
8235                 pr_err("error %d\n", rc);
8236                 goto rw_error;
8237         }
8238         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8239         if (rc != 0) {
8240                 pr_err("error %d\n", rc);
8241                 goto rw_error;
8242         }
8243         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8244         if (rc != 0) {
8245                 pr_err("error %d\n", rc);
8246                 goto rw_error;
8247         }
8248         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8249         if (rc != 0) {
8250                 pr_err("error %d\n", rc);
8251                 goto rw_error;
8252         }
8253         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8254         if (rc != 0) {
8255                 pr_err("error %d\n", rc);
8256                 goto rw_error;
8257         }
8258         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8259         if (rc != 0) {
8260                 pr_err("error %d\n", rc);
8261                 goto rw_error;
8262         }
8263         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8264         if (rc != 0) {
8265                 pr_err("error %d\n", rc);
8266                 goto rw_error;
8267         }
8268         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
8269         if (rc != 0) {
8270                 pr_err("error %d\n", rc);
8271                 goto rw_error;
8272         }
8273         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8274         if (rc != 0) {
8275                 pr_err("error %d\n", rc);
8276                 goto rw_error;
8277         }
8278         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8279         if (rc != 0) {
8280                 pr_err("error %d\n", rc);
8281                 goto rw_error;
8282         }
8283         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
8284         if (rc != 0) {
8285                 pr_err("error %d\n", rc);
8286                 goto rw_error;
8287         }
8288
8289         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
8290         if (rc != 0) {
8291                 pr_err("error %d\n", rc);
8292                 goto rw_error;
8293         }
8294
8295         return 0;
8296 rw_error:
8297         return -EIO;
8298 }
8299
8300 /*============================================================================*/
8301
8302 /**
8303 * \fn int set_qam32 ()
8304 * \brief QAM32 specific setup
8305 * \param demod instance of demod.
8306 * \return int.
8307 */
8308 static int set_qam32(struct drx_demod_instance *demod)
8309 {
8310         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8311         int rc;
8312         const u8 qam_dq_qual_fun[] = {
8313                 DRXJ_16TO8(3),  /* fun0  */
8314                 DRXJ_16TO8(3),  /* fun1  */
8315                 DRXJ_16TO8(3),  /* fun2  */
8316                 DRXJ_16TO8(3),  /* fun3  */
8317                 DRXJ_16TO8(4),  /* fun4  */
8318                 DRXJ_16TO8(4),  /* fun5  */
8319         };
8320         const u8 qam_eq_cma_rad[] = {
8321                 DRXJ_16TO8(6707),       /* RAD0  */
8322                 DRXJ_16TO8(6707),       /* RAD1  */
8323                 DRXJ_16TO8(6707),       /* RAD2  */
8324                 DRXJ_16TO8(6707),       /* RAD3  */
8325                 DRXJ_16TO8(6707),       /* RAD4  */
8326                 DRXJ_16TO8(6707),       /* RAD5  */
8327         };
8328
8329         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8330         if (rc != 0) {
8331                 pr_err("error %d\n", rc);
8332                 goto rw_error;
8333         }
8334         rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
8335         if (rc != 0) {
8336                 pr_err("error %d\n", rc);
8337                 goto rw_error;
8338         }
8339
8340         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
8341         if (rc != 0) {
8342                 pr_err("error %d\n", rc);
8343                 goto rw_error;
8344         }
8345         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
8346         if (rc != 0) {
8347                 pr_err("error %d\n", rc);
8348                 goto rw_error;
8349         }
8350         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8351         if (rc != 0) {
8352                 pr_err("error %d\n", rc);
8353                 goto rw_error;
8354         }
8355         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
8356         if (rc != 0) {
8357                 pr_err("error %d\n", rc);
8358                 goto rw_error;
8359         }
8360         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8361         if (rc != 0) {
8362                 pr_err("error %d\n", rc);
8363                 goto rw_error;
8364         }
8365         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
8366         if (rc != 0) {
8367                 pr_err("error %d\n", rc);
8368                 goto rw_error;
8369         }
8370
8371         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8372         if (rc != 0) {
8373                 pr_err("error %d\n", rc);
8374                 goto rw_error;
8375         }
8376         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
8377         if (rc != 0) {
8378                 pr_err("error %d\n", rc);
8379                 goto rw_error;
8380         }
8381         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8382         if (rc != 0) {
8383                 pr_err("error %d\n", rc);
8384                 goto rw_error;
8385         }
8386
8387         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
8388         if (rc != 0) {
8389                 pr_err("error %d\n", rc);
8390                 goto rw_error;
8391         }
8392         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
8393         if (rc != 0) {
8394                 pr_err("error %d\n", rc);
8395                 goto rw_error;
8396         }
8397         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
8398         if (rc != 0) {
8399                 pr_err("error %d\n", rc);
8400                 goto rw_error;
8401         }
8402         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
8403         if (rc != 0) {
8404                 pr_err("error %d\n", rc);
8405                 goto rw_error;
8406         }
8407         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
8408         if (rc != 0) {
8409                 pr_err("error %d\n", rc);
8410                 goto rw_error;
8411         }
8412         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
8413         if (rc != 0) {
8414                 pr_err("error %d\n", rc);
8415                 goto rw_error;
8416         }
8417         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
8418         if (rc != 0) {
8419                 pr_err("error %d\n", rc);
8420                 goto rw_error;
8421         }
8422
8423         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8424         if (rc != 0) {
8425                 pr_err("error %d\n", rc);
8426                 goto rw_error;
8427         }
8428         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8429         if (rc != 0) {
8430                 pr_err("error %d\n", rc);
8431                 goto rw_error;
8432         }
8433         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8434         if (rc != 0) {
8435                 pr_err("error %d\n", rc);
8436                 goto rw_error;
8437         }
8438         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
8439         if (rc != 0) {
8440                 pr_err("error %d\n", rc);
8441                 goto rw_error;
8442         }
8443         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8444         if (rc != 0) {
8445                 pr_err("error %d\n", rc);
8446                 goto rw_error;
8447         }
8448         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8449         if (rc != 0) {
8450                 pr_err("error %d\n", rc);
8451                 goto rw_error;
8452         }
8453         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
8454         if (rc != 0) {
8455                 pr_err("error %d\n", rc);
8456                 goto rw_error;
8457         }
8458         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
8459         if (rc != 0) {
8460                 pr_err("error %d\n", rc);
8461                 goto rw_error;
8462         }
8463         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8464         if (rc != 0) {
8465                 pr_err("error %d\n", rc);
8466                 goto rw_error;
8467         }
8468         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8469         if (rc != 0) {
8470                 pr_err("error %d\n", rc);
8471                 goto rw_error;
8472         }
8473         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8474         if (rc != 0) {
8475                 pr_err("error %d\n", rc);
8476                 goto rw_error;
8477         }
8478         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8479         if (rc != 0) {
8480                 pr_err("error %d\n", rc);
8481                 goto rw_error;
8482         }
8483         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8484         if (rc != 0) {
8485                 pr_err("error %d\n", rc);
8486                 goto rw_error;
8487         }
8488         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8489         if (rc != 0) {
8490                 pr_err("error %d\n", rc);
8491                 goto rw_error;
8492         }
8493         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8494         if (rc != 0) {
8495                 pr_err("error %d\n", rc);
8496                 goto rw_error;
8497         }
8498         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8499         if (rc != 0) {
8500                 pr_err("error %d\n", rc);
8501                 goto rw_error;
8502         }
8503         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
8504         if (rc != 0) {
8505                 pr_err("error %d\n", rc);
8506                 goto rw_error;
8507         }
8508         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8509         if (rc != 0) {
8510                 pr_err("error %d\n", rc);
8511                 goto rw_error;
8512         }
8513         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8514         if (rc != 0) {
8515                 pr_err("error %d\n", rc);
8516                 goto rw_error;
8517         }
8518         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
8519         if (rc != 0) {
8520                 pr_err("error %d\n", rc);
8521                 goto rw_error;
8522         }
8523
8524         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
8525         if (rc != 0) {
8526                 pr_err("error %d\n", rc);
8527                 goto rw_error;
8528         }
8529
8530         return 0;
8531 rw_error:
8532         return -EIO;
8533 }
8534
8535 /*============================================================================*/
8536
8537 /**
8538 * \fn int set_qam64 ()
8539 * \brief QAM64 specific setup
8540 * \param demod instance of demod.
8541 * \return int.
8542 */
8543 static int set_qam64(struct drx_demod_instance *demod)
8544 {
8545         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8546         int rc;
8547         const u8 qam_dq_qual_fun[] = {  /* this is hw reset value. no necessary to re-write */
8548                 DRXJ_16TO8(4),  /* fun0  */
8549                 DRXJ_16TO8(4),  /* fun1  */
8550                 DRXJ_16TO8(4),  /* fun2  */
8551                 DRXJ_16TO8(4),  /* fun3  */
8552                 DRXJ_16TO8(6),  /* fun4  */
8553                 DRXJ_16TO8(6),  /* fun5  */
8554         };
8555         const u8 qam_eq_cma_rad[] = {
8556                 DRXJ_16TO8(13336),      /* RAD0  */
8557                 DRXJ_16TO8(12618),      /* RAD1  */
8558                 DRXJ_16TO8(11988),      /* RAD2  */
8559                 DRXJ_16TO8(13809),      /* RAD3  */
8560                 DRXJ_16TO8(13809),      /* RAD4  */
8561                 DRXJ_16TO8(15609),      /* RAD5  */
8562         };
8563
8564         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8565         if (rc != 0) {
8566                 pr_err("error %d\n", rc);
8567                 goto rw_error;
8568         }
8569         rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
8570         if (rc != 0) {
8571                 pr_err("error %d\n", rc);
8572                 goto rw_error;
8573         }
8574
8575         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
8576         if (rc != 0) {
8577                 pr_err("error %d\n", rc);
8578                 goto rw_error;
8579         }
8580         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
8581         if (rc != 0) {
8582                 pr_err("error %d\n", rc);
8583                 goto rw_error;
8584         }
8585         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8586         if (rc != 0) {
8587                 pr_err("error %d\n", rc);
8588                 goto rw_error;
8589         }
8590         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
8591         if (rc != 0) {
8592                 pr_err("error %d\n", rc);
8593                 goto rw_error;
8594         }
8595         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8596         if (rc != 0) {
8597                 pr_err("error %d\n", rc);
8598                 goto rw_error;
8599         }
8600         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
8601         if (rc != 0) {
8602                 pr_err("error %d\n", rc);
8603                 goto rw_error;
8604         }
8605
8606         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8607         if (rc != 0) {
8608                 pr_err("error %d\n", rc);
8609                 goto rw_error;
8610         }
8611         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
8612         if (rc != 0) {
8613                 pr_err("error %d\n", rc);
8614                 goto rw_error;
8615         }
8616         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8617         if (rc != 0) {
8618                 pr_err("error %d\n", rc);
8619                 goto rw_error;
8620         }
8621
8622         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
8623         if (rc != 0) {
8624                 pr_err("error %d\n", rc);
8625                 goto rw_error;
8626         }
8627         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
8628         if (rc != 0) {
8629                 pr_err("error %d\n", rc);
8630                 goto rw_error;
8631         }
8632         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
8633         if (rc != 0) {
8634                 pr_err("error %d\n", rc);
8635                 goto rw_error;
8636         }
8637         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
8638         if (rc != 0) {
8639                 pr_err("error %d\n", rc);
8640                 goto rw_error;
8641         }
8642         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
8643         if (rc != 0) {
8644                 pr_err("error %d\n", rc);
8645                 goto rw_error;
8646         }
8647         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
8648         if (rc != 0) {
8649                 pr_err("error %d\n", rc);
8650                 goto rw_error;
8651         }
8652         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
8653         if (rc != 0) {
8654                 pr_err("error %d\n", rc);
8655                 goto rw_error;
8656         }
8657
8658         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8659         if (rc != 0) {
8660                 pr_err("error %d\n", rc);
8661                 goto rw_error;
8662         }
8663         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8664         if (rc != 0) {
8665                 pr_err("error %d\n", rc);
8666                 goto rw_error;
8667         }
8668         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8669         if (rc != 0) {
8670                 pr_err("error %d\n", rc);
8671                 goto rw_error;
8672         }
8673         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
8674         if (rc != 0) {
8675                 pr_err("error %d\n", rc);
8676                 goto rw_error;
8677         }
8678         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8679         if (rc != 0) {
8680                 pr_err("error %d\n", rc);
8681                 goto rw_error;
8682         }
8683         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8684         if (rc != 0) {
8685                 pr_err("error %d\n", rc);
8686                 goto rw_error;
8687         }
8688         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
8689         if (rc != 0) {
8690                 pr_err("error %d\n", rc);
8691                 goto rw_error;
8692         }
8693         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
8694         if (rc != 0) {
8695                 pr_err("error %d\n", rc);
8696                 goto rw_error;
8697         }
8698         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8699         if (rc != 0) {
8700                 pr_err("error %d\n", rc);
8701                 goto rw_error;
8702         }
8703         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8704         if (rc != 0) {
8705                 pr_err("error %d\n", rc);
8706                 goto rw_error;
8707         }
8708         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8709         if (rc != 0) {
8710                 pr_err("error %d\n", rc);
8711                 goto rw_error;
8712         }
8713         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8714         if (rc != 0) {
8715                 pr_err("error %d\n", rc);
8716                 goto rw_error;
8717         }
8718         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8719         if (rc != 0) {
8720                 pr_err("error %d\n", rc);
8721                 goto rw_error;
8722         }
8723         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8724         if (rc != 0) {
8725                 pr_err("error %d\n", rc);
8726                 goto rw_error;
8727         }
8728         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8729         if (rc != 0) {
8730                 pr_err("error %d\n", rc);
8731                 goto rw_error;
8732         }
8733         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
8734         if (rc != 0) {
8735                 pr_err("error %d\n", rc);
8736                 goto rw_error;
8737         }
8738         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
8739         if (rc != 0) {
8740                 pr_err("error %d\n", rc);
8741                 goto rw_error;
8742         }
8743         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8744         if (rc != 0) {
8745                 pr_err("error %d\n", rc);
8746                 goto rw_error;
8747         }
8748         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8749         if (rc != 0) {
8750                 pr_err("error %d\n", rc);
8751                 goto rw_error;
8752         }
8753         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
8754         if (rc != 0) {
8755                 pr_err("error %d\n", rc);
8756                 goto rw_error;
8757         }
8758
8759         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
8760         if (rc != 0) {
8761                 pr_err("error %d\n", rc);
8762                 goto rw_error;
8763         }
8764
8765         return 0;
8766 rw_error:
8767         return -EIO;
8768 }
8769
8770 /*============================================================================*/
8771
8772 /**
8773 * \fn int set_qam128 ()
8774 * \brief QAM128 specific setup
8775 * \param demod: instance of demod.
8776 * \return int.
8777 */
8778 static int set_qam128(struct drx_demod_instance *demod)
8779 {
8780         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8781         int rc;
8782         const u8 qam_dq_qual_fun[] = {
8783                 DRXJ_16TO8(6),  /* fun0  */
8784                 DRXJ_16TO8(6),  /* fun1  */
8785                 DRXJ_16TO8(6),  /* fun2  */
8786                 DRXJ_16TO8(6),  /* fun3  */
8787                 DRXJ_16TO8(9),  /* fun4  */
8788                 DRXJ_16TO8(9),  /* fun5  */
8789         };
8790         const u8 qam_eq_cma_rad[] = {
8791                 DRXJ_16TO8(6164),       /* RAD0  */
8792                 DRXJ_16TO8(6598),       /* RAD1  */
8793                 DRXJ_16TO8(6394),       /* RAD2  */
8794                 DRXJ_16TO8(6409),       /* RAD3  */
8795                 DRXJ_16TO8(6656),       /* RAD4  */
8796                 DRXJ_16TO8(7238),       /* RAD5  */
8797         };
8798
8799         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8800         if (rc != 0) {
8801                 pr_err("error %d\n", rc);
8802                 goto rw_error;
8803         }
8804         rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
8805         if (rc != 0) {
8806                 pr_err("error %d\n", rc);
8807                 goto rw_error;
8808         }
8809
8810         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
8811         if (rc != 0) {
8812                 pr_err("error %d\n", rc);
8813                 goto rw_error;
8814         }
8815         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
8816         if (rc != 0) {
8817                 pr_err("error %d\n", rc);
8818                 goto rw_error;
8819         }
8820         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8821         if (rc != 0) {
8822                 pr_err("error %d\n", rc);
8823                 goto rw_error;
8824         }
8825         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
8826         if (rc != 0) {
8827                 pr_err("error %d\n", rc);
8828                 goto rw_error;
8829         }
8830         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8831         if (rc != 0) {
8832                 pr_err("error %d\n", rc);
8833                 goto rw_error;
8834         }
8835         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
8836         if (rc != 0) {
8837                 pr_err("error %d\n", rc);
8838                 goto rw_error;
8839         }
8840
8841         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8842         if (rc != 0) {
8843                 pr_err("error %d\n", rc);
8844                 goto rw_error;
8845         }
8846         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
8847         if (rc != 0) {
8848                 pr_err("error %d\n", rc);
8849                 goto rw_error;
8850         }
8851         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8852         if (rc != 0) {
8853                 pr_err("error %d\n", rc);
8854                 goto rw_error;
8855         }
8856
8857         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
8858         if (rc != 0) {
8859                 pr_err("error %d\n", rc);
8860                 goto rw_error;
8861         }
8862         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
8863         if (rc != 0) {
8864                 pr_err("error %d\n", rc);
8865                 goto rw_error;
8866         }
8867         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
8868         if (rc != 0) {
8869                 pr_err("error %d\n", rc);
8870                 goto rw_error;
8871         }
8872         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
8873         if (rc != 0) {
8874                 pr_err("error %d\n", rc);
8875                 goto rw_error;
8876         }
8877         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
8878         if (rc != 0) {
8879                 pr_err("error %d\n", rc);
8880                 goto rw_error;
8881         }
8882         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
8883         if (rc != 0) {
8884                 pr_err("error %d\n", rc);
8885                 goto rw_error;
8886         }
8887         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
8888         if (rc != 0) {
8889                 pr_err("error %d\n", rc);
8890                 goto rw_error;
8891         }
8892
8893         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
8894         if (rc != 0) {
8895                 pr_err("error %d\n", rc);
8896                 goto rw_error;
8897         }
8898         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
8899         if (rc != 0) {
8900                 pr_err("error %d\n", rc);
8901                 goto rw_error;
8902         }
8903         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
8904         if (rc != 0) {
8905                 pr_err("error %d\n", rc);
8906                 goto rw_error;
8907         }
8908         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
8909         if (rc != 0) {
8910                 pr_err("error %d\n", rc);
8911                 goto rw_error;
8912         }
8913         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
8914         if (rc != 0) {
8915                 pr_err("error %d\n", rc);
8916                 goto rw_error;
8917         }
8918         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
8919         if (rc != 0) {
8920                 pr_err("error %d\n", rc);
8921                 goto rw_error;
8922         }
8923         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
8924         if (rc != 0) {
8925                 pr_err("error %d\n", rc);
8926                 goto rw_error;
8927         }
8928         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
8929         if (rc != 0) {
8930                 pr_err("error %d\n", rc);
8931                 goto rw_error;
8932         }
8933         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
8934         if (rc != 0) {
8935                 pr_err("error %d\n", rc);
8936                 goto rw_error;
8937         }
8938         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
8939         if (rc != 0) {
8940                 pr_err("error %d\n", rc);
8941                 goto rw_error;
8942         }
8943         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
8944         if (rc != 0) {
8945                 pr_err("error %d\n", rc);
8946                 goto rw_error;
8947         }
8948         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
8949         if (rc != 0) {
8950                 pr_err("error %d\n", rc);
8951                 goto rw_error;
8952         }
8953         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8954         if (rc != 0) {
8955                 pr_err("error %d\n", rc);
8956                 goto rw_error;
8957         }
8958         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8959         if (rc != 0) {
8960                 pr_err("error %d\n", rc);
8961                 goto rw_error;
8962         }
8963         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8964         if (rc != 0) {
8965                 pr_err("error %d\n", rc);
8966                 goto rw_error;
8967         }
8968         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8969         if (rc != 0) {
8970                 pr_err("error %d\n", rc);
8971                 goto rw_error;
8972         }
8973         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
8974         if (rc != 0) {
8975                 pr_err("error %d\n", rc);
8976                 goto rw_error;
8977         }
8978         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8979         if (rc != 0) {
8980                 pr_err("error %d\n", rc);
8981                 goto rw_error;
8982         }
8983         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8984         if (rc != 0) {
8985                 pr_err("error %d\n", rc);
8986                 goto rw_error;
8987         }
8988         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
8989         if (rc != 0) {
8990                 pr_err("error %d\n", rc);
8991                 goto rw_error;
8992         }
8993
8994         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
8995         if (rc != 0) {
8996                 pr_err("error %d\n", rc);
8997                 goto rw_error;
8998         }
8999
9000         return 0;
9001 rw_error:
9002         return -EIO;
9003 }
9004
9005 /*============================================================================*/
9006
9007 /**
9008 * \fn int set_qam256 ()
9009 * \brief QAM256 specific setup
9010 * \param demod: instance of demod.
9011 * \return int.
9012 */
9013 static int set_qam256(struct drx_demod_instance *demod)
9014 {
9015         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9016         int rc;
9017         const u8 qam_dq_qual_fun[] = {
9018                 DRXJ_16TO8(8),  /* fun0  */
9019                 DRXJ_16TO8(8),  /* fun1  */
9020                 DRXJ_16TO8(8),  /* fun2  */
9021                 DRXJ_16TO8(8),  /* fun3  */
9022                 DRXJ_16TO8(12), /* fun4  */
9023                 DRXJ_16TO8(12), /* fun5  */
9024         };
9025         const u8 qam_eq_cma_rad[] = {
9026                 DRXJ_16TO8(12345),      /* RAD0  */
9027                 DRXJ_16TO8(12345),      /* RAD1  */
9028                 DRXJ_16TO8(13626),      /* RAD2  */
9029                 DRXJ_16TO8(12931),      /* RAD3  */
9030                 DRXJ_16TO8(14719),      /* RAD4  */
9031                 DRXJ_16TO8(15356),      /* RAD5  */
9032         };
9033
9034         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9035         if (rc != 0) {
9036                 pr_err("error %d\n", rc);
9037                 goto rw_error;
9038         }
9039         rc = DRXJ_DAP.write_block_func(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
9040         if (rc != 0) {
9041                 pr_err("error %d\n", rc);
9042                 goto rw_error;
9043         }
9044
9045         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
9046         if (rc != 0) {
9047                 pr_err("error %d\n", rc);
9048                 goto rw_error;
9049         }
9050         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9051         if (rc != 0) {
9052                 pr_err("error %d\n", rc);
9053                 goto rw_error;
9054         }
9055         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9056         if (rc != 0) {
9057                 pr_err("error %d\n", rc);
9058                 goto rw_error;
9059         }
9060         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
9061         if (rc != 0) {
9062                 pr_err("error %d\n", rc);
9063                 goto rw_error;
9064         }
9065         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9066         if (rc != 0) {
9067                 pr_err("error %d\n", rc);
9068                 goto rw_error;
9069         }
9070         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
9071         if (rc != 0) {
9072                 pr_err("error %d\n", rc);
9073                 goto rw_error;
9074         }
9075
9076         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9077         if (rc != 0) {
9078                 pr_err("error %d\n", rc);
9079                 goto rw_error;
9080         }
9081         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
9082         if (rc != 0) {
9083                 pr_err("error %d\n", rc);
9084                 goto rw_error;
9085         }
9086         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9087         if (rc != 0) {
9088                 pr_err("error %d\n", rc);
9089                 goto rw_error;
9090         }
9091
9092         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
9093         if (rc != 0) {
9094                 pr_err("error %d\n", rc);
9095                 goto rw_error;
9096         }
9097         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
9098         if (rc != 0) {
9099                 pr_err("error %d\n", rc);
9100                 goto rw_error;
9101         }
9102         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
9103         if (rc != 0) {
9104                 pr_err("error %d\n", rc);
9105                 goto rw_error;
9106         }
9107         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
9108         if (rc != 0) {
9109                 pr_err("error %d\n", rc);
9110                 goto rw_error;
9111         }
9112         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
9113         if (rc != 0) {
9114                 pr_err("error %d\n", rc);
9115                 goto rw_error;
9116         }
9117         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
9118         if (rc != 0) {
9119                 pr_err("error %d\n", rc);
9120                 goto rw_error;
9121         }
9122         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
9123         if (rc != 0) {
9124                 pr_err("error %d\n", rc);
9125                 goto rw_error;
9126         }
9127
9128         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
9129         if (rc != 0) {
9130                 pr_err("error %d\n", rc);
9131                 goto rw_error;
9132         }
9133         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
9134         if (rc != 0) {
9135                 pr_err("error %d\n", rc);
9136                 goto rw_error;
9137         }
9138         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
9139         if (rc != 0) {
9140                 pr_err("error %d\n", rc);
9141                 goto rw_error;
9142         }
9143         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
9144         if (rc != 0) {
9145                 pr_err("error %d\n", rc);
9146                 goto rw_error;
9147         }
9148         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
9149         if (rc != 0) {
9150                 pr_err("error %d\n", rc);
9151                 goto rw_error;
9152         }
9153         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
9154         if (rc != 0) {
9155                 pr_err("error %d\n", rc);
9156                 goto rw_error;
9157         }
9158         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
9159         if (rc != 0) {
9160                 pr_err("error %d\n", rc);
9161                 goto rw_error;
9162         }
9163         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
9164         if (rc != 0) {
9165                 pr_err("error %d\n", rc);
9166                 goto rw_error;
9167         }
9168         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
9169         if (rc != 0) {
9170                 pr_err("error %d\n", rc);
9171                 goto rw_error;
9172         }
9173         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
9174         if (rc != 0) {
9175                 pr_err("error %d\n", rc);
9176                 goto rw_error;
9177         }
9178         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
9179         if (rc != 0) {
9180                 pr_err("error %d\n", rc);
9181                 goto rw_error;
9182         }
9183         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
9184         if (rc != 0) {
9185                 pr_err("error %d\n", rc);
9186                 goto rw_error;
9187         }
9188         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9189         if (rc != 0) {
9190                 pr_err("error %d\n", rc);
9191                 goto rw_error;
9192         }
9193         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9194         if (rc != 0) {
9195                 pr_err("error %d\n", rc);
9196                 goto rw_error;
9197         }
9198         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9199         if (rc != 0) {
9200                 pr_err("error %d\n", rc);
9201                 goto rw_error;
9202         }
9203         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
9204         if (rc != 0) {
9205                 pr_err("error %d\n", rc);
9206                 goto rw_error;
9207         }
9208         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
9209         if (rc != 0) {
9210                 pr_err("error %d\n", rc);
9211                 goto rw_error;
9212         }
9213         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9214         if (rc != 0) {
9215                 pr_err("error %d\n", rc);
9216                 goto rw_error;
9217         }
9218         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9219         if (rc != 0) {
9220                 pr_err("error %d\n", rc);
9221                 goto rw_error;
9222         }
9223         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9224         if (rc != 0) {
9225                 pr_err("error %d\n", rc);
9226                 goto rw_error;
9227         }
9228
9229         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
9230         if (rc != 0) {
9231                 pr_err("error %d\n", rc);
9232                 goto rw_error;
9233         }
9234
9235         return 0;
9236 rw_error:
9237         return -EIO;
9238 }
9239
9240 /*============================================================================*/
9241 #define QAM_SET_OP_ALL 0x1
9242 #define QAM_SET_OP_CONSTELLATION 0x2
9243 #define QAM_SET_OP_SPECTRUM 0X4
9244
9245 /**
9246 * \fn int set_qam ()
9247 * \brief Set QAM demod.
9248 * \param demod:   instance of demod.
9249 * \param channel: pointer to channel data.
9250 * \return int.
9251 */
9252 static int
9253 set_qam(struct drx_demod_instance *demod,
9254         struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
9255 {
9256         struct i2c_device_addr *dev_addr = NULL;
9257         struct drxj_data *ext_attr = NULL;
9258         struct drx_common_attr *common_attr = NULL;
9259         int rc;
9260         u32 adc_frequency = 0;
9261         u32 iqm_rc_rate = 0;
9262         u16 cmd_result = 0;
9263         u16 lc_symbol_freq = 0;
9264         u16 iqm_rc_stretch = 0;
9265         u16 set_env_parameters = 0;
9266         u16 set_param_parameters[2] = { 0 };
9267         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
9268                 /* parameter_len */ 0,
9269                 /* result_len    */ 0,
9270                 /* parameter    */ NULL,
9271                 /* result       */ NULL
9272         };
9273         const u8 qam_a_taps[] = {
9274                 DRXJ_16TO8(-1), /* re0  */
9275                 DRXJ_16TO8(1),  /* re1  */
9276                 DRXJ_16TO8(1),  /* re2  */
9277                 DRXJ_16TO8(-1), /* re3  */
9278                 DRXJ_16TO8(-1), /* re4  */
9279                 DRXJ_16TO8(2),  /* re5  */
9280                 DRXJ_16TO8(1),  /* re6  */
9281                 DRXJ_16TO8(-2), /* re7  */
9282                 DRXJ_16TO8(0),  /* re8  */
9283                 DRXJ_16TO8(3),  /* re9  */
9284                 DRXJ_16TO8(-1), /* re10 */
9285                 DRXJ_16TO8(-3), /* re11 */
9286                 DRXJ_16TO8(4),  /* re12 */
9287                 DRXJ_16TO8(1),  /* re13 */
9288                 DRXJ_16TO8(-8), /* re14 */
9289                 DRXJ_16TO8(4),  /* re15 */
9290                 DRXJ_16TO8(13), /* re16 */
9291                 DRXJ_16TO8(-13),        /* re17 */
9292                 DRXJ_16TO8(-19),        /* re18 */
9293                 DRXJ_16TO8(28), /* re19 */
9294                 DRXJ_16TO8(25), /* re20 */
9295                 DRXJ_16TO8(-53),        /* re21 */
9296                 DRXJ_16TO8(-31),        /* re22 */
9297                 DRXJ_16TO8(96), /* re23 */
9298                 DRXJ_16TO8(37), /* re24 */
9299                 DRXJ_16TO8(-190),       /* re25 */
9300                 DRXJ_16TO8(-40),        /* re26 */
9301                 DRXJ_16TO8(619) /* re27 */
9302         };
9303         const u8 qam_b64_taps[] = {
9304                 DRXJ_16TO8(0),  /* re0  */
9305                 DRXJ_16TO8(-2), /* re1  */
9306                 DRXJ_16TO8(1),  /* re2  */
9307                 DRXJ_16TO8(2),  /* re3  */
9308                 DRXJ_16TO8(-2), /* re4  */
9309                 DRXJ_16TO8(0),  /* re5  */
9310                 DRXJ_16TO8(4),  /* re6  */
9311                 DRXJ_16TO8(-2), /* re7  */
9312                 DRXJ_16TO8(-4), /* re8  */
9313                 DRXJ_16TO8(4),  /* re9  */
9314                 DRXJ_16TO8(3),  /* re10 */
9315                 DRXJ_16TO8(-6), /* re11 */
9316                 DRXJ_16TO8(0),  /* re12 */
9317                 DRXJ_16TO8(6),  /* re13 */
9318                 DRXJ_16TO8(-5), /* re14 */
9319                 DRXJ_16TO8(-3), /* re15 */
9320                 DRXJ_16TO8(11), /* re16 */
9321                 DRXJ_16TO8(-4), /* re17 */
9322                 DRXJ_16TO8(-19),        /* re18 */
9323                 DRXJ_16TO8(19), /* re19 */
9324                 DRXJ_16TO8(28), /* re20 */
9325                 DRXJ_16TO8(-45),        /* re21 */
9326                 DRXJ_16TO8(-36),        /* re22 */
9327                 DRXJ_16TO8(90), /* re23 */
9328                 DRXJ_16TO8(42), /* re24 */
9329                 DRXJ_16TO8(-185),       /* re25 */
9330                 DRXJ_16TO8(-46),        /* re26 */
9331                 DRXJ_16TO8(614) /* re27 */
9332         };
9333         const u8 qam_b256_taps[] = {
9334                 DRXJ_16TO8(-2), /* re0  */
9335                 DRXJ_16TO8(4),  /* re1  */
9336                 DRXJ_16TO8(1),  /* re2  */
9337                 DRXJ_16TO8(-4), /* re3  */
9338                 DRXJ_16TO8(0),  /* re4  */
9339                 DRXJ_16TO8(4),  /* re5  */
9340                 DRXJ_16TO8(-2), /* re6  */
9341                 DRXJ_16TO8(-4), /* re7  */
9342                 DRXJ_16TO8(5),  /* re8  */
9343                 DRXJ_16TO8(2),  /* re9  */
9344                 DRXJ_16TO8(-8), /* re10 */
9345                 DRXJ_16TO8(2),  /* re11 */
9346                 DRXJ_16TO8(11), /* re12 */
9347                 DRXJ_16TO8(-8), /* re13 */
9348                 DRXJ_16TO8(-15),        /* re14 */
9349                 DRXJ_16TO8(16), /* re15 */
9350                 DRXJ_16TO8(19), /* re16 */
9351                 DRXJ_16TO8(-27),        /* re17 */
9352                 DRXJ_16TO8(-22),        /* re18 */
9353                 DRXJ_16TO8(44), /* re19 */
9354                 DRXJ_16TO8(26), /* re20 */
9355                 DRXJ_16TO8(-69),        /* re21 */
9356                 DRXJ_16TO8(-28),        /* re22 */
9357                 DRXJ_16TO8(110),        /* re23 */
9358                 DRXJ_16TO8(31), /* re24 */
9359                 DRXJ_16TO8(-201),       /* re25 */
9360                 DRXJ_16TO8(-32),        /* re26 */
9361                 DRXJ_16TO8(628) /* re27 */
9362         };
9363         const u8 qam_c_taps[] = {
9364                 DRXJ_16TO8(-3), /* re0  */
9365                 DRXJ_16TO8(3),  /* re1  */
9366                 DRXJ_16TO8(2),  /* re2  */
9367                 DRXJ_16TO8(-4), /* re3  */
9368                 DRXJ_16TO8(0),  /* re4  */
9369                 DRXJ_16TO8(4),  /* re5  */
9370                 DRXJ_16TO8(-1), /* re6  */
9371                 DRXJ_16TO8(-4), /* re7  */
9372                 DRXJ_16TO8(3),  /* re8  */
9373                 DRXJ_16TO8(3),  /* re9  */
9374                 DRXJ_16TO8(-5), /* re10 */
9375                 DRXJ_16TO8(0),  /* re11 */
9376                 DRXJ_16TO8(9),  /* re12 */
9377                 DRXJ_16TO8(-4), /* re13 */
9378                 DRXJ_16TO8(-12),        /* re14 */
9379                 DRXJ_16TO8(10), /* re15 */
9380                 DRXJ_16TO8(16), /* re16 */
9381                 DRXJ_16TO8(-21),        /* re17 */
9382                 DRXJ_16TO8(-20),        /* re18 */
9383                 DRXJ_16TO8(37), /* re19 */
9384                 DRXJ_16TO8(25), /* re20 */
9385                 DRXJ_16TO8(-62),        /* re21 */
9386                 DRXJ_16TO8(-28),        /* re22 */
9387                 DRXJ_16TO8(105),        /* re23 */
9388                 DRXJ_16TO8(31), /* re24 */
9389                 DRXJ_16TO8(-197),       /* re25 */
9390                 DRXJ_16TO8(-33),        /* re26 */
9391                 DRXJ_16TO8(626) /* re27 */
9392         };
9393
9394         dev_addr = demod->my_i2c_dev_addr;
9395         ext_attr = (struct drxj_data *) demod->my_ext_attr;
9396         common_attr = (struct drx_common_attr *) demod->my_common_attr;
9397
9398         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9399                 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9400                         switch (channel->constellation) {
9401                         case DRX_CONSTELLATION_QAM256:
9402                                 iqm_rc_rate = 0x00AE3562;
9403                                 lc_symbol_freq =
9404                                     QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
9405                                 channel->symbolrate = 5360537;
9406                                 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
9407                                 break;
9408                         case DRX_CONSTELLATION_QAM64:
9409                                 iqm_rc_rate = 0x00C05A0E;
9410                                 lc_symbol_freq = 409;
9411                                 channel->symbolrate = 5056941;
9412                                 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
9413                                 break;
9414                         default:
9415                                 return -EINVAL;
9416                         }
9417                 } else {
9418                         adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
9419                         if (channel->symbolrate == 0) {
9420                                 pr_err("error: channel symbolrate is zero!\n");
9421                                 return -EIO;
9422                         }
9423                         iqm_rc_rate =
9424                             (adc_frequency / channel->symbolrate) * (1 << 21) +
9425                             (frac28
9426                              ((adc_frequency % channel->symbolrate),
9427                               channel->symbolrate) >> 7) - (1 << 23);
9428                         lc_symbol_freq =
9429                             (u16) (frac28
9430                                      (channel->symbolrate +
9431                                       (adc_frequency >> 13),
9432                                       adc_frequency) >> 16);
9433                         if (lc_symbol_freq > 511)
9434                                 lc_symbol_freq = 511;
9435
9436                         iqm_rc_stretch = 21;
9437                 }
9438
9439                 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
9440                         set_env_parameters = QAM_TOP_ANNEX_A;   /* annex             */
9441                         set_param_parameters[0] = channel->constellation;       /* constellation     */
9442                         set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
9443                 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9444                         set_env_parameters = QAM_TOP_ANNEX_B;   /* annex             */
9445                         set_param_parameters[0] = channel->constellation;       /* constellation     */
9446                         set_param_parameters[1] = channel->interleavemode;      /* interleave mode   */
9447                 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9448                         set_env_parameters = QAM_TOP_ANNEX_C;   /* annex             */
9449                         set_param_parameters[0] = channel->constellation;       /* constellation     */
9450                         set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
9451                 } else {
9452                         return -EINVAL;
9453                 }
9454         }
9455
9456         if (op & QAM_SET_OP_ALL) {
9457                 /*
9458                    STEP 1: reset demodulator
9459                    resets IQM, QAM and FEC HW blocks
9460                    resets SCU variables
9461                  */
9462                 /* stop all comm_exec */
9463                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9464                 if (rc != 0) {
9465                         pr_err("error %d\n", rc);
9466                         goto rw_error;
9467                 }
9468                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
9469                 if (rc != 0) {
9470                         pr_err("error %d\n", rc);
9471                         goto rw_error;
9472                 }
9473                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9474                 if (rc != 0) {
9475                         pr_err("error %d\n", rc);
9476                         goto rw_error;
9477                 }
9478                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9479                 if (rc != 0) {
9480                         pr_err("error %d\n", rc);
9481                         goto rw_error;
9482                 }
9483                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9484                 if (rc != 0) {
9485                         pr_err("error %d\n", rc);
9486                         goto rw_error;
9487                 }
9488                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9489                 if (rc != 0) {
9490                         pr_err("error %d\n", rc);
9491                         goto rw_error;
9492                 }
9493                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9494                 if (rc != 0) {
9495                         pr_err("error %d\n", rc);
9496                         goto rw_error;
9497                 }
9498
9499                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9500                     SCU_RAM_COMMAND_CMD_DEMOD_RESET;
9501                 cmd_scu.parameter_len = 0;
9502                 cmd_scu.result_len = 1;
9503                 cmd_scu.parameter = NULL;
9504                 cmd_scu.result = &cmd_result;
9505                 rc = scu_command(dev_addr, &cmd_scu);
9506                 if (rc != 0) {
9507                         pr_err("error %d\n", rc);
9508                         goto rw_error;
9509                 }
9510         }
9511
9512         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9513                 /*
9514                    STEP 2: configure demodulator
9515                    -set env
9516                    -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
9517                  */
9518                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9519                     SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
9520                 cmd_scu.parameter_len = 1;
9521                 cmd_scu.result_len = 1;
9522                 cmd_scu.parameter = &set_env_parameters;
9523                 cmd_scu.result = &cmd_result;
9524                 rc = scu_command(dev_addr, &cmd_scu);
9525                 if (rc != 0) {
9526                         pr_err("error %d\n", rc);
9527                         goto rw_error;
9528                 }
9529
9530                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9531                     SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
9532                 cmd_scu.parameter_len = 2;
9533                 cmd_scu.result_len = 1;
9534                 cmd_scu.parameter = set_param_parameters;
9535                 cmd_scu.result = &cmd_result;
9536                 rc = scu_command(dev_addr, &cmd_scu);
9537                 if (rc != 0) {
9538                         pr_err("error %d\n", rc);
9539                         goto rw_error;
9540                 }
9541                 /* set symbol rate */
9542                 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
9543                 if (rc != 0) {
9544                         pr_err("error %d\n", rc);
9545                         goto rw_error;
9546                 }
9547                 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
9548                 rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
9549                 if (rc != 0) {
9550                         pr_err("error %d\n", rc);
9551                         goto rw_error;
9552                 }
9553         }
9554         /* STEP 3: enable the system in a mode where the ADC provides valid signal
9555            setup constellation independent registers */
9556         /* from qam_cmd.py script (qam_driver_b) */
9557         /* TODO: remove re-writes of HW reset values */
9558         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
9559                 rc = set_frequency(demod, channel, tuner_freq_offset);
9560                 if (rc != 0) {
9561                         pr_err("error %d\n", rc);
9562                         goto rw_error;
9563                 }
9564         }
9565
9566         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9567
9568                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
9569                 if (rc != 0) {
9570                         pr_err("error %d\n", rc);
9571                         goto rw_error;
9572                 }
9573                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
9574                 if (rc != 0) {
9575                         pr_err("error %d\n", rc);
9576                         goto rw_error;
9577                 }
9578         }
9579
9580         if (op & QAM_SET_OP_ALL) {
9581                 if (!ext_attr->has_lna) {
9582                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
9583                         if (rc != 0) {
9584                                 pr_err("error %d\n", rc);
9585                                 goto rw_error;
9586                         }
9587                 }
9588                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
9589                 if (rc != 0) {
9590                         pr_err("error %d\n", rc);
9591                         goto rw_error;
9592                 }
9593                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
9594                 if (rc != 0) {
9595                         pr_err("error %d\n", rc);
9596                         goto rw_error;
9597                 }
9598                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
9599                 if (rc != 0) {
9600                         pr_err("error %d\n", rc);
9601                         goto rw_error;
9602                 }
9603
9604                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
9605                 if (rc != 0) {
9606                         pr_err("error %d\n", rc);
9607                         goto rw_error;
9608                 }       /* scu temporary shut down agc */
9609
9610                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
9611                 if (rc != 0) {
9612                         pr_err("error %d\n", rc);
9613                         goto rw_error;
9614                 }
9615                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
9616                 if (rc != 0) {
9617                         pr_err("error %d\n", rc);
9618                         goto rw_error;
9619                 }
9620                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
9621                 if (rc != 0) {
9622                         pr_err("error %d\n", rc);
9623                         goto rw_error;
9624                 }
9625                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
9626                 if (rc != 0) {
9627                         pr_err("error %d\n", rc);
9628                         goto rw_error;
9629                 }
9630                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PDREF__A, 4, 0);
9631                 if (rc != 0) {
9632                         pr_err("error %d\n", rc);
9633                         goto rw_error;
9634                 }
9635                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
9636                 if (rc != 0) {
9637                         pr_err("error %d\n", rc);
9638                         goto rw_error;
9639                 }
9640                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
9641                 if (rc != 0) {
9642                         pr_err("error %d\n", rc);
9643                         goto rw_error;
9644                 }
9645
9646                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
9647                 if (rc != 0) {
9648                         pr_err("error %d\n", rc);
9649                         goto rw_error;
9650                 }
9651                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
9652                 if (rc != 0) {
9653                         pr_err("error %d\n", rc);
9654                         goto rw_error;
9655                 }       /*! reset default val ! */
9656
9657                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
9658                 if (rc != 0) {
9659                         pr_err("error %d\n", rc);
9660                         goto rw_error;
9661                 }       /*! reset default val ! */
9662                 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9663                         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
9664                         if (rc != 0) {
9665                                 pr_err("error %d\n", rc);
9666                                 goto rw_error;
9667                         }       /*! reset default val ! */
9668                         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
9669                         if (rc != 0) {
9670                                 pr_err("error %d\n", rc);
9671                                 goto rw_error;
9672                         }       /*! reset default val ! */
9673                         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9674                         if (rc != 0) {
9675                                 pr_err("error %d\n", rc);
9676                                 goto rw_error;
9677                         }       /*! reset default val ! */
9678                 } else {
9679                         switch (channel->constellation) {
9680                         case DRX_CONSTELLATION_QAM16:
9681                         case DRX_CONSTELLATION_QAM64:
9682                         case DRX_CONSTELLATION_QAM256:
9683                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9684                                 if (rc != 0) {
9685                                         pr_err("error %d\n", rc);
9686                                         goto rw_error;
9687                                 }
9688                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
9689                                 if (rc != 0) {
9690                                         pr_err("error %d\n", rc);
9691                                         goto rw_error;
9692                                 }
9693                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9694                                 if (rc != 0) {
9695                                         pr_err("error %d\n", rc);
9696                                         goto rw_error;
9697                                 }       /*! reset default val ! */
9698                                 break;
9699                         case DRX_CONSTELLATION_QAM32:
9700                         case DRX_CONSTELLATION_QAM128:
9701                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9702                                 if (rc != 0) {
9703                                         pr_err("error %d\n", rc);
9704                                         goto rw_error;
9705                                 }
9706                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
9707                                 if (rc != 0) {
9708                                         pr_err("error %d\n", rc);
9709                                         goto rw_error;
9710                                 }
9711                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
9712                                 if (rc != 0) {
9713                                         pr_err("error %d\n", rc);
9714                                         goto rw_error;
9715                                 }
9716                                 break;
9717                         default:
9718                                 return -EIO;
9719                         }       /* switch */
9720                 }
9721
9722                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
9723                 if (rc != 0) {
9724                         pr_err("error %d\n", rc);
9725                         goto rw_error;
9726                 }       /*! reset default val ! */
9727                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
9728                 if (rc != 0) {
9729                         pr_err("error %d\n", rc);
9730                         goto rw_error;
9731                 }
9732                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
9733                 if (rc != 0) {
9734                         pr_err("error %d\n", rc);
9735                         goto rw_error;
9736                 }
9737                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
9738                 if (rc != 0) {
9739                         pr_err("error %d\n", rc);
9740                         goto rw_error;
9741                 }
9742                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_MODE__A, 7, 0);
9743                 if (rc != 0) {
9744                         pr_err("error %d\n", rc);
9745                         goto rw_error;
9746                 }
9747                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
9748                 if (rc != 0) {
9749                         pr_err("error %d\n", rc);
9750                         goto rw_error;
9751                 }
9752                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
9753                 if (rc != 0) {
9754                         pr_err("error %d\n", rc);
9755                         goto rw_error;
9756                 }
9757                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
9758                 if (rc != 0) {
9759                         pr_err("error %d\n", rc);
9760                         goto rw_error;
9761                 }
9762                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
9763                 if (rc != 0) {
9764                         pr_err("error %d\n", rc);
9765                         goto rw_error;
9766                 }
9767                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
9768                 if (rc != 0) {
9769                         pr_err("error %d\n", rc);
9770                         goto rw_error;
9771                 }
9772                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
9773                 if (rc != 0) {
9774                         pr_err("error %d\n", rc);
9775                         goto rw_error;
9776                 }
9777                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
9778                 if (rc != 0) {
9779                         pr_err("error %d\n", rc);
9780                         goto rw_error;
9781                 }
9782                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
9783                 if (rc != 0) {
9784                         pr_err("error %d\n", rc);
9785                         goto rw_error;
9786                 }
9787                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
9788                 if (rc != 0) {
9789                         pr_err("error %d\n", rc);
9790                         goto rw_error;
9791                 }
9792                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
9793                 if (rc != 0) {
9794                         pr_err("error %d\n", rc);
9795                         goto rw_error;
9796                 }
9797                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
9798                 if (rc != 0) {
9799                         pr_err("error %d\n", rc);
9800                         goto rw_error;
9801                 }
9802                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
9803                 if (rc != 0) {
9804                         pr_err("error %d\n", rc);
9805                         goto rw_error;
9806                 }
9807                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
9808                 if (rc != 0) {
9809                         pr_err("error %d\n", rc);
9810                         goto rw_error;
9811                 }
9812                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
9813                 if (rc != 0) {
9814                         pr_err("error %d\n", rc);
9815                         goto rw_error;
9816                 }
9817                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
9818                 if (rc != 0) {
9819                         pr_err("error %d\n", rc);
9820                         goto rw_error;
9821                 }
9822
9823                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
9824                 if (rc != 0) {
9825                         pr_err("error %d\n", rc);
9826                         goto rw_error;
9827                 }
9828                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
9829                 if (rc != 0) {
9830                         pr_err("error %d\n", rc);
9831                         goto rw_error;
9832                 }
9833                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
9834                 if (rc != 0) {
9835                         pr_err("error %d\n", rc);
9836                         goto rw_error;
9837                 }
9838                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
9839                 if (rc != 0) {
9840                         pr_err("error %d\n", rc);
9841                         goto rw_error;
9842                 }
9843                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
9844                 if (rc != 0) {
9845                         pr_err("error %d\n", rc);
9846                         goto rw_error;
9847                 }
9848
9849                 /* No more resets of the IQM, current standard correctly set =>
9850                    now AGCs can be configured. */
9851                 /* turn on IQMAF. It has to be in front of setAgc**() */
9852                 rc = set_iqm_af(demod, true);
9853                 if (rc != 0) {
9854                         pr_err("error %d\n", rc);
9855                         goto rw_error;
9856                 }
9857                 rc = adc_synchronization(demod);
9858                 if (rc != 0) {
9859                         pr_err("error %d\n", rc);
9860                         goto rw_error;
9861                 }
9862
9863                 rc = init_agc(demod);
9864                 if (rc != 0) {
9865                         pr_err("error %d\n", rc);
9866                         goto rw_error;
9867                 }
9868                 rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
9869                 if (rc != 0) {
9870                         pr_err("error %d\n", rc);
9871                         goto rw_error;
9872                 }
9873                 rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
9874                 if (rc != 0) {
9875                         pr_err("error %d\n", rc);
9876                         goto rw_error;
9877                 }
9878                 {
9879                         /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
9880                            of only the gain */
9881                         struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
9882
9883                         qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
9884                         rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
9885                         if (rc != 0) {
9886                                 pr_err("error %d\n", rc);
9887                                 goto rw_error;
9888                         }
9889                 }
9890                 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
9891                 if (rc != 0) {
9892                         pr_err("error %d\n", rc);
9893                         goto rw_error;
9894                 }
9895         }
9896
9897         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9898                 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
9899                         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9900                         if (rc != 0) {
9901                                 pr_err("error %d\n", rc);
9902                                 goto rw_error;
9903                         }
9904                         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
9905                         if (rc != 0) {
9906                                 pr_err("error %d\n", rc);
9907                                 goto rw_error;
9908                         }
9909                 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9910                         switch (channel->constellation) {
9911                         case DRX_CONSTELLATION_QAM64:
9912                                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9913                                 if (rc != 0) {
9914                                         pr_err("error %d\n", rc);
9915                                         goto rw_error;
9916                                 }
9917                                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9918                                 if (rc != 0) {
9919                                         pr_err("error %d\n", rc);
9920                                         goto rw_error;
9921                                 }
9922                                 break;
9923                         case DRX_CONSTELLATION_QAM256:
9924                                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9925                                 if (rc != 0) {
9926                                         pr_err("error %d\n", rc);
9927                                         goto rw_error;
9928                                 }
9929                                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9930                                 if (rc != 0) {
9931                                         pr_err("error %d\n", rc);
9932                                         goto rw_error;
9933                                 }
9934                                 break;
9935                         default:
9936                                 return -EIO;
9937                         }
9938                 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9939                         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9940                         if (rc != 0) {
9941                                 pr_err("error %d\n", rc);
9942                                 goto rw_error;
9943                         }
9944                         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9945                         if (rc != 0) {
9946                                 pr_err("error %d\n", rc);
9947                                 goto rw_error;
9948                         }
9949                 }
9950
9951                 /* SETP 4: constellation specific setup */
9952                 switch (channel->constellation) {
9953                 case DRX_CONSTELLATION_QAM16:
9954                         rc = set_qam16(demod);
9955                         if (rc != 0) {
9956                                 pr_err("error %d\n", rc);
9957                                 goto rw_error;
9958                         }
9959                         break;
9960                 case DRX_CONSTELLATION_QAM32:
9961                         rc = set_qam32(demod);
9962                         if (rc != 0) {
9963                                 pr_err("error %d\n", rc);
9964                                 goto rw_error;
9965                         }
9966                         break;
9967                 case DRX_CONSTELLATION_QAM64:
9968                         rc = set_qam64(demod);
9969                         if (rc != 0) {
9970                                 pr_err("error %d\n", rc);
9971                                 goto rw_error;
9972                         }
9973                         break;
9974                 case DRX_CONSTELLATION_QAM128:
9975                         rc = set_qam128(demod);
9976                         if (rc != 0) {
9977                                 pr_err("error %d\n", rc);
9978                                 goto rw_error;
9979                         }
9980                         break;
9981                 case DRX_CONSTELLATION_QAM256:
9982                         rc = set_qam256(demod);
9983                         if (rc != 0) {
9984                                 pr_err("error %d\n", rc);
9985                                 goto rw_error;
9986                         }
9987                         break;
9988                 default:
9989                         return -EIO;
9990                 }               /* switch */
9991         }
9992
9993         if ((op & QAM_SET_OP_ALL)) {
9994                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
9995                 if (rc != 0) {
9996                         pr_err("error %d\n", rc);
9997                         goto rw_error;
9998                 }
9999
10000                 /* Mpeg output has to be in front of FEC active */
10001                 rc = set_mpegtei_handling(demod);
10002                 if (rc != 0) {
10003                         pr_err("error %d\n", rc);
10004                         goto rw_error;
10005                 }
10006                 rc = bit_reverse_mpeg_output(demod);
10007                 if (rc != 0) {
10008                         pr_err("error %d\n", rc);
10009                         goto rw_error;
10010                 }
10011                 rc = set_mpeg_start_width(demod);
10012                 if (rc != 0) {
10013                         pr_err("error %d\n", rc);
10014                         goto rw_error;
10015                 }
10016                 {
10017                         /* TODO: move to set_standard after hardware reset value problem is solved */
10018                         /* Configure initial MPEG output */
10019                         struct drx_cfg_mpeg_output cfg_mpeg_output;
10020
10021                         cfg_mpeg_output.enable_mpeg_output = true;
10022                         cfg_mpeg_output.insert_rs_byte =
10023                             common_attr->mpeg_cfg.insert_rs_byte;
10024                         cfg_mpeg_output.enable_parallel =
10025                             common_attr->mpeg_cfg.enable_parallel;
10026                         cfg_mpeg_output.invert_data =
10027                             common_attr->mpeg_cfg.invert_data;
10028                         cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
10029                         cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
10030                         cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
10031                         cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
10032                         cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
10033                         cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
10034                         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
10035                         if (rc != 0) {
10036                                 pr_err("error %d\n", rc);
10037                                 goto rw_error;
10038                         }
10039                 }
10040         }
10041
10042         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
10043
10044                 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
10045                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10046                     SCU_RAM_COMMAND_CMD_DEMOD_START;
10047                 cmd_scu.parameter_len = 0;
10048                 cmd_scu.result_len = 1;
10049                 cmd_scu.parameter = NULL;
10050                 cmd_scu.result = &cmd_result;
10051                 rc = scu_command(dev_addr, &cmd_scu);
10052                 if (rc != 0) {
10053                         pr_err("error %d\n", rc);
10054                         goto rw_error;
10055                 }
10056         }
10057
10058         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
10059         if (rc != 0) {
10060                 pr_err("error %d\n", rc);
10061                 goto rw_error;
10062         }
10063         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
10064         if (rc != 0) {
10065                 pr_err("error %d\n", rc);
10066                 goto rw_error;
10067         }
10068         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
10069         if (rc != 0) {
10070                 pr_err("error %d\n", rc);
10071                 goto rw_error;
10072         }
10073
10074         return 0;
10075 rw_error:
10076         return -EIO;
10077 }
10078
10079 /*============================================================================*/
10080 static int
10081 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality);
10082 static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
10083 {
10084         int rc;
10085         u32 iqm_fs_rate_ofs = 0;
10086         u32 iqm_fs_rate_lo = 0;
10087         u16 qam_ctl_ena = 0;
10088         u16 data = 0;
10089         u16 equ_mode = 0;
10090         u16 fsm_state = 0;
10091         int i = 0;
10092         int ofsofs = 0;
10093         struct i2c_device_addr *dev_addr = NULL;
10094         struct drxj_data *ext_attr = NULL;
10095
10096         dev_addr = demod->my_i2c_dev_addr;
10097         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10098
10099         /* Silence the controlling of lc, equ, and the acquisition state machine */
10100         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10101         if (rc != 0) {
10102                 pr_err("error %d\n", rc);
10103                 goto rw_error;
10104         }
10105         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M), 0);
10106         if (rc != 0) {
10107                 pr_err("error %d\n", rc);
10108                 goto rw_error;
10109         }
10110
10111         /* freeze the frequency control loop */
10112         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CF__A, 0, 0);
10113         if (rc != 0) {
10114                 pr_err("error %d\n", rc);
10115                 goto rw_error;
10116         }
10117         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CF1__A, 0, 0);
10118         if (rc != 0) {
10119                 pr_err("error %d\n", rc);
10120                 goto rw_error;
10121         }
10122
10123         rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
10124         if (rc != 0) {
10125                 pr_err("error %d\n", rc);
10126                 goto rw_error;
10127         }
10128         rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
10129         if (rc != 0) {
10130                 pr_err("error %d\n", rc);
10131                 goto rw_error;
10132         }
10133         ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
10134         iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
10135         iqm_fs_rate_ofs -= 2 * ofsofs;
10136
10137         /* freeze dq/fq updating */
10138         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_MODE__A, &data, 0);
10139         if (rc != 0) {
10140                 pr_err("error %d\n", rc);
10141                 goto rw_error;
10142         }
10143         data = (data & 0xfff9);
10144         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10145         if (rc != 0) {
10146                 pr_err("error %d\n", rc);
10147                 goto rw_error;
10148         }
10149         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10150         if (rc != 0) {
10151                 pr_err("error %d\n", rc);
10152                 goto rw_error;
10153         }
10154
10155         /* lc_cp / _ci / _ca */
10156         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CI__A, 0, 0);
10157         if (rc != 0) {
10158                 pr_err("error %d\n", rc);
10159                 goto rw_error;
10160         }
10161         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_EP__A, 0, 0);
10162         if (rc != 0) {
10163                 pr_err("error %d\n", rc);
10164                 goto rw_error;
10165         }
10166         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
10167         if (rc != 0) {
10168                 pr_err("error %d\n", rc);
10169                 goto rw_error;
10170         }
10171
10172         /* flip the spec */
10173         rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
10174         if (rc != 0) {
10175                 pr_err("error %d\n", rc);
10176                 goto rw_error;
10177         }
10178         ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
10179         ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
10180
10181         /* freeze dq/fq updating */
10182         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_MODE__A, &data, 0);
10183         if (rc != 0) {
10184                 pr_err("error %d\n", rc);
10185                 goto rw_error;
10186         }
10187         equ_mode = data;
10188         data = (data & 0xfff9);
10189         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10190         if (rc != 0) {
10191                 pr_err("error %d\n", rc);
10192                 goto rw_error;
10193         }
10194         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10195         if (rc != 0) {
10196                 pr_err("error %d\n", rc);
10197                 goto rw_error;
10198         }
10199
10200         for (i = 0; i < 28; i++) {
10201                 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
10202                 if (rc != 0) {
10203                         pr_err("error %d\n", rc);
10204                         goto rw_error;
10205                 }
10206                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
10207                 if (rc != 0) {
10208                         pr_err("error %d\n", rc);
10209                         goto rw_error;
10210                 }
10211         }
10212
10213         for (i = 0; i < 24; i++) {
10214                 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
10215                 if (rc != 0) {
10216                         pr_err("error %d\n", rc);
10217                         goto rw_error;
10218                 }
10219                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
10220                 if (rc != 0) {
10221                         pr_err("error %d\n", rc);
10222                         goto rw_error;
10223                 }
10224         }
10225
10226         data = equ_mode;
10227         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10228         if (rc != 0) {
10229                 pr_err("error %d\n", rc);
10230                 goto rw_error;
10231         }
10232         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10233         if (rc != 0) {
10234                 pr_err("error %d\n", rc);
10235                 goto rw_error;
10236         }
10237
10238         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
10239         if (rc != 0) {
10240                 pr_err("error %d\n", rc);
10241                 goto rw_error;
10242         }
10243
10244         i = 0;
10245         while ((fsm_state != 4) && (i++ < 100)) {
10246                 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
10247                 if (rc != 0) {
10248                         pr_err("error %d\n", rc);
10249                         goto rw_error;
10250                 }
10251         }
10252         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
10253         if (rc != 0) {
10254                 pr_err("error %d\n", rc);
10255                 goto rw_error;
10256         }
10257
10258         return 0;
10259 rw_error:
10260         return -EIO;
10261
10262 }
10263
10264 #define  NO_LOCK        0x0
10265 #define  DEMOD_LOCKED   0x1
10266 #define  SYNC_FLIPPED   0x2
10267 #define  SPEC_MIRRORED  0x4
10268 /**
10269 * \fn int qam64auto ()
10270 * \brief auto do sync pattern switching and mirroring.
10271 * \param demod:   instance of demod.
10272 * \param channel: pointer to channel data.
10273 * \param tuner_freq_offset: tuner frequency offset.
10274 * \param lock_status: pointer to lock status.
10275 * \return int.
10276 */
10277 static int
10278 qam64auto(struct drx_demod_instance *demod,
10279           struct drx_channel *channel,
10280           s32 tuner_freq_offset, enum drx_lock_status *lock_status)
10281 {
10282         struct drx_sig_quality sig_quality;
10283         struct drxj_data *ext_attr = NULL;
10284         int rc;
10285         u32 state = NO_LOCK;
10286         u32 start_time = 0;
10287         u32 d_locked_time = 0;
10288         u32 timeout_ofs = 0;
10289         u16 data = 0;
10290
10291         /* external attributes for storing aquired channel constellation */
10292         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10293         *lock_status = DRX_NOT_LOCKED;
10294         start_time = drxbsp_hst_clock();
10295         state = NO_LOCK;
10296         do {
10297                 rc = ctrl_lock_status(demod, lock_status);
10298                 if (rc != 0) {
10299                         pr_err("error %d\n", rc);
10300                         goto rw_error;
10301                 }
10302
10303                 switch (state) {
10304                 case NO_LOCK:
10305                         if (*lock_status == DRXJ_DEMOD_LOCK) {
10306                                 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10307                                 if (rc != 0) {
10308                                         pr_err("error %d\n", rc);
10309                                         goto rw_error;
10310                                 }
10311                                 if (sig_quality.MER > 208) {
10312                                         state = DEMOD_LOCKED;
10313                                         /* some delay to see if fec_lock possible TODO find the right value */
10314                                         timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;        /* see something, waiting longer */
10315                                         d_locked_time = drxbsp_hst_clock();
10316                                 }
10317                         }
10318                         break;
10319                 case DEMOD_LOCKED:
10320                         if ((*lock_status == DRXJ_DEMOD_LOCK) &&        /* still demod_lock in 150ms */
10321                             ((drxbsp_hst_clock() - d_locked_time) >
10322                              DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10323                                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10324                                 if (rc != 0) {
10325                                         pr_err("error %d\n", rc);
10326                                         goto rw_error;
10327                                 }
10328                                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
10329                                 if (rc != 0) {
10330                                         pr_err("error %d\n", rc);
10331                                         goto rw_error;
10332                                 }
10333                                 state = SYNC_FLIPPED;
10334                                 drxbsp_hst_sleep(10);
10335                         }
10336                         break;
10337                 case SYNC_FLIPPED:
10338                         if (*lock_status == DRXJ_DEMOD_LOCK) {
10339                                 if (channel->mirror == DRX_MIRROR_AUTO) {
10340                                         /* flip sync pattern back */
10341                                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10342                                         if (rc != 0) {
10343                                                 pr_err("error %d\n", rc);
10344                                                 goto rw_error;
10345                                         }
10346                                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
10347                                         if (rc != 0) {
10348                                                 pr_err("error %d\n", rc);
10349                                                 goto rw_error;
10350                                         }
10351                                         /* flip spectrum */
10352                                         ext_attr->mirror = DRX_MIRROR_YES;
10353                                         rc = qam_flip_spec(demod, channel);
10354                                         if (rc != 0) {
10355                                                 pr_err("error %d\n", rc);
10356                                                 goto rw_error;
10357                                         }
10358                                         state = SPEC_MIRRORED;
10359                                         /* reset timer TODO: still need 500ms? */
10360                                         start_time = d_locked_time =
10361                                             drxbsp_hst_clock();
10362                                         timeout_ofs = 0;
10363                                 } else {        /* no need to wait lock */
10364
10365                                         start_time =
10366                                             drxbsp_hst_clock() -
10367                                             DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
10368                                 }
10369                         }
10370                         break;
10371                 case SPEC_MIRRORED:
10372                         if ((*lock_status == DRXJ_DEMOD_LOCK) &&        /* still demod_lock in 150ms */
10373                             ((drxbsp_hst_clock() - d_locked_time) >
10374                              DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10375                                 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10376                                 if (rc != 0) {
10377                                         pr_err("error %d\n", rc);
10378                                         goto rw_error;
10379                                 }
10380                                 if (sig_quality.MER > 208) {
10381                                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10382                                         if (rc != 0) {
10383                                                 pr_err("error %d\n", rc);
10384                                                 goto rw_error;
10385                                         }
10386                                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
10387                                         if (rc != 0) {
10388                                                 pr_err("error %d\n", rc);
10389                                                 goto rw_error;
10390                                         }
10391                                         /* no need to wait lock */
10392                                         start_time =
10393                                             drxbsp_hst_clock() -
10394                                             DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
10395                                 }
10396                         }
10397                         break;
10398                 default:
10399                         break;
10400                 }
10401                 drxbsp_hst_sleep(10);
10402         } while
10403             ((*lock_status != DRX_LOCKED) &&
10404              (*lock_status != DRX_NEVER_LOCK) &&
10405              ((drxbsp_hst_clock() - start_time) <
10406               (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
10407             );
10408         /* Returning control to apllication ... */
10409
10410         return 0;
10411 rw_error:
10412         return -EIO;
10413 }
10414
10415 /**
10416 * \fn int qam256auto ()
10417 * \brief auto do sync pattern switching and mirroring.
10418 * \param demod:   instance of demod.
10419 * \param channel: pointer to channel data.
10420 * \param tuner_freq_offset: tuner frequency offset.
10421 * \param lock_status: pointer to lock status.
10422 * \return int.
10423 */
10424 static int
10425 qam256auto(struct drx_demod_instance *demod,
10426            struct drx_channel *channel,
10427            s32 tuner_freq_offset, enum drx_lock_status *lock_status)
10428 {
10429         struct drx_sig_quality sig_quality;
10430         struct drxj_data *ext_attr = NULL;
10431         int rc;
10432         u32 state = NO_LOCK;
10433         u32 start_time = 0;
10434         u32 d_locked_time = 0;
10435         u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
10436
10437         /* external attributes for storing aquired channel constellation */
10438         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10439         *lock_status = DRX_NOT_LOCKED;
10440         start_time = drxbsp_hst_clock();
10441         state = NO_LOCK;
10442         do {
10443                 rc = ctrl_lock_status(demod, lock_status);
10444                 if (rc != 0) {
10445                         pr_err("error %d\n", rc);
10446                         goto rw_error;
10447                 }
10448                 switch (state) {
10449                 case NO_LOCK:
10450                         if (*lock_status == DRXJ_DEMOD_LOCK) {
10451                                 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10452                                 if (rc != 0) {
10453                                         pr_err("error %d\n", rc);
10454                                         goto rw_error;
10455                                 }
10456                                 if (sig_quality.MER > 268) {
10457                                         state = DEMOD_LOCKED;
10458                                         timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;        /* see something, wait longer */
10459                                         d_locked_time = drxbsp_hst_clock();
10460                                 }
10461                         }
10462                         break;
10463                 case DEMOD_LOCKED:
10464                         if (*lock_status == DRXJ_DEMOD_LOCK) {
10465                                 if ((channel->mirror == DRX_MIRROR_AUTO) &&
10466                                     ((drxbsp_hst_clock() - d_locked_time) >
10467                                      DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10468                                         ext_attr->mirror = DRX_MIRROR_YES;
10469                                         rc = qam_flip_spec(demod, channel);
10470                                         if (rc != 0) {
10471                                                 pr_err("error %d\n", rc);
10472                                                 goto rw_error;
10473                                         }
10474                                         state = SPEC_MIRRORED;
10475                                         /* reset timer TODO: still need 300ms? */
10476                                         start_time = drxbsp_hst_clock();
10477                                         timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
10478                                 }
10479                         }
10480                         break;
10481                 case SPEC_MIRRORED:
10482                         break;
10483                 default:
10484                         break;
10485                 }
10486                 drxbsp_hst_sleep(10);
10487         } while
10488             ((*lock_status < DRX_LOCKED) &&
10489              (*lock_status != DRX_NEVER_LOCK) &&
10490              ((drxbsp_hst_clock() - start_time) <
10491               (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
10492
10493         return 0;
10494 rw_error:
10495         return -EIO;
10496 }
10497
10498 /**
10499 * \fn int set_qam_channel ()
10500 * \brief Set QAM channel according to the requested constellation.
10501 * \param demod:   instance of demod.
10502 * \param channel: pointer to channel data.
10503 * \return int.
10504 */
10505 static int
10506 set_qam_channel(struct drx_demod_instance *demod,
10507                struct drx_channel *channel, s32 tuner_freq_offset)
10508 {
10509         struct drxj_data *ext_attr = NULL;
10510         int rc;
10511         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
10512         bool auto_flag = false;
10513
10514         /* external attributes for storing aquired channel constellation */
10515         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10516
10517         /* set QAM channel constellation */
10518         switch (channel->constellation) {
10519         case DRX_CONSTELLATION_QAM16:
10520         case DRX_CONSTELLATION_QAM32:
10521         case DRX_CONSTELLATION_QAM64:
10522         case DRX_CONSTELLATION_QAM128:
10523         case DRX_CONSTELLATION_QAM256:
10524                 ext_attr->constellation = channel->constellation;
10525                 if (channel->mirror == DRX_MIRROR_AUTO)
10526                         ext_attr->mirror = DRX_MIRROR_NO;
10527                 else
10528                         ext_attr->mirror = channel->mirror;
10529                 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
10530                 if (rc != 0) {
10531                         pr_err("error %d\n", rc);
10532                         goto rw_error;
10533                 }
10534
10535                 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
10536                     (channel->constellation == DRX_CONSTELLATION_QAM64)) {
10537                         rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10538                         if (rc != 0) {
10539                                 pr_err("error %d\n", rc);
10540                                 goto rw_error;
10541                         }
10542                 }
10543
10544                 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
10545                     (channel->mirror == DRX_MIRROR_AUTO) &&
10546                     (channel->constellation == DRX_CONSTELLATION_QAM256)) {
10547                         rc = qam256auto(demod, channel, tuner_freq_offset, &lock_status);
10548                         if (rc != 0) {
10549                                 pr_err("error %d\n", rc);
10550                                 goto rw_error;
10551                         }
10552                 }
10553                 break;
10554         case DRX_CONSTELLATION_AUTO:    /* for channel scan */
10555                 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
10556                         auto_flag = true;
10557                         /* try to lock default QAM constellation: QAM64 */
10558                         channel->constellation = DRX_CONSTELLATION_QAM256;
10559                         ext_attr->constellation = DRX_CONSTELLATION_QAM256;
10560                         if (channel->mirror == DRX_MIRROR_AUTO)
10561                                 ext_attr->mirror = DRX_MIRROR_NO;
10562                         else
10563                                 ext_attr->mirror = channel->mirror;
10564                         rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
10565                         if (rc != 0) {
10566                                 pr_err("error %d\n", rc);
10567                                 goto rw_error;
10568                         }
10569                         rc = qam256auto(demod, channel, tuner_freq_offset, &lock_status);
10570                         if (rc != 0) {
10571                                 pr_err("error %d\n", rc);
10572                                 goto rw_error;
10573                         }
10574
10575                         if (lock_status < DRX_LOCKED) {
10576                                 /* QAM254 not locked -> try to lock QAM64 constellation */
10577                                 channel->constellation =
10578                                     DRX_CONSTELLATION_QAM64;
10579                                 ext_attr->constellation =
10580                                     DRX_CONSTELLATION_QAM64;
10581                                 if (channel->mirror == DRX_MIRROR_AUTO)
10582                                         ext_attr->mirror = DRX_MIRROR_NO;
10583                                 else
10584                                         ext_attr->mirror = channel->mirror;
10585                                 {
10586                                         u16 qam_ctl_ena = 0;
10587                                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10588                                         if (rc != 0) {
10589                                                 pr_err("error %d\n", rc);
10590                                                 goto rw_error;
10591                                         }
10592                                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
10593                                         if (rc != 0) {
10594                                                 pr_err("error %d\n", rc);
10595                                                 goto rw_error;
10596                                         }
10597                                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2, 0);
10598                                         if (rc != 0) {
10599                                                 pr_err("error %d\n", rc);
10600                                                 goto rw_error;
10601                                         }       /* force to rate hunting */
10602
10603                                         rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_CONSTELLATION);
10604                                         if (rc != 0) {
10605                                                 pr_err("error %d\n", rc);
10606                                                 goto rw_error;
10607                                         }
10608                                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena, 0);
10609                                         if (rc != 0) {
10610                                                 pr_err("error %d\n", rc);
10611                                                 goto rw_error;
10612                                         }
10613                                 }
10614                                 rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10615                                 if (rc != 0) {
10616                                         pr_err("error %d\n", rc);
10617                                         goto rw_error;
10618                                 }
10619                         }
10620                         channel->constellation = DRX_CONSTELLATION_AUTO;
10621                 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
10622                         channel->constellation = DRX_CONSTELLATION_QAM64;
10623                         ext_attr->constellation = DRX_CONSTELLATION_QAM64;
10624                         auto_flag = true;
10625
10626                         if (channel->mirror == DRX_MIRROR_AUTO)
10627                                 ext_attr->mirror = DRX_MIRROR_NO;
10628                         else
10629                                 ext_attr->mirror = channel->mirror;
10630                         {
10631                                 u16 qam_ctl_ena = 0;
10632                                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10633                                 if (rc != 0) {
10634                                         pr_err("error %d\n", rc);
10635                                         goto rw_error;
10636                                 }
10637                                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
10638                                 if (rc != 0) {
10639                                         pr_err("error %d\n", rc);
10640                                         goto rw_error;
10641                                 }
10642                                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2, 0);
10643                                 if (rc != 0) {
10644                                         pr_err("error %d\n", rc);
10645                                         goto rw_error;
10646                                 }       /* force to rate hunting */
10647
10648                                 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_CONSTELLATION);
10649                                 if (rc != 0) {
10650                                         pr_err("error %d\n", rc);
10651                                         goto rw_error;
10652                                 }
10653                                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena, 0);
10654                                 if (rc != 0) {
10655                                         pr_err("error %d\n", rc);
10656                                         goto rw_error;
10657                                 }
10658                         }
10659                         rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10660                         if (rc != 0) {
10661                                 pr_err("error %d\n", rc);
10662                                 goto rw_error;
10663                         }
10664                         channel->constellation = DRX_CONSTELLATION_AUTO;
10665                 } else {
10666                         channel->constellation = DRX_CONSTELLATION_AUTO;
10667                         return -EINVAL;
10668                 }
10669                 break;
10670         default:
10671                 return -EINVAL;
10672         }
10673
10674         return 0;
10675 rw_error:
10676         /* restore starting value */
10677         if (auto_flag)
10678                 channel->constellation = DRX_CONSTELLATION_AUTO;
10679         return -EIO;
10680 }
10681
10682 /*============================================================================*/
10683
10684 /**
10685 * \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
10686 * \brief Get RS error count in QAM mode (used for post RS BER calculation)
10687 * \return Error code
10688 *
10689 * precondition: measurement period & measurement prescale must be set
10690 *
10691 */
10692 static int
10693 get_qamrs_err_count(struct i2c_device_addr *dev_addr, struct drxjrs_errors *rs_errors)
10694 {
10695         int rc;
10696         u16 nr_bit_errors = 0,
10697             nr_symbol_errors = 0,
10698             nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
10699
10700         /* check arguments */
10701         if (dev_addr == NULL)
10702                 return -EINVAL;
10703
10704         /* all reported errors are received in the  */
10705         /* most recently finished measurment period */
10706         /*   no of pre RS bit errors */
10707         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
10708         if (rc != 0) {
10709                 pr_err("error %d\n", rc);
10710                 goto rw_error;
10711         }
10712         /*   no of symbol errors      */
10713         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
10714         if (rc != 0) {
10715                 pr_err("error %d\n", rc);
10716                 goto rw_error;
10717         }
10718         /*   no of packet errors      */
10719         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
10720         if (rc != 0) {
10721                 pr_err("error %d\n", rc);
10722                 goto rw_error;
10723         }
10724         /*   no of failures to decode */
10725         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
10726         if (rc != 0) {
10727                 pr_err("error %d\n", rc);
10728                 goto rw_error;
10729         }
10730         /*   no of post RS bit erros  */
10731         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
10732         if (rc != 0) {
10733                 pr_err("error %d\n", rc);
10734                 goto rw_error;
10735         }
10736         /* TODO: NOTE */
10737         /* These register values are fetched in non-atomic fashion           */
10738         /* It is possible that the read values contain unrelated information */
10739
10740         rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
10741         rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
10742         rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
10743         rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
10744         rs_errors->nr_snc_par_fail_count =
10745             nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
10746
10747         return 0;
10748 rw_error:
10749         return -EIO;
10750 }
10751
10752 /*============================================================================*/
10753
10754 /**
10755 * \fn int ctrl_get_qam_sig_quality()
10756 * \brief Retreive QAM signal quality from device.
10757 * \param devmod Pointer to demodulator instance.
10758 * \param sig_quality Pointer to signal quality data.
10759 * \return int.
10760 * \retval 0 sig_quality contains valid data.
10761 * \retval -EINVAL sig_quality is NULL.
10762 * \retval -EIO Erroneous data, sig_quality contains invalid data.
10763
10764 *  Pre-condition: Device must be started and in lock.
10765 */
10766 static int
10767 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
10768 {
10769         struct i2c_device_addr *dev_addr = NULL;
10770         struct drxj_data *ext_attr = NULL;
10771         int rc;
10772         enum drx_modulation constellation = DRX_CONSTELLATION_UNKNOWN;
10773         struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
10774
10775         u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
10776         u32 post_bit_err_rs = 0;        /* post RedSolomon Bit Error Rate */
10777         u32 pkt_errs = 0;       /* no of packet errors in RS */
10778         u16 qam_sl_err_power = 0;       /* accumulated error between raw and sliced symbols */
10779         u16 qsym_err_vd = 0;    /* quadrature symbol errors in QAM_VD */
10780         u16 fec_oc_period = 0;  /* SNC sync failure measurement period */
10781         u16 fec_rs_prescale = 0;        /* ReedSolomon Measurement Prescale */
10782         u16 fec_rs_period = 0;  /* Value for corresponding I2C register */
10783         /* calculation constants */
10784         u32 rs_bit_cnt = 0;     /* RedSolomon Bit Count */
10785         u32 qam_sl_sig_power = 0;       /* used for MER, depends of QAM constellation */
10786         /* intermediate results */
10787         u32 e = 0;              /* exponent value used for QAM BER/SER */
10788         u32 m = 0;              /* mantisa value used for QAM BER/SER */
10789         u32 ber_cnt = 0;        /* BER count */
10790         /* signal quality info */
10791         u32 qam_sl_mer = 0;     /* QAM MER */
10792         u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
10793         u32 qam_post_rs_ber = 0;        /* Post RedSolomon BER */
10794         u32 qam_vd_ser = 0;     /* ViterbiDecoder SER */
10795         u16 qam_vd_prescale = 0;        /* Viterbi Measurement Prescale */
10796         u16 qam_vd_period = 0;  /* Viterbi Measurement period */
10797         u32 vd_bit_cnt = 0;     /* ViterbiDecoder Bit Count */
10798
10799         /* get device basic information */
10800         dev_addr = demod->my_i2c_dev_addr;
10801         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10802         constellation = ext_attr->constellation;
10803
10804         /* read the physical registers */
10805         /*   Get the RS error data */
10806         rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
10807         if (rc != 0) {
10808                 pr_err("error %d\n", rc);
10809                 goto rw_error;
10810         }
10811         /* get the register value needed for MER */
10812         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
10813         if (rc != 0) {
10814                 pr_err("error %d\n", rc);
10815                 goto rw_error;
10816         }
10817         /* get the register value needed for post RS BER */
10818         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
10819         if (rc != 0) {
10820                 pr_err("error %d\n", rc);
10821                 goto rw_error;
10822         }
10823
10824         /* get constants needed for signal quality calculation */
10825         fec_rs_period = ext_attr->fec_rs_period;
10826         fec_rs_prescale = ext_attr->fec_rs_prescale;
10827         rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
10828         qam_vd_period = ext_attr->qam_vd_period;
10829         qam_vd_prescale = ext_attr->qam_vd_prescale;
10830         vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
10831
10832         /* DRXJ_QAM_SL_SIG_POWER_QAMxxx  * 4     */
10833         switch (constellation) {
10834         case DRX_CONSTELLATION_QAM16:
10835                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
10836                 break;
10837         case DRX_CONSTELLATION_QAM32:
10838                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
10839                 break;
10840         case DRX_CONSTELLATION_QAM64:
10841                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
10842                 break;
10843         case DRX_CONSTELLATION_QAM128:
10844                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
10845                 break;
10846         case DRX_CONSTELLATION_QAM256:
10847                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
10848                 break;
10849         default:
10850                 return -EIO;
10851         }
10852
10853         /* ------------------------------ */
10854         /* MER Calculation                */
10855         /* ------------------------------ */
10856         /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
10857
10858         /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
10859         if (qam_sl_err_power == 0)
10860                 qam_sl_mer = 0;
10861         else
10862                 qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
10863
10864         /* ----------------------------------------- */
10865         /* Pre Viterbi Symbol Error Rate Calculation */
10866         /* ----------------------------------------- */
10867         /* pre viterbi SER is good if it is bellow 0.025 */
10868
10869         /* get the register value */
10870         /*   no of quadrature symbol errors */
10871         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
10872         if (rc != 0) {
10873                 pr_err("error %d\n", rc);
10874                 goto rw_error;
10875         }
10876         /* Extract the Exponent and the Mantisa  */
10877         /* of number of quadrature symbol errors */
10878         e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
10879             QAM_VD_NR_QSYM_ERRORS_EXP__B;
10880         m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
10881             QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
10882
10883         if ((m << e) >> 3 > 549752)
10884                 qam_vd_ser = 500000;
10885         else
10886                 qam_vd_ser = frac_times1e6(m << ((e > 2) ? (e - 3) : e), vd_bit_cnt * ((e > 2) ? 1 : 8) / 8);
10887
10888         /* --------------------------------------- */
10889         /* pre and post RedSolomon BER Calculation */
10890         /* --------------------------------------- */
10891         /* pre RS BER is good if it is below 3.5e-4 */
10892
10893         /* get the register values */
10894         pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
10895         pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
10896
10897         /* Extract the Exponent and the Mantisa of the */
10898         /* pre Reed-Solomon bit error count            */
10899         e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
10900             FEC_RS_NR_BIT_ERRORS_EXP__B;
10901         m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
10902             FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
10903
10904         ber_cnt = m << e;
10905
10906         /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
10907         if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
10908                 qam_pre_rs_ber = 500000;
10909         else
10910                 qam_pre_rs_ber = frac_times1e6(m, rs_bit_cnt >> e);
10911
10912         /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) /  */
10913         /*               (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A)  */
10914         /*
10915            => c = (1000000*100*11.17)/1504 =
10916            post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
10917            (100 * FEC_OC_SNC_FAIL_PERIOD__A)
10918            *100 and /100 is for more precision.
10919            => (20 bits * 12 bits) /(16 bits * 7 bits)  => safe in 32 bits computation
10920
10921            Precision errors still possible.
10922          */
10923         e = post_bit_err_rs * 742686;
10924         m = fec_oc_period * 100;
10925         if (fec_oc_period == 0)
10926                 qam_post_rs_ber = 0xFFFFFFFF;
10927         else
10928                 qam_post_rs_ber = e / m;
10929
10930         /* fill signal quality data structure */
10931         sig_quality->MER = ((u16) qam_sl_mer);
10932         if (ext_attr->standard == DRX_STANDARD_ITU_B)
10933                 sig_quality->pre_viterbi_ber = qam_vd_ser;
10934         else
10935                 sig_quality->pre_viterbi_ber = qam_pre_rs_ber;
10936         sig_quality->post_viterbi_ber = qam_pre_rs_ber;
10937         sig_quality->post_reed_solomon_ber = qam_post_rs_ber;
10938         sig_quality->scale_factor_ber = ((u32) 1000000);
10939 #ifdef DRXJ_SIGNAL_ACCUM_ERR
10940         rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
10941         if (rc != 0) {
10942                 pr_err("error %d\n", rc);
10943                 goto rw_error;
10944         }
10945 #else
10946         sig_quality->packet_error = ((u16) pkt_errs);
10947 #endif
10948
10949         return 0;
10950 rw_error:
10951         return -EIO;
10952 }
10953
10954 /**
10955 * \fn int ctrl_get_qam_constel()
10956 * \brief Retreive a QAM constellation point via I2C.
10957 * \param demod Pointer to demodulator instance.
10958 * \param complex_nr Pointer to the structure in which to store the
10959                    constellation point.
10960 * \return int.
10961 */
10962 static int
10963 ctrl_get_qam_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
10964 {
10965         struct i2c_device_addr *dev_addr = NULL;
10966         int rc;
10967         u32 data = 0;
10968         u16 fec_oc_ocr_mode = 0;
10969                               /**< FEC OCR grabber configuration        */
10970         u16 qam_sl_comm_mb = 0;/**< QAM SL MB configuration              */
10971         u16 qam_sl_comm_mb_init = 0;
10972                               /**< QAM SL MB intial configuration       */
10973         u16 im = 0;           /**< constellation Im part                */
10974         u16 re = 0;           /**< constellation Re part                */
10975                                      /**< device address */
10976
10977         /* read device info */
10978         dev_addr = demod->my_i2c_dev_addr;
10979
10980         /* TODO: */
10981         /* Monitor bus grabbing is an open external interface issue  */
10982         /* Needs to be checked when external interface PG is updated */
10983
10984         /* Configure MB (Monitor bus) */
10985         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_SL_COMM_MB__A, &qam_sl_comm_mb_init, 0);
10986         if (rc != 0) {
10987                 pr_err("error %d\n", rc);
10988                 goto rw_error;
10989         }
10990         /* set observe flag & MB mux */
10991         qam_sl_comm_mb = qam_sl_comm_mb_init & (~(QAM_SL_COMM_MB_OBS__M +
10992                                            QAM_SL_COMM_MB_MUX_OBS__M));
10993         qam_sl_comm_mb |= (QAM_SL_COMM_MB_OBS_ON +
10994                         QAM_SL_COMM_MB_MUX_OBS_CONST_CORR);
10995         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb, 0);
10996         if (rc != 0) {
10997                 pr_err("error %d\n", rc);
10998                 goto rw_error;
10999         }
11000
11001         /* Enable MB grabber in the FEC OC */
11002         fec_oc_ocr_mode = (/* output select:  observe bus */
11003                                (FEC_OC_OCR_MODE_MB_SELECT__M &
11004                                 (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B)) |
11005                                /* grabber enable: on          */
11006                                (FEC_OC_OCR_MODE_GRAB_ENABLE__M &
11007                                 (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B)) |
11008                                /* grabber select: observe bus */
11009                                (FEC_OC_OCR_MODE_GRAB_SELECT__M &
11010                                 (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B)) |
11011                                /* grabber mode:   continuous  */
11012                                (FEC_OC_OCR_MODE_GRAB_COUNTED__M &
11013                                 (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B)));
11014         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, fec_oc_ocr_mode, 0);
11015         if (rc != 0) {
11016                 pr_err("error %d\n", rc);
11017                 goto rw_error;
11018         }
11019
11020         /* Disable MB grabber in the FEC OC */
11021         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, 0x00, 0);
11022         if (rc != 0) {
11023                 pr_err("error %d\n", rc);
11024                 goto rw_error;
11025         }
11026
11027         /* read data */
11028         rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_OCR_GRAB_RD0__A, &data, 0);
11029         if (rc != 0) {
11030                 pr_err("error %d\n", rc);
11031                 goto rw_error;
11032         }
11033         re = (u16) (data & FEC_OC_OCR_GRAB_RD0__M);
11034         im = (u16) ((data >> 16) & FEC_OC_OCR_GRAB_RD1__M);
11035
11036         /* TODO: */
11037         /* interpret data (re & im) according to the Monitor bus mapping ?? */
11038
11039         /* sign extension, 10th bit is sign bit */
11040         if ((re & 0x0200) == 0x0200)
11041                 re |= 0xFC00;
11042         if ((im & 0x0200) == 0x0200)
11043                 im |= 0xFC00;
11044         complex_nr->re = ((s16) re);
11045         complex_nr->im = ((s16) im);
11046
11047         /* Restore MB (Monitor bus) */
11048         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb_init, 0);
11049         if (rc != 0) {
11050                 pr_err("error %d\n", rc);
11051                 goto rw_error;
11052         }
11053
11054         return 0;
11055 rw_error:
11056         return -EIO;
11057 }
11058 #endif /* #ifndef DRXJ_VSB_ONLY */
11059
11060 /*============================================================================*/
11061 /*==                     END QAM DATAPATH FUNCTIONS                         ==*/
11062 /*============================================================================*/
11063
11064 /*============================================================================*/
11065 /*============================================================================*/
11066 /*==                       ATV DATAPATH FUNCTIONS                           ==*/
11067 /*============================================================================*/
11068 /*============================================================================*/
11069
11070 /*
11071    Implementation notes.
11072
11073    NTSC/FM AGCs
11074
11075       Four AGCs are used for NTSC:
11076       (1) RF (used to attenuate the input signal in case of to much power)
11077       (2) IF (used to attenuate the input signal in case of to much power)
11078       (3) Video AGC (used to amplify the output signal in case input to low)
11079       (4) SIF AGC (used to amplify the output signal in case input to low)
11080
11081       Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
11082       that the coupling between Video AGC and the RF and IF AGCs also works in
11083       favor of the SIF AGC.
11084
11085       Three AGCs are used for FM:
11086       (1) RF (used to attenuate the input signal in case of to much power)
11087       (2) IF (used to attenuate the input signal in case of to much power)
11088       (3) SIF AGC (used to amplify the output signal in case input to low)
11089
11090       The SIF AGC is now coupled to the RF/IF AGCs.
11091       The SIF AGC is needed for both SIF ouput and the internal SIF signal to
11092       the AUD block.
11093
11094       RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
11095       the ATV block. The AGC control algorithms are all implemented in
11096       microcode.
11097
11098    ATV SETTINGS
11099
11100       (Shadow settings will not be used for now, they will be implemented
11101        later on because of the schedule)
11102
11103       Several HW/SCU "settings" can be used for ATV. The standard selection
11104       will reset most of these settings. To avoid that the end user apllication
11105       has to perform these settings each time the ATV or FM standards is
11106       selected the driver will shadow these settings. This enables the end user
11107       to perform the settings only once after a drx_open(). The driver must
11108       write the shadow settings to HW/SCU incase:
11109          ( setstandard FM/ATV) ||
11110          ( settings have changed && FM/ATV standard is active)
11111       The shadow settings will be stored in the device specific data container.
11112       A set of flags will be defined to flag changes in shadow settings.
11113       A routine will be implemented to write all changed shadow settings to
11114       HW/SCU.
11115
11116       The "settings" will consist of: AGC settings, filter settings etc.
11117
11118       Disadvantage of use of shadow settings:
11119       Direct changes in HW/SCU registers will not be reflected in the
11120       shadow settings and these changes will be overwritten during a next
11121       update. This can happen during evaluation. This will not be a problem
11122       for normal customer usage.
11123 */
11124 /* -------------------------------------------------------------------------- */
11125
11126 /**
11127 * \brief Get array index for atv coef (ext_attr->atvTopCoefX[index])
11128 * \param standard
11129 * \param pointer to index
11130 * \return int.
11131 *
11132 */
11133 static int atv_equ_coef_index(enum drx_standard standard, int *index)
11134 {
11135         switch (standard) {
11136         case DRX_STANDARD_PAL_SECAM_BG:
11137                 *index = (int)DRXJ_COEF_IDX_BG;
11138                 break;
11139         case DRX_STANDARD_PAL_SECAM_DK:
11140                 *index = (int)DRXJ_COEF_IDX_DK;
11141                 break;
11142         case DRX_STANDARD_PAL_SECAM_I:
11143                 *index = (int)DRXJ_COEF_IDX_I;
11144                 break;
11145         case DRX_STANDARD_PAL_SECAM_L:
11146                 *index = (int)DRXJ_COEF_IDX_L;
11147                 break;
11148         case DRX_STANDARD_PAL_SECAM_LP:
11149                 *index = (int)DRXJ_COEF_IDX_LP;
11150                 break;
11151         case DRX_STANDARD_NTSC:
11152                 *index = (int)DRXJ_COEF_IDX_MN;
11153                 break;
11154         case DRX_STANDARD_FM:
11155                 *index = (int)DRXJ_COEF_IDX_FM;
11156                 break;
11157         default:
11158                 *index = (int)DRXJ_COEF_IDX_MN; /* still return a valid index */
11159                 return -EIO;
11160                 break;
11161         }
11162
11163         return 0;
11164 }
11165
11166 /* -------------------------------------------------------------------------- */
11167 /**
11168 * \fn int atv_update_config ()
11169 * \brief Flush changes in ATV shadow registers to physical registers.
11170 * \param demod instance of demodulator
11171 * \param force_update don't look at standard or change flags, flush all.
11172 * \return int.
11173 *
11174 */
11175 static int
11176 atv_update_config(struct drx_demod_instance *demod, bool force_update)
11177 {
11178         struct i2c_device_addr *dev_addr = NULL;
11179         struct drxj_data *ext_attr = NULL;
11180         int rc;
11181
11182         dev_addr = demod->my_i2c_dev_addr;
11183         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11184
11185         /* equalizer coefficients */
11186         if (force_update ||
11187             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_COEF) != 0)) {
11188                 int index = 0;
11189
11190                 rc = atv_equ_coef_index(ext_attr->standard, &index);
11191                 if (rc != 0) {
11192                         pr_err("error %d\n", rc);
11193                         goto rw_error;
11194                 }
11195                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU0__A, ext_attr->atv_top_equ0[index], 0);
11196                 if (rc != 0) {
11197                         pr_err("error %d\n", rc);
11198                         goto rw_error;
11199                 }
11200                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU1__A, ext_attr->atv_top_equ1[index], 0);
11201                 if (rc != 0) {
11202                         pr_err("error %d\n", rc);
11203                         goto rw_error;
11204                 }
11205                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU2__A, ext_attr->atv_top_equ2[index], 0);
11206                 if (rc != 0) {
11207                         pr_err("error %d\n", rc);
11208                         goto rw_error;
11209                 }
11210                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU3__A, ext_attr->atv_top_equ3[index], 0);
11211                 if (rc != 0) {
11212                         pr_err("error %d\n", rc);
11213                         goto rw_error;
11214                 }
11215         }
11216
11217         /* bypass fast carrier recovery */
11218         if (force_update) {
11219                 u16 data = 0;
11220
11221                 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_RT_ROT_BP__A, &data, 0);
11222                 if (rc != 0) {
11223                         pr_err("error %d\n", rc);
11224                         goto rw_error;
11225                 }
11226                 data &= (~((u16) IQM_RT_ROT_BP_ROT_OFF__M));
11227                 if (ext_attr->phase_correction_bypass)
11228                         data |= IQM_RT_ROT_BP_ROT_OFF_OFF;
11229                 else
11230                         data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE;
11231                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ROT_BP__A, data, 0);
11232                 if (rc != 0) {
11233                         pr_err("error %d\n", rc);
11234                         goto rw_error;
11235                 }
11236         }
11237
11238         /* peak filter setting */
11239         if (force_update ||
11240             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0)) {
11241                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_PEAK__A, ext_attr->atv_top_vid_peak, 0);
11242                 if (rc != 0) {
11243                         pr_err("error %d\n", rc);
11244                         goto rw_error;
11245                 }
11246         }
11247
11248         /* noise filter setting */
11249         if (force_update ||
11250             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0)) {
11251                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_NOISE_TH__A, ext_attr->atv_top_noise_th, 0);
11252                 if (rc != 0) {
11253                         pr_err("error %d\n", rc);
11254                         goto rw_error;
11255                 }
11256         }
11257
11258         /* SIF attenuation */
11259         if (force_update ||
11260             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_SIF_ATT) != 0)) {
11261                 u16 attenuation = 0;
11262
11263                 switch (ext_attr->sif_attenuation) {
11264                 case DRXJ_SIF_ATTENUATION_0DB:
11265                         attenuation = ATV_TOP_AF_SIF_ATT_0DB;
11266                         break;
11267                 case DRXJ_SIF_ATTENUATION_3DB:
11268                         attenuation = ATV_TOP_AF_SIF_ATT_M3DB;
11269                         break;
11270                 case DRXJ_SIF_ATTENUATION_6DB:
11271                         attenuation = ATV_TOP_AF_SIF_ATT_M6DB;
11272                         break;
11273                 case DRXJ_SIF_ATTENUATION_9DB:
11274                         attenuation = ATV_TOP_AF_SIF_ATT_M9DB;
11275                         break;
11276                 default:
11277                         return -EIO;
11278                         break;
11279                 }
11280                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_AF_SIF_ATT__A, attenuation, 0);
11281                 if (rc != 0) {
11282                         pr_err("error %d\n", rc);
11283                         goto rw_error;
11284                 }
11285         }
11286
11287         /* SIF & CVBS enable */
11288         if (force_update ||
11289             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_OUTPUT) != 0)) {
11290                 u16 data = 0;
11291
11292                 rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_STDBY__A, &data, 0);
11293                 if (rc != 0) {
11294                         pr_err("error %d\n", rc);
11295                         goto rw_error;
11296                 }
11297                 if (ext_attr->enable_cvbs_output)
11298                         data |= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE;
11299                 else
11300                         data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE);
11301
11302                 if (ext_attr->enable_sif_output)
11303                         data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY);
11304                 else
11305                         data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY;
11306                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, data, 0);
11307                 if (rc != 0) {
11308                         pr_err("error %d\n", rc);
11309                         goto rw_error;
11310                 }
11311         }
11312
11313         ext_attr->atv_cfg_changed_flags = 0;
11314
11315         return 0;
11316 rw_error:
11317         return -EIO;
11318 }
11319
11320 /* -------------------------------------------------------------------------- */
11321 /**
11322 * \fn int ctrl_set_cfg_atv_output()
11323 * \brief Configure ATV ouputs
11324 * \param demod instance of demodulator
11325 * \param output_cfg output configuaration
11326 * \return int.
11327 *
11328 */
11329 static int
11330 ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11331 {
11332         struct drxj_data *ext_attr = NULL;
11333         int rc;
11334
11335         /* Check arguments */
11336         if (output_cfg == NULL)
11337                 return -EINVAL;
11338
11339         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11340         if (output_cfg->enable_sif_output) {
11341                 switch (output_cfg->sif_attenuation) {
11342                 case DRXJ_SIF_ATTENUATION_0DB:  /* fallthrough */
11343                 case DRXJ_SIF_ATTENUATION_3DB:  /* fallthrough */
11344                 case DRXJ_SIF_ATTENUATION_6DB:  /* fallthrough */
11345                 case DRXJ_SIF_ATTENUATION_9DB:
11346                         /* Do nothing */
11347                         break;
11348                 default:
11349                         return -EINVAL;
11350                         break;
11351                 }
11352
11353                 if (ext_attr->sif_attenuation != output_cfg->sif_attenuation) {
11354                         ext_attr->sif_attenuation = output_cfg->sif_attenuation;
11355                         ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_SIF_ATT;
11356                 }
11357         }
11358
11359         if (ext_attr->enable_cvbs_output != output_cfg->enable_cvbs_output) {
11360                 ext_attr->enable_cvbs_output = output_cfg->enable_cvbs_output;
11361                 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11362         }
11363
11364         if (ext_attr->enable_sif_output != output_cfg->enable_sif_output) {
11365                 ext_attr->enable_sif_output = output_cfg->enable_sif_output;
11366                 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11367         }
11368
11369         rc = atv_update_config(demod, false);
11370         if (rc != 0) {
11371                 pr_err("error %d\n", rc);
11372                 goto rw_error;
11373         }
11374
11375         return 0;
11376 rw_error:
11377         return -EIO;
11378 }
11379
11380 /* -------------------------------------------------------------------------- */
11381 #ifndef DRXJ_DIGITAL_ONLY
11382 /**
11383 * \fn int ctrl_set_cfg_atv_equ_coef()
11384 * \brief Set ATV equalizer coefficients
11385 * \param demod instance of demodulator
11386 * \param coef  the equalizer coefficients
11387 * \return int.
11388 *
11389 */
11390 static int
11391 ctrl_set_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11392 {
11393         struct drxj_data *ext_attr = NULL;
11394         int rc;
11395         int index;
11396
11397         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11398
11399         /* current standard needs to be an ATV standard */
11400         if (!DRXJ_ISATVSTD(ext_attr->standard))
11401                 return -EIO;
11402
11403         /* Check arguments */
11404         if ((coef == NULL) ||
11405             (coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2)) ||
11406             (coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2)) ||
11407             (coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2)) ||
11408             (coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2)) ||
11409             (coef->coef0 < ((s16) ~(ATV_TOP_EQU0_EQU_C0__M >> 1))) ||
11410             (coef->coef1 < ((s16) ~(ATV_TOP_EQU1_EQU_C1__M >> 1))) ||
11411             (coef->coef2 < ((s16) ~(ATV_TOP_EQU2_EQU_C2__M >> 1))) ||
11412             (coef->coef3 < ((s16) ~(ATV_TOP_EQU3_EQU_C3__M >> 1)))) {
11413                 return -EINVAL;
11414         }
11415
11416         rc = atv_equ_coef_index(ext_attr->standard, &index);
11417         if (rc != 0) {
11418                 pr_err("error %d\n", rc);
11419                 goto rw_error;
11420         }
11421         ext_attr->atv_top_equ0[index] = coef->coef0;
11422         ext_attr->atv_top_equ1[index] = coef->coef1;
11423         ext_attr->atv_top_equ2[index] = coef->coef2;
11424         ext_attr->atv_top_equ3[index] = coef->coef3;
11425         ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_COEF;
11426
11427         rc = atv_update_config(demod, false);
11428         if (rc != 0) {
11429                 pr_err("error %d\n", rc);
11430                 goto rw_error;
11431         }
11432
11433         return 0;
11434 rw_error:
11435         return -EIO;
11436 }
11437
11438 /* -------------------------------------------------------------------------- */
11439 /**
11440 * \fn int ctrl_get_cfg_atv_equ_coef()
11441 * \brief Get ATV equ coef settings
11442 * \param demod instance of demodulator
11443 * \param coef The ATV equ coefficients
11444 * \return int.
11445 *
11446 * The values are read from the shadow registers maintained by the drxdriver
11447 * If registers are manipulated outside of the drxdriver scope the reported
11448 * settings will not reflect these changes because of the use of shadow
11449 * regitsers.
11450 *
11451 */
11452 static int
11453 ctrl_get_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11454 {
11455         struct drxj_data *ext_attr = NULL;
11456         int rc;
11457         int index = 0;
11458
11459         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11460
11461         /* current standard needs to be an ATV standard */
11462         if (!DRXJ_ISATVSTD(ext_attr->standard))
11463                 return -EIO;
11464
11465         /* Check arguments */
11466         if (coef == NULL)
11467                 return -EINVAL;
11468
11469         rc = atv_equ_coef_index(ext_attr->standard, &index);
11470         if (rc != 0) {
11471                 pr_err("error %d\n", rc);
11472                 goto rw_error;
11473         }
11474         coef->coef0 = ext_attr->atv_top_equ0[index];
11475         coef->coef1 = ext_attr->atv_top_equ1[index];
11476         coef->coef2 = ext_attr->atv_top_equ2[index];
11477         coef->coef3 = ext_attr->atv_top_equ3[index];
11478
11479         return 0;
11480 rw_error:
11481         return -EIO;
11482 }
11483
11484 /* -------------------------------------------------------------------------- */
11485 /**
11486 * \fn int ctrl_set_cfg_atv_misc()
11487 * \brief Set misc. settings for ATV.
11488 * \param demod instance of demodulator
11489 * \param
11490 * \return int.
11491 *
11492 */
11493 static int
11494 ctrl_set_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11495 {
11496         struct drxj_data *ext_attr = NULL;
11497         int rc;
11498
11499         /* Check arguments */
11500         if ((settings == NULL) ||
11501             ((settings->peak_filter) < (s16) (-8)) ||
11502             ((settings->peak_filter) > (s16) (15)) ||
11503             ((settings->noise_filter) > 15)) {
11504                 return -EINVAL;
11505         }
11506         /* if */
11507         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11508
11509         if (settings->peak_filter != ext_attr->atv_top_vid_peak) {
11510                 ext_attr->atv_top_vid_peak = settings->peak_filter;
11511                 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_PEAK_FLT;
11512         }
11513
11514         if (settings->noise_filter != ext_attr->atv_top_noise_th) {
11515                 ext_attr->atv_top_noise_th = settings->noise_filter;
11516                 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_NOISE_FLT;
11517         }
11518
11519         rc = atv_update_config(demod, false);
11520         if (rc != 0) {
11521                 pr_err("error %d\n", rc);
11522                 goto rw_error;
11523         }
11524
11525         return 0;
11526 rw_error:
11527         return -EIO;
11528 }
11529
11530 /* -------------------------------------------------------------------------- */
11531 /**
11532 * \fn int  ctrl_get_cfg_atv_misc()
11533 * \brief Get misc settings of ATV.
11534 * \param demod instance of demodulator
11535 * \param settings misc. ATV settings
11536 * \return int.
11537 *
11538 * The values are read from the shadow registers maintained by the drxdriver
11539 * If registers are manipulated outside of the drxdriver scope the reported
11540 * settings will not reflect these changes because of the use of shadow
11541 * regitsers.
11542 */
11543 static int
11544 ctrl_get_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11545 {
11546         struct drxj_data *ext_attr = NULL;
11547
11548         /* Check arguments */
11549         if (settings == NULL)
11550                 return -EINVAL;
11551
11552         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11553
11554         settings->peak_filter = ext_attr->atv_top_vid_peak;
11555         settings->noise_filter = ext_attr->atv_top_noise_th;
11556
11557         return 0;
11558 }
11559
11560 /* -------------------------------------------------------------------------- */
11561
11562 /* -------------------------------------------------------------------------- */
11563 /**
11564 * \fn int  ctrl_get_cfg_atv_output()
11565 * \brief
11566 * \param demod instance of demodulator
11567 * \param output_cfg output configuaration
11568 * \return int.
11569 *
11570 */
11571 static int
11572 ctrl_get_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11573 {
11574         int rc;
11575         u16 data = 0;
11576
11577         /* Check arguments */
11578         if (output_cfg == NULL)
11579                 return -EINVAL;
11580
11581         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, ATV_TOP_STDBY__A, &data, 0);
11582         if (rc != 0) {
11583                 pr_err("error %d\n", rc);
11584                 goto rw_error;
11585         }
11586         if (data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)
11587                 output_cfg->enable_cvbs_output = true;
11588         else
11589                 output_cfg->enable_cvbs_output = false;
11590
11591         if (data & ATV_TOP_STDBY_SIF_STDBY_STANDBY) {
11592                 output_cfg->enable_sif_output = false;
11593         } else {
11594                 output_cfg->enable_sif_output = true;
11595                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, ATV_TOP_AF_SIF_ATT__A, &data, 0);
11596                 if (rc != 0) {
11597                         pr_err("error %d\n", rc);
11598                         goto rw_error;
11599                 }
11600                 output_cfg->sif_attenuation = (enum drxjsif_attenuation) data;
11601         }
11602
11603         return 0;
11604 rw_error:
11605         return -EIO;
11606 }
11607
11608 /* -------------------------------------------------------------------------- */
11609 /**
11610 * \fn int  ctrl_get_cfg_atv_agc_status()
11611 * \brief
11612 * \param demod instance of demodulator
11613 * \param agc_status agc status
11614 * \return int.
11615 *
11616 */
11617 static int
11618 ctrl_get_cfg_atv_agc_status(struct drx_demod_instance *demod,
11619                             struct drxj_cfg_atv_agc_status *agc_status)
11620 {
11621         struct i2c_device_addr *dev_addr = NULL;
11622         int rc;
11623         u16 data = 0;
11624         u32 tmp = 0;
11625
11626         /* Check arguments */
11627         if (agc_status == NULL)
11628                 return -EINVAL;
11629
11630         dev_addr = demod->my_i2c_dev_addr;
11631
11632         /*
11633            RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
11634            = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
11635
11636            IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
11637          */
11638         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &data, 0);
11639         if (rc != 0) {
11640                 pr_err("error %d\n", rc);
11641                 goto rw_error;
11642         }
11643         tmp = ((u32) data) * 27 - ((u32) (data >> 2));  /* nA */
11644         agc_status->rf_agc_gain = (u16) (tmp / 1000);   /* uA */
11645         /* rounding */
11646         if (tmp % 1000 >= 500)
11647                 (agc_status->rf_agc_gain)++;
11648
11649         /*
11650            IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
11651            = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
11652
11653            IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
11654          */
11655         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &data, 0);
11656         if (rc != 0) {
11657                 pr_err("error %d\n", rc);
11658                 goto rw_error;
11659         }
11660         tmp = ((u32) data) * 27 - ((u32) (data >> 2));  /* nA */
11661         agc_status->if_agc_gain = (u16) (tmp / 1000);   /* uA */
11662         /* rounding */
11663         if (tmp % 1000 >= 500)
11664                 (agc_status->if_agc_gain)++;
11665
11666         /*
11667            videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
11668            = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
11669            = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
11670            = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
11671            = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
11672          */
11673
11674         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &data, 0);
11675         if (rc != 0) {
11676                 pr_err("error %d\n", rc);
11677                 goto rw_error;
11678         }
11679         /* dividing by 32 inclusive rounding */
11680         data >>= 4;
11681         if ((data & 1) != 0)
11682                 data++;
11683         data >>= 1;
11684         agc_status->video_agc_gain = ((s16) data) - 75; /* 0.1 dB */
11685
11686         /*
11687            audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
11688            = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
11689            = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
11690            = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
11691            = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
11692          */
11693
11694         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &data, 0);
11695         if (rc != 0) {
11696                 pr_err("error %d\n", rc);
11697                 goto rw_error;
11698         }
11699         data &= SCU_RAM_ATV_SIF_GAIN__M;
11700         /* dividing by 2 inclusive rounding */
11701         if ((data & 1) != 0)
11702                 data++;
11703         data >>= 1;
11704         agc_status->audio_agc_gain = ((s16) data) - 4;  /* 0.1 dB */
11705
11706         /* Loop gain's */
11707         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
11708         if (rc != 0) {
11709                 pr_err("error %d\n", rc);
11710                 goto rw_error;
11711         }
11712         agc_status->video_agc_loop_gain =
11713             ((data & SCU_RAM_AGC_KI_DGAIN__M) >> SCU_RAM_AGC_KI_DGAIN__B);
11714         agc_status->rf_agc_loop_gain =
11715             ((data & SCU_RAM_AGC_KI_RF__M) >> SCU_RAM_AGC_KI_RF__B);
11716         agc_status->if_agc_loop_gain =
11717             ((data & SCU_RAM_AGC_KI_IF__M) >> SCU_RAM_AGC_KI_IF__B);
11718
11719         return 0;
11720 rw_error:
11721         return -EIO;
11722 }
11723
11724 /* -------------------------------------------------------------------------- */
11725
11726 /**
11727 * \fn int power_up_atv ()
11728 * \brief Power up ATV.
11729 * \param demod instance of demodulator
11730 * \param standard either NTSC or FM (sub strandard for ATV )
11731 * \return int.
11732 *
11733 * * Starts ATV and IQM
11734 * * AUdio already started during standard init for ATV.
11735 */
11736 static int power_up_atv(struct drx_demod_instance *demod, enum drx_standard standard)
11737 {
11738         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11739         int rc;
11740
11741         /* ATV NTSC */
11742         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE, 0);
11743         if (rc != 0) {
11744                 pr_err("error %d\n", rc);
11745                 goto rw_error;
11746         }
11747         /* turn on IQM_AF */
11748         rc = set_iqm_af(demod, true);
11749         if (rc != 0) {
11750                 pr_err("error %d\n", rc);
11751                 goto rw_error;
11752         }
11753         rc = adc_synchronization(demod);
11754         if (rc != 0) {
11755                 pr_err("error %d\n", rc);
11756                 goto rw_error;
11757         }
11758
11759         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
11760         if (rc != 0) {
11761                 pr_err("error %d\n", rc);
11762                 goto rw_error;
11763         }
11764
11765         /* Audio, already done during set standard */
11766
11767         return 0;
11768 rw_error:
11769         return -EIO;
11770 }
11771 #endif /* #ifndef DRXJ_DIGITAL_ONLY */
11772
11773 /* -------------------------------------------------------------------------- */
11774
11775 /**
11776 * \fn int power_down_atv ()
11777 * \brief Power down ATV.
11778 * \param demod instance of demodulator
11779 * \param standard either NTSC or FM (sub strandard for ATV )
11780 * \return int.
11781 *
11782 *  Stops and thus resets ATV and IQM block
11783 *  SIF and CVBS ADC are powered down
11784 *  Calls audio power down
11785 */
11786 static int
11787 power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
11788 {
11789         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11790         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
11791                 /* parameter_len */ 0,
11792                 /* result_len    */ 0,
11793                 /* *parameter   */ NULL,
11794                 /* *result      */ NULL
11795         };
11796         int rc;
11797         u16 cmd_result = 0;
11798
11799         /* ATV NTSC */
11800
11801         /* Stop ATV SCU (will reset ATV and IQM hardware */
11802         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
11803             SCU_RAM_COMMAND_CMD_DEMOD_STOP;
11804         cmd_scu.parameter_len = 0;
11805         cmd_scu.result_len = 1;
11806         cmd_scu.parameter = NULL;
11807         cmd_scu.result = &cmd_result;
11808         rc = scu_command(dev_addr, &cmd_scu);
11809         if (rc != 0) {
11810                 pr_err("error %d\n", rc);
11811                 goto rw_error;
11812         }
11813         /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
11814         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
11815         if (rc != 0) {
11816                 pr_err("error %d\n", rc);
11817                 goto rw_error;
11818         }
11819
11820         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
11821         if (rc != 0) {
11822                 pr_err("error %d\n", rc);
11823                 goto rw_error;
11824         }
11825         if (primary) {
11826                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
11827                 if (rc != 0) {
11828                         pr_err("error %d\n", rc);
11829                         goto rw_error;
11830                 }
11831                 rc = set_iqm_af(demod, false);
11832                 if (rc != 0) {
11833                         pr_err("error %d\n", rc);
11834                         goto rw_error;
11835                 }
11836         } else {
11837                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
11838                 if (rc != 0) {
11839                         pr_err("error %d\n", rc);
11840                         goto rw_error;
11841                 }
11842                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
11843                 if (rc != 0) {
11844                         pr_err("error %d\n", rc);
11845                         goto rw_error;
11846                 }
11847                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
11848                 if (rc != 0) {
11849                         pr_err("error %d\n", rc);
11850                         goto rw_error;
11851                 }
11852                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
11853                 if (rc != 0) {
11854                         pr_err("error %d\n", rc);
11855                         goto rw_error;
11856                 }
11857                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
11858                 if (rc != 0) {
11859                         pr_err("error %d\n", rc);
11860                         goto rw_error;
11861                 }
11862         }
11863         rc = power_down_aud(demod);
11864         if (rc != 0) {
11865                 pr_err("error %d\n", rc);
11866                 goto rw_error;
11867         }
11868
11869         return 0;
11870 rw_error:
11871         return -EIO;
11872 }
11873
11874 /* -------------------------------------------------------------------------- */
11875 /**
11876 * \fn int set_atv_standard ()
11877 * \brief Set up ATV demodulator.
11878 * \param demod instance of demodulator
11879 * \param standard either NTSC or FM (sub strandard for ATV )
11880 * \return int.
11881 *
11882 * Init all channel independent registers.
11883 * Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
11884 *
11885 */
11886 #ifndef DRXJ_DIGITAL_ONLY
11887 #define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D   /* TODO remove after done with reg import */
11888 static int
11889 set_atv_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
11890 {
11891 /* TODO: enable alternative for tap settings via external file
11892
11893 something like:
11894 #ifdef   DRXJ_ATV_COEF_FILE
11895 #include DRXJ_ATV_COEF_FILE
11896 #else
11897 ... code defining fixed coef's ...
11898 #endif
11899
11900 Cutsomer must create file "customer_coefs.c.inc" containing
11901 modified copy off the constants below, and define the compiler
11902 switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
11903
11904 Still to check if this will work; DRXJ_16TO8 macro may cause
11905 trouble ?
11906 */
11907         const u8 ntsc_taps_re[] = {
11908                 DRXJ_16TO8(-12),        /* re0  */
11909                 DRXJ_16TO8(-9), /* re1  */
11910                 DRXJ_16TO8(9),  /* re2  */
11911                 DRXJ_16TO8(19), /* re3  */
11912                 DRXJ_16TO8(-4), /* re4  */
11913                 DRXJ_16TO8(-24),        /* re5  */
11914                 DRXJ_16TO8(-6), /* re6  */
11915                 DRXJ_16TO8(16), /* re7  */
11916                 DRXJ_16TO8(6),  /* re8  */
11917                 DRXJ_16TO8(-16),        /* re9  */
11918                 DRXJ_16TO8(-5), /* re10 */
11919                 DRXJ_16TO8(13), /* re11 */
11920                 DRXJ_16TO8(-2), /* re12 */
11921                 DRXJ_16TO8(-20),        /* re13 */
11922                 DRXJ_16TO8(4),  /* re14 */
11923                 DRXJ_16TO8(25), /* re15 */
11924                 DRXJ_16TO8(-6), /* re16 */
11925                 DRXJ_16TO8(-36),        /* re17 */
11926                 DRXJ_16TO8(2),  /* re18 */
11927                 DRXJ_16TO8(38), /* re19 */
11928                 DRXJ_16TO8(-10),        /* re20 */
11929                 DRXJ_16TO8(-48),        /* re21 */
11930                 DRXJ_16TO8(35), /* re22 */
11931                 DRXJ_16TO8(94), /* re23 */
11932                 DRXJ_16TO8(-59),        /* re24 */
11933                 DRXJ_16TO8(-217),       /* re25 */
11934                 DRXJ_16TO8(50), /* re26 */
11935                 DRXJ_16TO8(679) /* re27 */
11936         };
11937         const u8 ntsc_taps_im[] = {
11938                 DRXJ_16TO8(11), /* im0  */
11939                 DRXJ_16TO8(1),  /* im1  */
11940                 DRXJ_16TO8(-10),        /* im2  */
11941                 DRXJ_16TO8(2),  /* im3  */
11942                 DRXJ_16TO8(24), /* im4  */
11943                 DRXJ_16TO8(21), /* im5  */
11944                 DRXJ_16TO8(1),  /* im6  */
11945                 DRXJ_16TO8(-4), /* im7  */
11946                 DRXJ_16TO8(7),  /* im8  */
11947                 DRXJ_16TO8(14), /* im9  */
11948                 DRXJ_16TO8(27), /* im10 */
11949                 DRXJ_16TO8(42), /* im11 */
11950                 DRXJ_16TO8(22), /* im12 */
11951                 DRXJ_16TO8(-20),        /* im13 */
11952                 DRXJ_16TO8(2),  /* im14 */
11953                 DRXJ_16TO8(98), /* im15 */
11954                 DRXJ_16TO8(122),        /* im16 */
11955                 DRXJ_16TO8(0),  /* im17 */
11956                 DRXJ_16TO8(-85),        /* im18 */
11957                 DRXJ_16TO8(51), /* im19 */
11958                 DRXJ_16TO8(247),        /* im20 */
11959                 DRXJ_16TO8(192),        /* im21 */
11960                 DRXJ_16TO8(-55),        /* im22 */
11961                 DRXJ_16TO8(-95),        /* im23 */
11962                 DRXJ_16TO8(217),        /* im24 */
11963                 DRXJ_16TO8(544),        /* im25 */
11964                 DRXJ_16TO8(553),        /* im26 */
11965                 DRXJ_16TO8(302) /* im27 */
11966         };
11967         const u8 bg_taps_re[] = {
11968                 DRXJ_16TO8(-18),        /* re0  */
11969                 DRXJ_16TO8(18), /* re1  */
11970                 DRXJ_16TO8(19), /* re2  */
11971                 DRXJ_16TO8(-26),        /* re3  */
11972                 DRXJ_16TO8(-20),        /* re4  */
11973                 DRXJ_16TO8(36), /* re5  */
11974                 DRXJ_16TO8(5),  /* re6  */
11975                 DRXJ_16TO8(-51),        /* re7  */
11976                 DRXJ_16TO8(15), /* re8  */
11977                 DRXJ_16TO8(45), /* re9  */
11978                 DRXJ_16TO8(-46),        /* re10 */
11979                 DRXJ_16TO8(-24),        /* re11 */
11980                 DRXJ_16TO8(71), /* re12 */
11981                 DRXJ_16TO8(-17),        /* re13 */
11982                 DRXJ_16TO8(-83),        /* re14 */
11983                 DRXJ_16TO8(74), /* re15 */
11984                 DRXJ_16TO8(75), /* re16 */
11985                 DRXJ_16TO8(-134),       /* re17 */
11986                 DRXJ_16TO8(-40),        /* re18 */
11987                 DRXJ_16TO8(191),        /* re19 */
11988                 DRXJ_16TO8(-11),        /* re20 */
11989                 DRXJ_16TO8(-233),       /* re21 */
11990                 DRXJ_16TO8(74), /* re22 */
11991                 DRXJ_16TO8(271),        /* re23 */
11992                 DRXJ_16TO8(-132),       /* re24 */
11993                 DRXJ_16TO8(-341),       /* re25 */
11994                 DRXJ_16TO8(172),        /* re26 */
11995                 DRXJ_16TO8(801) /* re27 */
11996         };
11997         const u8 bg_taps_im[] = {
11998                 DRXJ_16TO8(-24),        /* im0  */
11999                 DRXJ_16TO8(-10),        /* im1  */
12000                 DRXJ_16TO8(9),  /* im2  */
12001                 DRXJ_16TO8(-5), /* im3  */
12002                 DRXJ_16TO8(-51),        /* im4  */
12003                 DRXJ_16TO8(-17),        /* im5  */
12004                 DRXJ_16TO8(31), /* im6  */
12005                 DRXJ_16TO8(-48),        /* im7  */
12006                 DRXJ_16TO8(-95),        /* im8  */
12007                 DRXJ_16TO8(25), /* im9  */
12008                 DRXJ_16TO8(37), /* im10 */
12009                 DRXJ_16TO8(-123),       /* im11 */
12010                 DRXJ_16TO8(-77),        /* im12 */
12011                 DRXJ_16TO8(94), /* im13 */
12012                 DRXJ_16TO8(-10),        /* im14 */
12013                 DRXJ_16TO8(-149),       /* im15 */
12014                 DRXJ_16TO8(10), /* im16 */
12015                 DRXJ_16TO8(108),        /* im17 */
12016                 DRXJ_16TO8(-49),        /* im18 */
12017                 DRXJ_16TO8(-59),        /* im19 */
12018                 DRXJ_16TO8(90), /* im20 */
12019                 DRXJ_16TO8(73), /* im21 */
12020                 DRXJ_16TO8(55), /* im22 */
12021                 DRXJ_16TO8(148),        /* im23 */
12022                 DRXJ_16TO8(86), /* im24 */
12023                 DRXJ_16TO8(146),        /* im25 */
12024                 DRXJ_16TO8(687),        /* im26 */
12025                 DRXJ_16TO8(877) /* im27 */
12026         };
12027         const u8 dk_i_l_lp_taps_re[] = {
12028                 DRXJ_16TO8(-23),        /* re0  */
12029                 DRXJ_16TO8(9),  /* re1  */
12030                 DRXJ_16TO8(16), /* re2  */
12031                 DRXJ_16TO8(-26),        /* re3  */
12032                 DRXJ_16TO8(-3), /* re4  */
12033                 DRXJ_16TO8(13), /* re5  */
12034                 DRXJ_16TO8(-19),        /* re6  */
12035                 DRXJ_16TO8(-3), /* re7  */
12036                 DRXJ_16TO8(13), /* re8  */
12037                 DRXJ_16TO8(-26),        /* re9  */
12038                 DRXJ_16TO8(-4), /* re10 */
12039                 DRXJ_16TO8(28), /* re11 */
12040                 DRXJ_16TO8(-15),        /* re12 */
12041                 DRXJ_16TO8(-14),        /* re13 */
12042                 DRXJ_16TO8(10), /* re14 */
12043                 DRXJ_16TO8(1),  /* re15 */
12044                 DRXJ_16TO8(39), /* re16 */
12045                 DRXJ_16TO8(-18),        /* re17 */
12046                 DRXJ_16TO8(-90),        /* re18 */
12047                 DRXJ_16TO8(109),        /* re19 */
12048                 DRXJ_16TO8(113),        /* re20 */
12049                 DRXJ_16TO8(-235),       /* re21 */
12050                 DRXJ_16TO8(-49),        /* re22 */
12051                 DRXJ_16TO8(359),        /* re23 */
12052                 DRXJ_16TO8(-79),        /* re24 */
12053                 DRXJ_16TO8(-459),       /* re25 */
12054                 DRXJ_16TO8(206),        /* re26 */
12055                 DRXJ_16TO8(894) /* re27 */
12056         };
12057         const u8 dk_i_l_lp_taps_im[] = {
12058                 DRXJ_16TO8(-8), /* im0  */
12059                 DRXJ_16TO8(-20),        /* im1  */
12060                 DRXJ_16TO8(17), /* im2  */
12061                 DRXJ_16TO8(-14),        /* im3  */
12062                 DRXJ_16TO8(-52),        /* im4  */
12063                 DRXJ_16TO8(4),  /* im5  */
12064                 DRXJ_16TO8(9),  /* im6  */
12065                 DRXJ_16TO8(-62),        /* im7  */
12066                 DRXJ_16TO8(-47),        /* im8  */
12067                 DRXJ_16TO8(0),  /* im9  */
12068                 DRXJ_16TO8(-20),        /* im10 */
12069                 DRXJ_16TO8(-48),        /* im11 */
12070                 DRXJ_16TO8(-65),        /* im12 */
12071                 DRXJ_16TO8(-23),        /* im13 */
12072                 DRXJ_16TO8(44), /* im14 */
12073                 DRXJ_16TO8(-60),        /* im15 */
12074                 DRXJ_16TO8(-113),       /* im16 */
12075                 DRXJ_16TO8(92), /* im17 */
12076                 DRXJ_16TO8(81), /* im18 */
12077                 DRXJ_16TO8(-125),       /* im19 */
12078                 DRXJ_16TO8(28), /* im20 */
12079                 DRXJ_16TO8(182),        /* im21 */
12080                 DRXJ_16TO8(35), /* im22 */
12081                 DRXJ_16TO8(94), /* im23 */
12082                 DRXJ_16TO8(180),        /* im24 */
12083                 DRXJ_16TO8(134),        /* im25 */
12084                 DRXJ_16TO8(657),        /* im26 */
12085                 DRXJ_16TO8(1023)        /* im27 */
12086         };
12087         const u8 fm_taps_re[] = {
12088                 DRXJ_16TO8(0),  /* re0  */
12089                 DRXJ_16TO8(0),  /* re1  */
12090                 DRXJ_16TO8(0),  /* re2  */
12091                 DRXJ_16TO8(0),  /* re3  */
12092                 DRXJ_16TO8(0),  /* re4  */
12093                 DRXJ_16TO8(0),  /* re5  */
12094                 DRXJ_16TO8(0),  /* re6  */
12095                 DRXJ_16TO8(0),  /* re7  */
12096                 DRXJ_16TO8(0),  /* re8  */
12097                 DRXJ_16TO8(0),  /* re9  */
12098                 DRXJ_16TO8(0),  /* re10 */
12099                 DRXJ_16TO8(0),  /* re11 */
12100                 DRXJ_16TO8(0),  /* re12 */
12101                 DRXJ_16TO8(0),  /* re13 */
12102                 DRXJ_16TO8(0),  /* re14 */
12103                 DRXJ_16TO8(0),  /* re15 */
12104                 DRXJ_16TO8(0),  /* re16 */
12105                 DRXJ_16TO8(0),  /* re17 */
12106                 DRXJ_16TO8(0),  /* re18 */
12107                 DRXJ_16TO8(0),  /* re19 */
12108                 DRXJ_16TO8(0),  /* re20 */
12109                 DRXJ_16TO8(0),  /* re21 */
12110                 DRXJ_16TO8(0),  /* re22 */
12111                 DRXJ_16TO8(0),  /* re23 */
12112                 DRXJ_16TO8(0),  /* re24 */
12113                 DRXJ_16TO8(0),  /* re25 */
12114                 DRXJ_16TO8(0),  /* re26 */
12115                 DRXJ_16TO8(0)   /* re27 */
12116         };
12117         const u8 fm_taps_im[] = {
12118                 DRXJ_16TO8(-6), /* im0  */
12119                 DRXJ_16TO8(2),  /* im1  */
12120                 DRXJ_16TO8(14), /* im2  */
12121                 DRXJ_16TO8(-38),        /* im3  */
12122                 DRXJ_16TO8(58), /* im4  */
12123                 DRXJ_16TO8(-62),        /* im5  */
12124                 DRXJ_16TO8(42), /* im6  */
12125                 DRXJ_16TO8(0),  /* im7  */
12126                 DRXJ_16TO8(-45),        /* im8  */
12127                 DRXJ_16TO8(73), /* im9  */
12128                 DRXJ_16TO8(-65),        /* im10 */
12129                 DRXJ_16TO8(23), /* im11 */
12130                 DRXJ_16TO8(34), /* im12 */
12131                 DRXJ_16TO8(-77),        /* im13 */
12132                 DRXJ_16TO8(80), /* im14 */
12133                 DRXJ_16TO8(-39),        /* im15 */
12134                 DRXJ_16TO8(-25),        /* im16 */
12135                 DRXJ_16TO8(78), /* im17 */
12136                 DRXJ_16TO8(-90),        /* im18 */
12137                 DRXJ_16TO8(52), /* im19 */
12138                 DRXJ_16TO8(16), /* im20 */
12139                 DRXJ_16TO8(-77),        /* im21 */
12140                 DRXJ_16TO8(97), /* im22 */
12141                 DRXJ_16TO8(-62),        /* im23 */
12142                 DRXJ_16TO8(-8), /* im24 */
12143                 DRXJ_16TO8(75), /* im25 */
12144                 DRXJ_16TO8(-100),       /* im26 */
12145                 DRXJ_16TO8(70)  /* im27 */
12146         };
12147
12148         struct i2c_device_addr *dev_addr = NULL;
12149         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
12150                 /* parameter_len */ 0,
12151                 /* result_len    */ 0,
12152                 /* *parameter   */ NULL,
12153                 /* *result      */ NULL
12154         };
12155         u16 cmd_result = 0;
12156         u16 cmd_param = 0;
12157 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
12158         struct drxu_code_info ucode_info;
12159         struct drx_common_attr *common_attr = NULL;
12160 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
12161         struct drxj_data *ext_attr = NULL;
12162         int rc;
12163
12164         ext_attr = (struct drxj_data *) demod->my_ext_attr;
12165         dev_addr = demod->my_i2c_dev_addr;
12166
12167 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
12168         common_attr = demod->my_common_attr;
12169
12170         /* Check if audio microcode is already uploaded */
12171         if (!(ext_attr->flag_aud_mc_uploaded)) {
12172                 ucode_info.mc_data = common_attr->microcode;
12173
12174                 /* Upload only audio microcode */
12175                 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_UPLOAD, true);
12176                 if (rc != 0) {
12177                         pr_err("error %d\n", rc);
12178                         goto rw_error;
12179                 }
12180
12181                 if (common_attr->verify_microcode == true) {
12182                         rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_VERIFY, true);
12183                         if (rc != 0) {
12184                                 pr_err("error %d\n", rc);
12185                                 goto rw_error;
12186                         }
12187                 }
12188
12189                 /* Prevent uploading audio microcode again */
12190                 ext_attr->flag_aud_mc_uploaded = true;
12191         }
12192 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
12193
12194         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
12195         if (rc != 0) {
12196                 pr_err("error %d\n", rc);
12197                 goto rw_error;
12198         }
12199         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
12200         if (rc != 0) {
12201                 pr_err("error %d\n", rc);
12202                 goto rw_error;
12203         }
12204         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
12205         if (rc != 0) {
12206                 pr_err("error %d\n", rc);
12207                 goto rw_error;
12208         }
12209         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
12210         if (rc != 0) {
12211                 pr_err("error %d\n", rc);
12212                 goto rw_error;
12213         }
12214         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
12215         if (rc != 0) {
12216                 pr_err("error %d\n", rc);
12217                 goto rw_error;
12218         }
12219         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
12220         if (rc != 0) {
12221                 pr_err("error %d\n", rc);
12222                 goto rw_error;
12223         }
12224         /* Reset ATV SCU */
12225         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12226             SCU_RAM_COMMAND_CMD_DEMOD_RESET;
12227         cmd_scu.parameter_len = 0;
12228         cmd_scu.result_len = 1;
12229         cmd_scu.parameter = NULL;
12230         cmd_scu.result = &cmd_result;
12231         rc = scu_command(dev_addr, &cmd_scu);
12232         if (rc != 0) {
12233                 pr_err("error %d\n", rc);
12234                 goto rw_error;
12235         }
12236
12237         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE, 0);
12238         if (rc != 0) {
12239                 pr_err("error %d\n", rc);
12240                 goto rw_error;
12241         }
12242
12243         /* TODO remove AUTO/OFF patches after ucode fix. */
12244         switch (*standard) {
12245         case DRX_STANDARD_NTSC:
12246                 /* NTSC */
12247                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_MN;
12248
12249                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, IQM_RT_LO_INCR_MN, 0);
12250                 if (rc != 0) {
12251                         pr_err("error %d\n", rc);
12252                         goto rw_error;
12253                 }
12254                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12255                 if (rc != 0) {
12256                         pr_err("error %d\n", rc);
12257                         goto rw_error;
12258                 }
12259                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(ntsc_taps_re), ((u8 *)ntsc_taps_re), 0);
12260                 if (rc != 0) {
12261                         pr_err("error %d\n", rc);
12262                         goto rw_error;
12263                 }
12264                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(ntsc_taps_im), ((u8 *)ntsc_taps_im), 0);
12265                 if (rc != 0) {
12266                         pr_err("error %d\n", rc);
12267                         goto rw_error;
12268                 }
12269
12270                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_MN, 0);
12271                 if (rc != 0) {
12272                         pr_err("error %d\n", rc);
12273                         goto rw_error;
12274                 }
12275                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_MN | ATV_TOP_CR_CONT_CR_D_MN | ATV_TOP_CR_CONT_CR_I_MN), 0);
12276                 if (rc != 0) {
12277                         pr_err("error %d\n", rc);
12278                         goto rw_error;
12279                 }
12280                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_MN, 0);
12281                 if (rc != 0) {
12282                         pr_err("error %d\n", rc);
12283                         goto rw_error;
12284                 }
12285                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_MN | ATV_TOP_STD_VID_POL_MN), 0);
12286                 if (rc != 0) {
12287                         pr_err("error %d\n", rc);
12288                         goto rw_error;
12289                 }
12290                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_MN, 0);
12291                 if (rc != 0) {
12292                         pr_err("error %d\n", rc);
12293                         goto rw_error;
12294                 }
12295
12296                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
12297                 if (rc != 0) {
12298                         pr_err("error %d\n", rc);
12299                         goto rw_error;
12300                 }
12301                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12302                 if (rc != 0) {
12303                         pr_err("error %d\n", rc);
12304                         goto rw_error;
12305                 }
12306                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12307                 if (rc != 0) {
12308                         pr_err("error %d\n", rc);
12309                         goto rw_error;
12310                 }
12311                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN, 0);
12312                 if (rc != 0) {
12313                         pr_err("error %d\n", rc);
12314                         goto rw_error;
12315                 }
12316                 ext_attr->phase_correction_bypass = false;
12317                 ext_attr->enable_cvbs_output = true;
12318                 break;
12319         case DRX_STANDARD_FM:
12320                 /* FM */
12321                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_FM;
12322
12323                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2994, 0);
12324                 if (rc != 0) {
12325                         pr_err("error %d\n", rc);
12326                         goto rw_error;
12327                 }
12328                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 0, 0);
12329                 if (rc != 0) {
12330                         pr_err("error %d\n", rc);
12331                         goto rw_error;
12332                 }
12333                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(fm_taps_re), ((u8 *)fm_taps_re), 0);
12334                 if (rc != 0) {
12335                         pr_err("error %d\n", rc);
12336                         goto rw_error;
12337                 }
12338                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(fm_taps_im), ((u8 *)fm_taps_im), 0);
12339                 if (rc != 0) {
12340                         pr_err("error %d\n", rc);
12341                         goto rw_error;
12342                 }
12343                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_FM | ATV_TOP_STD_VID_POL_FM), 0);
12344                 if (rc != 0) {
12345                         pr_err("error %d\n", rc);
12346                         goto rw_error;
12347                 }
12348                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_CONTROL__A, 0, 0);
12349                 if (rc != 0) {
12350                         pr_err("error %d\n", rc);
12351                         goto rw_error;
12352                 }
12353                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, 0, 0);
12354                 if (rc != 0) {
12355                         pr_err("error %d\n", rc);
12356                         goto rw_error;
12357                 }
12358
12359                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW | SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM), 0);
12360                 if (rc != 0) {
12361                         pr_err("error %d\n", rc);
12362                         goto rw_error;
12363                 }
12364                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF, 0);
12365                 if (rc != 0) {
12366                         pr_err("error %d\n", rc);
12367                         goto rw_error;
12368                 }
12369                 ext_attr->phase_correction_bypass = true;
12370                 ext_attr->enable_cvbs_output = false;
12371                 break;
12372         case DRX_STANDARD_PAL_SECAM_BG:
12373                 /* PAL/SECAM B/G */
12374                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_B;
12375
12376                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 1820, 0);
12377                 if (rc != 0) {
12378                         pr_err("error %d\n", rc);
12379                         goto rw_error;
12380                 }       /* TODO check with IS */
12381                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12382                 if (rc != 0) {
12383                         pr_err("error %d\n", rc);
12384                         goto rw_error;
12385                 }
12386                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(bg_taps_re), ((u8 *)bg_taps_re), 0);
12387                 if (rc != 0) {
12388                         pr_err("error %d\n", rc);
12389                         goto rw_error;
12390                 }
12391                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(bg_taps_im), ((u8 *)bg_taps_im), 0);
12392                 if (rc != 0) {
12393                         pr_err("error %d\n", rc);
12394                         goto rw_error;
12395                 }
12396                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_BG, 0);
12397                 if (rc != 0) {
12398                         pr_err("error %d\n", rc);
12399                         goto rw_error;
12400                 }
12401                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG, 0);
12402                 if (rc != 0) {
12403                         pr_err("error %d\n", rc);
12404                         goto rw_error;
12405                 }
12406                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_BG | ATV_TOP_CR_CONT_CR_D_BG | ATV_TOP_CR_CONT_CR_I_BG), 0);
12407                 if (rc != 0) {
12408                         pr_err("error %d\n", rc);
12409                         goto rw_error;
12410                 }
12411                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_BG, 0);
12412                 if (rc != 0) {
12413                         pr_err("error %d\n", rc);
12414                         goto rw_error;
12415                 }
12416                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_BG | ATV_TOP_STD_VID_POL_BG), 0);
12417                 if (rc != 0) {
12418                         pr_err("error %d\n", rc);
12419                         goto rw_error;
12420                 }
12421                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
12422                 if (rc != 0) {
12423                         pr_err("error %d\n", rc);
12424                         goto rw_error;
12425                 }
12426                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12427                 if (rc != 0) {
12428                         pr_err("error %d\n", rc);
12429                         goto rw_error;
12430                 }
12431                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12432                 if (rc != 0) {
12433                         pr_err("error %d\n", rc);
12434                         goto rw_error;
12435                 }
12436                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_BG_MN, 0);
12437                 if (rc != 0) {
12438                         pr_err("error %d\n", rc);
12439                         goto rw_error;
12440                 }
12441                 ext_attr->phase_correction_bypass = false;
12442                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12443                 ext_attr->enable_cvbs_output = true;
12444                 break;
12445         case DRX_STANDARD_PAL_SECAM_DK:
12446                 /* PAL/SECAM D/K */
12447                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_DK;
12448
12449                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12450                 if (rc != 0) {
12451                         pr_err("error %d\n", rc);
12452                         goto rw_error;
12453                 }       /* TODO check with IS */
12454                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12455                 if (rc != 0) {
12456                         pr_err("error %d\n", rc);
12457                         goto rw_error;
12458                 }
12459                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
12460                 if (rc != 0) {
12461                         pr_err("error %d\n", rc);
12462                         goto rw_error;
12463                 }
12464                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
12465                 if (rc != 0) {
12466                         pr_err("error %d\n", rc);
12467                         goto rw_error;
12468                 }
12469                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_DK, 0);
12470                 if (rc != 0) {
12471                         pr_err("error %d\n", rc);
12472                         goto rw_error;
12473                 }
12474                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_DK, 0);
12475                 if (rc != 0) {
12476                         pr_err("error %d\n", rc);
12477                         goto rw_error;
12478                 }
12479                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_DK | ATV_TOP_CR_CONT_CR_D_DK | ATV_TOP_CR_CONT_CR_I_DK), 0);
12480                 if (rc != 0) {
12481                         pr_err("error %d\n", rc);
12482                         goto rw_error;
12483                 }
12484                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_DK, 0);
12485                 if (rc != 0) {
12486                         pr_err("error %d\n", rc);
12487                         goto rw_error;
12488                 }
12489                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_DK | ATV_TOP_STD_VID_POL_DK), 0);
12490                 if (rc != 0) {
12491                         pr_err("error %d\n", rc);
12492                         goto rw_error;
12493                 }
12494                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
12495                 if (rc != 0) {
12496                         pr_err("error %d\n", rc);
12497                         goto rw_error;
12498                 }
12499                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12500                 if (rc != 0) {
12501                         pr_err("error %d\n", rc);
12502                         goto rw_error;
12503                 }
12504                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12505                 if (rc != 0) {
12506                         pr_err("error %d\n", rc);
12507                         goto rw_error;
12508                 }
12509                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_DK, 0);
12510                 if (rc != 0) {
12511                         pr_err("error %d\n", rc);
12512                         goto rw_error;
12513                 }
12514                 ext_attr->phase_correction_bypass = false;
12515                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12516                 ext_attr->enable_cvbs_output = true;
12517                 break;
12518         case DRX_STANDARD_PAL_SECAM_I:
12519                 /* PAL/SECAM I   */
12520                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_I;
12521
12522                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12523                 if (rc != 0) {
12524                         pr_err("error %d\n", rc);
12525                         goto rw_error;
12526                 }       /* TODO check with IS */
12527                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12528                 if (rc != 0) {
12529                         pr_err("error %d\n", rc);
12530                         goto rw_error;
12531                 }
12532                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
12533                 if (rc != 0) {
12534                         pr_err("error %d\n", rc);
12535                         goto rw_error;
12536                 }
12537                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
12538                 if (rc != 0) {
12539                         pr_err("error %d\n", rc);
12540                         goto rw_error;
12541                 }
12542                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_I, 0);
12543                 if (rc != 0) {
12544                         pr_err("error %d\n", rc);
12545                         goto rw_error;
12546                 }
12547                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_I, 0);
12548                 if (rc != 0) {
12549                         pr_err("error %d\n", rc);
12550                         goto rw_error;
12551                 }
12552                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_I | ATV_TOP_CR_CONT_CR_D_I | ATV_TOP_CR_CONT_CR_I_I), 0);
12553                 if (rc != 0) {
12554                         pr_err("error %d\n", rc);
12555                         goto rw_error;
12556                 }
12557                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_I, 0);
12558                 if (rc != 0) {
12559                         pr_err("error %d\n", rc);
12560                         goto rw_error;
12561                 }
12562                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_I | ATV_TOP_STD_VID_POL_I), 0);
12563                 if (rc != 0) {
12564                         pr_err("error %d\n", rc);
12565                         goto rw_error;
12566                 }
12567                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_FM | SCU_RAM_ATV_AGC_MODE_FAST_VAGC_EN_FAGC_ENABLE), 0);
12568                 if (rc != 0) {
12569                         pr_err("error %d\n", rc);
12570                         goto rw_error;
12571                 }
12572                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12573                 if (rc != 0) {
12574                         pr_err("error %d\n", rc);
12575                         goto rw_error;
12576                 }
12577                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12578                 if (rc != 0) {
12579                         pr_err("error %d\n", rc);
12580                         goto rw_error;
12581                 }
12582                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_I, 0);
12583                 if (rc != 0) {
12584                         pr_err("error %d\n", rc);
12585                         goto rw_error;
12586                 }
12587                 ext_attr->phase_correction_bypass = false;
12588                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12589                 ext_attr->enable_cvbs_output = true;
12590                 break;
12591         case DRX_STANDARD_PAL_SECAM_L:
12592                 /* PAL/SECAM L with negative modulation */
12593                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_L;
12594
12595                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12596                 if (rc != 0) {
12597                         pr_err("error %d\n", rc);
12598                         goto rw_error;
12599                 }       /* TODO check with IS */
12600                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_L, 0);
12601                 if (rc != 0) {
12602                         pr_err("error %d\n", rc);
12603                         goto rw_error;
12604                 }
12605                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12606                 if (rc != 0) {
12607                         pr_err("error %d\n", rc);
12608                         goto rw_error;
12609                 }
12610                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
12611                 if (rc != 0) {
12612                         pr_err("error %d\n", rc);
12613                         goto rw_error;
12614                 }
12615                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
12616                 if (rc != 0) {
12617                         pr_err("error %d\n", rc);
12618                         goto rw_error;
12619                 }
12620                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12621                 if (rc != 0) {
12622                         pr_err("error %d\n", rc);
12623                         goto rw_error;
12624                 }       /* TODO check with IS */
12625                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_L | ATV_TOP_CR_CONT_CR_D_L | ATV_TOP_CR_CONT_CR_I_L), 0);
12626                 if (rc != 0) {
12627                         pr_err("error %d\n", rc);
12628                         goto rw_error;
12629                 }
12630                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_L, 0);
12631                 if (rc != 0) {
12632                         pr_err("error %d\n", rc);
12633                         goto rw_error;
12634                 }
12635                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_L | ATV_TOP_STD_VID_POL_L), 0);
12636                 if (rc != 0) {
12637                         pr_err("error %d\n", rc);
12638                         goto rw_error;
12639                 }
12640                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM | SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE | SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW), 0);
12641                 if (rc != 0) {
12642                         pr_err("error %d\n", rc);
12643                         goto rw_error;
12644                 }
12645                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12646                 if (rc != 0) {
12647                         pr_err("error %d\n", rc);
12648                         goto rw_error;
12649                 }
12650                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12651                 if (rc != 0) {
12652                         pr_err("error %d\n", rc);
12653                         goto rw_error;
12654                 }
12655                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP, 0);
12656                 if (rc != 0) {
12657                         pr_err("error %d\n", rc);
12658                         goto rw_error;
12659                 }
12660                 ext_attr->phase_correction_bypass = false;
12661                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12662                 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12663                 ext_attr->enable_cvbs_output = true;
12664                 break;
12665         case DRX_STANDARD_PAL_SECAM_LP:
12666                 /* PAL/SECAM L with positive modulation */
12667                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_LP;
12668
12669                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_LP, 0);
12670                 if (rc != 0) {
12671                         pr_err("error %d\n", rc);
12672                         goto rw_error;
12673                 }
12674                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12675                 if (rc != 0) {
12676                         pr_err("error %d\n", rc);
12677                         goto rw_error;
12678                 }       /* TODO check with IS */
12679                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12680                 if (rc != 0) {
12681                         pr_err("error %d\n", rc);
12682                         goto rw_error;
12683                 }
12684                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(dk_i_l_lp_taps_re), ((u8 *)dk_i_l_lp_taps_re), 0);
12685                 if (rc != 0) {
12686                         pr_err("error %d\n", rc);
12687                         goto rw_error;
12688                 }
12689                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(dk_i_l_lp_taps_im), ((u8 *)dk_i_l_lp_taps_im), 0);
12690                 if (rc != 0) {
12691                         pr_err("error %d\n", rc);
12692                         goto rw_error;
12693                 }
12694                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12695                 if (rc != 0) {
12696                         pr_err("error %d\n", rc);
12697                         goto rw_error;
12698                 }       /* TODO check with IS */
12699                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, (ATV_TOP_CR_CONT_CR_P_LP | ATV_TOP_CR_CONT_CR_D_LP | ATV_TOP_CR_CONT_CR_I_LP), 0);
12700                 if (rc != 0) {
12701                         pr_err("error %d\n", rc);
12702                         goto rw_error;
12703                 }
12704                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_LP, 0);
12705                 if (rc != 0) {
12706                         pr_err("error %d\n", rc);
12707                         goto rw_error;
12708                 }
12709                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_LP | ATV_TOP_STD_VID_POL_LP), 0);
12710                 if (rc != 0) {
12711                         pr_err("error %d\n", rc);
12712                         goto rw_error;
12713                 }
12714                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AGC_MODE__A, (SCU_RAM_ATV_AGC_MODE_SIF_STD_SIF_AGC_AM | SCU_RAM_ATV_AGC_MODE_BP_EN_BPC_ENABLE | SCU_RAM_ATV_AGC_MODE_VAGC_VEL_AGC_SLOW), 0);
12715                 if (rc != 0) {
12716                         pr_err("error %d\n", rc);
12717                         goto rw_error;
12718                 }
12719                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12720                 if (rc != 0) {
12721                         pr_err("error %d\n", rc);
12722                         goto rw_error;
12723                 }
12724                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12725                 if (rc != 0) {
12726                         pr_err("error %d\n", rc);
12727                         goto rw_error;
12728                 }
12729                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX_REF__A, SCU_RAM_ATV_AMS_MAX_REF_AMS_MAX_REF_LLP, 0);
12730                 if (rc != 0) {
12731                         pr_err("error %d\n", rc);
12732                         goto rw_error;
12733                 }
12734                 ext_attr->phase_correction_bypass = false;
12735                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12736                 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12737                 ext_attr->enable_cvbs_output = true;
12738                 break;
12739         default:
12740                 return -EIO;
12741         }
12742
12743         /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
12744         if (!ext_attr->has_lna) {
12745                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x01, 0);
12746                 if (rc != 0) {
12747                         pr_err("error %d\n", rc);
12748                         goto rw_error;
12749                 }
12750         }
12751
12752         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_STANDARD__A, 0x002, 0);
12753         if (rc != 0) {
12754                 pr_err("error %d\n", rc);
12755                 goto rw_error;
12756         }
12757         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, IQM_AF_CLP_LEN_ATV, 0);
12758         if (rc != 0) {
12759                 pr_err("error %d\n", rc);
12760                 goto rw_error;
12761         }
12762         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, IQM_AF_CLP_TH_ATV, 0);
12763         if (rc != 0) {
12764                 pr_err("error %d\n", rc);
12765                 goto rw_error;
12766         }
12767         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, IQM_AF_SNS_LEN_ATV, 0);
12768         if (rc != 0) {
12769                 pr_err("error %d\n", rc);
12770                 goto rw_error;
12771         }
12772         rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12773         if (rc != 0) {
12774                 pr_err("error %d\n", rc);
12775                 goto rw_error;
12776         }
12777         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_IF__A, 10248, 0);
12778         if (rc != 0) {
12779                 pr_err("error %d\n", rc);
12780                 goto rw_error;
12781         }
12782
12783         ext_attr->iqm_rc_rate_ofs = 0x00200000L;
12784         rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
12785         if (rc != 0) {
12786                 pr_err("error %d\n", rc);
12787                 goto rw_error;
12788         }
12789         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_OFF, 0);
12790         if (rc != 0) {
12791                 pr_err("error %d\n", rc);
12792                 goto rw_error;
12793         }
12794         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, IQM_RC_STRETCH_ATV, 0);
12795         if (rc != 0) {
12796                 pr_err("error %d\n", rc);
12797                 goto rw_error;
12798         }
12799
12800         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ACTIVE__A, IQM_RT_ACTIVE_ACTIVE_RT_ATV_FCR_ON | IQM_RT_ACTIVE_ACTIVE_CR_ATV_CR_ON, 0);
12801         if (rc != 0) {
12802                 pr_err("error %d\n", rc);
12803                 goto rw_error;
12804         }
12805
12806         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_ATV__M, 0);
12807         if (rc != 0) {
12808                 pr_err("error %d\n", rc);
12809                 goto rw_error;
12810         }
12811         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, IQM_CF_SYMMETRIC_IM__M, 0);
12812         if (rc != 0) {
12813                 pr_err("error %d\n", rc);
12814                 goto rw_error;
12815         }
12816         /* default: SIF in standby */
12817         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_SYNC_SLICE__A, ATV_TOP_SYNC_SLICE_MN, 0);
12818         if (rc != 0) {
12819                 pr_err("error %d\n", rc);
12820                 goto rw_error;
12821         }
12822         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_ACCU__A, ATV_TOP_MOD_ACCU__PRE, 0);
12823         if (rc != 0) {
12824                 pr_err("error %d\n", rc);
12825                 goto rw_error;
12826         }
12827
12828         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, 0x080, 0);
12829         if (rc != 0) {
12830                 pr_err("error %d\n", rc);
12831                 goto rw_error;
12832         }
12833         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_FAGC_TH_RED__A, 10, 0);
12834         if (rc != 0) {
12835                 pr_err("error %d\n", rc);
12836                 goto rw_error;
12837         }
12838         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AAGC_CNT__A, 7, 0);
12839         if (rc != 0) {
12840                 pr_err("error %d\n", rc);
12841                 goto rw_error;
12842         }
12843         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_NAGC_KI_MIN__A, 0x0225, 0);
12844         if (rc != 0) {
12845                 pr_err("error %d\n", rc);
12846                 goto rw_error;
12847         }
12848         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_NAGC_KI_MAX__A, 0x0547, 0);
12849         if (rc != 0) {
12850                 pr_err("error %d\n", rc);
12851                 goto rw_error;
12852         }
12853         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_KI_CHANGE_TH__A, 20, 0);
12854         if (rc != 0) {
12855                 pr_err("error %d\n", rc);
12856                 goto rw_error;
12857         }
12858         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_LOCK__A, 0, 0);
12859         if (rc != 0) {
12860                 pr_err("error %d\n", rc);
12861                 goto rw_error;
12862         }
12863
12864         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_DELAY__A, IQM_RT_DELAY__PRE, 0);
12865         if (rc != 0) {
12866                 pr_err("error %d\n", rc);
12867                 goto rw_error;
12868         }
12869         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BPC_KI_MIN__A, 531, 0);
12870         if (rc != 0) {
12871                 pr_err("error %d\n", rc);
12872                 goto rw_error;
12873         }
12874         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061, 0);
12875         if (rc != 0) {
12876                 pr_err("error %d\n", rc);
12877                 goto rw_error;
12878         }
12879         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_REF_MIN__A, 100, 0);
12880         if (rc != 0) {
12881                 pr_err("error %d\n", rc);
12882                 goto rw_error;
12883         }
12884         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_REF_MAX__A, 260, 0);
12885         if (rc != 0) {
12886                 pr_err("error %d\n", rc);
12887                 goto rw_error;
12888         }
12889         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_LVL__A, 0, 0);
12890         if (rc != 0) {
12891                 pr_err("error %d\n", rc);
12892                 goto rw_error;
12893         }
12894         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX__A, 0, 0);
12895         if (rc != 0) {
12896                 pr_err("error %d\n", rc);
12897                 goto rw_error;
12898         }
12899         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MIN__A, 2047, 0);
12900         if (rc != 0) {
12901                 pr_err("error %d\n", rc);
12902                 goto rw_error;
12903         }
12904         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
12905         if (rc != 0) {
12906                 pr_err("error %d\n", rc);
12907                 goto rw_error;
12908         }
12909
12910         /* Override reset values with current shadow settings */
12911         rc = atv_update_config(demod, true);
12912         if (rc != 0) {
12913                 pr_err("error %d\n", rc);
12914                 goto rw_error;
12915         }
12916
12917         /* Configure/restore AGC settings */
12918         rc = init_agc(demod);
12919         if (rc != 0) {
12920                 pr_err("error %d\n", rc);
12921                 goto rw_error;
12922         }
12923         rc = set_agc_if(demod, &(ext_attr->atv_if_agc_cfg), false);
12924         if (rc != 0) {
12925                 pr_err("error %d\n", rc);
12926                 goto rw_error;
12927         }
12928         rc = set_agc_rf(demod, &(ext_attr->atv_rf_agc_cfg), false);
12929         if (rc != 0) {
12930                 pr_err("error %d\n", rc);
12931                 goto rw_error;
12932         }
12933         rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12934         if (rc != 0) {
12935                 pr_err("error %d\n", rc);
12936                 goto rw_error;
12937         }
12938
12939         /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
12940         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12941             SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
12942         cmd_scu.parameter_len = 1;
12943         cmd_scu.result_len = 1;
12944         cmd_scu.parameter = &cmd_param;
12945         cmd_scu.result = &cmd_result;
12946         rc = scu_command(dev_addr, &cmd_scu);
12947         if (rc != 0) {
12948                 pr_err("error %d\n", rc);
12949                 goto rw_error;
12950         }
12951
12952         /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
12953         if (ext_attr->mfx == 0x03) {
12954                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0, 0);
12955                 if (rc != 0) {
12956                         pr_err("error %d\n", rc);
12957                         goto rw_error;
12958                 }
12959         } else {
12960                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1, 0);
12961                 if (rc != 0) {
12962                         pr_err("error %d\n", rc);
12963                         goto rw_error;
12964                 }
12965                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_IIR_CRIT__A, 225, 0);
12966                 if (rc != 0) {
12967                         pr_err("error %d\n", rc);
12968                         goto rw_error;
12969                 }
12970         }
12971
12972         return 0;
12973 rw_error:
12974         return -EIO;
12975 }
12976 #endif
12977
12978 /* -------------------------------------------------------------------------- */
12979
12980 #ifndef DRXJ_DIGITAL_ONLY
12981 /**
12982 * \fn int set_atv_channel ()
12983 * \brief Set ATV channel.
12984 * \param demod:   instance of demod.
12985 * \return int.
12986 *
12987 * Not much needs to be done here, only start the SCU for NTSC/FM.
12988 * Mirrored channels are not expected in the RF domain, so IQM FS setting
12989 * doesn't need to be remembered.
12990 * The channel->mirror parameter is therefor ignored.
12991 *
12992 */
12993 static int
12994 set_atv_channel(struct drx_demod_instance *demod,
12995                 s32 tuner_freq_offset,
12996               struct drx_channel *channel, enum drx_standard standard)
12997 {
12998         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
12999                 /* parameter_len */ 0,
13000                 /* result_len    */ 0,
13001                 /* parameter    */ NULL,
13002                 /* result       */ NULL
13003         };
13004         u16 cmd_result = 0;
13005         struct drxj_data *ext_attr = NULL;
13006         struct i2c_device_addr *dev_addr = NULL;
13007         int rc;
13008
13009         dev_addr = demod->my_i2c_dev_addr;
13010         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13011
13012         /*
13013            Program frequency shifter
13014            No need to account for mirroring on RF
13015          */
13016         if (channel->mirror == DRX_MIRROR_AUTO)
13017                 ext_attr->mirror = DRX_MIRROR_NO;
13018         else
13019                 ext_attr->mirror = channel->mirror;
13020
13021         rc = set_frequency(demod, channel, tuner_freq_offset);
13022         if (rc != 0) {
13023                 pr_err("error %d\n", rc);
13024                 goto rw_error;
13025         }
13026         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE, 0);
13027         if (rc != 0) {
13028                 pr_err("error %d\n", rc);
13029                 goto rw_error;
13030         }
13031
13032         /* Start ATV SCU */
13033         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
13034             SCU_RAM_COMMAND_CMD_DEMOD_START;
13035         cmd_scu.parameter_len = 0;
13036         cmd_scu.result_len = 1;
13037         cmd_scu.parameter = NULL;
13038         cmd_scu.result = &cmd_result;
13039         rc = scu_command(dev_addr, &cmd_scu);
13040         if (rc != 0) {
13041                 pr_err("error %d\n", rc);
13042                 goto rw_error;
13043         }
13044
13045 /*   if ( (ext_attr->standard == DRX_STANDARD_FM) && (ext_attr->flagSetAUDdone == true) )
13046    {
13047       ext_attr->detectedRDS = (bool)false;
13048    }*/
13049
13050         return 0;
13051 rw_error:
13052         return -EIO;
13053 }
13054 #endif
13055
13056 /* -------------------------------------------------------------------------- */
13057
13058 /**
13059 * \fn int get_atv_channel ()
13060 * \brief Set ATV channel.
13061 * \param demod:   instance of demod.
13062 * \param channel: pointer to channel data.
13063 * \param standard: NTSC or FM.
13064 * \return int.
13065 *
13066 * Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
13067 * Computes the frequency offset in te RF domain and adds it to
13068 * channel->frequency. Determines the value for channel->bandwidth.
13069 *
13070 */
13071 #ifndef DRXJ_DIGITAL_ONLY
13072 static int
13073 get_atv_channel(struct drx_demod_instance *demod,
13074                 struct drx_channel *channel, enum drx_standard standard)
13075 {
13076         s32 offset = 0;
13077         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
13078         int rc;
13079
13080         /* Bandwidth */
13081         channel->bandwidth = ((struct drxj_data *) demod->my_ext_attr)->curr_bandwidth;
13082
13083         switch (standard) {
13084         case DRX_STANDARD_NTSC:
13085         case DRX_STANDARD_PAL_SECAM_BG:
13086         case DRX_STANDARD_PAL_SECAM_DK:
13087         case DRX_STANDARD_PAL_SECAM_I:
13088         case DRX_STANDARD_PAL_SECAM_L:
13089                 {
13090                         u16 measured_offset = 0;
13091
13092                         /* get measured frequency offset */
13093                         rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13094                         if (rc != 0) {
13095                                 pr_err("error %d\n", rc);
13096                                 goto rw_error;
13097                         }
13098                         /* Signed 8 bit register => sign extension needed */
13099                         if ((measured_offset & 0x0080) != 0)
13100                                 measured_offset |= 0xFF80;
13101                         offset +=
13102                             (s32) (((s16) measured_offset) * 10);
13103                         break;
13104                 }
13105         case DRX_STANDARD_PAL_SECAM_LP:
13106                 {
13107                         u16 measured_offset = 0;
13108
13109                         /* get measured frequency offset */
13110                         rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13111                         if (rc != 0) {
13112                                 pr_err("error %d\n", rc);
13113                                 goto rw_error;
13114                         }
13115                         /* Signed 8 bit register => sign extension needed */
13116                         if ((measured_offset & 0x0080) != 0)
13117                                 measured_offset |= 0xFF80;
13118                         offset -=
13119                             (s32) (((s16) measured_offset) * 10);
13120                 }
13121                 break;
13122         case DRX_STANDARD_FM:
13123                 /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
13124                    AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
13125                  */
13126                 /* No bandwidth know for FM */
13127                 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
13128                 break;
13129         default:
13130                 return -EIO;
13131         }
13132
13133         channel->frequency -= offset;
13134
13135         return 0;
13136 rw_error:
13137         return -EIO;
13138 }
13139
13140 /* -------------------------------------------------------------------------- */
13141 /**
13142 * \fn int get_atv_sig_strength()
13143 * \brief Retrieve signal strength for ATV & FM.
13144 * \param devmod Pointer to demodulator instance.
13145 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
13146 * \return int.
13147 * \retval 0 sig_strength contains valid data.
13148 * \retval -EIO Erroneous data, sig_strength equals 0.
13149 *
13150 * Taking into account:
13151 *  * digital gain
13152 *  * IF gain      (not implemented yet, waiting for IF gain control by ucode)
13153 *  * RF gain
13154 *
13155 * All weights (digital, if, rf) must add up to 100.
13156 *
13157 * TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
13158 *         is not used ?
13159 */
13160 static int
13161 get_atv_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
13162 {
13163         struct i2c_device_addr *dev_addr = NULL;
13164         struct drxj_data *ext_attr = NULL;
13165         int rc;
13166
13167         /* All weights must add up to 100 (%)
13168            TODO: change weights when IF ctrl is available */
13169         u32 digital_weight = 50;        /* 0 .. 100 */
13170         u32 rf_weight = 50;     /* 0 .. 100 */
13171         u32 if_weight = 0;      /* 0 .. 100 */
13172
13173         u16 digital_curr_gain = 0;
13174         u32 digital_max_gain = 0;
13175         u32 digital_min_gain = 0;
13176         u16 rf_curr_gain = 0;
13177         u32 rf_max_gain = 0x800;        /* taken from ucode */
13178         u32 rf_min_gain = 0x7fff;
13179         u16 if_curr_gain = 0;
13180         u32 if_max_gain = 0x800;        /* taken from ucode */
13181         u32 if_min_gain = 0x7fff;
13182
13183         u32 digital_strength = 0;       /* 0.. 100 */
13184         u32 rf_strength = 0;    /* 0.. 100 */
13185         u32 if_strength = 0;    /* 0.. 100 */
13186
13187         dev_addr = demod->my_i2c_dev_addr;
13188         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13189
13190         *sig_strength = 0;
13191
13192         switch (ext_attr->standard) {
13193         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13194         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13195         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
13196         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
13197         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
13198         case DRX_STANDARD_NTSC:
13199                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &digital_curr_gain, 0);
13200                 if (rc != 0) {
13201                         pr_err("error %d\n", rc);
13202                         goto rw_error;
13203                 }
13204                 digital_max_gain = 22512;       /* taken from ucode */
13205                 digital_min_gain = 2400;        /* taken from ucode */
13206                 break;
13207         case DRX_STANDARD_FM:
13208                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &digital_curr_gain, 0);
13209                 if (rc != 0) {
13210                         pr_err("error %d\n", rc);
13211                         goto rw_error;
13212                 }
13213                 digital_max_gain = 0x4ff;       /* taken from ucode */
13214                 digital_min_gain = 0;   /* taken from ucode */
13215                 break;
13216         default:
13217                 return -EIO;
13218                 break;
13219         }
13220         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &rf_curr_gain, 0);
13221         if (rc != 0) {
13222                 pr_err("error %d\n", rc);
13223                 goto rw_error;
13224         }
13225         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &if_curr_gain, 0);
13226         if (rc != 0) {
13227                 pr_err("error %d\n", rc);
13228                 goto rw_error;
13229         }
13230
13231         /* clipping */
13232         if (digital_curr_gain >= digital_max_gain)
13233                 digital_curr_gain = (u16)digital_max_gain;
13234         if (digital_curr_gain <= digital_min_gain)
13235                 digital_curr_gain = (u16)digital_min_gain;
13236         if (if_curr_gain <= if_max_gain)
13237                 if_curr_gain = (u16)if_max_gain;
13238         if (if_curr_gain >= if_min_gain)
13239                 if_curr_gain = (u16)if_min_gain;
13240         if (rf_curr_gain <= rf_max_gain)
13241                 rf_curr_gain = (u16)rf_max_gain;
13242         if (rf_curr_gain >= rf_min_gain)
13243                 rf_curr_gain = (u16)rf_min_gain;
13244
13245         /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
13246            of clipping at ADC */
13247
13248         /* Compute signal strength (in %) per "gain domain" */
13249
13250         /* Digital gain  */
13251         /* TODO: ADC clipping not handled */
13252         digital_strength = (100 * (digital_max_gain - (u32) digital_curr_gain)) /
13253             (digital_max_gain - digital_min_gain);
13254
13255         /* TODO: IF gain not implemented yet in microcode, check after impl. */
13256         if_strength = (100 * ((u32) if_curr_gain - if_max_gain)) /
13257             (if_min_gain - if_max_gain);
13258
13259         /* Rf gain */
13260         /* TODO: ADC clipping not handled */
13261         rf_strength = (100 * ((u32) rf_curr_gain - rf_max_gain)) /
13262             (rf_min_gain - rf_max_gain);
13263
13264         /* Compute a weighted signal strength (in %) */
13265         *sig_strength = (u16) (digital_weight * digital_strength +
13266                                 rf_weight * rf_strength + if_weight * if_strength);
13267         *sig_strength /= 100;
13268
13269         return 0;
13270 rw_error:
13271         return -EIO;
13272 }
13273
13274 /* -------------------------------------------------------------------------- */
13275 /**
13276 * \fn int atv_sig_quality()
13277 * \brief Retrieve signal quality indication for ATV.
13278 * \param devmod Pointer to demodulator instance.
13279 * \param sig_quality Pointer to signal quality structure.
13280 * \return int.
13281 * \retval 0 sig_quality contains valid data.
13282 * \retval -EIO Erroneous data, sig_quality indicator equals 0.
13283 *
13284 *
13285 */
13286 static int
13287 atv_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
13288 {
13289         struct i2c_device_addr *dev_addr = NULL;
13290         u16 quality_indicator = 0;
13291         int rc;
13292
13293         dev_addr = demod->my_i2c_dev_addr;
13294
13295         /* defined values for fields not used */
13296         sig_quality->MER = 0;
13297         sig_quality->pre_viterbi_ber = 0;
13298         sig_quality->post_viterbi_ber = 0;
13299         sig_quality->scale_factor_ber = 1;
13300         sig_quality->packet_error = 0;
13301         sig_quality->post_reed_solomon_ber = 0;
13302
13303         /*
13304            Mapping:
13305            0x000..0x080: strong signal  => 80% .. 100%
13306            0x080..0x700: weak signal    => 30% .. 80%
13307            0x700..0x7ff: no signal      => 0%  .. 30%
13308          */
13309
13310         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_CR_LOCK__A, &quality_indicator, 0);
13311         if (rc != 0) {
13312                 pr_err("error %d\n", rc);
13313                 goto rw_error;
13314         }
13315         quality_indicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
13316         if (quality_indicator <= 0x80) {
13317                 sig_quality->indicator =
13318                     80 + ((20 * (0x80 - quality_indicator)) / 0x80);
13319         } else if (quality_indicator <= 0x700)
13320                 sig_quality->indicator = 30 + ((50 * (0x700 - quality_indicator)) / (0x700 - 0x81));
13321         else
13322                 sig_quality->indicator = (30 * (0x7FF - quality_indicator)) / (0x7FF - 0x701);
13323
13324         return 0;
13325 rw_error:
13326         return -EIO;
13327 }
13328 #endif /* DRXJ_DIGITAL_ONLY */
13329
13330 /*============================================================================*/
13331 /*==                     END ATV DATAPATH FUNCTIONS                         ==*/
13332 /*============================================================================*/
13333
13334 #ifndef DRXJ_EXCLUDE_AUDIO
13335 /*===========================================================================*/
13336 /*===========================================================================*/
13337 /*==                      AUDIO DATAPATH FUNCTIONS                         ==*/
13338 /*===========================================================================*/
13339 /*===========================================================================*/
13340
13341 /*
13342 * \brief Power up AUD.
13343 * \param demod instance of demodulator
13344 * \return int.
13345 *
13346 */
13347 static int power_up_aud(struct drx_demod_instance *demod, bool set_standard)
13348 {
13349         enum drx_aud_standard aud_standard = DRX_AUD_STANDARD_AUTO;
13350         struct i2c_device_addr *dev_addr = NULL;
13351         int rc;
13352
13353         dev_addr = demod->my_i2c_dev_addr;
13354
13355         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE, 0);
13356         if (rc != 0) {
13357                 pr_err("error %d\n", rc);
13358                 goto rw_error;
13359         }
13360         /* setup TR interface: R/W mode, fifosize=8 */
13361         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_TOP_TR_MDE__A, 8, 0);
13362         if (rc != 0) {
13363                 pr_err("error %d\n", rc);
13364                 goto rw_error;
13365         }
13366         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE, 0);
13367         if (rc != 0) {
13368                 pr_err("error %d\n", rc);
13369                 goto rw_error;
13370         }
13371
13372         if (set_standard) {
13373                 rc = aud_ctrl_set_standard(demod, &aud_standard);
13374                 if (rc != 0) {
13375                         pr_err("error %d\n", rc);
13376                         goto rw_error;
13377                 }
13378         }
13379
13380         return 0;
13381 rw_error:
13382         return -EIO;
13383 }
13384
13385 /*============================================================================*/
13386
13387 /**
13388 * \brief Power up AUD.
13389 * \param demod instance of demodulator
13390 * \return int.
13391 *
13392 */
13393 static int power_down_aud(struct drx_demod_instance *demod)
13394 {
13395         struct i2c_device_addr *dev_addr = NULL;
13396         struct drxj_data *ext_attr = NULL;
13397         int rc;
13398
13399         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13400         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13401
13402         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
13403         if (rc != 0) {
13404                 pr_err("error %d\n", rc);
13405                 goto rw_error;
13406         }
13407
13408         ext_attr->aud_data.audio_is_active = false;
13409
13410         return 0;
13411 rw_error:
13412         return -EIO;
13413 }
13414
13415 /*============================================================================*/
13416 /**
13417 * \brief Get Modus data from audio RAM
13418 * \param demod instance of demodulator
13419 * \param pointer to modus
13420 * \return int.
13421 *
13422 */
13423 static int aud_get_modus(struct drx_demod_instance *demod, u16 *modus)
13424 {
13425         struct i2c_device_addr *dev_addr = NULL;
13426         struct drxj_data *ext_attr = NULL;
13427         int rc;
13428
13429         u16 r_modus = 0;
13430         u16 r_modus_hi = 0;
13431         u16 r_modus_lo = 0;
13432
13433         if (modus == NULL)
13434                 return -EINVAL;
13435
13436         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13437         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13438
13439         /* power up */
13440         if (ext_attr->aud_data.audio_is_active == false) {
13441                 rc = power_up_aud(demod, true);
13442                 if (rc != 0) {
13443                         pr_err("error %d\n", rc);
13444                         goto rw_error;
13445                 }
13446                 ext_attr->aud_data.audio_is_active = true;
13447         }
13448
13449         /* Modus register is combined in to RAM location */
13450         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_MODUS_HI__A, &r_modus_hi, 0);
13451         if (rc != 0) {
13452                 pr_err("error %d\n", rc);
13453                 goto rw_error;
13454         }
13455         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_MODUS_LO__A, &r_modus_lo, 0);
13456         if (rc != 0) {
13457                 pr_err("error %d\n", rc);
13458                 goto rw_error;
13459         }
13460
13461         r_modus = ((r_modus_hi << 12) & AUD_DEM_RAM_MODUS_HI__M)
13462             | (((r_modus_lo & AUD_DEM_RAM_MODUS_LO__M)));
13463
13464         *modus = r_modus;
13465
13466         return 0;
13467 rw_error:
13468         return -EIO;
13469
13470 }
13471
13472 /*============================================================================*/
13473 /**
13474 * \brief Get audio RDS dat
13475 * \param demod instance of demodulator
13476 * \param pointer to struct drx_cfg_aud_rds * \return int.
13477 *
13478 */
13479 static int
13480 aud_ctrl_get_cfg_rds(struct drx_demod_instance *demod, struct drx_cfg_aud_rds *status)
13481 {
13482         struct i2c_device_addr *addr = NULL;
13483         struct drxj_data *ext_attr = NULL;
13484         int rc;
13485
13486         u16 r_rds_array_cnt_init = 0;
13487         u16 r_rds_array_cnt_check = 0;
13488         u16 r_rds_data = 0;
13489         u16 rds_data_cnt = 0;
13490
13491         addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13492         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13493
13494         if (status == NULL)
13495                 return -EINVAL;
13496
13497         /* power up */
13498         if (ext_attr->aud_data.audio_is_active == false) {
13499                 rc = power_up_aud(demod, true);
13500                 if (rc != 0) {
13501                         pr_err("error %d\n", rc);
13502                         goto rw_error;
13503                 }
13504                 ext_attr->aud_data.audio_is_active = true;
13505         }
13506
13507         status->valid = false;
13508
13509         rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_init, 0);
13510         if (rc != 0) {
13511                 pr_err("error %d\n", rc);
13512                 goto rw_error;
13513         }
13514
13515         if (r_rds_array_cnt_init ==
13516             AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID) {
13517                 /* invalid data */
13518                 return 0;
13519         }
13520
13521         if (ext_attr->aud_data.rds_data_counter == r_rds_array_cnt_init) {
13522                 /* no new data */
13523                 return 0;
13524         }
13525
13526         /* RDS is detected, as long as FM radio is selected assume
13527            RDS will be available                                    */
13528         ext_attr->aud_data.rds_data_present = true;
13529
13530         /* new data */
13531         /* read the data */
13532         for (rds_data_cnt = 0; rds_data_cnt < AUD_RDS_ARRAY_SIZE; rds_data_cnt++) {
13533                 rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_DATA__A, &r_rds_data, 0);
13534                 if (rc != 0) {
13535                         pr_err("error %d\n", rc);
13536                         goto rw_error;
13537                 }
13538                 status->data[rds_data_cnt] = r_rds_data;
13539         }
13540
13541         rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_check, 0);
13542         if (rc != 0) {
13543                 pr_err("error %d\n", rc);
13544                 goto rw_error;
13545         }
13546
13547         if (r_rds_array_cnt_check == r_rds_array_cnt_init) {
13548                 status->valid = true;
13549                 ext_attr->aud_data.rds_data_counter = r_rds_array_cnt_check;
13550         }
13551
13552         return 0;
13553 rw_error:
13554         return -EIO;
13555 }
13556
13557 /*============================================================================*/
13558 /**
13559 * \brief Get the current audio carrier detection status
13560 * \param demod instance of demodulator
13561 * \param pointer to aud_ctrl_get_status
13562 * \return int.
13563 *
13564 */
13565 static int
13566 aud_ctrl_get_carrier_detect_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13567 {
13568         struct drxj_data *ext_attr = NULL;
13569         struct i2c_device_addr *dev_addr = NULL;
13570         int rc;
13571         u16 r_data = 0;
13572
13573         if (status == NULL)
13574                 return -EINVAL;
13575
13576         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13577         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13578
13579         /* power up */
13580         if (ext_attr->aud_data.audio_is_active == false) {
13581                 rc = power_up_aud(demod, true);
13582                 if (rc != 0) {
13583                         pr_err("error %d\n", rc);
13584                         goto rw_error;
13585                 }
13586                 ext_attr->aud_data.audio_is_active = true;
13587         }
13588
13589         /* initialize the variables */
13590         status->carrier_a = false;
13591         status->carrier_b = false;
13592         status->nicam_status = DRX_AUD_NICAM_NOT_DETECTED;
13593         status->sap = false;
13594         status->stereo = false;
13595
13596         /* read stereo sound mode indication */
13597         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RD_STATUS__A, &r_data, 0);
13598         if (rc != 0) {
13599                 pr_err("error %d\n", rc);
13600                 goto rw_error;
13601         }
13602
13603         /* carrier a detected */
13604         if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_A__M) == AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED)
13605                 status->carrier_a = true;
13606
13607         /* carrier b detected */
13608         if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_B__M) == AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED)
13609                 status->carrier_b = true;
13610         /* nicam detected */
13611         if ((r_data & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
13612             AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED) {
13613                 if ((r_data & AUD_DEM_RD_STATUS_BAD_NICAM__M) == AUD_DEM_RD_STATUS_BAD_NICAM_OK)
13614                         status->nicam_status = DRX_AUD_NICAM_DETECTED;
13615                 else
13616                         status->nicam_status = DRX_AUD_NICAM_BAD;
13617         }
13618
13619         /* audio mode bilingual or SAP detected */
13620         if ((r_data & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) == AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP)
13621                 status->sap = true;
13622
13623         /* stereo detected */
13624         if ((r_data & AUD_DEM_RD_STATUS_STAT_STEREO__M) == AUD_DEM_RD_STATUS_STAT_STEREO_STEREO)
13625                 status->stereo = true;
13626
13627         return 0;
13628 rw_error:
13629         return -EIO;
13630 }
13631
13632 /*============================================================================*/
13633 /**
13634 * \brief Get the current audio status parameters
13635 * \param demod instance of demodulator
13636 * \param pointer to aud_ctrl_get_status
13637 * \return int.
13638 *
13639 */
13640 static int
13641 aud_ctrl_get_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13642 {
13643         struct drxj_data *ext_attr = NULL;
13644         struct i2c_device_addr *dev_addr = NULL;
13645         struct drx_cfg_aud_rds rds = { false, {0} };
13646         int rc;
13647         u16 r_data = 0;
13648
13649         if (status == NULL)
13650                 return -EINVAL;
13651
13652         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13653         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13654
13655         /* carrier detection */
13656         rc = aud_ctrl_get_carrier_detect_status(demod, status);
13657         if (rc != 0) {
13658                 pr_err("error %d\n", rc);
13659                 goto rw_error;
13660         }
13661
13662         /* rds data */
13663         status->rds = false;
13664         rc = aud_ctrl_get_cfg_rds(demod, &rds);
13665         if (rc != 0) {
13666                 pr_err("error %d\n", rc);
13667                 goto rw_error;
13668         }
13669         status->rds = ext_attr->aud_data.rds_data_present;
13670
13671         /* fm_ident */
13672         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_IDENT_VALUE__A, &r_data, 0);
13673         if (rc != 0) {
13674                 pr_err("error %d\n", rc);
13675                 goto rw_error;
13676         }
13677         r_data >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
13678         status->fm_ident = (s8) r_data;
13679
13680         return 0;
13681 rw_error:
13682         return -EIO;
13683 }
13684
13685 /*============================================================================*/
13686 /**
13687 * \brief Get the current volume settings
13688 * \param demod instance of demodulator
13689 * \param pointer to struct drx_cfg_aud_volume * \return int.
13690 *
13691 */
13692 static int
13693 aud_ctrl_get_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13694 {
13695         struct i2c_device_addr *dev_addr = NULL;
13696         struct drxj_data *ext_attr = NULL;
13697         int rc;
13698
13699         u16 r_volume = 0;
13700         u16 r_avc = 0;
13701         u16 r_strength_left = 0;
13702         u16 r_strength_right = 0;
13703
13704         if (volume == NULL)
13705                 return -EINVAL;
13706
13707         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13708         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13709
13710         /* power up */
13711         if (ext_attr->aud_data.audio_is_active == false) {
13712                 rc = power_up_aud(demod, true);
13713                 if (rc != 0) {
13714                         pr_err("error %d\n", rc);
13715                         goto rw_error;
13716                 }
13717                 ext_attr->aud_data.audio_is_active = true;
13718         }
13719
13720         /* volume */
13721         volume->mute = ext_attr->aud_data.volume.mute;
13722         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, &r_volume, 0);
13723         if (rc != 0) {
13724                 pr_err("error %d\n", rc);
13725                 goto rw_error;
13726         }
13727         if (r_volume == 0) {
13728                 volume->mute = true;
13729                 volume->volume = ext_attr->aud_data.volume.volume;
13730         } else {
13731                 volume->mute = false;
13732                 volume->volume = ((r_volume & AUD_DSP_WR_VOLUME_VOL_MAIN__M) >>
13733                                   AUD_DSP_WR_VOLUME_VOL_MAIN__B) -
13734                     AUD_VOLUME_ZERO_DB;
13735                 if (volume->volume < AUD_VOLUME_DB_MIN)
13736                         volume->volume = AUD_VOLUME_DB_MIN;
13737                 if (volume->volume > AUD_VOLUME_DB_MAX)
13738                         volume->volume = AUD_VOLUME_DB_MAX;
13739         }
13740
13741         /* automatic volume control */
13742         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AVC__A, &r_avc, 0);
13743         if (rc != 0) {
13744                 pr_err("error %d\n", rc);
13745                 goto rw_error;
13746         }
13747
13748         if ((r_avc & AUD_DSP_WR_AVC_AVC_ON__M) == AUD_DSP_WR_AVC_AVC_ON_OFF) {
13749                 volume->avc_mode = DRX_AUD_AVC_OFF;
13750         } else {
13751                 switch (r_avc & AUD_DSP_WR_AVC_AVC_DECAY__M) {
13752                 case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
13753                         volume->avc_mode = DRX_AUD_AVC_DECAYTIME_20MS;
13754                         break;
13755                 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
13756                         volume->avc_mode = DRX_AUD_AVC_DECAYTIME_8S;
13757                         break;
13758                 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
13759                         volume->avc_mode = DRX_AUD_AVC_DECAYTIME_4S;
13760                         break;
13761                 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
13762                         volume->avc_mode = DRX_AUD_AVC_DECAYTIME_2S;
13763                         break;
13764                 default:
13765                         return -EIO;
13766                         break;
13767                 }
13768         }
13769
13770         /* max attenuation */
13771         switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_ATT__M) {
13772         case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
13773                 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_12DB;
13774                 break;
13775         case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
13776                 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_18DB;
13777                 break;
13778         case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
13779                 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_24DB;
13780                 break;
13781         default:
13782                 return -EIO;
13783                 break;
13784         }
13785
13786         /* max gain */
13787         switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M) {
13788         case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
13789                 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_0DB;
13790                 break;
13791         case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
13792                 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_6DB;
13793                 break;
13794         case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
13795                 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_12DB;
13796                 break;
13797         default:
13798                 return -EIO;
13799                 break;
13800         }
13801
13802         /* reference level */
13803         volume->avc_ref_level = (u16) ((r_avc & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
13804                                        AUD_DSP_WR_AVC_AVC_REF_LEV__B);
13805
13806         /* read qpeak registers and calculate strength of left and right carrier */
13807         /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
13808         /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
13809         /* left carrier */
13810
13811         /* QP vaues */
13812         /* left carrier */
13813         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_QPEAK_L__A, &r_strength_left, 0);
13814         if (rc != 0) {
13815                 pr_err("error %d\n", rc);
13816                 goto rw_error;
13817         }
13818         volume->strength_left = (((s16) log1_times100(r_strength_left)) -
13819                                 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
13820
13821         /* right carrier */
13822         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_QPEAK_R__A, &r_strength_right, 0);
13823         if (rc != 0) {
13824                 pr_err("error %d\n", rc);
13825                 goto rw_error;
13826         }
13827         volume->strength_right = (((s16) log1_times100(r_strength_right)) -
13828                                  AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
13829
13830         return 0;
13831 rw_error:
13832         return -EIO;
13833 }
13834
13835 /*============================================================================*/
13836 /**
13837 * \brief Set the current volume settings
13838 * \param demod instance of demodulator
13839 * \param pointer to struct drx_cfg_aud_volume * \return int.
13840 *
13841 */
13842 static int
13843 aud_ctrl_set_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13844 {
13845         struct i2c_device_addr *dev_addr = NULL;
13846         struct drxj_data *ext_attr = NULL;
13847         int rc;
13848
13849         u16 w_volume = 0;
13850         u16 w_avc = 0;
13851
13852         if (volume == NULL)
13853                 return -EINVAL;
13854
13855         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13856         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13857
13858         /* power up */
13859         if (ext_attr->aud_data.audio_is_active == false) {
13860                 rc = power_up_aud(demod, true);
13861                 if (rc != 0) {
13862                         pr_err("error %d\n", rc);
13863                         goto rw_error;
13864                 }
13865                 ext_attr->aud_data.audio_is_active = true;
13866         }
13867
13868         /* volume */
13869         /* volume range from -60 to 12 (expressed in dB) */
13870         if ((volume->volume < AUD_VOLUME_DB_MIN) ||
13871             (volume->volume > AUD_VOLUME_DB_MAX))
13872                 return -EINVAL;
13873
13874         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, &w_volume, 0);
13875         if (rc != 0) {
13876                 pr_err("error %d\n", rc);
13877                 goto rw_error;
13878         }
13879
13880         /* clear the volume mask */
13881         w_volume &= (u16) ~AUD_DSP_WR_VOLUME_VOL_MAIN__M;
13882         if (volume->mute == true)
13883                 w_volume |= (u16)(0);
13884         else
13885                 w_volume |= (u16)((volume->volume + AUD_VOLUME_ZERO_DB) << AUD_DSP_WR_VOLUME_VOL_MAIN__B);
13886
13887         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
13888         if (rc != 0) {
13889                 pr_err("error %d\n", rc);
13890                 goto rw_error;
13891         }
13892
13893         /* automatic volume control */
13894         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AVC__A, &w_avc, 0);
13895         if (rc != 0) {
13896                 pr_err("error %d\n", rc);
13897                 goto rw_error;
13898         }
13899
13900         /* clear masks that require writing */
13901         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_ON__M;
13902         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_DECAY__M;
13903
13904         if (volume->avc_mode == DRX_AUD_AVC_OFF) {
13905                 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_OFF);
13906         } else {
13907
13908                 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_ON);
13909
13910                 /* avc decay */
13911                 switch (volume->avc_mode) {
13912                 case DRX_AUD_AVC_DECAYTIME_20MS:
13913                         w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
13914                         break;
13915                 case DRX_AUD_AVC_DECAYTIME_8S:
13916                         w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
13917                         break;
13918                 case DRX_AUD_AVC_DECAYTIME_4S:
13919                         w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
13920                         break;
13921                 case DRX_AUD_AVC_DECAYTIME_2S:
13922                         w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
13923                         break;
13924                 default:
13925                         return -EINVAL;
13926                 }
13927         }
13928
13929         /* max attenuation */
13930         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
13931         switch (volume->avc_max_atten) {
13932         case DRX_AUD_AVC_MAX_ATTEN_12DB:
13933                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
13934                 break;
13935         case DRX_AUD_AVC_MAX_ATTEN_18DB:
13936                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
13937                 break;
13938         case DRX_AUD_AVC_MAX_ATTEN_24DB:
13939                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
13940                 break;
13941         default:
13942                 return -EINVAL;
13943         }
13944
13945         /* max gain */
13946         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
13947         switch (volume->avc_max_gain) {
13948         case DRX_AUD_AVC_MAX_GAIN_0DB:
13949                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
13950                 break;
13951         case DRX_AUD_AVC_MAX_GAIN_6DB:
13952                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
13953                 break;
13954         case DRX_AUD_AVC_MAX_GAIN_12DB:
13955                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
13956                 break;
13957         default:
13958                 return -EINVAL;
13959         }
13960
13961         /* avc reference level */
13962         if (volume->avc_ref_level > AUD_MAX_AVC_REF_LEVEL)
13963                 return -EINVAL;
13964
13965         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_REF_LEV__M;
13966         w_avc |= (u16) (volume->avc_ref_level << AUD_DSP_WR_AVC_AVC_REF_LEV__B);
13967
13968         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_AVC__A, w_avc, 0);
13969         if (rc != 0) {
13970                 pr_err("error %d\n", rc);
13971                 goto rw_error;
13972         }
13973
13974         /* all done, store config in data structure */
13975         ext_attr->aud_data.volume = *volume;
13976
13977         return 0;
13978 rw_error:
13979         return -EIO;
13980 }
13981
13982 /*============================================================================*/
13983 /**
13984 * \brief Get the I2S settings
13985 * \param demod instance of demodulator
13986 * \param pointer to struct drx_cfg_i2s_output * \return int.
13987 *
13988 */
13989 static int
13990 aud_ctrl_get_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
13991 {
13992         struct i2c_device_addr *dev_addr = NULL;
13993         struct drxj_data *ext_attr = NULL;
13994         int rc;
13995         u16 w_i2s_config = 0;
13996         u16 r_i2s_freq = 0;
13997
13998         if (output == NULL)
13999                 return -EINVAL;
14000
14001         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14002         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14003
14004         /* power up */
14005         if (ext_attr->aud_data.audio_is_active == false) {
14006                 rc = power_up_aud(demod, true);
14007                 if (rc != 0) {
14008                         pr_err("error %d\n", rc);
14009                         goto rw_error;
14010                 }
14011                 ext_attr->aud_data.audio_is_active = true;
14012         }
14013
14014         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14015         if (rc != 0) {
14016                 pr_err("error %d\n", rc);
14017                 goto rw_error;
14018         }
14019         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, &r_i2s_freq, 0);
14020         if (rc != 0) {
14021                 pr_err("error %d\n", rc);
14022                 goto rw_error;
14023         }
14024
14025         /* I2S mode */
14026         switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M) {
14027         case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
14028                 output->mode = DRX_I2S_MODE_MASTER;
14029                 break;
14030         case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
14031                 output->mode = DRX_I2S_MODE_SLAVE;
14032                 break;
14033         default:
14034                 return -EIO;
14035         }
14036
14037         /* I2S format */
14038         switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M) {
14039         case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
14040                 output->format = DRX_I2S_FORMAT_WS_ADVANCED;
14041                 break;
14042         case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
14043                 output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
14044                 break;
14045         default:
14046                 return -EIO;
14047         }
14048
14049         /* I2S word length */
14050         switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M) {
14051         case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
14052                 output->word_length = DRX_I2S_WORDLENGTH_16;
14053                 break;
14054         case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
14055                 output->word_length = DRX_I2S_WORDLENGTH_32;
14056                 break;
14057         default:
14058                 return -EIO;
14059         }
14060
14061         /* I2S polarity */
14062         switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M) {
14063         case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
14064                 output->polarity = DRX_I2S_POLARITY_LEFT;
14065                 break;
14066         case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
14067                 output->polarity = DRX_I2S_POLARITY_RIGHT;
14068                 break;
14069         default:
14070                 return -EIO;
14071         }
14072
14073         /* I2S output enabled */
14074         if ((w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M) == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE)
14075                 output->output_enable = true;
14076         else
14077                 output->output_enable = false;
14078
14079         if (r_i2s_freq > 0) {
14080                 output->frequency = 6144UL * 48000 / r_i2s_freq;
14081                 if (output->word_length == DRX_I2S_WORDLENGTH_16)
14082                         output->frequency *= 2;
14083         } else {
14084                 output->frequency = AUD_I2S_FREQUENCY_MAX;
14085         }
14086
14087         return 0;
14088 rw_error:
14089         return -EIO;
14090 }
14091
14092 /*============================================================================*/
14093 /**
14094 * \brief Set the I2S settings
14095 * \param demod instance of demodulator
14096 * \param pointer to struct drx_cfg_i2s_output * \return int.
14097 *
14098 */
14099 static int
14100 aud_ctrl_set_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
14101 {
14102         struct i2c_device_addr *dev_addr = NULL;
14103         struct drxj_data *ext_attr = NULL;
14104         int rc;
14105         u16 w_i2s_config = 0;
14106         u16 w_i2s_pads_data_da = 0;
14107         u16 w_i2s_pads_data_cl = 0;
14108         u16 w_i2s_pads_data_ws = 0;
14109         u32 w_i2s_freq = 0;
14110
14111         if (output == NULL)
14112                 return -EINVAL;
14113
14114         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14115         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14116
14117         /* power up */
14118         if (ext_attr->aud_data.audio_is_active == false) {
14119                 rc = power_up_aud(demod, true);
14120                 if (rc != 0) {
14121                         pr_err("error %d\n", rc);
14122                         goto rw_error;
14123                 }
14124                 ext_attr->aud_data.audio_is_active = true;
14125         }
14126
14127         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14128         if (rc != 0) {
14129                 pr_err("error %d\n", rc);
14130                 goto rw_error;
14131         }
14132
14133         /* I2S mode */
14134         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
14135
14136         switch (output->mode) {
14137         case DRX_I2S_MODE_MASTER:
14138                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
14139                 break;
14140         case DRX_I2S_MODE_SLAVE:
14141                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
14142                 break;
14143         default:
14144                 return -EINVAL;
14145         }
14146
14147         /* I2S format */
14148         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
14149
14150         switch (output->format) {
14151         case DRX_I2S_FORMAT_WS_ADVANCED:
14152                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
14153                 break;
14154         case DRX_I2S_FORMAT_WS_WITH_DATA:
14155                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
14156                 break;
14157         default:
14158                 return -EINVAL;
14159         }
14160
14161         /* I2S word length */
14162         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
14163
14164         switch (output->word_length) {
14165         case DRX_I2S_WORDLENGTH_16:
14166                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
14167                 break;
14168         case DRX_I2S_WORDLENGTH_32:
14169                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
14170                 break;
14171         default:
14172                 return -EINVAL;
14173         }
14174
14175         /* I2S polarity */
14176         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
14177         switch (output->polarity) {
14178         case DRX_I2S_POLARITY_LEFT:
14179                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
14180                 break;
14181         case DRX_I2S_POLARITY_RIGHT:
14182                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
14183                 break;
14184         default:
14185                 return -EINVAL;
14186         }
14187
14188         /* I2S output enabled */
14189         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
14190         if (output->output_enable == true)
14191                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
14192         else
14193                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
14194
14195         /*
14196            I2S frequency
14197
14198            w_i2s_freq = 6144 * 48000 * nrbits / ( 32 * frequency )
14199
14200            16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
14201            32bit: 6144 * 48000 / freq         = ( 6144 * 48000 / freq )
14202          */
14203         if ((output->frequency > AUD_I2S_FREQUENCY_MAX) ||
14204             output->frequency < AUD_I2S_FREQUENCY_MIN) {
14205                 return -EINVAL;
14206         }
14207
14208         w_i2s_freq = (6144UL * 48000UL) + (output->frequency >> 1);
14209         w_i2s_freq /= output->frequency;
14210
14211         if (output->word_length == DRX_I2S_WORDLENGTH_16)
14212                 w_i2s_freq *= 2;
14213
14214         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_I2S_CONFIG2__A, w_i2s_config, 0);
14215         if (rc != 0) {
14216                 pr_err("error %d\n", rc);
14217                 goto rw_error;
14218         }
14219         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, (u16)w_i2s_freq, 0);
14220         if (rc != 0) {
14221                 pr_err("error %d\n", rc);
14222                 goto rw_error;
14223         }
14224
14225         /* configure I2S output pads for master or slave mode */
14226         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
14227         if (rc != 0) {
14228                 pr_err("error %d\n", rc);
14229                 goto rw_error;
14230         }
14231
14232         if (output->mode == DRX_I2S_MODE_MASTER) {
14233                 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
14234                     SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
14235                 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
14236                     SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
14237                 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
14238                     SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
14239         } else {
14240                 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
14241                     SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
14242                 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
14243                     SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
14244                 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
14245                     SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
14246         }
14247
14248         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_DA_CFG__A, w_i2s_pads_data_da, 0);
14249         if (rc != 0) {
14250                 pr_err("error %d\n", rc);
14251                 goto rw_error;
14252         }
14253         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_CL_CFG__A, w_i2s_pads_data_cl, 0);
14254         if (rc != 0) {
14255                 pr_err("error %d\n", rc);
14256                 goto rw_error;
14257         }
14258         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_WS_CFG__A, w_i2s_pads_data_ws, 0);
14259         if (rc != 0) {
14260                 pr_err("error %d\n", rc);
14261                 goto rw_error;
14262         }
14263
14264         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
14265         if (rc != 0) {
14266                 pr_err("error %d\n", rc);
14267                 goto rw_error;
14268         }
14269
14270         /* all done, store config in data structure */
14271         ext_attr->aud_data.i2sdata = *output;
14272
14273         return 0;
14274 rw_error:
14275         return -EIO;
14276 }
14277
14278 /*============================================================================*/
14279 /**
14280 * \brief Get the Automatic Standard Select (ASS)
14281 *        and Automatic Sound Change (ASC)
14282 * \param demod instance of demodulator
14283 * \param pointer to pDRXAudAutoSound_t
14284 * \return int.
14285 *
14286 */
14287 static int
14288 aud_ctrl_get_cfg_auto_sound(struct drx_demod_instance *demod,
14289                             enum drx_cfg_aud_auto_sound *auto_sound)
14290 {
14291         struct drxj_data *ext_attr = NULL;
14292         int rc;
14293         u16 r_modus = 0;
14294
14295         if (auto_sound == NULL)
14296                 return -EINVAL;
14297
14298         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14299
14300         /* power up */
14301         if (ext_attr->aud_data.audio_is_active == false) {
14302                 rc = power_up_aud(demod, true);
14303                 if (rc != 0) {
14304                         pr_err("error %d\n", rc);
14305                         goto rw_error;
14306                 }
14307                 ext_attr->aud_data.audio_is_active = true;
14308         }
14309
14310         rc = aud_get_modus(demod, &r_modus);
14311         if (rc != 0) {
14312                 pr_err("error %d\n", rc);
14313                 goto rw_error;
14314         }
14315
14316         switch (r_modus & (AUD_DEM_WR_MODUS_MOD_ASS__M |
14317                           AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M)) {
14318         case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14319         case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14320                 *auto_sound =
14321                     DRX_AUD_AUTO_SOUND_OFF;
14322                 break;
14323         case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14324                 *auto_sound =
14325                     DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
14326                 break;
14327         case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14328                 *auto_sound =
14329                     DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
14330                 break;
14331         default:
14332                 return -EIO;
14333         }
14334
14335         return 0;
14336 rw_error:
14337         return -EIO;
14338 }
14339
14340 /*============================================================================*/
14341 /**
14342 * \brief Set the Automatic Standard Select (ASS)
14343 *        and Automatic Sound Change (ASC)
14344 * \param demod instance of demodulator
14345 * \param pointer to pDRXAudAutoSound_t
14346 * \return int.
14347 *
14348 */
14349 static int
14350 aud_ctr_setl_cfg_auto_sound(struct drx_demod_instance *demod,
14351                             enum drx_cfg_aud_auto_sound *auto_sound)
14352 {
14353         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14354         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14355         int rc;
14356         u16 r_modus = 0;
14357         u16 w_modus = 0;
14358
14359         if (auto_sound == NULL)
14360                 return -EINVAL;
14361
14362         dev_addr = demod->my_i2c_dev_addr;
14363         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14364
14365         /* power up */
14366         if (ext_attr->aud_data.audio_is_active == false) {
14367                 rc = power_up_aud(demod, true);
14368                 if (rc != 0) {
14369                         pr_err("error %d\n", rc);
14370                         goto rw_error;
14371                 }
14372                 ext_attr->aud_data.audio_is_active = true;
14373         }
14374
14375         rc = aud_get_modus(demod, &r_modus);
14376         if (rc != 0) {
14377                 pr_err("error %d\n", rc);
14378                 goto rw_error;
14379         }
14380
14381         w_modus = r_modus;
14382         /* clear ASS & ASC bits */
14383         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_ASS__M;
14384         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
14385
14386         switch (*auto_sound) {
14387         case DRX_AUD_AUTO_SOUND_OFF:
14388                 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
14389                 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14390                 break;
14391         case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
14392                 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14393                 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
14394                 break;
14395         case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
14396                 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14397                 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14398                 break;
14399         default:
14400                 return -EINVAL;
14401         }
14402
14403         if (w_modus != r_modus) {
14404                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14405                 if (rc != 0) {
14406                         pr_err("error %d\n", rc);
14407                         goto rw_error;
14408                 }
14409         }
14410         /* copy to data structure */
14411         ext_attr->aud_data.auto_sound = *auto_sound;
14412
14413         return 0;
14414 rw_error:
14415         return -EIO;
14416 }
14417
14418 /*============================================================================*/
14419 /**
14420 * \brief Get the Automatic Standard Select thresholds
14421 * \param demod instance of demodulator
14422 * \param pointer to pDRXAudASSThres_t
14423 * \return int.
14424 *
14425 */
14426 static int
14427 aud_ctrl_get_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14428 {
14429         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14430         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14431         int rc;
14432         u16 thres_a2 = 0;
14433         u16 thres_btsc = 0;
14434         u16 thres_nicam = 0;
14435
14436         if (thres == NULL)
14437                 return -EINVAL;
14438
14439         dev_addr = demod->my_i2c_dev_addr;
14440         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14441
14442         /* power up */
14443         if (ext_attr->aud_data.audio_is_active == false) {
14444                 rc = power_up_aud(demod, true);
14445                 if (rc != 0) {
14446                         pr_err("error %d\n", rc);
14447                         goto rw_error;
14448                 }
14449                 ext_attr->aud_data.audio_is_active = true;
14450         }
14451
14452         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_A2_THRSHLD__A, &thres_a2, 0);
14453         if (rc != 0) {
14454                 pr_err("error %d\n", rc);
14455                 goto rw_error;
14456         }
14457         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_BTSC_THRSHLD__A, &thres_btsc, 0);
14458         if (rc != 0) {
14459                 pr_err("error %d\n", rc);
14460                 goto rw_error;
14461         }
14462         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_NICAM_THRSHLD__A, &thres_nicam, 0);
14463         if (rc != 0) {
14464                 pr_err("error %d\n", rc);
14465                 goto rw_error;
14466         }
14467
14468         thres->a2 = thres_a2;
14469         thres->btsc = thres_btsc;
14470         thres->nicam = thres_nicam;
14471
14472         return 0;
14473 rw_error:
14474         return -EIO;
14475 }
14476
14477 /*============================================================================*/
14478 /**
14479 * \brief Get the Automatic Standard Select thresholds
14480 * \param demod instance of demodulator
14481 * \param pointer to pDRXAudASSThres_t
14482 * \return int.
14483 *
14484 */
14485 static int
14486 aud_ctrl_set_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14487 {
14488         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14489         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14490         int rc;
14491         if (thres == NULL)
14492                 return -EINVAL;
14493
14494         dev_addr = demod->my_i2c_dev_addr;
14495         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14496
14497         /* power up */
14498         if (ext_attr->aud_data.audio_is_active == false) {
14499                 rc = power_up_aud(demod, true);
14500                 if (rc != 0) {
14501                         pr_err("error %d\n", rc);
14502                         goto rw_error;
14503                 }
14504                 ext_attr->aud_data.audio_is_active = true;
14505         }
14506
14507         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_A2_THRSHLD__A, thres->a2, 0);
14508         if (rc != 0) {
14509                 pr_err("error %d\n", rc);
14510                 goto rw_error;
14511         }
14512         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc, 0);
14513         if (rc != 0) {
14514                 pr_err("error %d\n", rc);
14515                 goto rw_error;
14516         }
14517         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam, 0);
14518         if (rc != 0) {
14519                 pr_err("error %d\n", rc);
14520                 goto rw_error;
14521         }
14522
14523         /* update DRXK data structure with hardware values */
14524         ext_attr->aud_data.ass_thresholds = *thres;
14525
14526         return 0;
14527 rw_error:
14528         return -EIO;
14529 }
14530
14531 /*============================================================================*/
14532 /**
14533 * \brief Get Audio Carrier settings
14534 * \param demod instance of demodulator
14535 * \param pointer to struct drx_aud_carrier ** \return int.
14536 *
14537 */
14538 static int
14539 aud_ctrl_get_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14540 {
14541         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14542         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14543         int rc;
14544         u16 w_modus = 0;
14545
14546         u16 dco_a_hi = 0;
14547         u16 dco_a_lo = 0;
14548         u16 dco_b_hi = 0;
14549         u16 dco_b_lo = 0;
14550
14551         u32 valA = 0;
14552         u32 valB = 0;
14553
14554         u16 dc_lvl_a = 0;
14555         u16 dc_lvl_b = 0;
14556
14557         u16 cm_thes_a = 0;
14558         u16 cm_thes_b = 0;
14559
14560         if (carriers == NULL)
14561                 return -EINVAL;
14562
14563         dev_addr = demod->my_i2c_dev_addr;
14564         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14565
14566         /* power up */
14567         if (ext_attr->aud_data.audio_is_active == false) {
14568                 rc = power_up_aud(demod, true);
14569                 if (rc != 0) {
14570                         pr_err("error %d\n", rc);
14571                         goto rw_error;
14572                 }
14573                 ext_attr->aud_data.audio_is_active = true;
14574         }
14575
14576         rc = aud_get_modus(demod, &w_modus);
14577         if (rc != 0) {
14578                 pr_err("error %d\n", rc);
14579                 goto rw_error;
14580         }
14581
14582         /* Behaviour of primary audio channel */
14583         switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_A__M)) {
14584         case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
14585                 carriers->a.opt = DRX_NO_CARRIER_MUTE;
14586                 break;
14587         case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
14588                 carriers->a.opt = DRX_NO_CARRIER_NOISE;
14589                 break;
14590         default:
14591                 return -EIO;
14592                 break;
14593         }
14594
14595         /* Behaviour of secondary audio channel */
14596         switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_B__M)) {
14597         case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
14598                 carriers->b.opt = DRX_NO_CARRIER_MUTE;
14599                 break;
14600         case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
14601                 carriers->b.opt = DRX_NO_CARRIER_NOISE;
14602                 break;
14603         default:
14604                 return -EIO;
14605                 break;
14606         }
14607
14608         /* frequency adjustment for primary & secondary audio channel */
14609         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_A_HI__A, &dco_a_hi, 0);
14610         if (rc != 0) {
14611                 pr_err("error %d\n", rc);
14612                 goto rw_error;
14613         }
14614         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_A_LO__A, &dco_a_lo, 0);
14615         if (rc != 0) {
14616                 pr_err("error %d\n", rc);
14617                 goto rw_error;
14618         }
14619         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_B_HI__A, &dco_b_hi, 0);
14620         if (rc != 0) {
14621                 pr_err("error %d\n", rc);
14622                 goto rw_error;
14623         }
14624         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_B_LO__A, &dco_b_lo, 0);
14625         if (rc != 0) {
14626                 pr_err("error %d\n", rc);
14627                 goto rw_error;
14628         }
14629
14630         valA = (((u32) dco_a_hi) << 12) | ((u32) dco_a_lo & 0xFFF);
14631         valB = (((u32) dco_b_hi) << 12) | ((u32) dco_b_lo & 0xFFF);
14632
14633         /* Multiply by 20250 * 1>>24  ~= 2 / 1657 */
14634         carriers->a.dco = DRX_S24TODRXFREQ(valA) * 2L / 1657L;
14635         carriers->b.dco = DRX_S24TODRXFREQ(valB) * 2L / 1657L;
14636
14637         /* DC level of the incoming FM signal on the primary
14638            & seconday sound channel */
14639         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dc_lvl_a, 0);
14640         if (rc != 0) {
14641                 pr_err("error %d\n", rc);
14642                 goto rw_error;
14643         }
14644         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dc_lvl_b, 0);
14645         if (rc != 0) {
14646                 pr_err("error %d\n", rc);
14647                 goto rw_error;
14648         }
14649
14650         /* offset (kHz) = (dcLvl / 322) */
14651         carriers->a.shift = (DRX_U16TODRXFREQ(dc_lvl_a) / 322L);
14652         carriers->b.shift = (DRX_U16TODRXFREQ(dc_lvl_b) / 322L);
14653
14654         /* Carrier detetcion threshold for primary & secondary channel */
14655         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cm_thes_a, 0);
14656         if (rc != 0) {
14657                 pr_err("error %d\n", rc);
14658                 goto rw_error;
14659         }
14660         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cm_thes_b, 0);
14661         if (rc != 0) {
14662                 pr_err("error %d\n", rc);
14663                 goto rw_error;
14664         }
14665
14666         carriers->a.thres = cm_thes_a;
14667         carriers->b.thres = cm_thes_b;
14668
14669         return 0;
14670 rw_error:
14671         return -EIO;
14672 }
14673
14674 /*============================================================================*/
14675 /**
14676 * \brief Set Audio Carrier settings
14677 * \param demod instance of demodulator
14678 * \param pointer to struct drx_aud_carrier ** \return int.
14679 *
14680 */
14681 static int
14682 aud_ctrl_set_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14683 {
14684         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14685         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14686         int rc;
14687         u16 w_modus = 0;
14688         u16 r_modus = 0;
14689         u16 dco_a_hi = 0;
14690         u16 dco_a_lo = 0;
14691         u16 dco_b_hi = 0;
14692         u16 dco_b_lo = 0;
14693         s32 valA = 0;
14694         s32 valB = 0;
14695
14696         if (carriers == NULL)
14697                 return -EINVAL;
14698
14699         dev_addr = demod->my_i2c_dev_addr;
14700         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14701
14702         /* power up */
14703         if (ext_attr->aud_data.audio_is_active == false) {
14704                 rc = power_up_aud(demod, true);
14705                 if (rc != 0) {
14706                         pr_err("error %d\n", rc);
14707                         goto rw_error;
14708                 }
14709                 ext_attr->aud_data.audio_is_active = true;
14710         }
14711
14712         rc = aud_get_modus(demod, &r_modus);
14713         if (rc != 0) {
14714                 pr_err("error %d\n", rc);
14715                 goto rw_error;
14716         }
14717
14718         w_modus = r_modus;
14719         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_A__M;
14720         /* Behaviour of primary audio channel */
14721         switch (carriers->a.opt) {
14722         case DRX_NO_CARRIER_MUTE:
14723                 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
14724                 break;
14725         case DRX_NO_CARRIER_NOISE:
14726                 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
14727                 break;
14728         default:
14729                 return -EINVAL;
14730                 break;
14731         }
14732
14733         /* Behaviour of secondary audio channel */
14734         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_B__M;
14735         switch (carriers->b.opt) {
14736         case DRX_NO_CARRIER_MUTE:
14737                 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
14738                 break;
14739         case DRX_NO_CARRIER_NOISE:
14740                 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
14741                 break;
14742         default:
14743                 return -EINVAL;
14744                 break;
14745         }
14746
14747         /* now update the modus register */
14748         if (w_modus != r_modus) {
14749                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14750                 if (rc != 0) {
14751                         pr_err("error %d\n", rc);
14752                         goto rw_error;
14753                 }
14754         }
14755
14756         /* frequency adjustment for primary & secondary audio channel */
14757         valA = (s32) ((carriers->a.dco) * 1657L / 2);
14758         valB = (s32) ((carriers->b.dco) * 1657L / 2);
14759
14760         dco_a_hi = (u16) ((valA >> 12) & 0xFFF);
14761         dco_a_lo = (u16) (valA & 0xFFF);
14762         dco_b_hi = (u16) ((valB >> 12) & 0xFFF);
14763         dco_b_lo = (u16) (valB & 0xFFF);
14764
14765         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_A_HI__A, dco_a_hi, 0);
14766         if (rc != 0) {
14767                 pr_err("error %d\n", rc);
14768                 goto rw_error;
14769         }
14770         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_A_LO__A, dco_a_lo, 0);
14771         if (rc != 0) {
14772                 pr_err("error %d\n", rc);
14773                 goto rw_error;
14774         }
14775         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_B_HI__A, dco_b_hi, 0);
14776         if (rc != 0) {
14777                 pr_err("error %d\n", rc);
14778                 goto rw_error;
14779         }
14780         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_B_LO__A, dco_b_lo, 0);
14781         if (rc != 0) {
14782                 pr_err("error %d\n", rc);
14783                 goto rw_error;
14784         }
14785
14786         /* Carrier detetcion threshold for primary & secondary channel */
14787         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres, 0);
14788         if (rc != 0) {
14789                 pr_err("error %d\n", rc);
14790                 goto rw_error;
14791         }
14792         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres, 0);
14793         if (rc != 0) {
14794                 pr_err("error %d\n", rc);
14795                 goto rw_error;
14796         }
14797
14798         /* update DRXK data structure */
14799         ext_attr->aud_data.carriers = *carriers;
14800
14801         return 0;
14802 rw_error:
14803         return -EIO;
14804 }
14805
14806 /*============================================================================*/
14807 /**
14808 * \brief Get I2S Source, I2S matrix and FM matrix
14809 * \param demod instance of demodulator
14810 * \param pointer to pDRXAudmixer_t
14811 * \return int.
14812 *
14813 */
14814 static int
14815 aud_ctrl_get_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
14816 {
14817         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14818         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14819         int rc;
14820         u16 src_i2s_matr = 0;
14821         u16 fm_matr = 0;
14822
14823         if (mixer == NULL)
14824                 return -EINVAL;
14825
14826         dev_addr = demod->my_i2c_dev_addr;
14827         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14828
14829         /* power up */
14830         if (ext_attr->aud_data.audio_is_active == false) {
14831                 rc = power_up_aud(demod, true);
14832                 if (rc != 0) {
14833                         pr_err("error %d\n", rc);
14834                         goto rw_error;
14835                 }
14836                 ext_attr->aud_data.audio_is_active = true;
14837         }
14838
14839         /* Source Selctor */
14840         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
14841         if (rc != 0) {
14842                 pr_err("error %d\n", rc);
14843                 goto rw_error;
14844         }
14845
14846         switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M) {
14847         case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
14848                 mixer->source_i2s = DRX_AUD_SRC_MONO;
14849                 break;
14850         case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
14851                 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_AB;
14852                 break;
14853         case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
14854                 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_A;
14855                 break;
14856         case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
14857                 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_B;
14858                 break;
14859         default:
14860                 return -EIO;
14861         }
14862
14863         /* Matrix */
14864         switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M) {
14865         case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
14866                 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_MONO;
14867                 break;
14868         case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
14869                 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_STEREO;
14870                 break;
14871         case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
14872                 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_A_MONO;
14873                 break;
14874         case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
14875                 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_B_MONO;
14876                 break;
14877         default:
14878                 return -EIO;
14879         }
14880
14881         /* FM Matrix */
14882         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
14883         if (rc != 0) {
14884                 pr_err("error %d\n", rc);
14885                 goto rw_error;
14886         }
14887         switch (fm_matr & AUD_DEM_WR_FM_MATRIX__M) {
14888         case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
14889                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_NO_MATRIX;
14890                 break;
14891         case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
14892                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_GERMAN;
14893                 break;
14894         case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
14895                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_KOREAN;
14896                 break;
14897         case AUD_DEM_WR_FM_MATRIX_SOUND_A:
14898                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_A;
14899                 break;
14900         case AUD_DEM_WR_FM_MATRIX_SOUND_B:
14901                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_B;
14902                 break;
14903         default:
14904                 return -EIO;
14905         }
14906
14907         return 0;
14908 rw_error:
14909         return -EIO;
14910 }
14911
14912 /*============================================================================*/
14913 /**
14914 * \brief Set I2S Source, I2S matrix and FM matrix
14915 * \param demod instance of demodulator
14916 * \param pointer to DRXAudmixer_t
14917 * \return int.
14918 *
14919 */
14920 static int
14921 aud_ctrl_set_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
14922 {
14923         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14924         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14925         int rc;
14926         u16 src_i2s_matr = 0;
14927         u16 fm_matr = 0;
14928
14929         if (mixer == NULL)
14930                 return -EINVAL;
14931
14932         dev_addr = demod->my_i2c_dev_addr;
14933         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14934
14935         /* power up */
14936         if (ext_attr->aud_data.audio_is_active == false) {
14937                 rc = power_up_aud(demod, true);
14938                 if (rc != 0) {
14939                         pr_err("error %d\n", rc);
14940                         goto rw_error;
14941                 }
14942                 ext_attr->aud_data.audio_is_active = true;
14943         }
14944
14945         /* Source Selctor */
14946         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
14947         if (rc != 0) {
14948                 pr_err("error %d\n", rc);
14949                 goto rw_error;
14950         }
14951         src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
14952
14953         switch (mixer->source_i2s) {
14954         case DRX_AUD_SRC_MONO:
14955                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
14956                 break;
14957         case DRX_AUD_SRC_STEREO_OR_AB:
14958                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
14959                 break;
14960         case DRX_AUD_SRC_STEREO_OR_A:
14961                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
14962                 break;
14963         case DRX_AUD_SRC_STEREO_OR_B:
14964                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
14965                 break;
14966         default:
14967                 return -EINVAL;
14968         }
14969
14970         /* Matrix */
14971         src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
14972         switch (mixer->matrix_i2s) {
14973         case DRX_AUD_I2S_MATRIX_MONO:
14974                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
14975                 break;
14976         case DRX_AUD_I2S_MATRIX_STEREO:
14977                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO;
14978                 break;
14979         case DRX_AUD_I2S_MATRIX_A_MONO:
14980                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
14981                 break;
14982         case DRX_AUD_I2S_MATRIX_B_MONO:
14983                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
14984                 break;
14985         default:
14986                 return -EINVAL;
14987         }
14988         /* write the result */
14989         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, src_i2s_matr, 0);
14990         if (rc != 0) {
14991                 pr_err("error %d\n", rc);
14992                 goto rw_error;
14993         }
14994
14995         /* FM Matrix */
14996         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
14997         if (rc != 0) {
14998                 pr_err("error %d\n", rc);
14999                 goto rw_error;
15000         }
15001         fm_matr &= (u16) ~AUD_DEM_WR_FM_MATRIX__M;
15002         switch (mixer->matrix_fm) {
15003         case DRX_AUD_FM_MATRIX_NO_MATRIX:
15004                 fm_matr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
15005                 break;
15006         case DRX_AUD_FM_MATRIX_GERMAN:
15007                 fm_matr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
15008                 break;
15009         case DRX_AUD_FM_MATRIX_KOREAN:
15010                 fm_matr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
15011                 break;
15012         case DRX_AUD_FM_MATRIX_SOUND_A:
15013                 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
15014                 break;
15015         case DRX_AUD_FM_MATRIX_SOUND_B:
15016                 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
15017                 break;
15018         default:
15019                 return -EINVAL;
15020         }
15021
15022         /* Only write if ASS is off */
15023         if (ext_attr->aud_data.auto_sound == DRX_AUD_AUTO_SOUND_OFF) {
15024                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, fm_matr, 0);
15025                 if (rc != 0) {
15026                         pr_err("error %d\n", rc);
15027                         goto rw_error;
15028                 }
15029         }
15030
15031         /* update the data structure with hardware state */
15032         ext_attr->aud_data.mixer = *mixer;
15033
15034         return 0;
15035 rw_error:
15036         return -EIO;
15037 }
15038
15039 /*============================================================================*/
15040 /**
15041 * \brief Set AV Sync settings
15042 * \param demod instance of demodulator
15043 * \param pointer to DRXICfgAVSync_t
15044 * \return int.
15045 *
15046 */
15047 static int
15048 aud_ctrl_set_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15049 {
15050         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15051         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15052         int rc;
15053         u16 w_aud_vid_sync = 0;
15054
15055         if (av_sync == NULL)
15056                 return -EINVAL;
15057
15058         dev_addr = demod->my_i2c_dev_addr;
15059         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15060
15061         /* power up */
15062         if (ext_attr->aud_data.audio_is_active == false) {
15063                 rc = power_up_aud(demod, true);
15064                 if (rc != 0) {
15065                         pr_err("error %d\n", rc);
15066                         goto rw_error;
15067                 }
15068                 ext_attr->aud_data.audio_is_active = true;
15069         }
15070
15071         /* audio/video synchronisation */
15072         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15073         if (rc != 0) {
15074                 pr_err("error %d\n", rc);
15075                 goto rw_error;
15076         }
15077
15078         w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_ON__M;
15079
15080         if (*av_sync == DRX_AUD_AVSYNC_OFF)
15081                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
15082         else
15083                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
15084
15085         w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
15086
15087         switch (*av_sync) {
15088         case DRX_AUD_AVSYNC_NTSC:
15089                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
15090                 break;
15091         case DRX_AUD_AVSYNC_MONOCHROME:
15092                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
15093                 break;
15094         case DRX_AUD_AVSYNC_PAL_SECAM:
15095                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
15096                 break;
15097         case DRX_AUD_AVSYNC_OFF:
15098                 /* OK */
15099                 break;
15100         default:
15101                 return -EINVAL;
15102         }
15103
15104         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, w_aud_vid_sync, 0);
15105         if (rc != 0) {
15106                 pr_err("error %d\n", rc);
15107                 goto rw_error;
15108         }
15109         return 0;
15110 rw_error:
15111         return -EIO;
15112 }
15113
15114 /*============================================================================*/
15115 /**
15116 * \brief Get AV Sync settings
15117 * \param demod instance of demodulator
15118 * \param pointer to DRXICfgAVSync_t
15119 * \return int.
15120 *
15121 */
15122 static int
15123 aud_ctrl_get_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15124 {
15125         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15126         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15127         int rc;
15128         u16 w_aud_vid_sync = 0;
15129
15130         if (av_sync == NULL)
15131                 return -EINVAL;
15132
15133         dev_addr = demod->my_i2c_dev_addr;
15134         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15135
15136         /* power up */
15137         if (ext_attr->aud_data.audio_is_active == false) {
15138                 rc = power_up_aud(demod, true);
15139                 if (rc != 0) {
15140                         pr_err("error %d\n", rc);
15141                         goto rw_error;
15142                 }
15143                 ext_attr->aud_data.audio_is_active = true;
15144         }
15145
15146         /* audio/video synchronisation */
15147         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15148         if (rc != 0) {
15149                 pr_err("error %d\n", rc);
15150                 goto rw_error;
15151         }
15152
15153         if ((w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_ON__M) ==
15154             AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE) {
15155                 *av_sync = DRX_AUD_AVSYNC_OFF;
15156                 return 0;
15157         }
15158
15159         switch (w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M) {
15160         case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
15161                 *av_sync = DRX_AUD_AVSYNC_NTSC;
15162                 break;
15163         case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
15164                 *av_sync = DRX_AUD_AVSYNC_MONOCHROME;
15165                 break;
15166         case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
15167                 *av_sync = DRX_AUD_AVSYNC_PAL_SECAM;
15168                 break;
15169         default:
15170                 return -EIO;
15171         }
15172
15173         return 0;
15174 rw_error:
15175         return -EIO;
15176 }
15177
15178 /*============================================================================*/
15179 /**
15180 * \brief Get deviation mode
15181 * \param demod instance of demodulator
15182 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15183 *
15184 */
15185 static int
15186 aud_ctrl_get_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15187 {
15188         u16 r_modus = 0;
15189         int rc;
15190
15191         if (dev == NULL)
15192                 return -EINVAL;
15193
15194         rc = aud_get_modus(demod, &r_modus);
15195         if (rc != 0) {
15196                 pr_err("error %d\n", rc);
15197                 goto rw_error;
15198         }
15199
15200         switch (r_modus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M) {
15201         case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
15202                 *dev = DRX_AUD_DEVIATION_NORMAL;
15203                 break;
15204         case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
15205                 *dev = DRX_AUD_DEVIATION_HIGH;
15206                 break;
15207         default:
15208                 return -EIO;
15209         }
15210
15211         return 0;
15212 rw_error:
15213         return -EIO;
15214 }
15215
15216 /*============================================================================*/
15217 /**
15218 * \brief Get deviation mode
15219 * \param demod instance of demodulator
15220 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15221 *
15222 */
15223 static int
15224 aud_ctrl_set_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15225 {
15226         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15227         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15228         int rc;
15229         u16 w_modus = 0;
15230         u16 r_modus = 0;
15231
15232         if (dev == NULL)
15233                 return -EINVAL;
15234
15235         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15236         dev_addr = demod->my_i2c_dev_addr;
15237
15238         rc = aud_get_modus(demod, &r_modus);
15239         if (rc != 0) {
15240                 pr_err("error %d\n", rc);
15241                 goto rw_error;
15242         }
15243
15244         w_modus = r_modus;
15245
15246         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
15247
15248         switch (*dev) {
15249         case DRX_AUD_DEVIATION_NORMAL:
15250                 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
15251                 break;
15252         case DRX_AUD_DEVIATION_HIGH:
15253                 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
15254                 break;
15255         default:
15256                 return -EINVAL;
15257         }
15258
15259         /* now update the modus register */
15260         if (w_modus != r_modus) {
15261                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15262                 if (rc != 0) {
15263                         pr_err("error %d\n", rc);
15264                         goto rw_error;
15265                 }
15266         }
15267         /* store in drxk data struct */
15268         ext_attr->aud_data.deviation = *dev;
15269
15270         return 0;
15271 rw_error:
15272         return -EIO;
15273 }
15274
15275 /*============================================================================*/
15276 /**
15277 * \brief Get Prescaler settings
15278 * \param demod instance of demodulator
15279 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15280 *
15281 */
15282 static int
15283 aud_ctrl_get_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15284 {
15285         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15286         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15287         int rc;
15288         u16 r_max_fm_deviation = 0;
15289         u16 r_nicam_prescaler = 0;
15290
15291         if (presc == NULL)
15292                 return -EINVAL;
15293
15294         dev_addr = demod->my_i2c_dev_addr;
15295         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15296
15297         /* power up */
15298         if (ext_attr->aud_data.audio_is_active == false) {
15299                 rc = power_up_aud(demod, true);
15300                 if (rc != 0) {
15301                         pr_err("error %d\n", rc);
15302                         goto rw_error;
15303                 }
15304                 ext_attr->aud_data.audio_is_active = true;
15305         }
15306
15307         /* read register data */
15308         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, &r_nicam_prescaler, 0);
15309         if (rc != 0) {
15310                 pr_err("error %d\n", rc);
15311                 goto rw_error;
15312         }
15313         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_FM_PRESC__A, &r_max_fm_deviation, 0);
15314         if (rc != 0) {
15315                 pr_err("error %d\n", rc);
15316                 goto rw_error;
15317         }
15318
15319         /* calculate max FM deviation */
15320         r_max_fm_deviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15321         if (r_max_fm_deviation > 0) {
15322                 presc->fm_deviation = 3600UL + (r_max_fm_deviation >> 1);
15323                 presc->fm_deviation /= r_max_fm_deviation;
15324         } else {
15325                 presc->fm_deviation = 380;      /* kHz */
15326         }
15327
15328         /* calculate NICAM gain from pre-scaler */
15329         /*
15330            nicam_gain   = 20 * ( log10( preScaler / 16) )
15331            = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
15332
15333            because log1_times100() cannot return negative numbers
15334            = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
15335
15336            for 0.1dB resolution:
15337
15338            nicam_gain   = 200 * ( log10( preScaler / 16) )
15339            = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
15340            = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
15341
15342          */
15343         r_nicam_prescaler >>= 8;
15344         if (r_nicam_prescaler <= 1)
15345                 presc->nicam_gain = -241;
15346         else
15347                 presc->nicam_gain = (s16)(((s32)(log1_times100(10 * r_nicam_prescaler * r_nicam_prescaler)) - (s32)(log1_times100(10 * 16 * 16))));
15348
15349         return 0;
15350 rw_error:
15351         return -EIO;
15352 }
15353
15354 /*============================================================================*/
15355 /**
15356 * \brief Set Prescaler settings
15357 * \param demod instance of demodulator
15358 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15359 *
15360 */
15361 static int
15362 aud_ctrl_set_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15363 {
15364         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15365         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15366         int rc;
15367         u16 w_max_fm_deviation = 0;
15368         u16 nicam_prescaler;
15369
15370         if (presc == NULL)
15371                 return -EINVAL;
15372
15373         dev_addr = demod->my_i2c_dev_addr;
15374         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15375
15376         /* power up */
15377         if (ext_attr->aud_data.audio_is_active == false) {
15378                 rc = power_up_aud(demod, true);
15379                 if (rc != 0) {
15380                         pr_err("error %d\n", rc);
15381                         goto rw_error;
15382                 }
15383                 ext_attr->aud_data.audio_is_active = true;
15384         }
15385
15386         /* setting of max FM deviation */
15387         w_max_fm_deviation = (u16) (frac(3600UL, presc->fm_deviation, 0));
15388         w_max_fm_deviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15389         if (w_max_fm_deviation >= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION)
15390                 w_max_fm_deviation = AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
15391
15392         /* NICAM Prescaler */
15393         if ((presc->nicam_gain >= -241) && (presc->nicam_gain <= 180)) {
15394                 /* calculation
15395
15396                    prescaler = 16 * 10^( gd_b / 20 )
15397
15398                    minval of gd_b = -20*log( 16 ) = -24.1dB
15399
15400                    negative numbers not allowed for d_b2lin_times100, so
15401
15402                    prescaler = 16 * 10^( gd_b / 20 )
15403                    = 10^( (gd_b / 20) + log10(16) )
15404                    = 10^( (gd_b + 20log10(16)) / 20 )
15405
15406                    in 0.1dB
15407
15408                    = 10^( G0.1dB + 200log10(16)) / 200 )
15409
15410                  */
15411                 nicam_prescaler = (u16)
15412                     ((d_b2lin_times100(presc->nicam_gain + 241UL) + 50UL) / 100UL);
15413
15414                 /* clip result */
15415                 if (nicam_prescaler > 127)
15416                         nicam_prescaler = 127;
15417
15418                 /* shift before writing to register */
15419                 nicam_prescaler <<= 8;
15420         } else {
15421                 return -EINVAL;
15422         }
15423         /* end of setting NICAM Prescaler */
15424
15425         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, nicam_prescaler, 0);
15426         if (rc != 0) {
15427                 pr_err("error %d\n", rc);
15428                 goto rw_error;
15429         }
15430         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_FM_PRESC__A, w_max_fm_deviation, 0);
15431         if (rc != 0) {
15432                 pr_err("error %d\n", rc);
15433                 goto rw_error;
15434         }
15435
15436         ext_attr->aud_data.prescale = *presc;
15437
15438         return 0;
15439 rw_error:
15440         return -EIO;
15441 }
15442
15443 /*============================================================================*/
15444 /**
15445 * \brief Beep
15446 * \param demod instance of demodulator
15447 * \param pointer to struct drx_aud_beep * \return int.
15448 *
15449 */
15450 static int aud_ctrl_beep(struct drx_demod_instance *demod, struct drx_aud_beep *beep)
15451 {
15452         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15453         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15454         int rc;
15455         u16 the_beep = 0;
15456         u16 volume = 0;
15457         u32 frequency = 0;
15458
15459         if (beep == NULL)
15460                 return -EINVAL;
15461
15462         dev_addr = demod->my_i2c_dev_addr;
15463         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15464
15465         /* power up */
15466         if (ext_attr->aud_data.audio_is_active == false) {
15467                 rc = power_up_aud(demod, true);
15468                 if (rc != 0) {
15469                         pr_err("error %d\n", rc);
15470                         goto rw_error;
15471                 }
15472                 ext_attr->aud_data.audio_is_active = true;
15473         }
15474
15475         if ((beep->volume > 0) || (beep->volume < -127))
15476                 return -EINVAL;
15477
15478         if (beep->frequency > 3000)
15479                 return -EINVAL;
15480
15481         volume = (u16) beep->volume + 127;
15482         the_beep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
15483
15484         frequency = ((u32) beep->frequency) * 23 / 500;
15485         if (frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M)
15486                 frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
15487         the_beep |= (u16) frequency;
15488
15489         if (beep->mute == true)
15490                 the_beep = 0;
15491
15492         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_BEEPER__A, the_beep, 0);
15493         if (rc != 0) {
15494                 pr_err("error %d\n", rc);
15495                 goto rw_error;
15496         }
15497
15498         return 0;
15499 rw_error:
15500         return -EIO;
15501 }
15502
15503 /*============================================================================*/
15504 /**
15505 * \brief Set an audio standard
15506 * \param demod instance of demodulator
15507 * \param pointer to enum drx_aud_standard * \return int.
15508 *
15509 */
15510 static int
15511 aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15512 {
15513         struct i2c_device_addr *dev_addr = NULL;
15514         struct drxj_data *ext_attr = NULL;
15515         enum drx_standard current_standard = DRX_STANDARD_UNKNOWN;
15516         int rc;
15517         u16 w_standard = 0;
15518         u16 w_modus = 0;
15519         u16 r_modus = 0;
15520
15521         bool mute_buffer = false;
15522         s16 volume_buffer = 0;
15523         u16 w_volume = 0;
15524
15525         if (standard == NULL)
15526                 return -EINVAL;
15527
15528         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15529         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15530
15531         /* power up */
15532         if (ext_attr->aud_data.audio_is_active == false) {
15533                 rc = power_up_aud(demod, false);
15534                 if (rc != 0) {
15535                         pr_err("error %d\n", rc);
15536                         goto rw_error;
15537                 }
15538                 ext_attr->aud_data.audio_is_active = true;
15539         }
15540
15541         /* reset RDS data availability flag */
15542         ext_attr->aud_data.rds_data_present = false;
15543
15544         /* we need to mute from here to avoid noise during standard switching */
15545         mute_buffer = ext_attr->aud_data.volume.mute;
15546         volume_buffer = ext_attr->aud_data.volume.volume;
15547
15548         ext_attr->aud_data.volume.mute = true;
15549         /* restore data structure from DRX ExtAttr, call volume first to mute */
15550         rc = aud_ctrl_set_cfg_volume(demod, &ext_attr->aud_data.volume);
15551         if (rc != 0) {
15552                 pr_err("error %d\n", rc);
15553                 goto rw_error;
15554         }
15555         rc = aud_ctrl_set_cfg_carrier(demod, &ext_attr->aud_data.carriers);
15556         if (rc != 0) {
15557                 pr_err("error %d\n", rc);
15558                 goto rw_error;
15559         }
15560         rc = aud_ctrl_set_cfg_ass_thres(demod, &ext_attr->aud_data.ass_thresholds);
15561         if (rc != 0) {
15562                 pr_err("error %d\n", rc);
15563                 goto rw_error;
15564         }
15565         rc = aud_ctr_setl_cfg_auto_sound(demod, &ext_attr->aud_data.auto_sound);
15566         if (rc != 0) {
15567                 pr_err("error %d\n", rc);
15568                 goto rw_error;
15569         }
15570         rc = aud_ctrl_set_cfg_mixer(demod, &ext_attr->aud_data.mixer);
15571         if (rc != 0) {
15572                 pr_err("error %d\n", rc);
15573                 goto rw_error;
15574         }
15575         rc = aud_ctrl_set_cfg_av_sync(demod, &ext_attr->aud_data.av_sync);
15576         if (rc != 0) {
15577                 pr_err("error %d\n", rc);
15578                 goto rw_error;
15579         }
15580         rc = aud_ctrl_set_cfg_output_i2s(demod, &ext_attr->aud_data.i2sdata);
15581         if (rc != 0) {
15582                 pr_err("error %d\n", rc);
15583                 goto rw_error;
15584         }
15585
15586         /* get prescaler from presets */
15587         rc = aud_ctrl_set_cfg_prescale(demod, &ext_attr->aud_data.prescale);
15588         if (rc != 0) {
15589                 pr_err("error %d\n", rc);
15590                 goto rw_error;
15591         }
15592
15593         rc = aud_get_modus(demod, &r_modus);
15594         if (rc != 0) {
15595                 pr_err("error %d\n", rc);
15596                 goto rw_error;
15597         }
15598
15599         w_modus = r_modus;
15600
15601         switch (*standard) {
15602         case DRX_AUD_STANDARD_AUTO:
15603                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15604                 break;
15605         case DRX_AUD_STANDARD_BTSC:
15606                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
15607                 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_MONO_AND_SAP)
15608                         w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
15609                 break;
15610         case DRX_AUD_STANDARD_A2:
15611                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
15612                 break;
15613         case DRX_AUD_STANDARD_EIAJ:
15614                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
15615                 break;
15616         case DRX_AUD_STANDARD_FM_STEREO:
15617                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
15618                 break;
15619         case DRX_AUD_STANDARD_BG_FM:
15620                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
15621                 break;
15622         case DRX_AUD_STANDARD_D_K1:
15623                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
15624                 break;
15625         case DRX_AUD_STANDARD_D_K2:
15626                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
15627                 break;
15628         case DRX_AUD_STANDARD_D_K3:
15629                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
15630                 break;
15631         case DRX_AUD_STANDARD_BG_NICAM_FM:
15632                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
15633                 break;
15634         case DRX_AUD_STANDARD_L_NICAM_AM:
15635                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
15636                 break;
15637         case DRX_AUD_STANDARD_I_NICAM_FM:
15638                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
15639                 break;
15640         case DRX_AUD_STANDARD_D_K_NICAM_FM:
15641                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
15642                 break;
15643         case DRX_AUD_STANDARD_UNKNOWN:
15644                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15645                 break;
15646         default:
15647                 return -EIO;
15648         }
15649
15650         if (*standard == DRX_AUD_STANDARD_AUTO) {
15651                 /* we need the current standard here */
15652                 current_standard = ext_attr->standard;
15653
15654                 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
15655
15656                 if ((current_standard == DRX_STANDARD_PAL_SECAM_L) || (current_standard == DRX_STANDARD_PAL_SECAM_LP))
15657                         w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
15658                 else
15659                         w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
15660
15661                 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
15662                 if (current_standard == DRX_STANDARD_NTSC)
15663                         w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
15664                 else
15665                         w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
15666
15667         }
15668
15669         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
15670
15671         /* just get hardcoded deemphasis and activate here */
15672         if (ext_attr->aud_data.deemph == DRX_AUD_FM_DEEMPH_50US)
15673                 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
15674         else
15675                 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
15676
15677         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_BTSC__M;
15678         if (ext_attr->aud_data.btsc_detect == DRX_BTSC_STEREO)
15679                 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
15680         else
15681                 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
15682
15683         if (w_modus != r_modus) {
15684                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15685                 if (rc != 0) {
15686                         pr_err("error %d\n", rc);
15687                         goto rw_error;
15688                 }
15689         }
15690
15691         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_STANDARD_SEL__A, w_standard, 0);
15692         if (rc != 0) {
15693                 pr_err("error %d\n", rc);
15694                 goto rw_error;
15695         }
15696
15697    /**************************************************************************/
15698         /* NOT calling aud_ctrl_set_cfg_volume to avoid interfering standard          */
15699         /* detection, need to keep things very minimal here, but keep audio       */
15700         /* buffers intact                                                         */
15701    /**************************************************************************/
15702         ext_attr->aud_data.volume.mute = mute_buffer;
15703         if (ext_attr->aud_data.volume.mute == false) {
15704                 w_volume |= (u16) ((volume_buffer + AUD_VOLUME_ZERO_DB) <<
15705                                     AUD_DSP_WR_VOLUME_VOL_MAIN__B);
15706                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
15707                 if (rc != 0) {
15708                         pr_err("error %d\n", rc);
15709                         goto rw_error;
15710                 }
15711         }
15712
15713         /* write standard selected */
15714         ext_attr->aud_data.audio_standard = *standard;
15715
15716         return 0;
15717 rw_error:
15718         return -EIO;
15719 }
15720
15721 /*============================================================================*/
15722 /**
15723 * \brief Get the current audio standard
15724 * \param demod instance of demodulator
15725 * \param pointer to enum drx_aud_standard * \return int.
15726 *
15727 */
15728 static int
15729 aud_ctrl_get_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15730 {
15731         struct i2c_device_addr *dev_addr = NULL;
15732         struct drxj_data *ext_attr = NULL;
15733         int rc;
15734         u16 r_data = 0;
15735
15736         if (standard == NULL)
15737                 return -EINVAL;
15738
15739         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15740         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15741
15742         /* power up */
15743         if (ext_attr->aud_data.audio_is_active == false) {
15744                 rc = power_up_aud(demod, true);
15745                 if (rc != 0) {
15746                         pr_err("error %d\n", rc);
15747                         goto rw_error;
15748                 }
15749                 ext_attr->aud_data.audio_is_active = true;
15750         }
15751
15752         *standard = DRX_AUD_STANDARD_UNKNOWN;
15753
15754         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RD_STANDARD_RES__A, &r_data, 0);
15755         if (rc != 0) {
15756                 pr_err("error %d\n", rc);
15757                 goto rw_error;
15758         }
15759
15760         /* return OK if the detection is not ready yet */
15761         if (r_data >= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE) {
15762                 *standard = DRX_AUD_STANDARD_NOT_READY;
15763                 return 0;
15764         }
15765
15766         /* detection done, return correct standard */
15767         switch (r_data) {
15768                 /* no standard detected */
15769         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
15770                 *standard = DRX_AUD_STANDARD_UNKNOWN;
15771                 break;
15772                 /* standard is KOREA(A2) */
15773         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
15774                 *standard = DRX_AUD_STANDARD_A2;
15775                 break;
15776                 /* standard is EIA-J (Japan) */
15777         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
15778                 *standard = DRX_AUD_STANDARD_EIAJ;
15779                 break;
15780                 /* standard is BTSC-stereo */
15781         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
15782                 *standard = DRX_AUD_STANDARD_BTSC;
15783                 break;
15784                 /* standard is BTSC-mono (SAP) */
15785         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
15786                 *standard = DRX_AUD_STANDARD_BTSC;
15787                 break;
15788                 /* standard is FM radio */
15789         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
15790                 *standard = DRX_AUD_STANDARD_FM_STEREO;
15791                 break;
15792                 /* standard is BG FM */
15793         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
15794                 *standard = DRX_AUD_STANDARD_BG_FM;
15795                 break;
15796                 /* standard is DK-1 FM */
15797         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
15798                 *standard = DRX_AUD_STANDARD_D_K1;
15799                 break;
15800                 /* standard is DK-2 FM */
15801         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
15802                 *standard = DRX_AUD_STANDARD_D_K2;
15803                 break;
15804                 /* standard is DK-3 FM */
15805         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
15806                 *standard = DRX_AUD_STANDARD_D_K3;
15807                 break;
15808                 /* standard is BG-NICAM FM */
15809         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
15810                 *standard = DRX_AUD_STANDARD_BG_NICAM_FM;
15811                 break;
15812                 /* standard is L-NICAM AM */
15813         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
15814                 *standard = DRX_AUD_STANDARD_L_NICAM_AM;
15815                 break;
15816                 /* standard is I-NICAM FM */
15817         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
15818                 *standard = DRX_AUD_STANDARD_I_NICAM_FM;
15819                 break;
15820                 /* standard is DK-NICAM FM */
15821         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
15822                 *standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
15823                 break;
15824         default:
15825                 *standard = DRX_AUD_STANDARD_UNKNOWN;
15826         }
15827
15828         return 0;
15829 rw_error:
15830         return -EIO;
15831
15832 }
15833
15834 /*============================================================================*/
15835 /**
15836 * \brief Retreive lock status in case of FM standard
15837 * \param demod instance of demodulator
15838 * \param pointer to lock status
15839 * \return int.
15840 *
15841 */
15842 static int
15843 fm_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
15844 {
15845         struct drx_aud_status status;
15846         int rc;
15847
15848         /* Check detection of audio carriers */
15849         rc = aud_ctrl_get_carrier_detect_status(demod, &status);
15850         if (rc != 0) {
15851                 pr_err("error %d\n", rc);
15852                 goto rw_error;
15853         }
15854
15855         /* locked if either primary or secondary carrier is detected */
15856         if ((status.carrier_a == true) || (status.carrier_b == true))
15857                 *lock_stat = DRX_LOCKED;
15858         else
15859                 *lock_stat = DRX_NOT_LOCKED;
15860
15861         return 0;
15862
15863 rw_error:
15864         return -EIO;
15865 }
15866
15867 /*============================================================================*/
15868 /**
15869 * \brief retreive signal quality in case of FM standard
15870 * \param demod instance of demodulator
15871 * \param pointer to signal quality
15872 * \return int.
15873 *
15874 * Only the quality indicator field is will be supplied.
15875 * This will either be 0% or 100%, nothing in between.
15876 *
15877 */
15878 static int
15879 fm_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
15880 {
15881         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
15882         int rc;
15883
15884         rc = fm_lock_status(demod, &lock_status);
15885         if (rc != 0) {
15886                 pr_err("error %d\n", rc);
15887                 goto rw_error;
15888         }
15889         if (lock_status == DRX_LOCKED)
15890                 sig_quality->indicator = 100;
15891         else
15892                 sig_quality->indicator = 0;
15893
15894         return 0;
15895
15896 rw_error:
15897         return -EIO;
15898 }
15899
15900 #endif
15901
15902 /*===========================================================================*/
15903 /*==                    END AUDIO DATAPATH FUNCTIONS                       ==*/
15904 /*===========================================================================*/
15905
15906 /*============================================================================*/
15907 /*============================================================================*/
15908 /*==                       OOB DATAPATH FUNCTIONS                           ==*/
15909 /*============================================================================*/
15910 /*============================================================================*/
15911 #ifndef DRXJ_DIGITAL_ONLY
15912 /**
15913 * \fn int get_oob_lock_status ()
15914 * \brief Get OOB lock status.
15915 * \param dev_addr I2C address
15916   \      oob_lock OOB lock status.
15917 * \return int.
15918 *
15919 * Gets OOB lock status
15920 *
15921 */
15922 static int
15923 get_oob_lock_status(struct drx_demod_instance *demod,
15924                     struct i2c_device_addr *dev_addr, enum drx_lock_status *oob_lock)
15925 {
15926         struct drxjscu_cmd scu_cmd;
15927         int rc;
15928         u16 cmd_result[2];
15929         u16 oob_lock_state;
15930
15931         *oob_lock = DRX_NOT_LOCKED;
15932
15933         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
15934             SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
15935         scu_cmd.result_len = 2;
15936         scu_cmd.result = cmd_result;
15937         scu_cmd.parameter_len = 0;
15938
15939         rc = scu_command(dev_addr, &scu_cmd);
15940         if (rc != 0) {
15941                 pr_err("error %d\n", rc);
15942                 goto rw_error;
15943         }
15944
15945         if (scu_cmd.result[1] < 0x4000) {
15946                 /* 0x00 NOT LOCKED */
15947                 *oob_lock = DRX_NOT_LOCKED;
15948         } else if (scu_cmd.result[1] < 0x8000) {
15949                 /* 0x40 DEMOD LOCKED */
15950                 *oob_lock = DRXJ_OOB_SYNC_LOCK;
15951         } else if (scu_cmd.result[1] < 0xC000) {
15952                 /* 0x80 DEMOD + OOB LOCKED (system lock) */
15953                 oob_lock_state = scu_cmd.result[1] & 0x00FF;
15954
15955                 if (oob_lock_state & 0x0008)
15956                         *oob_lock = DRXJ_OOB_SYNC_LOCK;
15957                 else if ((oob_lock_state & 0x0002) && (oob_lock_state & 0x0001))
15958                         *oob_lock = DRXJ_OOB_AGC_LOCK;
15959         } else {
15960                 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
15961                 *oob_lock = DRX_NEVER_LOCK;
15962         }
15963
15964         /* *oob_lock = scu_cmd.result[1]; */
15965
15966         return 0;
15967 rw_error:
15968         return -EIO;
15969 }
15970
15971 /**
15972 * \fn int get_oob_symbol_rate_offset ()
15973 * \brief Get OOB Symbol rate offset. Unit is [ppm]
15974 * \param dev_addr I2C address
15975 * \      Symbol Rate Offset OOB parameter.
15976 * \return int.
15977 *
15978 * Gets OOB frequency offset
15979 *
15980 */
15981 static int
15982 get_oob_symbol_rate_offset(struct i2c_device_addr *dev_addr, s32 *symbol_rate_offset)
15983 {
15984 /*  offset = -{(timing_offset/2^19)*(symbol_rate/12,656250MHz)}*10^6 [ppm]  */
15985 /*  offset = -{(timing_offset/2^19)*(symbol_rate/12656250)}*10^6 [ppm]  */
15986 /*  after reconfiguration: */
15987 /*  offset = -{(timing_offset*symbol_rate)/(2^19*12656250)}*10^6 [ppm]  */
15988 /*  shift symbol rate left by 5 without lossing information */
15989 /*  offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
15990 /*  shift 10^6 left by 6 without loosing information */
15991 /*  offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
15992 /*  trim 12656250/15625 = 810 */
15993 /*  offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*810)} [ppm]  */
15994 /*  offset = -[(symbol_rate * 2^-5)*(timing_offset)/(2^8)]/810 [ppm]  */
15995         int rc;
15996         s32 timing_offset = 0;
15997         u32 unsigned_timing_offset = 0;
15998         s32 division_factor = 810;
15999         u16 data = 0;
16000         u32 symbol_rate = 0;
16001         bool negative = false;
16002
16003         *symbol_rate_offset = 0;
16004         /* read data rate */
16005         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data, 0);
16006         if (rc != 0) {
16007                 pr_err("error %d\n", rc);
16008                 goto rw_error;
16009         }
16010         switch (data & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16011         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16012         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16013         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16014         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16015                 symbol_rate = 1024000;  /* bps */
16016                 break;
16017         case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16018         case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16019                 symbol_rate = 772000;   /* bps */
16020                 break;
16021         case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16022         case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16023                 symbol_rate = 1544000;  /* bps */
16024                 break;
16025         default:
16026                 return -EIO;
16027         }
16028
16029         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_CON_CTI_DTI_R__A, &data, 0);
16030         if (rc != 0) {
16031                 pr_err("error %d\n", rc);
16032                 goto rw_error;
16033         }
16034         /* convert data to positive and keep information about sign */
16035         if ((data & 0x8000) == 0x8000) {
16036                 if (data == 0x8000)
16037                         unsigned_timing_offset = 32768;
16038                 else
16039                         unsigned_timing_offset = 0x00007FFF & (u32) (-data);
16040                 negative = true;
16041         } else
16042                 unsigned_timing_offset = (u32) data;
16043
16044         symbol_rate = symbol_rate >> 5;
16045         unsigned_timing_offset = (unsigned_timing_offset * symbol_rate);
16046         unsigned_timing_offset = frac(unsigned_timing_offset, 256, FRAC_ROUND);
16047         unsigned_timing_offset = frac(unsigned_timing_offset,
16048                                     division_factor, FRAC_ROUND);
16049         if (negative)
16050                 timing_offset = (s32) unsigned_timing_offset;
16051         else
16052                 timing_offset = -(s32) unsigned_timing_offset;
16053
16054         *symbol_rate_offset = timing_offset;
16055
16056         return 0;
16057 rw_error:
16058         return -EIO;
16059 }
16060
16061 /**
16062 * \fn int get_oob_freq_offset ()
16063 * \brief Get OOB lock status.
16064 * \param dev_addr I2C address
16065 * \      freq_offset OOB frequency offset.
16066 * \return int.
16067 *
16068 * Gets OOB frequency offset
16069 *
16070 */
16071 static int
16072 get_oob_freq_offset(struct drx_demod_instance *demod, s32 *freq_offset)
16073 {
16074         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
16075         struct i2c_device_addr *dev_addr = NULL;
16076         int rc;
16077         u16 data = 0;
16078         u16 rot = 0;
16079         u16 symbol_rate_reg = 0;
16080         u32 symbol_rate = 0;
16081         s32 coarse_freq_offset = 0;
16082         s32 fine_freq_offset = 0;
16083         s32 fine_sign = 1;
16084         s32 coarse_sign = 1;
16085         u32 data64hi = 0;
16086         u32 data64lo = 0;
16087         u32 temp_freq_offset = 0;
16088
16089         /* check arguments */
16090         if ((demod == NULL) || (freq_offset == NULL))
16091                 return -EINVAL;
16092
16093         dev_addr = demod->my_i2c_dev_addr;
16094         common_attr = (struct drx_common_attr *) demod->my_common_attr;
16095
16096         *freq_offset = 0;
16097
16098         /* read sign (spectrum inversion) */
16099         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_IQM_FRQ_W__A, &rot, 0);
16100         if (rc != 0) {
16101                 pr_err("error %d\n", rc);
16102                 goto rw_error;
16103         }
16104
16105         /* read frequency offset */
16106         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_FRQ_OFFSET__A, &data, 0);
16107         if (rc != 0) {
16108                 pr_err("error %d\n", rc);
16109                 goto rw_error;
16110         }
16111         /* find COARSE frequency offset */
16112         /* coarse_freq_offset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
16113         if (data & 0x8000) {
16114                 data = (0xffff - data + 1);
16115                 coarse_sign = -1;
16116         }
16117         mult32(data, (common_attr->sys_clock_freq * 1000) / 6, &data64hi,
16118                &data64lo);
16119         temp_freq_offset = (((data64lo >> 21) & 0x7ff) | (data64hi << 11));
16120
16121         /* get value in KHz */
16122         coarse_freq_offset = coarse_sign * frac(temp_freq_offset, 1000, FRAC_ROUND);    /* KHz */
16123         /* read data rate */
16124         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbol_rate_reg, 0);
16125         if (rc != 0) {
16126                 pr_err("error %d\n", rc);
16127                 goto rw_error;
16128         }
16129         switch (symbol_rate_reg & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16130         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16131         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16132         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16133         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16134                 symbol_rate = 1024000;
16135                 break;
16136         case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16137         case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16138                 symbol_rate = 772000;
16139                 break;
16140         case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16141         case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16142                 symbol_rate = 1544000;
16143                 break;
16144         default:
16145                 return -EIO;
16146         }
16147
16148         /* find FINE frequency offset */
16149         /* fine_freq_offset = ( (CORRECTION_VALUE*symbol_rate) >> 18 ); */
16150         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_CON_CPH_FRQ_R__A, &data, 0);
16151         if (rc != 0) {
16152                 pr_err("error %d\n", rc);
16153                 goto rw_error;
16154         }
16155         /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
16156         fine_freq_offset = (symbol_rate >> 5);
16157         if (data & 0x8000) {
16158                 fine_freq_offset *= 0xffff - data + 1;  /* Hz */
16159                 fine_sign = -1;
16160         } else {
16161                 fine_freq_offset *= data;       /* Hz */
16162         }
16163         /* Left to divide with 8192 (2^13) */
16164         fine_freq_offset = frac(fine_freq_offset, 8192, FRAC_ROUND);
16165         /* and to divide with 1000 to get KHz */
16166         fine_freq_offset = fine_sign * frac(fine_freq_offset, 1000, FRAC_ROUND);        /* KHz */
16167
16168         if ((rot & 0x8000) == 0x8000)
16169                 *freq_offset = -(coarse_freq_offset + fine_freq_offset);
16170         else
16171                 *freq_offset = (coarse_freq_offset + fine_freq_offset);
16172
16173         return 0;
16174 rw_error:
16175         return -EIO;
16176 }
16177
16178 /**
16179 * \fn int get_oob_frequency ()
16180 * \brief Get OOB frequency (Unit:KHz).
16181 * \param dev_addr I2C address
16182 * \      frequency OOB frequency parameters.
16183 * \return int.
16184 *
16185 * Gets OOB frequency
16186 *
16187 */
16188 static int
16189 get_oob_frequency(struct drx_demod_instance *demod, s32 *frequency)
16190 {
16191         struct i2c_device_addr *dev_addr = NULL;
16192         int rc;
16193         u16 data = 0;
16194         s32 freq_offset = 0;
16195         s32 freq = 0;
16196
16197         dev_addr = demod->my_i2c_dev_addr;
16198
16199         *frequency = 0;         /* KHz */
16200
16201         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data, 0);
16202         if (rc != 0) {
16203                 pr_err("error %d\n", rc);
16204                 goto rw_error;
16205         }
16206
16207         freq = (s32) ((s32) data * 50 + 50000L);
16208
16209         rc = get_oob_freq_offset(demod, &freq_offset);
16210         if (rc != 0) {
16211                 pr_err("error %d\n", rc);
16212                 goto rw_error;
16213         }
16214
16215         *frequency = freq + freq_offset;
16216
16217         return 0;
16218 rw_error:
16219         return -EIO;
16220 }
16221
16222 /**
16223 * \fn int get_oobmer ()
16224 * \brief Get OOB MER.
16225 * \param dev_addr I2C address
16226   \      MER OOB parameter in dB.
16227 * \return int.
16228 *
16229 * Gets OOB MER. Table for MER is in Programming guide.
16230 *
16231 */
16232 static int get_oobmer(struct i2c_device_addr *dev_addr, u32 *mer)
16233 {
16234         int rc;
16235         u16 data = 0;
16236
16237         *mer = 0;
16238         /* READ MER */
16239         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_EQU_MER_MER_R__A, &data, 0);
16240         if (rc != 0) {
16241                 pr_err("error %d\n", rc);
16242                 goto rw_error;
16243         }
16244         switch (data) {
16245         case 0:         /* fall through */
16246         case 1:
16247                 *mer = 39;
16248                 break;
16249         case 2:
16250                 *mer = 33;
16251                 break;
16252         case 3:
16253                 *mer = 29;
16254                 break;
16255         case 4:
16256                 *mer = 27;
16257                 break;
16258         case 5:
16259                 *mer = 25;
16260                 break;
16261         case 6:
16262                 *mer = 23;
16263                 break;
16264         case 7:
16265                 *mer = 22;
16266                 break;
16267         case 8:
16268                 *mer = 21;
16269                 break;
16270         case 9:
16271                 *mer = 20;
16272                 break;
16273         case 10:
16274                 *mer = 19;
16275                 break;
16276         case 11:
16277                 *mer = 18;
16278                 break;
16279         case 12:
16280                 *mer = 17;
16281                 break;
16282         case 13:                /* fall through */
16283         case 14:
16284                 *mer = 16;
16285                 break;
16286         case 15:                /* fall through */
16287         case 16:
16288                 *mer = 15;
16289                 break;
16290         case 17:                /* fall through */
16291         case 18:
16292                 *mer = 14;
16293                 break;
16294         case 19:                /* fall through */
16295         case 20:
16296                 *mer = 13;
16297                 break;
16298         case 21:                /* fall through */
16299         case 22:
16300                 *mer = 12;
16301                 break;
16302         case 23:                /* fall through */
16303         case 24:                /* fall through */
16304         case 25:
16305                 *mer = 11;
16306                 break;
16307         case 26:                /* fall through */
16308         case 27:                /* fall through */
16309         case 28:
16310                 *mer = 10;
16311                 break;
16312         case 29:                /* fall through */
16313         case 30:                /* fall through */
16314         case 31:                /* fall through */
16315         case 32:
16316                 *mer = 9;
16317                 break;
16318         case 33:                /* fall through */
16319         case 34:                /* fall through */
16320         case 35:                /* fall through */
16321         case 36:
16322                 *mer = 8;
16323                 break;
16324         case 37:                /* fall through */
16325         case 38:                /* fall through */
16326         case 39:                /* fall through */
16327         case 40:
16328                 *mer = 7;
16329                 break;
16330         case 41:                /* fall through */
16331         case 42:                /* fall through */
16332         case 43:                /* fall through */
16333         case 44:                /* fall through */
16334         case 45:
16335                 *mer = 6;
16336                 break;
16337         case 46:                /* fall through */
16338         case 47:                /* fall through */
16339         case 48:                /* fall through */
16340         case 49:                /* fall through */
16341         case 50:                /* fall through */
16342                 *mer = 5;
16343                 break;
16344         case 51:                /* fall through */
16345         case 52:                /* fall through */
16346         case 53:                /* fall through */
16347         case 54:                /* fall through */
16348         case 55:                /* fall through */
16349         case 56:                /* fall through */
16350         case 57:
16351                 *mer = 4;
16352                 break;
16353         case 58:                /* fall through */
16354         case 59:                /* fall through */
16355         case 60:                /* fall through */
16356         case 61:                /* fall through */
16357         case 62:                /* fall through */
16358         case 63:
16359                 *mer = 0;
16360                 break;
16361         default:
16362                 *mer = 0;
16363                 break;
16364         }
16365         return 0;
16366 rw_error:
16367         return -EIO;
16368 }
16369 #endif /*#ifndef DRXJ_DIGITAL_ONLY */
16370
16371 /**
16372 * \fn int set_orx_nsu_aox()
16373 * \brief Configure OrxNsuAox for OOB
16374 * \param demod instance of demodulator.
16375 * \param active
16376 * \return int.
16377 */
16378 static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
16379 {
16380         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
16381         int rc;
16382         u16 data = 0;
16383
16384         /* Configure NSU_AOX */
16385         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
16386         if (rc != 0) {
16387                 pr_err("error %d\n", rc);
16388                 goto rw_error;
16389         }
16390         if (!active)
16391                 data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON));
16392         else
16393                 data |= (ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON | ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON);
16394         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
16395         if (rc != 0) {
16396                 pr_err("error %d\n", rc);
16397                 goto rw_error;
16398         }
16399
16400         return 0;
16401 rw_error:
16402         return -EIO;
16403 }
16404
16405 /**
16406 * \fn int ctrl_set_oob()
16407 * \brief Set OOB channel to be used.
16408 * \param demod instance of demodulator
16409 * \param oob_param OOB parameters for channel setting.
16410 * \frequency should be in KHz
16411 * \return int.
16412 *
16413 * Accepts  only. Returns error otherwise.
16414 * Demapper value is written after scu_command START
16415 * because START command causes COMM_EXEC transition
16416 * from 0 to 1 which causes all registers to be
16417 * overwritten with initial value
16418 *
16419 */
16420
16421 /* Nyquist filter impulse response */
16422 #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 */
16423 #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 */
16424 #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) */
16425
16426 /* Coefficients for the nyquist fitler (total: 27 taps) */
16427 #define NYQFILTERLEN 27
16428
16429 static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
16430 {
16431 #ifndef DRXJ_DIGITAL_ONLY
16432         int rc;
16433         s32 freq = 0;   /* KHz */
16434         struct i2c_device_addr *dev_addr = NULL;
16435         struct drxj_data *ext_attr = NULL;
16436         u16 i = 0;
16437         bool mirror_freq_spect_oob = false;
16438         u16 trk_filter_value = 0;
16439         struct drxjscu_cmd scu_cmd;
16440         u16 set_param_parameters[3];
16441         u16 cmd_result[2] = { 0, 0 };
16442         s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
16443                 IMPULSE_COSINE_ALPHA_0_3,       /* Target Mode 0 */
16444                 IMPULSE_COSINE_ALPHA_0_3,       /* Target Mode 1 */
16445                 IMPULSE_COSINE_ALPHA_0_5,       /* Target Mode 2 */
16446                 IMPULSE_COSINE_ALPHA_RO_0_5     /* Target Mode 3 */
16447         };
16448         u8 mode_val[4] = { 2, 2, 0, 1 };
16449         u8 pfi_coeffs[4][6] = {
16450                 {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) */
16451                 {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) */
16452                 {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) */
16453                 {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) */
16454         };
16455         u16 mode_index;
16456
16457         dev_addr = demod->my_i2c_dev_addr;
16458         ext_attr = (struct drxj_data *) demod->my_ext_attr;
16459         mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
16460
16461         /* Check parameters */
16462         if (oob_param == NULL) {
16463                 /* power off oob module  */
16464                 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16465                     | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
16466                 scu_cmd.parameter_len = 0;
16467                 scu_cmd.result_len = 1;
16468                 scu_cmd.result = cmd_result;
16469                 rc = scu_command(dev_addr, &scu_cmd);
16470                 if (rc != 0) {
16471                         pr_err("error %d\n", rc);
16472                         goto rw_error;
16473                 }
16474                 rc = set_orx_nsu_aox(demod, false);
16475                 if (rc != 0) {
16476                         pr_err("error %d\n", rc);
16477                         goto rw_error;
16478                 }
16479                 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
16480                 if (rc != 0) {
16481                         pr_err("error %d\n", rc);
16482                         goto rw_error;
16483                 }
16484
16485                 ext_attr->oob_power_on = false;
16486                 return 0;
16487         }
16488
16489         freq = oob_param->frequency;
16490         if ((freq < 70000) || (freq > 130000))
16491                 return -EIO;
16492         freq = (freq - 50000) / 50;
16493
16494         {
16495                 u16 index = 0;
16496                 u16 remainder = 0;
16497                 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
16498
16499                 index = (u16) ((freq - 400) / 200);
16500                 remainder = (u16) ((freq - 400) % 200);
16501                 trk_filter_value =
16502                     trk_filtercfg[index] - (trk_filtercfg[index] -
16503                                            trk_filtercfg[index +
16504                                                         1]) / 10 * remainder /
16505                     20;
16506         }
16507
16508    /*********/
16509         /* Stop  */
16510    /*********/
16511         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
16512         if (rc != 0) {
16513                 pr_err("error %d\n", rc);
16514                 goto rw_error;
16515         }
16516         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16517             | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
16518         scu_cmd.parameter_len = 0;
16519         scu_cmd.result_len = 1;
16520         scu_cmd.result = cmd_result;
16521         rc = scu_command(dev_addr, &scu_cmd);
16522         if (rc != 0) {
16523                 pr_err("error %d\n", rc);
16524                 goto rw_error;
16525         }
16526    /*********/
16527         /* Reset */
16528    /*********/
16529         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16530             | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
16531         scu_cmd.parameter_len = 0;
16532         scu_cmd.result_len = 1;
16533         scu_cmd.result = cmd_result;
16534         rc = scu_command(dev_addr, &scu_cmd);
16535         if (rc != 0) {
16536                 pr_err("error %d\n", rc);
16537                 goto rw_error;
16538         }
16539    /***********/
16540         /* SET_ENV */
16541    /***********/
16542         /* set frequency, spectrum inversion and data rate */
16543         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16544             | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
16545         scu_cmd.parameter_len = 3;
16546         /* 1-data rate;2-frequency */
16547         switch (oob_param->standard) {
16548         case DRX_OOB_MODE_A:
16549                 if (
16550                            /* signal is transmitted inverted */
16551                            ((oob_param->spectrum_inverted == true) &
16552                             /* and tuner is not mirroring the signal */
16553                             (!mirror_freq_spect_oob)) |
16554                            /* or */
16555                            /* signal is transmitted noninverted */
16556                            ((oob_param->spectrum_inverted == false) &
16557                             /* and tuner is mirroring the signal */
16558                             (mirror_freq_spect_oob))
16559                     )
16560                         set_param_parameters[0] =
16561                             SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
16562                 else
16563                         set_param_parameters[0] =
16564                             SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
16565                 break;
16566         case DRX_OOB_MODE_B_GRADE_A:
16567                 if (
16568                            /* signal is transmitted inverted */
16569                            ((oob_param->spectrum_inverted == true) &
16570                             /* and tuner is not mirroring the signal */
16571                             (!mirror_freq_spect_oob)) |
16572                            /* or */
16573                            /* signal is transmitted noninverted */
16574                            ((oob_param->spectrum_inverted == false) &
16575                             /* and tuner is mirroring the signal */
16576                             (mirror_freq_spect_oob))
16577                     )
16578                         set_param_parameters[0] =
16579                             SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
16580                 else
16581                         set_param_parameters[0] =
16582                             SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
16583                 break;
16584         case DRX_OOB_MODE_B_GRADE_B:
16585         default:
16586                 if (
16587                            /* signal is transmitted inverted */
16588                            ((oob_param->spectrum_inverted == true) &
16589                             /* and tuner is not mirroring the signal */
16590                             (!mirror_freq_spect_oob)) |
16591                            /* or */
16592                            /* signal is transmitted noninverted */
16593                            ((oob_param->spectrum_inverted == false) &
16594                             /* and tuner is mirroring the signal */
16595                             (mirror_freq_spect_oob))
16596                     )
16597                         set_param_parameters[0] =
16598                             SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
16599                 else
16600                         set_param_parameters[0] =
16601                             SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
16602                 break;
16603         }
16604         set_param_parameters[1] = (u16) (freq & 0xFFFF);
16605         set_param_parameters[2] = trk_filter_value;
16606         scu_cmd.parameter = set_param_parameters;
16607         scu_cmd.result_len = 1;
16608         scu_cmd.result = cmd_result;
16609         mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
16610         rc = scu_command(dev_addr, &scu_cmd);
16611         if (rc != 0) {
16612                 pr_err("error %d\n", rc);
16613                 goto rw_error;
16614         }
16615
16616         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
16617         if (rc != 0) {
16618                 pr_err("error %d\n", rc);
16619                 goto rw_error;
16620         }       /*  Write magic word to enable pdr reg write  */
16621         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_OOB_CRX_CFG__A, OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B, 0);
16622         if (rc != 0) {
16623                 pr_err("error %d\n", rc);
16624                 goto rw_error;
16625         }
16626         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_OOB_DRX_CFG__A, OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B, 0);
16627         if (rc != 0) {
16628                 pr_err("error %d\n", rc);
16629                 goto rw_error;
16630         }
16631         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
16632         if (rc != 0) {
16633                 pr_err("error %d\n", rc);
16634                 goto rw_error;
16635         }       /*  Write magic word to disable pdr reg write */
16636
16637         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
16638         if (rc != 0) {
16639                 pr_err("error %d\n", rc);
16640                 goto rw_error;
16641         }
16642         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
16643         if (rc != 0) {
16644                 pr_err("error %d\n", rc);
16645                 goto rw_error;
16646         }
16647         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
16648         if (rc != 0) {
16649                 pr_err("error %d\n", rc);
16650                 goto rw_error;
16651         }
16652
16653         /* ddc */
16654         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
16655         if (rc != 0) {
16656                 pr_err("error %d\n", rc);
16657                 goto rw_error;
16658         }
16659
16660         /* nsu */
16661         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
16662         if (rc != 0) {
16663                 pr_err("error %d\n", rc);
16664                 goto rw_error;
16665         }
16666
16667         /* initialization for target mode */
16668         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
16669         if (rc != 0) {
16670                 pr_err("error %d\n", rc);
16671                 goto rw_error;
16672         }
16673         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
16674         if (rc != 0) {
16675                 pr_err("error %d\n", rc);
16676                 goto rw_error;
16677         }
16678
16679         /* Reset bits for timing and freq. recovery */
16680         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
16681         if (rc != 0) {
16682                 pr_err("error %d\n", rc);
16683                 goto rw_error;
16684         }
16685         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
16686         if (rc != 0) {
16687                 pr_err("error %d\n", rc);
16688                 goto rw_error;
16689         }
16690         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
16691         if (rc != 0) {
16692                 pr_err("error %d\n", rc);
16693                 goto rw_error;
16694         }
16695         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
16696         if (rc != 0) {
16697                 pr_err("error %d\n", rc);
16698                 goto rw_error;
16699         }
16700
16701         /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
16702         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
16703         if (rc != 0) {
16704                 pr_err("error %d\n", rc);
16705                 goto rw_error;
16706         }
16707         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
16708         if (rc != 0) {
16709                 pr_err("error %d\n", rc);
16710                 goto rw_error;
16711         }
16712         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
16713         if (rc != 0) {
16714                 pr_err("error %d\n", rc);
16715                 goto rw_error;
16716         }
16717         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
16718         if (rc != 0) {
16719                 pr_err("error %d\n", rc);
16720                 goto rw_error;
16721         }
16722         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
16723         if (rc != 0) {
16724                 pr_err("error %d\n", rc);
16725                 goto rw_error;
16726         }
16727
16728         /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
16729         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
16730         if (rc != 0) {
16731                 pr_err("error %d\n", rc);
16732                 goto rw_error;
16733         }
16734         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
16735         if (rc != 0) {
16736                 pr_err("error %d\n", rc);
16737                 goto rw_error;
16738         }
16739         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
16740         if (rc != 0) {
16741                 pr_err("error %d\n", rc);
16742                 goto rw_error;
16743         }
16744         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
16745         if (rc != 0) {
16746                 pr_err("error %d\n", rc);
16747                 goto rw_error;
16748         }
16749         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
16750         if (rc != 0) {
16751                 pr_err("error %d\n", rc);
16752                 goto rw_error;
16753         }
16754
16755         /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
16756         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
16757         if (rc != 0) {
16758                 pr_err("error %d\n", rc);
16759                 goto rw_error;
16760         }
16761         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
16762         if (rc != 0) {
16763                 pr_err("error %d\n", rc);
16764                 goto rw_error;
16765         }
16766         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
16767         if (rc != 0) {
16768                 pr_err("error %d\n", rc);
16769                 goto rw_error;
16770         }
16771         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
16772         if (rc != 0) {
16773                 pr_err("error %d\n", rc);
16774                 goto rw_error;
16775         }
16776         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
16777         if (rc != 0) {
16778                 pr_err("error %d\n", rc);
16779                 goto rw_error;
16780         }
16781
16782         /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
16783         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
16784         if (rc != 0) {
16785                 pr_err("error %d\n", rc);
16786                 goto rw_error;
16787         }
16788         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
16789         if (rc != 0) {
16790                 pr_err("error %d\n", rc);
16791                 goto rw_error;
16792         }
16793         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
16794         if (rc != 0) {
16795                 pr_err("error %d\n", rc);
16796                 goto rw_error;
16797         }
16798         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
16799         if (rc != 0) {
16800                 pr_err("error %d\n", rc);
16801                 goto rw_error;
16802         }
16803         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
16804         if (rc != 0) {
16805                 pr_err("error %d\n", rc);
16806                 goto rw_error;
16807         }
16808
16809         /* TIM_LOCK = {300,      -2048, 8, -8, 0, 1<<4}; */
16810         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
16811         if (rc != 0) {
16812                 pr_err("error %d\n", rc);
16813                 goto rw_error;
16814         }
16815         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
16816         if (rc != 0) {
16817                 pr_err("error %d\n", rc);
16818                 goto rw_error;
16819         }
16820         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
16821         if (rc != 0) {
16822                 pr_err("error %d\n", rc);
16823                 goto rw_error;
16824         }
16825         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
16826         if (rc != 0) {
16827                 pr_err("error %d\n", rc);
16828                 goto rw_error;
16829         }
16830         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
16831         if (rc != 0) {
16832                 pr_err("error %d\n", rc);
16833                 goto rw_error;
16834         }
16835
16836         /* EQU_LOCK = {20,      -2048, 8, -8, 0, 1<<5}; */
16837         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
16838         if (rc != 0) {
16839                 pr_err("error %d\n", rc);
16840                 goto rw_error;
16841         }
16842         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
16843         if (rc != 0) {
16844                 pr_err("error %d\n", rc);
16845                 goto rw_error;
16846         }
16847         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
16848         if (rc != 0) {
16849                 pr_err("error %d\n", rc);
16850                 goto rw_error;
16851         }
16852         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
16853         if (rc != 0) {
16854                 pr_err("error %d\n", rc);
16855                 goto rw_error;
16856         }
16857         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
16858         if (rc != 0) {
16859                 pr_err("error %d\n", rc);
16860                 goto rw_error;
16861         }
16862
16863         /* PRE-Filter coefficients (PFI) */
16864         rc = DRXJ_DAP.write_block_func(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
16865         if (rc != 0) {
16866                 pr_err("error %d\n", rc);
16867                 goto rw_error;
16868         }
16869         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
16870         if (rc != 0) {
16871                 pr_err("error %d\n", rc);
16872                 goto rw_error;
16873         }
16874
16875         /* NYQUIST-Filter coefficients (NYQ) */
16876         for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
16877                 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
16878                 if (rc != 0) {
16879                         pr_err("error %d\n", rc);
16880                         goto rw_error;
16881                 }
16882                 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
16883                 if (rc != 0) {
16884                         pr_err("error %d\n", rc);
16885                         goto rw_error;
16886                 }
16887         }
16888         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
16889         if (rc != 0) {
16890                 pr_err("error %d\n", rc);
16891                 goto rw_error;
16892         }
16893         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
16894         if (rc != 0) {
16895                 pr_err("error %d\n", rc);
16896                 goto rw_error;
16897         }
16898         /*********/
16899         /* Start */
16900         /*********/
16901         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16902             | SCU_RAM_COMMAND_CMD_DEMOD_START;
16903         scu_cmd.parameter_len = 0;
16904         scu_cmd.result_len = 1;
16905         scu_cmd.result = cmd_result;
16906         rc = scu_command(dev_addr, &scu_cmd);
16907         if (rc != 0) {
16908                 pr_err("error %d\n", rc);
16909                 goto rw_error;
16910         }
16911
16912         rc = set_orx_nsu_aox(demod, true);
16913         if (rc != 0) {
16914                 pr_err("error %d\n", rc);
16915                 goto rw_error;
16916         }
16917         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
16918         if (rc != 0) {
16919                 pr_err("error %d\n", rc);
16920                 goto rw_error;
16921         }
16922
16923         ext_attr->oob_power_on = true;
16924
16925         return 0;
16926 rw_error:
16927 #endif
16928         return -EIO;
16929 }
16930
16931 /**
16932 * \fn int ctrl_get_oob()
16933 * \brief Set modulation standard to be used.
16934 * \param demod instance of demodulator
16935 * \param oob_status OOB status parameters.
16936 * \return int.
16937 */
16938 static int
16939 ctrl_get_oob(struct drx_demod_instance *demod, struct drxoob_status *oob_status)
16940 {
16941 #ifndef DRXJ_DIGITAL_ONLY
16942         int rc;
16943         struct i2c_device_addr *dev_addr = NULL;
16944         struct drxj_data *ext_attr = NULL;
16945         u16 data = 0;
16946
16947         dev_addr = demod->my_i2c_dev_addr;
16948         ext_attr = (struct drxj_data *) demod->my_ext_attr;
16949
16950         /* check arguments */
16951         if (oob_status == NULL)
16952                 return -EINVAL;
16953
16954         if (!ext_attr->oob_power_on)
16955                 return -EIO;
16956
16957         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_DDC_OFO_SET_W__A, &data, 0);
16958         if (rc != 0) {
16959                 pr_err("error %d\n", rc);
16960                 goto rw_error;
16961         }
16962         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &data, 0);
16963         if (rc != 0) {
16964                 pr_err("error %d\n", rc);
16965                 goto rw_error;
16966         }
16967         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_AAG_THR_W__A, &data, 0);
16968         if (rc != 0) {
16969                 pr_err("error %d\n", rc);
16970                 goto rw_error;
16971         }
16972         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_DGN_KI__A, &data, 0);
16973         if (rc != 0) {
16974                 pr_err("error %d\n", rc);
16975                 goto rw_error;
16976         }
16977         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
16978         if (rc != 0) {
16979                 pr_err("error %d\n", rc);
16980                 goto rw_error;
16981         }
16982
16983         rc = get_oob_lock_status(demod, dev_addr, &oob_status->lock);
16984         if (rc != 0) {
16985                 pr_err("error %d\n", rc);
16986                 goto rw_error;
16987         }
16988         rc = get_oob_frequency(demod, &oob_status->frequency);
16989         if (rc != 0) {
16990                 pr_err("error %d\n", rc);
16991                 goto rw_error;
16992         }
16993         rc = get_oobmer(dev_addr, &oob_status->mer);
16994         if (rc != 0) {
16995                 pr_err("error %d\n", rc);
16996                 goto rw_error;
16997         }
16998         rc = get_oob_symbol_rate_offset(dev_addr, &oob_status->symbol_rate_offset);
16999         if (rc != 0) {
17000                 pr_err("error %d\n", rc);
17001                 goto rw_error;
17002         }
17003
17004         return 0;
17005 rw_error:
17006 #endif
17007         return -EIO;
17008 }
17009
17010 /**
17011 * \fn int ctrl_set_cfg_oob_pre_saw()
17012 * \brief Configure PreSAW treshold value
17013 * \param cfg_data Pointer to configuration parameter
17014 * \return Error code
17015 */
17016 #ifndef DRXJ_DIGITAL_ONLY
17017 static int
17018 ctrl_set_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17019 {
17020         struct i2c_device_addr *dev_addr = NULL;
17021         struct drxj_data *ext_attr = NULL;
17022         int rc;
17023
17024         if (cfg_data == NULL)
17025                 return -EINVAL;
17026
17027         dev_addr = demod->my_i2c_dev_addr;
17028         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17029
17030         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STHR_W__A, *cfg_data, 0);
17031         if (rc != 0) {
17032                 pr_err("error %d\n", rc);
17033                 goto rw_error;
17034         }
17035         ext_attr->oob_pre_saw = *cfg_data;
17036         return 0;
17037 rw_error:
17038         return -EIO;
17039 }
17040 #endif
17041
17042 /**
17043 * \fn int ctrl_get_cfg_oob_pre_saw()
17044 * \brief Configure PreSAW treshold value
17045 * \param cfg_data Pointer to configuration parameter
17046 * \return Error code
17047 */
17048 #ifndef DRXJ_DIGITAL_ONLY
17049 static int
17050 ctrl_get_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17051 {
17052         struct drxj_data *ext_attr = NULL;
17053
17054         if (cfg_data == NULL)
17055                 return -EINVAL;
17056
17057         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17058
17059         *cfg_data = ext_attr->oob_pre_saw;
17060
17061         return 0;
17062 }
17063 #endif
17064
17065 /**
17066 * \fn int ctrl_set_cfg_oob_lo_power()
17067 * \brief Configure LO Power value
17068 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17069 */
17070 #ifndef DRXJ_DIGITAL_ONLY
17071 static int
17072 ctrl_set_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17073 {
17074         struct i2c_device_addr *dev_addr = NULL;
17075         struct drxj_data *ext_attr = NULL;
17076         int rc;
17077
17078         if (cfg_data == NULL)
17079                 return -EINVAL;
17080
17081         dev_addr = demod->my_i2c_dev_addr;
17082         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17083
17084         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_LOPOW_W__A, *cfg_data, 0);
17085         if (rc != 0) {
17086                 pr_err("error %d\n", rc);
17087                 goto rw_error;
17088         }
17089         ext_attr->oob_lo_pow = *cfg_data;
17090         return 0;
17091 rw_error:
17092         return -EIO;
17093 }
17094 #endif
17095
17096 /**
17097 * \fn int ctrl_get_cfg_oob_lo_power()
17098 * \brief Configure LO Power value
17099 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17100 */
17101 #ifndef DRXJ_DIGITAL_ONLY
17102 static int
17103 ctrl_get_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17104 {
17105         struct drxj_data *ext_attr = NULL;
17106
17107         if (cfg_data == NULL)
17108                 return -EINVAL;
17109
17110         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17111
17112         *cfg_data = ext_attr->oob_lo_pow;
17113
17114         return 0;
17115 }
17116 #endif
17117 /*============================================================================*/
17118 /*==                     END OOB DATAPATH FUNCTIONS                         ==*/
17119 /*============================================================================*/
17120
17121 /*=============================================================================
17122   ===== MC command related functions ==========================================
17123   ===========================================================================*/
17124
17125 /*=============================================================================
17126   ===== ctrl_set_channel() ==========================================================
17127   ===========================================================================*/
17128 /**
17129 * \fn int ctrl_set_channel()
17130 * \brief Select a new transmission channel.
17131 * \param demod instance of demod.
17132 * \param channel Pointer to channel data.
17133 * \return int.
17134 *
17135 * In case the tuner module is not used and in case of NTSC/FM the pogrammer
17136 * must tune the tuner to the centre frequency of the NTSC/FM channel.
17137 *
17138 */
17139 static int
17140 ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17141 {
17142         int rc;
17143         s32 tuner_set_freq = 0;
17144         s32 tuner_get_freq = 0;
17145         s32 tuner_freq_offset = 0;
17146         s32 intermediate_freq = 0;
17147         struct drxj_data *ext_attr = NULL;
17148         struct i2c_device_addr *dev_addr = NULL;
17149         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17150         u32 tuner_mode = 0;
17151         struct drx_common_attr *common_attr = NULL;
17152         bool bridge_closed = false;
17153 #ifndef DRXJ_VSB_ONLY
17154         u32 min_symbol_rate = 0;
17155         u32 max_symbol_rate = 0;
17156         int bandwidth_temp = 0;
17157         int bandwidth = 0;
17158 #endif
17159    /*== check arguments ======================================================*/
17160         if ((demod == NULL) || (channel == NULL))
17161                 return -EINVAL;
17162
17163         common_attr = (struct drx_common_attr *) demod->my_common_attr;
17164         dev_addr = demod->my_i2c_dev_addr;
17165         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17166         standard = ext_attr->standard;
17167
17168         /* check valid standards */
17169         switch (standard) {
17170         case DRX_STANDARD_8VSB:
17171 #ifndef DRXJ_VSB_ONLY
17172         case DRX_STANDARD_ITU_A:
17173         case DRX_STANDARD_ITU_B:
17174         case DRX_STANDARD_ITU_C:
17175 #endif /* DRXJ_VSB_ONLY */
17176 #ifndef DRXJ_DIGITAL_ONLY
17177         case DRX_STANDARD_NTSC:
17178         case DRX_STANDARD_FM:
17179         case DRX_STANDARD_PAL_SECAM_BG:
17180         case DRX_STANDARD_PAL_SECAM_DK:
17181         case DRX_STANDARD_PAL_SECAM_I:
17182         case DRX_STANDARD_PAL_SECAM_L:
17183         case DRX_STANDARD_PAL_SECAM_LP:
17184 #endif /* DRXJ_DIGITAL_ONLY */
17185                 break;
17186         case DRX_STANDARD_UNKNOWN:
17187         default:
17188                 return -EINVAL;
17189         }
17190
17191         /* check bandwidth QAM annex B, NTSC and 8VSB */
17192         if ((standard == DRX_STANDARD_ITU_B) ||
17193             (standard == DRX_STANDARD_8VSB) ||
17194             (standard == DRX_STANDARD_NTSC)) {
17195                 switch (channel->bandwidth) {
17196                 case DRX_BANDWIDTH_6MHZ:
17197                 case DRX_BANDWIDTH_UNKNOWN:     /* fall through */
17198                         channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17199                         break;
17200                 case DRX_BANDWIDTH_8MHZ:        /* fall through */
17201                 case DRX_BANDWIDTH_7MHZ:        /* fall through */
17202                 default:
17203                         return -EINVAL;
17204                 }
17205         }
17206 #ifndef DRXJ_DIGITAL_ONLY
17207         if (standard == DRX_STANDARD_PAL_SECAM_BG) {
17208                 switch (channel->bandwidth) {
17209                 case DRX_BANDWIDTH_7MHZ:        /* fall through */
17210                 case DRX_BANDWIDTH_8MHZ:
17211                         /* ok */
17212                         break;
17213                 case DRX_BANDWIDTH_6MHZ:        /* fall through */
17214                 case DRX_BANDWIDTH_UNKNOWN:     /* fall through */
17215                 default:
17216                         return -EINVAL;
17217                 }
17218         }
17219         /* check bandwidth PAL/SECAM  */
17220         if ((standard == DRX_STANDARD_PAL_SECAM_BG) ||
17221             (standard == DRX_STANDARD_PAL_SECAM_DK) ||
17222             (standard == DRX_STANDARD_PAL_SECAM_I) ||
17223             (standard == DRX_STANDARD_PAL_SECAM_L) ||
17224             (standard == DRX_STANDARD_PAL_SECAM_LP)) {
17225                 switch (channel->bandwidth) {
17226                 case DRX_BANDWIDTH_8MHZ:
17227                 case DRX_BANDWIDTH_UNKNOWN:     /* fall through */
17228                         channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17229                         break;
17230                 case DRX_BANDWIDTH_6MHZ:        /* fall through */
17231                 case DRX_BANDWIDTH_7MHZ:        /* fall through */
17232                 default:
17233                         return -EINVAL;
17234                 }
17235         }
17236 #endif
17237
17238         /* For QAM annex A and annex C:
17239            -check symbolrate and constellation
17240            -derive bandwidth from symbolrate (input bandwidth is ignored)
17241          */
17242 #ifndef DRXJ_VSB_ONLY
17243         if ((standard == DRX_STANDARD_ITU_A) ||
17244             (standard == DRX_STANDARD_ITU_C)) {
17245                 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
17246                 int bw_rolloff_factor = 0;
17247
17248                 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
17249                 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
17250                 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
17251                 /* config SMA_TX pin to SAW switch mode */
17252                 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
17253                 if (rc != 0) {
17254                         pr_err("error %d\n", rc);
17255                         goto rw_error;
17256                 }
17257
17258                 if (channel->symbolrate < min_symbol_rate ||
17259                     channel->symbolrate > max_symbol_rate) {
17260                         return -EINVAL;
17261                 }
17262
17263                 switch (channel->constellation) {
17264                 case DRX_CONSTELLATION_QAM16:   /* fall through */
17265                 case DRX_CONSTELLATION_QAM32:   /* fall through */
17266                 case DRX_CONSTELLATION_QAM64:   /* fall through */
17267                 case DRX_CONSTELLATION_QAM128:  /* fall through */
17268                 case DRX_CONSTELLATION_QAM256:
17269                         bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
17270                         bandwidth = bandwidth_temp / 100;
17271
17272                         if ((bandwidth_temp % 100) >= 50)
17273                                 bandwidth++;
17274
17275                         if (bandwidth <= 6100000) {
17276                                 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17277                         } else if ((bandwidth > 6100000)
17278                                    && (bandwidth <= 7100000)) {
17279                                 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
17280                         } else if (bandwidth > 7100000) {
17281                                 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17282                         }
17283                         break;
17284                 default:
17285                         return -EINVAL;
17286                 }
17287         }
17288
17289         /* For QAM annex B:
17290            -check constellation
17291          */
17292         if (standard == DRX_STANDARD_ITU_B) {
17293                 switch (channel->constellation) {
17294                 case DRX_CONSTELLATION_AUTO:
17295                 case DRX_CONSTELLATION_QAM256:
17296                 case DRX_CONSTELLATION_QAM64:
17297                         break;
17298                 default:
17299                         return -EINVAL;
17300                 }
17301
17302                 switch (channel->interleavemode) {
17303                 case DRX_INTERLEAVEMODE_I128_J1:
17304                 case DRX_INTERLEAVEMODE_I128_J1_V2:
17305                 case DRX_INTERLEAVEMODE_I128_J2:
17306                 case DRX_INTERLEAVEMODE_I64_J2:
17307                 case DRX_INTERLEAVEMODE_I128_J3:
17308                 case DRX_INTERLEAVEMODE_I32_J4:
17309                 case DRX_INTERLEAVEMODE_I128_J4:
17310                 case DRX_INTERLEAVEMODE_I16_J8:
17311                 case DRX_INTERLEAVEMODE_I128_J5:
17312                 case DRX_INTERLEAVEMODE_I8_J16:
17313                 case DRX_INTERLEAVEMODE_I128_J6:
17314                 case DRX_INTERLEAVEMODE_I128_J7:
17315                 case DRX_INTERLEAVEMODE_I128_J8:
17316                 case DRX_INTERLEAVEMODE_I12_J17:
17317                 case DRX_INTERLEAVEMODE_I5_J4:
17318                 case DRX_INTERLEAVEMODE_B52_M240:
17319                 case DRX_INTERLEAVEMODE_B52_M720:
17320                 case DRX_INTERLEAVEMODE_UNKNOWN:
17321                 case DRX_INTERLEAVEMODE_AUTO:
17322                         break;
17323                 default:
17324                         return -EINVAL;
17325                 }
17326         }
17327
17328         if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
17329                 /* SAW SW, user UIO is used for switchable SAW */
17330                 struct drxuio_data uio1 = { DRX_UIO1, false };
17331
17332                 switch (channel->bandwidth) {
17333                 case DRX_BANDWIDTH_8MHZ:
17334                         uio1.value = true;
17335                         break;
17336                 case DRX_BANDWIDTH_7MHZ:
17337                         uio1.value = false;
17338                         break;
17339                 case DRX_BANDWIDTH_6MHZ:
17340                         uio1.value = false;
17341                         break;
17342                 case DRX_BANDWIDTH_UNKNOWN:
17343                 default:
17344                         return -EINVAL;
17345                 }
17346
17347                 rc = ctrl_uio_write(demod, &uio1);
17348                 if (rc != 0) {
17349                         pr_err("error %d\n", rc);
17350                         goto rw_error;
17351                 }
17352         }
17353 #endif /* DRXJ_VSB_ONLY */
17354         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
17355         if (rc != 0) {
17356                 pr_err("error %d\n", rc);
17357                 goto rw_error;
17358         }
17359    /*== Tune, fast mode ======================================================*/
17360         if (demod->my_tuner != NULL) {
17361                 /* Determine tuner mode and freq to tune to ... */
17362                 switch (standard) {
17363 #ifndef DRXJ_DIGITAL_ONLY
17364                 case DRX_STANDARD_NTSC: /* fallthrough */
17365                 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17366                 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17367                 case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
17368                 case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
17369                 case DRX_STANDARD_PAL_SECAM_LP:
17370                         /* expecting center frequency, not picture carrier so no
17371                            conversion .... */
17372                         tuner_mode |= TUNER_MODE_ANALOG;
17373                         tuner_set_freq = channel->frequency;
17374                         break;
17375                 case DRX_STANDARD_FM:
17376                         /* center frequency (equals sound carrier) as input,
17377                            tune to edge of SAW */
17378                         tuner_mode |= TUNER_MODE_ANALOG;
17379                         tuner_set_freq =
17380                             channel->frequency + DRXJ_FM_CARRIER_FREQ_OFFSET;
17381                         break;
17382 #endif
17383                 case DRX_STANDARD_8VSB: /* fallthrough */
17384 #ifndef DRXJ_VSB_ONLY
17385                 case DRX_STANDARD_ITU_A:        /* fallthrough */
17386                 case DRX_STANDARD_ITU_B:        /* fallthrough */
17387                 case DRX_STANDARD_ITU_C:
17388 #endif
17389                         tuner_mode |= TUNER_MODE_DIGITAL;
17390                         tuner_set_freq = channel->frequency;
17391                         break;
17392                 case DRX_STANDARD_UNKNOWN:
17393                 default:
17394                         return -EIO;
17395                 }               /* switch(standard) */
17396
17397                 tuner_mode |= TUNER_MODE_SWITCH;
17398                 switch (channel->bandwidth) {
17399                 case DRX_BANDWIDTH_8MHZ:
17400                         tuner_mode |= TUNER_MODE_8MHZ;
17401                         break;
17402                 case DRX_BANDWIDTH_7MHZ:
17403                         tuner_mode |= TUNER_MODE_7MHZ;
17404                         break;
17405                 case DRX_BANDWIDTH_6MHZ:
17406                         tuner_mode |= TUNER_MODE_6MHZ;
17407                         break;
17408                 default:
17409                         /* TODO: for FM which bandwidth to use ?
17410                            also check offset from centre frequency ?
17411                            For now using 6MHz.
17412                          */
17413                         tuner_mode |= TUNER_MODE_6MHZ;
17414                         break;
17415                         /* return (-EINVAL); */
17416                 }
17417
17418                 /* store bandwidth for GetChannel() */
17419                 ext_attr->curr_bandwidth = channel->bandwidth;
17420                 ext_attr->curr_symbol_rate = channel->symbolrate;
17421                 ext_attr->frequency = tuner_set_freq;
17422                 if (common_attr->tuner_port_nr == 1) {
17423                         /* close tuner bridge */
17424                         bridge_closed = true;
17425                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
17426                         if (rc != 0) {
17427                                 pr_err("error %d\n", rc);
17428                                 goto rw_error;
17429                         }
17430                         /* set tuner frequency */
17431                 }
17432
17433                 rc = drxbsp_tuner_set_frequency(demod->my_tuner, tuner_mode, tuner_set_freq);
17434                 if (rc != 0) {
17435                         pr_err("error %d\n", rc);
17436                         goto rw_error;
17437                 }
17438                 if (common_attr->tuner_port_nr == 1) {
17439                         /* open tuner bridge */
17440                         bridge_closed = false;
17441                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
17442                         if (rc != 0) {
17443                                 pr_err("error %d\n", rc);
17444                                 goto rw_error;
17445                         }
17446                 }
17447
17448                 /* Get actual frequency set by tuner and compute offset */
17449                 rc = drxbsp_tuner_get_frequency(demod->my_tuner, 0, &tuner_get_freq, &intermediate_freq);
17450                 if (rc != 0) {
17451                         pr_err("error %d\n", rc);
17452                         goto rw_error;
17453                 }
17454                 tuner_freq_offset = tuner_get_freq - tuner_set_freq;
17455                 common_attr->intermediate_freq = intermediate_freq;
17456         } else {
17457                 /* no tuner instance defined, use fixed intermediate frequency */
17458                 tuner_freq_offset = 0;
17459                 intermediate_freq = demod->my_common_attr->intermediate_freq;
17460         }                       /* if ( demod->my_tuner != NULL ) */
17461
17462    /*== Setup demod for specific standard ====================================*/
17463         switch (standard) {
17464         case DRX_STANDARD_8VSB:
17465                 if (channel->mirror == DRX_MIRROR_AUTO)
17466                         ext_attr->mirror = DRX_MIRROR_NO;
17467                 else
17468                         ext_attr->mirror = channel->mirror;
17469                 rc = set_vsb(demod);
17470                 if (rc != 0) {
17471                         pr_err("error %d\n", rc);
17472                         goto rw_error;
17473                 }
17474                 rc = set_frequency(demod, channel, tuner_freq_offset);
17475                 if (rc != 0) {
17476                         pr_err("error %d\n", rc);
17477                         goto rw_error;
17478                 }
17479                 break;
17480 #ifndef DRXJ_DIGITAL_ONLY
17481         case DRX_STANDARD_NTSC: /* fallthrough */
17482         case DRX_STANDARD_FM:   /* fallthrough */
17483         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17484         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17485         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
17486         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
17487         case DRX_STANDARD_PAL_SECAM_LP:
17488                 if (channel->mirror == DRX_MIRROR_AUTO)
17489                         ext_attr->mirror = DRX_MIRROR_NO;
17490                 else
17491                         ext_attr->mirror = channel->mirror;
17492                 rc = set_atv_channel(demod, tuner_freq_offset, channel, standard);
17493                 if (rc != 0) {
17494                         pr_err("error %d\n", rc);
17495                         goto rw_error;
17496                 }
17497                 break;
17498 #endif
17499 #ifndef DRXJ_VSB_ONLY
17500         case DRX_STANDARD_ITU_A:        /* fallthrough */
17501         case DRX_STANDARD_ITU_B:        /* fallthrough */
17502         case DRX_STANDARD_ITU_C:
17503                 rc = set_qam_channel(demod, channel, tuner_freq_offset);
17504                 if (rc != 0) {
17505                         pr_err("error %d\n", rc);
17506                         goto rw_error;
17507                 }
17508                 break;
17509 #endif
17510         case DRX_STANDARD_UNKNOWN:
17511         default:
17512                 return -EIO;
17513         }
17514
17515    /*== Re-tune, slow mode ===================================================*/
17516         if (demod->my_tuner != NULL) {
17517                 /* tune to slow mode */
17518                 tuner_mode &= ~TUNER_MODE_SWITCH;
17519                 tuner_mode |= TUNER_MODE_LOCK;
17520
17521                 if (common_attr->tuner_port_nr == 1) {
17522                         /* close tuner bridge */
17523                         bridge_closed = true;
17524                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
17525                         if (rc != 0) {
17526                                 pr_err("error %d\n", rc);
17527                                 goto rw_error;
17528                         }
17529                 }
17530
17531                 /* set tuner frequency */
17532                 rc = drxbsp_tuner_set_frequency(demod->my_tuner, tuner_mode, tuner_set_freq);
17533                 if (rc != 0) {
17534                         pr_err("error %d\n", rc);
17535                         goto rw_error;
17536                 }
17537                 if (common_attr->tuner_port_nr == 1) {
17538                         /* open tuner bridge */
17539                         bridge_closed = false;
17540                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
17541                         if (rc != 0) {
17542                                 pr_err("error %d\n", rc);
17543                                 goto rw_error;
17544                         }
17545                 }
17546         }
17547
17548         /* if ( demod->my_tuner !=NULL ) */
17549         /* flag the packet error counter reset */
17550         ext_attr->reset_pkt_err_acc = true;
17551
17552         return 0;
17553 rw_error:
17554         return -EIO;
17555 }
17556
17557 /*=============================================================================
17558   ===== ctrl_get_channel() ==========================================================
17559   ===========================================================================*/
17560 /**
17561 * \fn int ctrl_get_channel()
17562 * \brief Retreive parameters of current transmission channel.
17563 * \param demod   Pointer to demod instance.
17564 * \param channel Pointer to channel data.
17565 * \return int.
17566 */
17567 static int
17568 ctrl_get_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17569 {
17570         struct i2c_device_addr *dev_addr = NULL;
17571         struct drxj_data *ext_attr = NULL;
17572         int rc;
17573         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17574         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17575         struct drx_common_attr *common_attr = NULL;
17576         s32 intermediate_freq = 0;
17577         s32 ctl_freq_offset = 0;
17578         u32 iqm_rc_rate_lo = 0;
17579         u32 adc_frequency = 0;
17580 #ifndef DRXJ_VSB_ONLY
17581         int bandwidth_temp = 0;
17582         int bandwidth = 0;
17583 #endif
17584
17585         /* check arguments */
17586         if ((demod == NULL) || (channel == NULL))
17587                 return -EINVAL;
17588
17589         dev_addr = demod->my_i2c_dev_addr;
17590         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17591         standard = ext_attr->standard;
17592         common_attr = (struct drx_common_attr *) demod->my_common_attr;
17593
17594         /* initialize channel fields */
17595         channel->mirror = DRX_MIRROR_UNKNOWN;
17596         channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
17597         channel->priority = DRX_PRIORITY_UNKNOWN;
17598         channel->coderate = DRX_CODERATE_UNKNOWN;
17599         channel->guard = DRX_GUARD_UNKNOWN;
17600         channel->fftmode = DRX_FFTMODE_UNKNOWN;
17601         channel->classification = DRX_CLASSIFICATION_UNKNOWN;
17602         channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
17603         channel->constellation = DRX_CONSTELLATION_UNKNOWN;
17604         channel->symbolrate = 0;
17605         channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
17606         channel->carrier = DRX_CARRIER_UNKNOWN;
17607         channel->framemode = DRX_FRAMEMODE_UNKNOWN;
17608 /*   channel->interleaver       = DRX_INTERLEAVER_UNKNOWN;*/
17609         channel->ldpc = DRX_LDPC_UNKNOWN;
17610
17611         if (demod->my_tuner != NULL) {
17612                 s32 tuner_freq_offset = 0;
17613                 bool tuner_mirror = common_attr->mirror_freq_spect ? false : true;
17614
17615                 /* Get frequency from tuner */
17616                 rc = drxbsp_tuner_get_frequency(demod->my_tuner, 0, &(channel->frequency), &intermediate_freq);
17617                 if (rc != 0) {
17618                         pr_err("error %d\n", rc);
17619                         goto rw_error;
17620                 }
17621                 tuner_freq_offset = channel->frequency - ext_attr->frequency;
17622                 if (tuner_mirror) {
17623                         /* positive image */
17624                         channel->frequency += tuner_freq_offset;
17625                 } else {
17626                         /* negative image */
17627                         channel->frequency -= tuner_freq_offset;
17628                 }
17629
17630                 /* Handle sound carrier offset in RF domain */
17631                 if (standard == DRX_STANDARD_FM)
17632                         channel->frequency -= DRXJ_FM_CARRIER_FREQ_OFFSET;
17633         } else {
17634                 intermediate_freq = common_attr->intermediate_freq;
17635         }
17636
17637         /* check lock status */
17638         rc = ctrl_lock_status(demod, &lock_status);
17639         if (rc != 0) {
17640                 pr_err("error %d\n", rc);
17641                 goto rw_error;
17642         }
17643         if ((lock_status == DRX_LOCKED) || (lock_status == DRXJ_DEMOD_LOCK)) {
17644                 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &iqm_rc_rate_lo, 0);
17645                 if (rc != 0) {
17646                         pr_err("error %d\n", rc);
17647                         goto rw_error;
17648                 }
17649                 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
17650
17651                 channel->symbolrate =
17652                     frac28(adc_frequency, (iqm_rc_rate_lo + (1 << 23))) >> 7;
17653
17654                 switch (standard) {
17655                 case DRX_STANDARD_8VSB:
17656                         channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17657                         /* get the channel frequency */
17658                         rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17659                         if (rc != 0) {
17660                                 pr_err("error %d\n", rc);
17661                                 goto rw_error;
17662                         }
17663                         channel->frequency -= ctl_freq_offset;
17664                         /* get the channel constellation */
17665                         channel->constellation = DRX_CONSTELLATION_AUTO;
17666                         break;
17667 #ifndef DRXJ_VSB_ONLY
17668                 case DRX_STANDARD_ITU_A:
17669                 case DRX_STANDARD_ITU_B:
17670                 case DRX_STANDARD_ITU_C:
17671                         {
17672                                 /* get the channel frequency */
17673                                 rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17674                                 if (rc != 0) {
17675                                         pr_err("error %d\n", rc);
17676                                         goto rw_error;
17677                                 }
17678                                 channel->frequency -= ctl_freq_offset;
17679
17680                                 if (standard == DRX_STANDARD_ITU_B) {
17681                                         channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17682                                 } else {
17683                                         /* annex A & C */
17684
17685                                         u32 roll_off = 113;     /* default annex C */
17686
17687                                         if (standard == DRX_STANDARD_ITU_A)
17688                                                 roll_off = 115;
17689
17690                                         bandwidth_temp =
17691                                             channel->symbolrate * roll_off;
17692                                         bandwidth = bandwidth_temp / 100;
17693
17694                                         if ((bandwidth_temp % 100) >= 50)
17695                                                 bandwidth++;
17696
17697                                         if (bandwidth <= 6000000) {
17698                                                 channel->bandwidth =
17699                                                     DRX_BANDWIDTH_6MHZ;
17700                                         } else if ((bandwidth > 6000000)
17701                                                    && (bandwidth <= 7000000)) {
17702                                                 channel->bandwidth =
17703                                                     DRX_BANDWIDTH_7MHZ;
17704                                         } else if (bandwidth > 7000000) {
17705                                                 channel->bandwidth =
17706                                                     DRX_BANDWIDTH_8MHZ;
17707                                         }
17708                                 }       /* if (standard == DRX_STANDARD_ITU_B) */
17709
17710                                 {
17711                                         struct drxjscu_cmd cmd_scu = { 0, 0, 0, NULL, NULL };
17712                                         u16 cmd_result[3] = { 0, 0, 0 };
17713
17714                                         cmd_scu.command =
17715                                             SCU_RAM_COMMAND_STANDARD_QAM |
17716                                             SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
17717                                         cmd_scu.parameter_len = 0;
17718                                         cmd_scu.result_len = 3;
17719                                         cmd_scu.parameter = NULL;
17720                                         cmd_scu.result = cmd_result;
17721                                         rc = scu_command(dev_addr, &cmd_scu);
17722                                         if (rc != 0) {
17723                                                 pr_err("error %d\n", rc);
17724                                                 goto rw_error;
17725                                         }
17726
17727                                         channel->interleavemode =
17728                                             (enum drx_interleave_mode) (cmd_scu.
17729                                                                     result[2]);
17730                                 }
17731
17732                                 switch (ext_attr->constellation) {
17733                                 case DRX_CONSTELLATION_QAM256:
17734                                         channel->constellation =
17735                                             DRX_CONSTELLATION_QAM256;
17736                                         break;
17737                                 case DRX_CONSTELLATION_QAM128:
17738                                         channel->constellation =
17739                                             DRX_CONSTELLATION_QAM128;
17740                                         break;
17741                                 case DRX_CONSTELLATION_QAM64:
17742                                         channel->constellation =
17743                                             DRX_CONSTELLATION_QAM64;
17744                                         break;
17745                                 case DRX_CONSTELLATION_QAM32:
17746                                         channel->constellation =
17747                                             DRX_CONSTELLATION_QAM32;
17748                                         break;
17749                                 case DRX_CONSTELLATION_QAM16:
17750                                         channel->constellation =
17751                                             DRX_CONSTELLATION_QAM16;
17752                                         break;
17753                                 default:
17754                                         channel->constellation =
17755                                             DRX_CONSTELLATION_UNKNOWN;
17756                                         return -EIO;
17757                                 }
17758                         }
17759                         break;
17760 #endif
17761 #ifndef DRXJ_DIGITAL_ONLY
17762                 case DRX_STANDARD_NTSC: /* fall trough */
17763                 case DRX_STANDARD_PAL_SECAM_BG:
17764                 case DRX_STANDARD_PAL_SECAM_DK:
17765                 case DRX_STANDARD_PAL_SECAM_I:
17766                 case DRX_STANDARD_PAL_SECAM_L:
17767                 case DRX_STANDARD_PAL_SECAM_LP:
17768                 case DRX_STANDARD_FM:
17769                         rc = get_atv_channel(demod, channel, standard);
17770                         if (rc != 0) {
17771                                 pr_err("error %d\n", rc);
17772                                 goto rw_error;
17773                         }
17774                         break;
17775 #endif
17776                 case DRX_STANDARD_UNKNOWN:      /* fall trough */
17777                 default:
17778                         return -EIO;
17779                 }               /* switch ( standard ) */
17780
17781                 if (lock_status == DRX_LOCKED)
17782                         channel->mirror = ext_attr->mirror;
17783         }
17784         /* if ( lock_status == DRX_LOCKED ) */
17785         return 0;
17786 rw_error:
17787         return -EIO;
17788 }
17789
17790 /*=============================================================================
17791   ===== SigQuality() ==========================================================
17792   ===========================================================================*/
17793
17794 static u16
17795 mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
17796 {
17797         u16 indicator = 0;
17798
17799         if (mer < min_mer) {
17800                 indicator = 0;
17801         } else if (mer < threshold_mer) {
17802                 if ((threshold_mer - min_mer) != 0)
17803                         indicator = 25 * (mer - min_mer) / (threshold_mer - min_mer);
17804         } else if (mer < max_mer) {
17805                 if ((max_mer - threshold_mer) != 0)
17806                         indicator = 25 + 75 * (mer - threshold_mer) / (max_mer - threshold_mer);
17807                 else
17808                         indicator = 25;
17809         } else {
17810                 indicator = 100;
17811         }
17812
17813         return indicator;
17814 }
17815
17816 /**
17817 * \fn int ctrl_sig_quality()
17818 * \brief Retreive signal quality form device.
17819 * \param devmod Pointer to demodulator instance.
17820 * \param sig_quality Pointer to signal quality data.
17821 * \return int.
17822 * \retval 0 sig_quality contains valid data.
17823 * \retval -EINVAL sig_quality is NULL.
17824 * \retval -EIO Erroneous data, sig_quality contains invalid data.
17825
17826 */
17827 static int
17828 ctrl_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
17829 {
17830         struct i2c_device_addr *dev_addr = NULL;
17831         struct drxj_data *ext_attr = NULL;
17832         int rc;
17833         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17834         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17835         u16 min_mer = 0;
17836         u16 max_mer = 0;
17837         u16 threshold_mer = 0;
17838
17839         /* Check arguments */
17840         if ((sig_quality == NULL) || (demod == NULL))
17841                 return -EINVAL;
17842
17843         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17844         standard = ext_attr->standard;
17845
17846         /* get basic information */
17847         dev_addr = demod->my_i2c_dev_addr;
17848         rc = ctrl_lock_status(demod, &lock_status);
17849         if (rc != 0) {
17850                 pr_err("error %d\n", rc);
17851                 goto rw_error;
17852         }
17853         switch (standard) {
17854         case DRX_STANDARD_8VSB:
17855 #ifdef DRXJ_SIGNAL_ACCUM_ERR
17856                 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
17857                 if (rc != 0) {
17858                         pr_err("error %d\n", rc);
17859                         goto rw_error;
17860                 }
17861 #else
17862                 rc = get_vsb_post_rs_pck_err(dev_addr, &sig_quality->packet_error);
17863                 if (rc != 0) {
17864                         pr_err("error %d\n", rc);
17865                         goto rw_error;
17866                 }
17867 #endif
17868                 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
17869                         sig_quality->post_viterbi_ber = 500000;
17870                         sig_quality->MER = 20;
17871                         sig_quality->pre_viterbi_ber = 0;
17872                 } else {
17873                         /* PostViterbi is compute in steps of 10^(-6) */
17874                         rc = get_vs_bpre_viterbi_ber(dev_addr, &sig_quality->pre_viterbi_ber);
17875                         if (rc != 0) {
17876                                 pr_err("error %d\n", rc);
17877                                 goto rw_error;
17878                         }
17879                         rc = get_vs_bpost_viterbi_ber(dev_addr, &sig_quality->post_viterbi_ber);
17880                         if (rc != 0) {
17881                                 pr_err("error %d\n", rc);
17882                                 goto rw_error;
17883                         }
17884                         rc = get_vsbmer(dev_addr, &sig_quality->MER);
17885                         if (rc != 0) {
17886                                 pr_err("error %d\n", rc);
17887                                 goto rw_error;
17888                         }
17889                 }
17890                 min_mer = 20;
17891                 max_mer = 360;
17892                 threshold_mer = 145;
17893                 sig_quality->post_reed_solomon_ber = 0;
17894                 sig_quality->scale_factor_ber = 1000000;
17895                 sig_quality->indicator =
17896                     mer2indicator(sig_quality->MER, min_mer, threshold_mer,
17897                                   max_mer);
17898                 break;
17899 #ifndef DRXJ_VSB_ONLY
17900         case DRX_STANDARD_ITU_A:
17901         case DRX_STANDARD_ITU_B:
17902         case DRX_STANDARD_ITU_C:
17903                 rc = ctrl_get_qam_sig_quality(demod, sig_quality);
17904                 if (rc != 0) {
17905                         pr_err("error %d\n", rc);
17906                         goto rw_error;
17907                 }
17908                 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
17909                         switch (ext_attr->constellation) {
17910                         case DRX_CONSTELLATION_QAM256:
17911                                 sig_quality->MER = 210;
17912                                 break;
17913                         case DRX_CONSTELLATION_QAM128:
17914                                 sig_quality->MER = 180;
17915                                 break;
17916                         case DRX_CONSTELLATION_QAM64:
17917                                 sig_quality->MER = 150;
17918                                 break;
17919                         case DRX_CONSTELLATION_QAM32:
17920                                 sig_quality->MER = 120;
17921                                 break;
17922                         case DRX_CONSTELLATION_QAM16:
17923                                 sig_quality->MER = 90;
17924                                 break;
17925                         default:
17926                                 sig_quality->MER = 0;
17927                                 return -EIO;
17928                         }
17929                 }
17930
17931                 switch (ext_attr->constellation) {
17932                 case DRX_CONSTELLATION_QAM256:
17933                         min_mer = 210;
17934                         threshold_mer = 270;
17935                         max_mer = 380;
17936                         break;
17937                 case DRX_CONSTELLATION_QAM64:
17938                         min_mer = 150;
17939                         threshold_mer = 210;
17940                         max_mer = 380;
17941                         break;
17942                 case DRX_CONSTELLATION_QAM128:
17943                 case DRX_CONSTELLATION_QAM32:
17944                 case DRX_CONSTELLATION_QAM16:
17945                         break;
17946                 default:
17947                         return -EIO;
17948                 }
17949                 sig_quality->indicator =
17950                     mer2indicator(sig_quality->MER, min_mer, threshold_mer,
17951                                   max_mer);
17952                 break;
17953 #endif
17954 #ifndef DRXJ_DIGITAL_ONLY
17955         case DRX_STANDARD_PAL_SECAM_BG:
17956         case DRX_STANDARD_PAL_SECAM_DK:
17957         case DRX_STANDARD_PAL_SECAM_I:
17958         case DRX_STANDARD_PAL_SECAM_L:
17959         case DRX_STANDARD_PAL_SECAM_LP:
17960         case DRX_STANDARD_NTSC:
17961                 rc = atv_sig_quality(demod, sig_quality);
17962                 if (rc != 0) {
17963                         pr_err("error %d\n", rc);
17964                         goto rw_error;
17965                 }
17966                 break;
17967         case DRX_STANDARD_FM:
17968                 rc = fm_sig_quality(demod, sig_quality);
17969                 if (rc != 0) {
17970                         pr_err("error %d\n", rc);
17971                         goto rw_error;
17972                 }
17973                 break;
17974 #endif
17975         default:
17976                 return -EIO;
17977         }
17978
17979         return 0;
17980 rw_error:
17981         return -EIO;
17982 }
17983
17984 /*============================================================================*/
17985
17986 /**
17987 * \fn int ctrl_lock_status()
17988 * \brief Retreive lock status .
17989 * \param dev_addr Pointer to demodulator device address.
17990 * \param lock_stat Pointer to lock status structure.
17991 * \return int.
17992 *
17993 */
17994 static int
17995 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
17996 {
17997         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17998         struct drxj_data *ext_attr = NULL;
17999         struct i2c_device_addr *dev_addr = NULL;
18000         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
18001                 /* parameter_len */ 0,
18002                 /* result_len    */ 0,
18003                 /* *parameter   */ NULL,
18004                 /* *result      */ NULL
18005         };
18006         int rc;
18007         u16 cmd_result[2] = { 0, 0 };
18008         u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
18009
18010         /* check arguments */
18011         if ((demod == NULL) || (lock_stat == NULL))
18012                 return -EINVAL;
18013
18014         dev_addr = demod->my_i2c_dev_addr;
18015         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18016         standard = ext_attr->standard;
18017
18018         *lock_stat = DRX_NOT_LOCKED;
18019
18020         /* define the SCU command code */
18021         switch (standard) {
18022         case DRX_STANDARD_8VSB:
18023                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
18024                     SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18025                 demod_lock |= 0x6;
18026                 break;
18027 #ifndef DRXJ_VSB_ONLY
18028         case DRX_STANDARD_ITU_A:
18029         case DRX_STANDARD_ITU_B:
18030         case DRX_STANDARD_ITU_C:
18031                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
18032                     SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18033                 break;
18034 #endif
18035 #ifndef DRXJ_DIGITAL_ONLY
18036         case DRX_STANDARD_NTSC:
18037         case DRX_STANDARD_PAL_SECAM_BG:
18038         case DRX_STANDARD_PAL_SECAM_DK:
18039         case DRX_STANDARD_PAL_SECAM_I:
18040         case DRX_STANDARD_PAL_SECAM_L:
18041         case DRX_STANDARD_PAL_SECAM_LP:
18042                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
18043                     SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18044                 break;
18045         case DRX_STANDARD_FM:
18046                 return fm_lock_status(demod, lock_stat);
18047 #endif
18048         case DRX_STANDARD_UNKNOWN:      /* fallthrough */
18049         default:
18050                 return -EIO;
18051         }
18052
18053         /* define the SCU command paramters and execute the command */
18054         cmd_scu.parameter_len = 0;
18055         cmd_scu.result_len = 2;
18056         cmd_scu.parameter = NULL;
18057         cmd_scu.result = cmd_result;
18058         rc = scu_command(dev_addr, &cmd_scu);
18059         if (rc != 0) {
18060                 pr_err("error %d\n", rc);
18061                 goto rw_error;
18062         }
18063
18064         /* set the lock status */
18065         if (cmd_scu.result[1] < demod_lock) {
18066                 /* 0x0000 NOT LOCKED */
18067                 *lock_stat = DRX_NOT_LOCKED;
18068         } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
18069                 *lock_stat = DRXJ_DEMOD_LOCK;
18070         } else if (cmd_scu.result[1] <
18071                    SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
18072                 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
18073                 *lock_stat = DRX_LOCKED;
18074         } else {
18075                 /* 0xC000 NEVER LOCKED */
18076                 /* (system will never be able to lock to the signal) */
18077                 *lock_stat = DRX_NEVER_LOCK;
18078         }
18079
18080         return 0;
18081 rw_error:
18082         return -EIO;
18083 }
18084
18085 /*============================================================================*/
18086
18087 /**
18088 * \fn int ctrl_constel()
18089 * \brief Retreive a constellation point via I2C.
18090 * \param demod Pointer to demodulator instance.
18091 * \param complex_nr Pointer to the structure in which to store the
18092                    constellation point.
18093 * \return int.
18094 */
18095 static int
18096 ctrl_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
18097 {
18098         int rc;
18099         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18100                                                      /**< active standard */
18101
18102         /* check arguments */
18103         if ((demod == NULL) || (complex_nr == NULL))
18104                 return -EINVAL;
18105
18106         /* read device info */
18107         standard = ((struct drxj_data *) demod->my_ext_attr)->standard;
18108
18109         /* Read constellation point  */
18110         switch (standard) {
18111         case DRX_STANDARD_8VSB:
18112                 rc = ctrl_get_vsb_constel(demod, complex_nr);
18113                 if (rc != 0) {
18114                         pr_err("error %d\n", rc);
18115                         goto rw_error;
18116                 }
18117                 break;
18118 #ifndef DRXJ_VSB_ONLY
18119         case DRX_STANDARD_ITU_A:        /* fallthrough */
18120         case DRX_STANDARD_ITU_B:        /* fallthrough */
18121         case DRX_STANDARD_ITU_C:
18122                 rc = ctrl_get_qam_constel(demod, complex_nr);
18123                 if (rc != 0) {
18124                         pr_err("error %d\n", rc);
18125                         goto rw_error;
18126                 }
18127                 break;
18128 #endif
18129         case DRX_STANDARD_UNKNOWN:
18130         default:
18131                 return -EIO;
18132         }
18133
18134         return 0;
18135 rw_error:
18136         return -EIO;
18137 }
18138
18139 /*============================================================================*/
18140
18141 /**
18142 * \fn int ctrl_set_standard()
18143 * \brief Set modulation standard to be used.
18144 * \param standard Modulation standard.
18145 * \return int.
18146 *
18147 * Setup stuff for the desired demodulation standard.
18148 * Disable and power down the previous selected demodulation standard
18149 *
18150 */
18151 static int
18152 ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18153 {
18154         struct drxj_data *ext_attr = NULL;
18155         int rc;
18156         enum drx_standard prev_standard;
18157
18158         /* check arguments */
18159         if ((standard == NULL) || (demod == NULL))
18160                 return -EINVAL;
18161
18162         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18163         prev_standard = ext_attr->standard;
18164
18165         /*
18166            Stop and power down previous standard
18167          */
18168         switch (prev_standard) {
18169 #ifndef DRXJ_VSB_ONLY
18170         case DRX_STANDARD_ITU_A:        /* fallthrough */
18171         case DRX_STANDARD_ITU_B:        /* fallthrough */
18172         case DRX_STANDARD_ITU_C:
18173                 rc = power_down_qam(demod, false);
18174                 if (rc != 0) {
18175                         pr_err("error %d\n", rc);
18176                         goto rw_error;
18177                 }
18178                 break;
18179 #endif
18180         case DRX_STANDARD_8VSB:
18181                 rc = power_down_vsb(demod, false);
18182                 if (rc != 0) {
18183                         pr_err("error %d\n", rc);
18184                         goto rw_error;
18185                 }
18186                 break;
18187 #ifndef DRXJ_DIGITAL_ONLY
18188         case DRX_STANDARD_NTSC: /* fallthrough */
18189         case DRX_STANDARD_FM:   /* fallthrough */
18190         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18191         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18192         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
18193         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
18194         case DRX_STANDARD_PAL_SECAM_LP:
18195                 rc = power_down_atv(demod, prev_standard, false);
18196                 if (rc != 0) {
18197                         pr_err("error %d\n", rc);
18198                         goto rw_error;
18199                 }
18200                 break;
18201 #endif
18202         case DRX_STANDARD_UNKNOWN:
18203                 /* Do nothing */
18204                 break;
18205         case DRX_STANDARD_AUTO: /* fallthrough */
18206         default:
18207                 return -EINVAL;
18208         }
18209
18210         /*
18211            Initialize channel independent registers
18212            Power up new standard
18213          */
18214         ext_attr->standard = *standard;
18215
18216         switch (*standard) {
18217 #ifndef DRXJ_VSB_ONLY
18218         case DRX_STANDARD_ITU_A:        /* fallthrough */
18219         case DRX_STANDARD_ITU_B:        /* fallthrough */
18220         case DRX_STANDARD_ITU_C:
18221                 do {
18222                         u16 dummy;
18223                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18224                         if (rc != 0) {
18225                                 pr_err("error %d\n", rc);
18226                                 goto rw_error;
18227                         }
18228                 } while (0);
18229                 break;
18230 #endif
18231         case DRX_STANDARD_8VSB:
18232                 rc = set_vsb_leak_n_gain(demod);
18233                 if (rc != 0) {
18234                         pr_err("error %d\n", rc);
18235                         goto rw_error;
18236                 }
18237                 break;
18238 #ifndef DRXJ_DIGITAL_ONLY
18239         case DRX_STANDARD_NTSC: /* fallthrough */
18240         case DRX_STANDARD_FM:   /* fallthrough */
18241         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18242         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18243         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
18244         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
18245         case DRX_STANDARD_PAL_SECAM_LP:
18246                 rc = set_atv_standard(demod, standard);
18247                 if (rc != 0) {
18248                         pr_err("error %d\n", rc);
18249                         goto rw_error;
18250                 }
18251                 rc = power_up_atv(demod, *standard);
18252                 if (rc != 0) {
18253                         pr_err("error %d\n", rc);
18254                         goto rw_error;
18255                 }
18256                 break;
18257 #endif
18258         default:
18259                 ext_attr->standard = DRX_STANDARD_UNKNOWN;
18260                 return -EINVAL;
18261                 break;
18262         }
18263
18264         return 0;
18265 rw_error:
18266         /* Don't know what the standard is now ... try again */
18267         ext_attr->standard = DRX_STANDARD_UNKNOWN;
18268         return -EIO;
18269 }
18270
18271 /*============================================================================*/
18272
18273 /**
18274 * \fn int ctrl_get_standard()
18275 * \brief Get modulation standard currently used to demodulate.
18276 * \param standard Modulation standard.
18277 * \return int.
18278 *
18279 * Returns 8VSB, NTSC, QAM only.
18280 *
18281 */
18282 static int
18283 ctrl_get_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18284 {
18285         struct drxj_data *ext_attr = NULL;
18286         int rc;
18287         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18288
18289         /* check arguments */
18290         if (standard == NULL)
18291                 return -EINVAL;
18292
18293         *standard = ext_attr->standard;
18294         do {
18295                 u16 dummy;
18296                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18297                 if (rc != 0) {
18298                         pr_err("error %d\n", rc);
18299                         goto rw_error;
18300                 }
18301         } while (0);
18302
18303         return 0;
18304 rw_error:
18305         return -EIO;
18306 }
18307
18308 /*============================================================================*/
18309
18310 /**
18311 * \fn int ctrl_get_cfg_symbol_clock_offset()
18312 * \brief Get frequency offsets of STR.
18313 * \param pointer to s32.
18314 * \return int.
18315 *
18316 */
18317 static int
18318 ctrl_get_cfg_symbol_clock_offset(struct drx_demod_instance *demod, s32 *rate_offset)
18319 {
18320         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18321         int rc;
18322         struct drxj_data *ext_attr = NULL;
18323
18324         /* check arguments */
18325         if (rate_offset == NULL)
18326                 return -EINVAL;
18327
18328         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18329         standard = ext_attr->standard;
18330
18331         switch (standard) {
18332         case DRX_STANDARD_8VSB: /* fallthrough */
18333 #ifndef DRXJ_VSB_ONLY
18334         case DRX_STANDARD_ITU_A:        /* fallthrough */
18335         case DRX_STANDARD_ITU_B:        /* fallthrough */
18336         case DRX_STANDARD_ITU_C:
18337 #endif
18338                 rc = get_str_freq_offset(demod, rate_offset);
18339                 if (rc != 0) {
18340                         pr_err("error %d\n", rc);
18341                         goto rw_error;
18342                 }
18343                 break;
18344         case DRX_STANDARD_NTSC:
18345         case DRX_STANDARD_UNKNOWN:
18346         default:
18347                 return -EINVAL;
18348         }
18349
18350         return 0;
18351 rw_error:
18352         return -EIO;
18353 }
18354
18355 /*============================================================================*/
18356
18357 /**
18358 * \fn int ctrl_power_mode()
18359 * \brief Set the power mode of the device to the specified power mode
18360 * \param demod Pointer to demodulator instance.
18361 * \param mode  Pointer to new power mode.
18362 * \return int.
18363 * \retval 0          Success
18364 * \retval -EIO       I2C error or other failure
18365 * \retval -EINVAL Invalid mode argument.
18366 *
18367 *
18368 */
18369 static int
18370 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
18371 {
18372         struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
18373         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
18374         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
18375         int rc;
18376         u16 sio_cc_pwd_mode = 0;
18377
18378         common_attr = (struct drx_common_attr *) demod->my_common_attr;
18379         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18380         dev_addr = demod->my_i2c_dev_addr;
18381
18382         /* Check arguments */
18383         if (mode == NULL)
18384                 return -EINVAL;
18385
18386         /* If already in requested power mode, do nothing */
18387         if (common_attr->current_power_mode == *mode)
18388                 return 0;
18389
18390         switch (*mode) {
18391         case DRX_POWER_UP:
18392         case DRXJ_POWER_DOWN_MAIN_PATH:
18393                 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
18394                 break;
18395         case DRXJ_POWER_DOWN_CORE:
18396                 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
18397                 break;
18398         case DRXJ_POWER_DOWN_PLL:
18399                 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
18400                 break;
18401         case DRX_POWER_DOWN:
18402                 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
18403                 break;
18404         default:
18405                 /* Unknow sleep mode */
18406                 return -EINVAL;
18407                 break;
18408         }
18409
18410         /* Check if device needs to be powered up */
18411         if ((common_attr->current_power_mode != DRX_POWER_UP)) {
18412                 rc = power_up_device(demod);
18413                 if (rc != 0) {
18414                         pr_err("error %d\n", rc);
18415                         goto rw_error;
18416                 }
18417         }
18418
18419         if ((*mode == DRX_POWER_UP)) {
18420                 /* Restore analog & pin configuartion */
18421         } else {
18422                 /* Power down to requested mode */
18423                 /* Backup some register settings */
18424                 /* Set pins with possible pull-ups connected to them in input mode */
18425                 /* Analog power down */
18426                 /* ADC power down */
18427                 /* Power down device */
18428                 /* stop all comm_exec */
18429                 /*
18430                    Stop and power down previous standard
18431                  */
18432
18433                 switch (ext_attr->standard) {
18434                 case DRX_STANDARD_ITU_A:
18435                 case DRX_STANDARD_ITU_B:
18436                 case DRX_STANDARD_ITU_C:
18437                         rc = power_down_qam(demod, true);
18438                         if (rc != 0) {
18439                                 pr_err("error %d\n", rc);
18440                                 goto rw_error;
18441                         }
18442                         break;
18443                 case DRX_STANDARD_8VSB:
18444                         rc = power_down_vsb(demod, true);
18445                         if (rc != 0) {
18446                                 pr_err("error %d\n", rc);
18447                                 goto rw_error;
18448                         }
18449                         break;
18450                 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18451                 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18452                 case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
18453                 case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
18454                 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
18455                 case DRX_STANDARD_NTSC: /* fallthrough */
18456                 case DRX_STANDARD_FM:
18457                         rc = power_down_atv(demod, ext_attr->standard, true);
18458                         if (rc != 0) {
18459                                 pr_err("error %d\n", rc);
18460                                 goto rw_error;
18461                         }
18462                         break;
18463                 case DRX_STANDARD_UNKNOWN:
18464                         /* Do nothing */
18465                         break;
18466                 case DRX_STANDARD_AUTO: /* fallthrough */
18467                 default:
18468                         return -EIO;
18469                 }
18470
18471                 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
18472                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
18473                         if (rc != 0) {
18474                                 pr_err("error %d\n", rc);
18475                                 goto rw_error;
18476                         }
18477                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
18478                         if (rc != 0) {
18479                                 pr_err("error %d\n", rc);
18480                                 goto rw_error;
18481                         }
18482
18483                         /* Initialize HI, wakeup key especially before put IC to sleep */
18484                         rc = init_hi(demod);
18485                         if (rc != 0) {
18486                                 pr_err("error %d\n", rc);
18487                                 goto rw_error;
18488                         }
18489
18490                         ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
18491                         rc = hi_cfg_command(demod);
18492                         if (rc != 0) {
18493                                 pr_err("error %d\n", rc);
18494                                 goto rw_error;
18495                         }
18496                 }
18497         }
18498
18499         common_attr->current_power_mode = *mode;
18500
18501         return 0;
18502 rw_error:
18503         return -EIO;
18504 }
18505
18506 /*============================================================================*/
18507
18508 /**
18509 * \fn int ctrl_version()
18510 * \brief Report version of microcode and if possible version of device
18511 * \param demod Pointer to demodulator instance.
18512 * \param version_list Pointer to pointer of linked list of versions.
18513 * \return int.
18514 *
18515 * Using static structures so no allocation of memory is needed.
18516 * Filling in all the fields each time, cause you don't know if they are
18517 * changed by the application.
18518 *
18519 * For device:
18520 * Major version number will be last two digits of family number.
18521 * Minor number will be full respin number
18522 * Patch will be metal fix number+1
18523 * Examples:
18524 * DRX3942J A2 => number: 42.1.2 text: "DRX3942J:A2"
18525 * DRX3933J B1 => number: 33.2.1 text: "DRX3933J:B1"
18526 *
18527 */
18528 static int
18529 ctrl_version(struct drx_demod_instance *demod, struct drx_version_list **version_list)
18530 {
18531         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
18532         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
18533         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18534         int rc;
18535         u16 ucode_major_minor = 0;      /* BCD Ma:Ma:Ma:Mi */
18536         u16 ucode_patch = 0;    /* BCD Pa:Pa:Pa:Pa */
18537         u16 major = 0;
18538         u16 minor = 0;
18539         u16 patch = 0;
18540         u16 idx = 0;
18541         u32 jtag = 0;
18542         u16 subtype = 0;
18543         u16 mfx = 0;
18544         u16 bid = 0;
18545         u16 key = 0;
18546         static char ucode_name[] = "Microcode";
18547         static char device_name[] = "Device";
18548
18549         dev_addr = demod->my_i2c_dev_addr;
18550         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18551         common_attr = (struct drx_common_attr *) demod->my_common_attr;
18552
18553         /* Microcode version *************************************** */
18554
18555         ext_attr->v_version[0].module_type = DRX_MODULE_MICROCODE;
18556         ext_attr->v_version[0].module_name = ucode_name;
18557         ext_attr->v_version[0].v_string = ext_attr->v_text[0];
18558
18559         if (common_attr->is_opened == true) {
18560                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_VERSION_HI__A, &ucode_major_minor, 0);
18561                 if (rc != 0) {
18562                         pr_err("error %d\n", rc);
18563                         goto rw_error;
18564                 }
18565                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_VERSION_LO__A, &ucode_patch, 0);
18566                 if (rc != 0) {
18567                         pr_err("error %d\n", rc);
18568                         goto rw_error;
18569                 }
18570
18571                 /* Translate BCD to numbers and string */
18572                 /* TODO: The most significant Ma and Pa will be ignored, check with spec */
18573                 minor = (ucode_major_minor & 0xF);
18574                 ucode_major_minor >>= 4;
18575                 major = (ucode_major_minor & 0xF);
18576                 ucode_major_minor >>= 4;
18577                 major += (10 * (ucode_major_minor & 0xF));
18578                 patch = (ucode_patch & 0xF);
18579                 ucode_patch >>= 4;
18580                 patch += (10 * (ucode_patch & 0xF));
18581                 ucode_patch >>= 4;
18582                 patch += (100 * (ucode_patch & 0xF));
18583         } else {
18584                 /* No microcode uploaded, No Rom existed, set version to 0.0.0 */
18585                 patch = 0;
18586                 minor = 0;
18587                 major = 0;
18588         }
18589         ext_attr->v_version[0].v_major = major;
18590         ext_attr->v_version[0].v_minor = minor;
18591         ext_attr->v_version[0].v_patch = patch;
18592
18593         if (major / 10 != 0) {
18594                 ext_attr->v_version[0].v_string[idx++] =
18595                     ((char)(major / 10)) + '0';
18596                 major %= 10;
18597         }
18598         ext_attr->v_version[0].v_string[idx++] = ((char)major) + '0';
18599         ext_attr->v_version[0].v_string[idx++] = '.';
18600         ext_attr->v_version[0].v_string[idx++] = ((char)minor) + '0';
18601         ext_attr->v_version[0].v_string[idx++] = '.';
18602         if (patch / 100 != 0) {
18603                 ext_attr->v_version[0].v_string[idx++] =
18604                     ((char)(patch / 100)) + '0';
18605                 patch %= 100;
18606         }
18607         if (patch / 10 != 0) {
18608                 ext_attr->v_version[0].v_string[idx++] =
18609                     ((char)(patch / 10)) + '0';
18610                 patch %= 10;
18611         }
18612         ext_attr->v_version[0].v_string[idx++] = ((char)patch) + '0';
18613         ext_attr->v_version[0].v_string[idx] = '\0';
18614
18615         ext_attr->v_list_elements[0].version = &(ext_attr->v_version[0]);
18616         ext_attr->v_list_elements[0].next = &(ext_attr->v_list_elements[1]);
18617
18618         /* Device version *************************************** */
18619         /* Check device id */
18620         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, &key, 0);
18621         if (rc != 0) {
18622                 pr_err("error %d\n", rc);
18623                 goto rw_error;
18624         }
18625         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
18626         if (rc != 0) {
18627                 pr_err("error %d\n", rc);
18628                 goto rw_error;
18629         }
18630         rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0);
18631         if (rc != 0) {
18632                 pr_err("error %d\n", rc);
18633                 goto rw_error;
18634         }
18635         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
18636         if (rc != 0) {
18637                 pr_err("error %d\n", rc);
18638                 goto rw_error;
18639         }
18640         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, key, 0);
18641         if (rc != 0) {
18642                 pr_err("error %d\n", rc);
18643                 goto rw_error;
18644         }
18645
18646         ext_attr->v_version[1].module_type = DRX_MODULE_DEVICE;
18647         ext_attr->v_version[1].module_name = device_name;
18648         ext_attr->v_version[1].v_string = ext_attr->v_text[1];
18649         ext_attr->v_version[1].v_string[0] = 'D';
18650         ext_attr->v_version[1].v_string[1] = 'R';
18651         ext_attr->v_version[1].v_string[2] = 'X';
18652         ext_attr->v_version[1].v_string[3] = '3';
18653         ext_attr->v_version[1].v_string[4] = '9';
18654         ext_attr->v_version[1].v_string[7] = 'J';
18655         ext_attr->v_version[1].v_string[8] = ':';
18656         ext_attr->v_version[1].v_string[11] = '\0';
18657
18658         /* DRX39xxJ type Ax */
18659         /* TODO semantics of mfx and spin are unclear */
18660         subtype = (u16) ((jtag >> 12) & 0xFF);
18661         mfx = (u16) (jtag >> 29);
18662         ext_attr->v_version[1].v_minor = 1;
18663         if (mfx == 0x03)
18664                 ext_attr->v_version[1].v_patch = mfx + 2;
18665         else
18666                 ext_attr->v_version[1].v_patch = mfx + 1;
18667         ext_attr->v_version[1].v_string[6] = ((char)(subtype & 0xF)) + '0';
18668         ext_attr->v_version[1].v_major = (subtype & 0x0F);
18669         subtype >>= 4;
18670         ext_attr->v_version[1].v_string[5] = ((char)(subtype & 0xF)) + '0';
18671         ext_attr->v_version[1].v_major += 10 * subtype;
18672         ext_attr->v_version[1].v_string[9] = 'A';
18673         if (mfx == 0x03)
18674                 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '2';
18675         else
18676                 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '1';
18677
18678         ext_attr->v_list_elements[1].version = &(ext_attr->v_version[1]);
18679         ext_attr->v_list_elements[1].next = (struct drx_version_list *) (NULL);
18680
18681         *version_list = &(ext_attr->v_list_elements[0]);
18682
18683         return 0;
18684
18685 rw_error:
18686         *version_list = (struct drx_version_list *) (NULL);
18687         return -EIO;
18688
18689 }
18690
18691 /*============================================================================*/
18692
18693 /**
18694 * \fn int ctrl_probe_device()
18695 * \brief Probe device, check if it is present
18696 * \param demod Pointer to demodulator instance.
18697 * \return int.
18698 * \retval 0    a drx39xxj device has been detected.
18699 * \retval -EIO no drx39xxj device detected.
18700 *
18701 * This funtion can be caled before open() and after close().
18702 *
18703 */
18704
18705 static int ctrl_probe_device(struct drx_demod_instance *demod)
18706 {
18707         enum drx_power_mode org_power_mode = DRX_POWER_UP;
18708         int ret_status = 0;
18709         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18710         int rc;
18711
18712         common_attr = (struct drx_common_attr *) demod->my_common_attr;
18713
18714         if (common_attr->is_opened == false
18715             || common_attr->current_power_mode != DRX_POWER_UP) {
18716                 struct i2c_device_addr *dev_addr = NULL;
18717                 enum drx_power_mode power_mode = DRX_POWER_UP;
18718                 u32 jtag = 0;
18719
18720                 dev_addr = demod->my_i2c_dev_addr;
18721
18722                 /* Remeber original power mode */
18723                 org_power_mode = common_attr->current_power_mode;
18724
18725                 if (demod->my_common_attr->is_opened == false) {
18726                         rc = power_up_device(demod);
18727                         if (rc != 0) {
18728                                 pr_err("error %d\n", rc);
18729                                 goto rw_error;
18730                         }
18731                         common_attr->current_power_mode = DRX_POWER_UP;
18732                 } else {
18733                         /* Wake-up device, feedback from device */
18734                         rc = ctrl_power_mode(demod, &power_mode);
18735                         if (rc != 0) {
18736                                 pr_err("error %d\n", rc);
18737                                 goto rw_error;
18738                         }
18739                 }
18740                 /* Initialize HI, wakeup key especially */
18741                 rc = init_hi(demod);
18742                 if (rc != 0) {
18743                         pr_err("error %d\n", rc);
18744                         goto rw_error;
18745                 }
18746
18747                 /* Check device id */
18748                 rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0);
18749                 if (rc != 0) {
18750                         pr_err("error %d\n", rc);
18751                         goto rw_error;
18752                 }
18753                 jtag = (jtag >> 12) & 0xFFFF;
18754                 switch (jtag) {
18755                 case 0x3931:    /* fallthrough */
18756                 case 0x3932:    /* fallthrough */
18757                 case 0x3933:    /* fallthrough */
18758                 case 0x3934:    /* fallthrough */
18759                 case 0x3941:    /* fallthrough */
18760                 case 0x3942:    /* fallthrough */
18761                 case 0x3943:    /* fallthrough */
18762                 case 0x3944:    /* fallthrough */
18763                 case 0x3945:    /* fallthrough */
18764                 case 0x3946:
18765                         /* ok , do nothing */
18766                         break;
18767                 default:
18768                         ret_status = -EIO;
18769                         break;
18770                 }
18771
18772                 /* Device was not opened, return to orginal powermode,
18773                    feedback from device */
18774                 rc = ctrl_power_mode(demod, &org_power_mode);
18775                 if (rc != 0) {
18776                         pr_err("error %d\n", rc);
18777                         goto rw_error;
18778                 }
18779         } else {
18780                 /* dummy read to make this function fail in case device
18781                    suddenly disappears after a succesful drx_open */
18782                 do {
18783                         u16 dummy;
18784                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18785                         if (rc != 0) {
18786                                 pr_err("error %d\n", rc);
18787                                 goto rw_error;
18788                         }
18789                 } while (0);
18790         }
18791
18792         return ret_status;
18793
18794 rw_error:
18795         common_attr->current_power_mode = org_power_mode;
18796         return -EIO;
18797 }
18798
18799 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
18800 /*============================================================================*/
18801
18802 /**
18803 * \fn int is_mc_block_audio()
18804 * \brief Check if MC block is Audio or not Audio.
18805 * \param addr        Pointer to demodulator instance.
18806 * \param audioUpload true  if MC block is Audio
18807                      false if MC block not Audio
18808 * \return bool.
18809 */
18810 bool is_mc_block_audio(u32 addr)
18811 {
18812         if ((addr == AUD_XFP_PRAM_4K__A) || (addr == AUD_XDFP_PRAM_4K__A))
18813                 return true;
18814
18815         return false;
18816 }
18817
18818 /*============================================================================*/
18819
18820 /**
18821 * \fn int ctrl_u_code_upload()
18822 * \brief Handle Audio or !Audio part of microcode upload.
18823 * \param demod          Pointer to demodulator instance.
18824 * \param mc_info         Pointer to information about microcode data.
18825 * \param action         Either UCODE_UPLOAD or UCODE_VERIFY.
18826 * \param upload_audio_mc  true  if Audio MC need to be uploaded.
18827                         false if !Audio MC need to be uploaded.
18828 * \return int.
18829 */
18830 static int
18831 ctrl_u_code_upload(struct drx_demod_instance *demod,
18832                    struct drxu_code_info *mc_info,
18833                    enum drxu_code_actionaction, bool upload_audio_mc)
18834 {
18835         u16 i = 0;
18836         u16 mc_nr_of_blks = 0;
18837         u16 mc_magic_word = 0;
18838         u8 *mc_data = (u8 *)(NULL);
18839         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
18840         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
18841         int rc;
18842
18843         dev_addr = demod->my_i2c_dev_addr;
18844         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18845
18846         /* Check arguments */
18847         if (!mc_info || !mc_info->mc_data) {
18848                 return -EINVAL;
18849         }
18850
18851         mc_data = mc_info->mc_data;
18852
18853         /* Check data */
18854         mc_magic_word = u_code_read16(mc_data);
18855         mc_data += sizeof(u16);
18856         mc_nr_of_blks = u_code_read16(mc_data);
18857         mc_data += sizeof(u16);
18858
18859         if ((mc_magic_word != DRXJ_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
18860                 /* wrong endianess or wrong data ? */
18861                 return -EINVAL;
18862         }
18863
18864         /* Process microcode blocks */
18865         for (i = 0; i < mc_nr_of_blks; i++) {
18866                 struct drxu_code_block_hdr block_hdr;
18867                 u16 mc_block_nr_bytes = 0;
18868
18869                 /* Process block header */
18870                 block_hdr.addr = u_code_read32(mc_data);
18871                 mc_data += sizeof(u32);
18872                 block_hdr.size = u_code_read16(mc_data);
18873                 mc_data += sizeof(u16);
18874                 block_hdr.flags = u_code_read16(mc_data);
18875                 mc_data += sizeof(u16);
18876                 block_hdr.CRC = u_code_read16(mc_data);
18877                 mc_data += sizeof(u16);
18878
18879                 /* Check block header on:
18880                    - no data
18881                    - data larger then 64Kb
18882                    - if CRC enabled check CRC
18883                  */
18884                 if ((block_hdr.size == 0) ||
18885                     (block_hdr.size > 0x7FFF) ||
18886                     (((block_hdr.flags & DRXJ_UCODE_CRC_FLAG) != 0) &&
18887                      (block_hdr.CRC != u_code_compute_crc(mc_data, block_hdr.size)))
18888                     ) {
18889                         /* Wrong data ! */
18890                         return -EINVAL;
18891                 }
18892
18893                 mc_block_nr_bytes = block_hdr.size * sizeof(u16);
18894
18895                 /* Perform the desired action */
18896                 /* Check which part of MC need to be uploaded - Audio or not Audio */
18897                 if (is_mc_block_audio(block_hdr.addr) == upload_audio_mc) {
18898                         switch (action) {
18899             /*===================================================================*/
18900                         case UCODE_UPLOAD:
18901                                 {
18902                                         /* Upload microcode */
18903                                         if (demod->my_access_funct->
18904                                             write_block_func(dev_addr,
18905                                                            (dr_xaddr_t) block_hdr.
18906                                                            addr, mc_block_nr_bytes,
18907                                                            mc_data,
18908                                                            0x0000) !=
18909                                             0) {
18910                                                 return -EIO;
18911                                         }
18912                                 }
18913                                 break;
18914
18915             /*===================================================================*/
18916                         case UCODE_VERIFY:
18917                                 {
18918                                         int result = 0;
18919                                         u8 mc_data_buffer
18920                                             [DRXJ_UCODE_MAX_BUF_SIZE];
18921                                         u32 bytes_to_compare = 0;
18922                                         u32 bytes_left_to_compare = 0;
18923                                         u32 curr_addr = (dr_xaddr_t) 0;
18924                                         u8 *curr_ptr = NULL;
18925
18926                                         bytes_left_to_compare = mc_block_nr_bytes;
18927                                         curr_addr = block_hdr.addr;
18928                                         curr_ptr = mc_data;
18929
18930                                         while (bytes_left_to_compare != 0) {
18931                                                 if (bytes_left_to_compare > ((u32)DRXJ_UCODE_MAX_BUF_SIZE))
18932                                                         bytes_to_compare = ((u32)DRXJ_UCODE_MAX_BUF_SIZE);
18933                                                 else
18934                                                         bytes_to_compare = bytes_left_to_compare;
18935
18936                                                 if (demod->my_access_funct->
18937                                                     read_block_func(dev_addr,
18938                                                                   curr_addr,
18939                                                                   (u16)
18940                                                                   bytes_to_compare,
18941                                                                   (u8 *)
18942                                                                   mc_data_buffer,
18943                                                                   0x0000) !=
18944                                                     0) {
18945                                                         return -EIO;
18946                                                 }
18947
18948                                                 result =
18949                                                     drxbsp_hst_memcmp(curr_ptr,
18950                                                                       mc_data_buffer,
18951                                                                       bytes_to_compare);
18952
18953                                                 if (result != 0)
18954                                                         return -EIO;
18955
18956                                                 curr_addr +=
18957                                                     ((dr_xaddr_t)
18958                                                      (bytes_to_compare / 2));
18959                                                 curr_ptr =
18960                                                     &(curr_ptr[bytes_to_compare]);
18961                                                 bytes_left_to_compare -=
18962                                                     ((u32) bytes_to_compare);
18963                                         }       /* while( bytes_to_compare > DRXJ_UCODE_MAX_BUF_SIZE ) */
18964                                 }
18965                                 break;
18966
18967             /*===================================================================*/
18968                         default:
18969                                 return -EINVAL;
18970                                 break;
18971
18972                         }       /* switch ( action ) */
18973                 }
18974
18975                 /* if( is_mc_block_audio( block_hdr.addr ) == upload_audio_mc ) */
18976                 /* Next block */
18977                 mc_data += mc_block_nr_bytes;
18978         }                       /* for( i = 0 ; i<mc_nr_of_blks ; i++ ) */
18979
18980         if (!upload_audio_mc)
18981                 ext_attr->flag_aud_mc_uploaded = false;
18982
18983         return 0;
18984 }
18985 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
18986
18987 /*============================================================================*/
18988 /*== CTRL Set/Get Config related functions ===================================*/
18989 /*============================================================================*/
18990
18991 /*===== SigStrength() =========================================================*/
18992 /**
18993 * \fn int ctrl_sig_strength()
18994 * \brief Retrieve signal strength.
18995 * \param devmod Pointer to demodulator instance.
18996 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
18997 * \return int.
18998 * \retval 0 sig_strength contains valid data.
18999 * \retval -EINVAL sig_strength is NULL.
19000 * \retval -EIO Erroneous data, sig_strength contains invalid data.
19001
19002 */
19003 static int
19004 ctrl_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
19005 {
19006         struct drxj_data *ext_attr = NULL;
19007         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
19008         int rc;
19009
19010         /* Check arguments */
19011         if ((sig_strength == NULL) || (demod == NULL))
19012                 return -EINVAL;
19013
19014         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19015         standard = ext_attr->standard;
19016         *sig_strength = 0;
19017
19018         /* Signal strength indication for each standard */
19019         switch (standard) {
19020         case DRX_STANDARD_8VSB: /* fallthrough */
19021 #ifndef DRXJ_VSB_ONLY
19022         case DRX_STANDARD_ITU_A:        /* fallthrough */
19023         case DRX_STANDARD_ITU_B:        /* fallthrough */
19024         case DRX_STANDARD_ITU_C:
19025 #endif
19026                 rc = get_sig_strength(demod, sig_strength);
19027                 if (rc != 0) {
19028                         pr_err("error %d\n", rc);
19029                         goto rw_error;
19030                 }
19031                 break;
19032 #ifndef DRXJ_DIGITAL_ONLY
19033         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19034         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19035         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19036         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19037         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19038         case DRX_STANDARD_NTSC: /* fallthrough */
19039         case DRX_STANDARD_FM:
19040                 rc = get_atv_sig_strength(demod, sig_strength);
19041                 if (rc != 0) {
19042                         pr_err("error %d\n", rc);
19043                         goto rw_error;
19044                 }
19045                 break;
19046 #endif
19047         case DRX_STANDARD_UNKNOWN:      /* fallthrough */
19048         default:
19049                 return -EINVAL;
19050         }
19051
19052         /* TODO */
19053         /* find out if signal strength is calculated in the same way for all standards */
19054         return 0;
19055 rw_error:
19056         return -EIO;
19057 }
19058
19059 /*============================================================================*/
19060 /**
19061 * \fn int ctrl_get_cfg_oob_misc()
19062 * \brief Get current state information of OOB.
19063 * \param pointer to struct drxj_cfg_oob_misc.
19064 * \return int.
19065 *
19066 */
19067 #ifndef DRXJ_DIGITAL_ONLY
19068 static int
19069 ctrl_get_cfg_oob_misc(struct drx_demod_instance *demod, struct drxj_cfg_oob_misc *misc)
19070 {
19071         struct i2c_device_addr *dev_addr = NULL;
19072         int rc;
19073         u16 lock = 0U;
19074         u16 state = 0U;
19075         u16 data = 0U;
19076         u16 digital_agc_mant = 0U;
19077         u16 digital_agc_exp = 0U;
19078
19079         /* check arguments */
19080         if (misc == NULL)
19081                 return -EINVAL;
19082
19083         dev_addr = demod->my_i2c_dev_addr;
19084
19085         /* TODO */
19086         /* check if the same registers are used for all standards (QAM/VSB/ATV) */
19087         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC, 0);
19088         if (rc != 0) {
19089                 pr_err("error %d\n", rc);
19090                 goto rw_error;
19091         }
19092         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &misc->agc.RFAGC, 0);
19093         if (rc != 0) {
19094                 pr_err("error %d\n", rc);
19095                 goto rw_error;
19096         }
19097         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
19098         if (rc != 0) {
19099                 pr_err("error %d\n", rc);
19100                 goto rw_error;
19101         }
19102
19103         digital_agc_mant = data & ORX_FWP_SRC_DGN_W_MANT__M;
19104         digital_agc_exp = (data & ORX_FWP_SRC_DGN_W_EXP__M)
19105             >> ORX_FWP_SRC_DGN_W_EXP__B;
19106         misc->agc.digital_agc = digital_agc_mant << digital_agc_exp;
19107
19108         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_LOCK__A, &lock, 0);
19109         if (rc != 0) {
19110                 pr_err("error %d\n", rc);
19111                 goto rw_error;
19112         }
19113
19114         misc->ana_gain_lock = ((lock & 0x0001) ? true : false);
19115         misc->dig_gain_lock = ((lock & 0x0002) ? true : false);
19116         misc->freq_lock = ((lock & 0x0004) ? true : false);
19117         misc->phase_lock = ((lock & 0x0008) ? true : false);
19118         misc->sym_timing_lock = ((lock & 0x0010) ? true : false);
19119         misc->eq_lock = ((lock & 0x0020) ? true : false);
19120
19121         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_STATE__A, &state, 0);
19122         if (rc != 0) {
19123                 pr_err("error %d\n", rc);
19124                 goto rw_error;
19125         }
19126         misc->state = (state >> 8) & 0xff;
19127
19128         return 0;
19129 rw_error:
19130         return -EIO;
19131 }
19132 #endif
19133
19134 /**
19135 * \fn int ctrl_get_cfg_vsb_misc()
19136 * \brief Get current state information of OOB.
19137 * \param pointer to struct drxj_cfg_oob_misc.
19138 * \return int.
19139 *
19140 */
19141 static int
19142 ctrl_get_cfg_vsb_misc(struct drx_demod_instance *demod, struct drxj_cfg_vsb_misc *misc)
19143 {
19144         struct i2c_device_addr *dev_addr = NULL;
19145         int rc;
19146
19147         /* check arguments */
19148         if (misc == NULL)
19149                 return -EINVAL;
19150
19151         dev_addr = demod->my_i2c_dev_addr;
19152
19153         rc = get_vsb_symb_err(dev_addr, &misc->symb_error);
19154         if (rc != 0) {
19155                 pr_err("error %d\n", rc);
19156                 goto rw_error;
19157         }
19158
19159         return 0;
19160 rw_error:
19161         return -EIO;
19162 }
19163
19164 /*============================================================================*/
19165
19166 /**
19167 * \fn int ctrl_set_cfg_agc_if()
19168 * \brief Set IF AGC.
19169 * \param demod demod instance
19170 * \param agc_settings If agc configuration
19171 * \return int.
19172 *
19173 * Check arguments
19174 * Dispatch handling to standard specific function.
19175 *
19176 */
19177 static int
19178 ctrl_set_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19179 {
19180         /* check arguments */
19181         if (agc_settings == NULL)
19182                 return -EINVAL;
19183
19184         switch (agc_settings->ctrl_mode) {
19185         case DRX_AGC_CTRL_AUTO: /* fallthrough */
19186         case DRX_AGC_CTRL_USER: /* fallthrough */
19187         case DRX_AGC_CTRL_OFF:  /* fallthrough */
19188                 break;
19189         default:
19190                 return -EINVAL;
19191         }
19192
19193         /* Distpatch */
19194         switch (agc_settings->standard) {
19195         case DRX_STANDARD_8VSB: /* fallthrough */
19196 #ifndef DRXJ_VSB_ONLY
19197         case DRX_STANDARD_ITU_A:        /* fallthrough */
19198         case DRX_STANDARD_ITU_B:        /* fallthrough */
19199         case DRX_STANDARD_ITU_C:
19200 #endif
19201 #ifndef DRXJ_DIGITAL_ONLY
19202         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19203         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19204         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19205         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19206         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19207         case DRX_STANDARD_NTSC: /* fallthrough */
19208         case DRX_STANDARD_FM:
19209 #endif
19210                 return set_agc_if(demod, agc_settings, true);
19211         case DRX_STANDARD_UNKNOWN:
19212         default:
19213                 return -EINVAL;
19214         }
19215
19216         return 0;
19217 }
19218
19219 /*============================================================================*/
19220
19221 /**
19222 * \fn int ctrl_get_cfg_agc_if()
19223 * \brief Retrieve IF AGC settings.
19224 * \param demod demod instance
19225 * \param agc_settings If agc configuration
19226 * \return int.
19227 *
19228 * Check arguments
19229 * Dispatch handling to standard specific function.
19230 *
19231 */
19232 static int
19233 ctrl_get_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19234 {
19235         /* check arguments */
19236         if (agc_settings == NULL)
19237                 return -EINVAL;
19238
19239         /* Distpatch */
19240         switch (agc_settings->standard) {
19241         case DRX_STANDARD_8VSB: /* fallthrough */
19242 #ifndef DRXJ_VSB_ONLY
19243         case DRX_STANDARD_ITU_A:        /* fallthrough */
19244         case DRX_STANDARD_ITU_B:        /* fallthrough */
19245         case DRX_STANDARD_ITU_C:
19246 #endif
19247 #ifndef DRXJ_DIGITAL_ONLY
19248         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19249         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19250         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19251         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19252         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19253         case DRX_STANDARD_NTSC: /* fallthrough */
19254         case DRX_STANDARD_FM:
19255 #endif
19256                 return get_agc_if(demod, agc_settings);
19257         case DRX_STANDARD_UNKNOWN:
19258         default:
19259                 return -EINVAL;
19260         }
19261
19262         return 0;
19263 }
19264
19265 /*============================================================================*/
19266
19267 /**
19268 * \fn int ctrl_set_cfg_agc_rf()
19269 * \brief Set RF AGC.
19270 * \param demod demod instance
19271 * \param agc_settings rf agc configuration
19272 * \return int.
19273 *
19274 * Check arguments
19275 * Dispatch handling to standard specific function.
19276 *
19277 */
19278 static int
19279 ctrl_set_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19280 {
19281         /* check arguments */
19282         if (agc_settings == NULL)
19283                 return -EINVAL;
19284
19285         switch (agc_settings->ctrl_mode) {
19286         case DRX_AGC_CTRL_AUTO: /* fallthrough */
19287         case DRX_AGC_CTRL_USER: /* fallthrough */
19288         case DRX_AGC_CTRL_OFF:
19289                 break;
19290         default:
19291                 return -EINVAL;
19292         }
19293
19294         /* Distpatch */
19295         switch (agc_settings->standard) {
19296         case DRX_STANDARD_8VSB: /* fallthrough */
19297 #ifndef DRXJ_VSB_ONLY
19298         case DRX_STANDARD_ITU_A:        /* fallthrough */
19299         case DRX_STANDARD_ITU_B:        /* fallthrough */
19300         case DRX_STANDARD_ITU_C:
19301 #endif
19302 #ifndef DRXJ_DIGITAL_ONLY
19303         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19304         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19305         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19306         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19307         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19308         case DRX_STANDARD_NTSC: /* fallthrough */
19309         case DRX_STANDARD_FM:
19310 #endif
19311                 return set_agc_rf(demod, agc_settings, true);
19312         case DRX_STANDARD_UNKNOWN:
19313         default:
19314                 return -EINVAL;
19315         }
19316
19317         return 0;
19318 }
19319
19320 /*============================================================================*/
19321
19322 /**
19323 * \fn int ctrl_get_cfg_agc_rf()
19324 * \brief Retrieve RF AGC settings.
19325 * \param demod demod instance
19326 * \param agc_settings Rf agc configuration
19327 * \return int.
19328 *
19329 * Check arguments
19330 * Dispatch handling to standard specific function.
19331 *
19332 */
19333 static int
19334 ctrl_get_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19335 {
19336         /* check arguments */
19337         if (agc_settings == NULL)
19338                 return -EINVAL;
19339
19340         /* Distpatch */
19341         switch (agc_settings->standard) {
19342         case DRX_STANDARD_8VSB: /* fallthrough */
19343 #ifndef DRXJ_VSB_ONLY
19344         case DRX_STANDARD_ITU_A:        /* fallthrough */
19345         case DRX_STANDARD_ITU_B:        /* fallthrough */
19346         case DRX_STANDARD_ITU_C:
19347 #endif
19348 #ifndef DRXJ_DIGITAL_ONLY
19349         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19350         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19351         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19352         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19353         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19354         case DRX_STANDARD_NTSC: /* fallthrough */
19355         case DRX_STANDARD_FM:
19356 #endif
19357                 return get_agc_rf(demod, agc_settings);
19358         case DRX_STANDARD_UNKNOWN:
19359         default:
19360                 return -EINVAL;
19361         }
19362
19363         return 0;
19364 }
19365
19366 /*============================================================================*/
19367
19368 /**
19369 * \fn int ctrl_get_cfg_agc_internal()
19370 * \brief Retrieve internal AGC value.
19371 * \param demod demod instance
19372 * \param u16
19373 * \return int.
19374 *
19375 * Check arguments
19376 * Dispatch handling to standard specific function.
19377 *
19378 */
19379 static int
19380 ctrl_get_cfg_agc_internal(struct drx_demod_instance *demod, u16 *agc_internal)
19381 {
19382         struct i2c_device_addr *dev_addr = NULL;
19383         int rc;
19384         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
19385         struct drxj_data *ext_attr = NULL;
19386         u16 iqm_cf_scale_sh = 0;
19387         u16 iqm_cf_power = 0;
19388         u16 iqm_cf_amp = 0;
19389         u16 iqm_cf_gain = 0;
19390
19391         /* check arguments */
19392         if (agc_internal == NULL)
19393                 return -EINVAL;
19394         dev_addr = demod->my_i2c_dev_addr;
19395         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19396
19397         rc = ctrl_lock_status(demod, &lock_status);
19398         if (rc != 0) {
19399                 pr_err("error %d\n", rc);
19400                 goto rw_error;
19401         }
19402         if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
19403                 *agc_internal = 0;
19404                 return 0;
19405         }
19406
19407         /* Distpatch */
19408         switch (ext_attr->standard) {
19409         case DRX_STANDARD_8VSB:
19410                 iqm_cf_gain = 57;
19411                 break;
19412 #ifndef DRXJ_VSB_ONLY
19413         case DRX_STANDARD_ITU_A:
19414         case DRX_STANDARD_ITU_B:
19415         case DRX_STANDARD_ITU_C:
19416                 switch (ext_attr->constellation) {
19417                 case DRX_CONSTELLATION_QAM256:
19418                 case DRX_CONSTELLATION_QAM128:
19419                 case DRX_CONSTELLATION_QAM32:
19420                 case DRX_CONSTELLATION_QAM16:
19421                         iqm_cf_gain = 57;
19422                         break;
19423                 case DRX_CONSTELLATION_QAM64:
19424                         iqm_cf_gain = 56;
19425                         break;
19426                 default:
19427                         return -EIO;
19428                 }
19429                 break;
19430 #endif
19431         default:
19432                 return -EINVAL;
19433         }
19434
19435         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_POW__A, &iqm_cf_power, 0);
19436         if (rc != 0) {
19437                 pr_err("error %d\n", rc);
19438                 goto rw_error;
19439         }
19440         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_SCALE_SH__A, &iqm_cf_scale_sh, 0);
19441         if (rc != 0) {
19442                 pr_err("error %d\n", rc);
19443                 goto rw_error;
19444         }
19445         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_AMP__A, &iqm_cf_amp, 0);
19446         if (rc != 0) {
19447                 pr_err("error %d\n", rc);
19448                 goto rw_error;
19449         }
19450         /* IQM_CF_PWR_CORRECTION_dB = 3;
19451            P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
19452         /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
19453            -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
19454            +6*7+10*log10(1+0.115/4); */
19455         /* PadcdB = P4dB +3 -6 +60; dBmV */
19456         *agc_internal = (u16) (log1_times100(iqm_cf_power)
19457                                 - 2 * log1_times100(iqm_cf_amp)
19458                                 - iqm_cf_gain - 120 * iqm_cf_scale_sh + 781);
19459
19460         return 0;
19461 rw_error:
19462         return -EIO;
19463 }
19464
19465 /*============================================================================*/
19466
19467 /**
19468 * \fn int ctrl_set_cfg_pre_saw()
19469 * \brief Set Pre-saw reference.
19470 * \param demod demod instance
19471 * \param u16 *
19472 * \return int.
19473 *
19474 * Check arguments
19475 * Dispatch handling to standard specific function.
19476 *
19477 */
19478 static int
19479 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19480 {
19481         struct i2c_device_addr *dev_addr = NULL;
19482         struct drxj_data *ext_attr = NULL;
19483         int rc;
19484
19485         dev_addr = demod->my_i2c_dev_addr;
19486         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19487
19488         /* check arguments */
19489         if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
19490             ) {
19491                 return -EINVAL;
19492         }
19493
19494         /* Only if standard is currently active */
19495         if ((ext_attr->standard == pre_saw->standard) ||
19496             (DRXJ_ISQAMSTD(ext_attr->standard) &&
19497              DRXJ_ISQAMSTD(pre_saw->standard)) ||
19498             (DRXJ_ISATVSTD(ext_attr->standard) &&
19499              DRXJ_ISATVSTD(pre_saw->standard))) {
19500                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
19501                 if (rc != 0) {
19502                         pr_err("error %d\n", rc);
19503                         goto rw_error;
19504                 }
19505         }
19506
19507         /* Store pre-saw settings */
19508         switch (pre_saw->standard) {
19509         case DRX_STANDARD_8VSB:
19510                 ext_attr->vsb_pre_saw_cfg = *pre_saw;
19511                 break;
19512 #ifndef DRXJ_VSB_ONLY
19513         case DRX_STANDARD_ITU_A:        /* fallthrough */
19514         case DRX_STANDARD_ITU_B:        /* fallthrough */
19515         case DRX_STANDARD_ITU_C:
19516                 ext_attr->qam_pre_saw_cfg = *pre_saw;
19517                 break;
19518 #endif
19519 #ifndef DRXJ_DIGITAL_ONLY
19520         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19521         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19522         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19523         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19524         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19525         case DRX_STANDARD_NTSC: /* fallthrough */
19526         case DRX_STANDARD_FM:
19527                 ext_attr->atv_pre_saw_cfg = *pre_saw;
19528                 break;
19529 #endif
19530         default:
19531                 return -EINVAL;
19532         }
19533
19534         return 0;
19535 rw_error:
19536         return -EIO;
19537 }
19538
19539 /*============================================================================*/
19540
19541 /**
19542 * \fn int ctrl_set_cfg_afe_gain()
19543 * \brief Set AFE Gain.
19544 * \param demod demod instance
19545 * \param u16 *
19546 * \return int.
19547 *
19548 * Check arguments
19549 * Dispatch handling to standard specific function.
19550 *
19551 */
19552 static int
19553 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19554 {
19555         struct i2c_device_addr *dev_addr = NULL;
19556         struct drxj_data *ext_attr = NULL;
19557         int rc;
19558         u8 gain = 0;
19559
19560         /* check arguments */
19561         if (afe_gain == NULL)
19562                 return -EINVAL;
19563
19564         dev_addr = demod->my_i2c_dev_addr;
19565         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19566
19567         switch (afe_gain->standard) {
19568         case DRX_STANDARD_8VSB: /* fallthrough */
19569 #ifndef DRXJ_VSB_ONLY
19570         case DRX_STANDARD_ITU_A:        /* fallthrough */
19571         case DRX_STANDARD_ITU_B:        /* fallthrough */
19572         case DRX_STANDARD_ITU_C:
19573 #endif
19574                 /* Do nothing */
19575                 break;
19576         default:
19577                 return -EINVAL;
19578         }
19579
19580         /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
19581            So I (PJ) think interface requires choice between auto, user mode */
19582
19583         if (afe_gain->gain >= 329)
19584                 gain = 15;
19585         else if (afe_gain->gain <= 147)
19586                 gain = 0;
19587         else
19588                 gain = (afe_gain->gain - 140 + 6) / 13;
19589
19590         /* Only if standard is currently active */
19591         if (ext_attr->standard == afe_gain->standard) {
19592                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
19593                         if (rc != 0) {
19594                                 pr_err("error %d\n", rc);
19595                                 goto rw_error;
19596                         }
19597                 }
19598
19599         /* Store AFE Gain settings */
19600         switch (afe_gain->standard) {
19601         case DRX_STANDARD_8VSB:
19602                 ext_attr->vsb_pga_cfg = gain * 13 + 140;
19603                 break;
19604 #ifndef DRXJ_VSB_ONLY
19605         case DRX_STANDARD_ITU_A:        /* fallthrough */
19606         case DRX_STANDARD_ITU_B:        /* fallthrough */
19607         case DRX_STANDARD_ITU_C:
19608                 ext_attr->qam_pga_cfg = gain * 13 + 140;
19609                 break;
19610 #endif
19611         default:
19612                 return -EIO;
19613         }
19614
19615         return 0;
19616 rw_error:
19617         return -EIO;
19618 }
19619
19620 /*============================================================================*/
19621
19622 /**
19623 * \fn int ctrl_get_cfg_pre_saw()
19624 * \brief Get Pre-saw reference setting.
19625 * \param demod demod instance
19626 * \param u16 *
19627 * \return int.
19628 *
19629 * Check arguments
19630 * Dispatch handling to standard specific function.
19631 *
19632 */
19633 static int
19634 ctrl_get_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19635 {
19636         struct drxj_data *ext_attr = NULL;
19637
19638         /* check arguments */
19639         if (pre_saw == NULL)
19640                 return -EINVAL;
19641
19642         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19643
19644         switch (pre_saw->standard) {
19645         case DRX_STANDARD_8VSB:
19646                 *pre_saw = ext_attr->vsb_pre_saw_cfg;
19647                 break;
19648 #ifndef DRXJ_VSB_ONLY
19649         case DRX_STANDARD_ITU_A:        /* fallthrough */
19650         case DRX_STANDARD_ITU_B:        /* fallthrough */
19651         case DRX_STANDARD_ITU_C:
19652                 *pre_saw = ext_attr->qam_pre_saw_cfg;
19653                 break;
19654 #endif
19655 #ifndef DRXJ_DIGITAL_ONLY
19656         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19657         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19658         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19659         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19660         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19661         case DRX_STANDARD_NTSC:
19662                 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
19663                 *pre_saw = ext_attr->atv_pre_saw_cfg;
19664                 break;
19665         case DRX_STANDARD_FM:
19666                 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_FM;
19667                 *pre_saw = ext_attr->atv_pre_saw_cfg;
19668                 break;
19669 #endif
19670         default:
19671                 return -EINVAL;
19672         }
19673
19674         return 0;
19675 }
19676
19677 /*============================================================================*/
19678
19679 /**
19680 * \fn int ctrl_get_cfg_afe_gain()
19681 * \brief Get AFE Gain.
19682 * \param demod demod instance
19683 * \param u16 *
19684 * \return int.
19685 *
19686 * Check arguments
19687 * Dispatch handling to standard specific function.
19688 *
19689 */
19690 static int
19691 ctrl_get_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19692 {
19693         struct drxj_data *ext_attr = NULL;
19694
19695         /* check arguments */
19696         if (afe_gain == NULL)
19697                 return -EINVAL;
19698
19699         ext_attr = demod->my_ext_attr;
19700
19701         switch (afe_gain->standard) {
19702         case DRX_STANDARD_8VSB:
19703                 afe_gain->gain = ext_attr->vsb_pga_cfg;
19704                 break;
19705 #ifndef DRXJ_VSB_ONLY
19706         case DRX_STANDARD_ITU_A:        /* fallthrough */
19707         case DRX_STANDARD_ITU_B:        /* fallthrough */
19708         case DRX_STANDARD_ITU_C:
19709                 afe_gain->gain = ext_attr->qam_pga_cfg;
19710                 break;
19711 #endif
19712         default:
19713                 return -EINVAL;
19714         }
19715
19716         return 0;
19717 }
19718
19719 /*============================================================================*/
19720
19721 /**
19722 * \fn int ctrl_get_fec_meas_seq_count()
19723 * \brief Get FEC measurement sequnce number.
19724 * \param demod demod instance
19725 * \param u16 *
19726 * \return int.
19727 *
19728 * Check arguments
19729 * Dispatch handling to standard specific function.
19730 *
19731 */
19732 static int
19733 ctrl_get_fec_meas_seq_count(struct drx_demod_instance *demod, u16 *fec_meas_seq_count)
19734 {
19735         int rc;
19736         /* check arguments */
19737         if (fec_meas_seq_count == NULL)
19738                 return -EINVAL;
19739
19740         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, fec_meas_seq_count, 0);
19741         if (rc != 0) {
19742                 pr_err("error %d\n", rc);
19743                 goto rw_error;
19744         }
19745
19746         return 0;
19747 rw_error:
19748         return -EIO;
19749 }
19750
19751 /*============================================================================*/
19752
19753 /**
19754 * \fn int ctrl_get_accum_cr_rs_cw_err()
19755 * \brief Get accumulative corrected RS codeword number.
19756 * \param demod demod instance
19757 * \param u32 *
19758 * \return int.
19759 *
19760 * Check arguments
19761 * Dispatch handling to standard specific function.
19762 *
19763 */
19764 static int
19765 ctrl_get_accum_cr_rs_cw_err(struct drx_demod_instance *demod, u32 *accum_cr_rs_cw_err)
19766 {
19767         int rc;
19768         if (accum_cr_rs_cw_err == NULL)
19769                 return -EINVAL;
19770
19771         rc = DRXJ_DAP.read_reg32func(demod->my_i2c_dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, accum_cr_rs_cw_err, 0);
19772         if (rc != 0) {
19773                 pr_err("error %d\n", rc);
19774                 goto rw_error;
19775         }
19776
19777         return 0;
19778 rw_error:
19779         return -EIO;
19780 }
19781
19782 /**
19783 * \fn int ctrl_set_cfg()
19784 * \brief Set 'some' configuration of the device.
19785 * \param devmod Pointer to demodulator instance.
19786 * \param config Pointer to configuration parameters (type and data).
19787 * \return int.
19788
19789 */
19790 static int ctrl_set_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
19791 {
19792         int rc;
19793
19794         if (config == NULL)
19795                 return -EINVAL;
19796
19797         do {
19798                 u16 dummy;
19799                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
19800                 if (rc != 0) {
19801                         pr_err("error %d\n", rc);
19802                         goto rw_error;
19803                 }
19804         } while (0);
19805         switch (config->cfg_type) {
19806         case DRX_CFG_MPEG_OUTPUT:
19807                 return ctrl_set_cfg_mpeg_output(demod,
19808                                             (struct drx_cfg_mpeg_output *) config->
19809                                             cfg_data);
19810         case DRX_CFG_PINS_SAFE_MODE:
19811                 return ctrl_set_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
19812         case DRXJ_CFG_AGC_RF:
19813                 return ctrl_set_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
19814         case DRXJ_CFG_AGC_IF:
19815                 return ctrl_set_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
19816         case DRXJ_CFG_PRE_SAW:
19817                 return ctrl_set_cfg_pre_saw(demod,
19818                                         (struct drxj_cfg_pre_saw *) config->cfg_data);
19819         case DRXJ_CFG_AFE_GAIN:
19820                 return ctrl_set_cfg_afe_gain(demod,
19821                                          (struct drxj_cfg_afe_gain *) config->cfg_data);
19822         case DRXJ_CFG_SMART_ANT:
19823                 return ctrl_set_cfg_smart_ant(demod,
19824                                           (struct drxj_cfg_smart_ant *) (config->
19825                                                                 cfg_data));
19826         case DRXJ_CFG_RESET_PACKET_ERR:
19827                 return ctrl_set_cfg_reset_pkt_err(demod);
19828 #ifndef DRXJ_DIGITAL_ONLY
19829         case DRXJ_CFG_OOB_PRE_SAW:
19830                 return ctrl_set_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
19831         case DRXJ_CFG_OOB_LO_POW:
19832                 return ctrl_set_cfg_oob_lo_power(demod,
19833                                             (enum drxj_cfg_oob_lo_power *) (config->
19834                                                                     cfg_data));
19835         case DRXJ_CFG_ATV_MISC:
19836                 return ctrl_set_cfg_atv_misc(demod,
19837                                          (struct drxj_cfg_atv_misc *) config->cfg_data);
19838         case DRXJ_CFG_ATV_EQU_COEF:
19839                 return ctrl_set_cfg_atv_equ_coef(demod,
19840                                             (struct drxj_cfg_atv_equ_coef *) config->
19841                                             cfg_data);
19842         case DRXJ_CFG_ATV_OUTPUT:
19843                 return ctrl_set_cfg_atv_output(demod,
19844                                            (struct drxj_cfg_atv_output *) config->
19845                                            cfg_data);
19846 #endif
19847         case DRXJ_CFG_MPEG_OUTPUT_MISC:
19848                 return ctrl_set_cfg_mpeg_output_misc(demod,
19849                                                 (struct drxj_cfg_mpeg_output_misc *)
19850                                                 config->cfg_data);
19851 #ifndef DRXJ_EXCLUDE_AUDIO
19852         case DRX_CFG_AUD_VOLUME:
19853                 return aud_ctrl_set_cfg_volume(demod,
19854                                            (struct drx_cfg_aud_volume *) config->
19855                                            cfg_data);
19856         case DRX_CFG_I2S_OUTPUT:
19857                 return aud_ctrl_set_cfg_output_i2s(demod,
19858                                               (struct drx_cfg_i2s_output *) config->
19859                                               cfg_data);
19860         case DRX_CFG_AUD_AUTOSOUND:
19861                 return aud_ctr_setl_cfg_auto_sound(demod, (enum drx_cfg_aud_auto_sound *)
19862                                               config->cfg_data);
19863         case DRX_CFG_AUD_ASS_THRES:
19864                 return aud_ctrl_set_cfg_ass_thres(demod, (struct drx_cfg_aud_ass_thres *)
19865                                              config->cfg_data);
19866         case DRX_CFG_AUD_CARRIER:
19867                 return aud_ctrl_set_cfg_carrier(demod,
19868                                             (struct drx_cfg_aud_carriers *) config->
19869                                             cfg_data);
19870         case DRX_CFG_AUD_DEVIATION:
19871                 return aud_ctrl_set_cfg_dev(demod,
19872                                         (enum drx_cfg_aud_deviation *) config->
19873                                         cfg_data);
19874         case DRX_CFG_AUD_PRESCALE:
19875                 return aud_ctrl_set_cfg_prescale(demod,
19876                                              (struct drx_cfg_aud_prescale *) config->
19877                                              cfg_data);
19878         case DRX_CFG_AUD_MIXER:
19879                 return aud_ctrl_set_cfg_mixer(demod,
19880                                           (struct drx_cfg_aud_mixer *) config->cfg_data);
19881         case DRX_CFG_AUD_AVSYNC:
19882                 return aud_ctrl_set_cfg_av_sync(demod,
19883                                            (enum drx_cfg_aud_av_sync *) config->
19884                                            cfg_data);
19885
19886 #endif
19887         default:
19888                 return -EINVAL;
19889         }
19890
19891         return 0;
19892 rw_error:
19893         return -EIO;
19894 }
19895
19896 /*============================================================================*/
19897
19898 /**
19899 * \fn int ctrl_get_cfg()
19900 * \brief Get 'some' configuration of the device.
19901 * \param devmod Pointer to demodulator instance.
19902 * \param config Pointer to configuration parameters (type and data).
19903 * \return int.
19904 */
19905
19906 static int ctrl_get_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
19907 {
19908         int rc;
19909
19910         if (config == NULL)
19911                 return -EINVAL;
19912
19913         do {
19914                 u16 dummy;
19915                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
19916                 if (rc != 0) {
19917                         pr_err("error %d\n", rc);
19918                         goto rw_error;
19919                 }
19920         } while (0);
19921
19922         switch (config->cfg_type) {
19923         case DRX_CFG_MPEG_OUTPUT:
19924                 return ctrl_get_cfg_mpeg_output(demod,
19925                                             (struct drx_cfg_mpeg_output *) config->
19926                                             cfg_data);
19927         case DRX_CFG_PINS_SAFE_MODE:
19928                 return ctrl_get_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
19929         case DRXJ_CFG_AGC_RF:
19930                 return ctrl_get_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
19931         case DRXJ_CFG_AGC_IF:
19932                 return ctrl_get_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
19933         case DRXJ_CFG_AGC_INTERNAL:
19934                 return ctrl_get_cfg_agc_internal(demod, (u16 *)config->cfg_data);
19935         case DRXJ_CFG_PRE_SAW:
19936                 return ctrl_get_cfg_pre_saw(demod,
19937                                         (struct drxj_cfg_pre_saw *) config->cfg_data);
19938         case DRXJ_CFG_AFE_GAIN:
19939                 return ctrl_get_cfg_afe_gain(demod,
19940                                          (struct drxj_cfg_afe_gain *) config->cfg_data);
19941         case DRXJ_CFG_ACCUM_CR_RS_CW_ERR:
19942                 return ctrl_get_accum_cr_rs_cw_err(demod, (u32 *)config->cfg_data);
19943         case DRXJ_CFG_FEC_MERS_SEQ_COUNT:
19944                 return ctrl_get_fec_meas_seq_count(demod, (u16 *)config->cfg_data);
19945         case DRXJ_CFG_VSB_MISC:
19946                 return ctrl_get_cfg_vsb_misc(demod,
19947                                          (struct drxj_cfg_vsb_misc *) config->cfg_data);
19948         case DRXJ_CFG_SYMBOL_CLK_OFFSET:
19949                 return ctrl_get_cfg_symbol_clock_offset(demod,
19950                                                    (s32 *)config->cfg_data);
19951 #ifndef DRXJ_DIGITAL_ONLY
19952         case DRXJ_CFG_OOB_MISC:
19953                 return ctrl_get_cfg_oob_misc(demod,
19954                                          (struct drxj_cfg_oob_misc *) config->cfg_data);
19955         case DRXJ_CFG_OOB_PRE_SAW:
19956                 return ctrl_get_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
19957         case DRXJ_CFG_OOB_LO_POW:
19958                 return ctrl_get_cfg_oob_lo_power(demod,
19959                                             (enum drxj_cfg_oob_lo_power *) (config->
19960                                                                     cfg_data));
19961         case DRXJ_CFG_ATV_EQU_COEF:
19962                 return ctrl_get_cfg_atv_equ_coef(demod,
19963                                             (struct drxj_cfg_atv_equ_coef *) config->
19964                                             cfg_data);
19965         case DRXJ_CFG_ATV_MISC:
19966                 return ctrl_get_cfg_atv_misc(demod,
19967                                          (struct drxj_cfg_atv_misc *) config->cfg_data);
19968         case DRXJ_CFG_ATV_OUTPUT:
19969                 return ctrl_get_cfg_atv_output(demod,
19970                                            (struct drxj_cfg_atv_output *) config->
19971                                            cfg_data);
19972         case DRXJ_CFG_ATV_AGC_STATUS:
19973                 return ctrl_get_cfg_atv_agc_status(demod,
19974                                               (struct drxj_cfg_atv_agc_status *) config->
19975                                               cfg_data);
19976 #endif
19977         case DRXJ_CFG_MPEG_OUTPUT_MISC:
19978                 return ctrl_get_cfg_mpeg_output_misc(demod,
19979                                                 (struct drxj_cfg_mpeg_output_misc *)
19980                                                 config->cfg_data);
19981         case DRXJ_CFG_HW_CFG:
19982                 return ctrl_get_cfg_hw_cfg(demod,
19983                                        (struct drxj_cfg_hw_cfg *) config->cfg_data);
19984 #ifndef DRXJ_EXCLUDE_AUDIO
19985         case DRX_CFG_AUD_VOLUME:
19986                 return aud_ctrl_get_cfg_volume(demod,
19987                                            (struct drx_cfg_aud_volume *) config->
19988                                            cfg_data);
19989         case DRX_CFG_I2S_OUTPUT:
19990                 return aud_ctrl_get_cfg_output_i2s(demod,
19991                                               (struct drx_cfg_i2s_output *) config->
19992                                               cfg_data);
19993
19994         case DRX_CFG_AUD_RDS:
19995                 return aud_ctrl_get_cfg_rds(demod,
19996                                         (struct drx_cfg_aud_rds *) config->cfg_data);
19997         case DRX_CFG_AUD_AUTOSOUND:
19998                 return aud_ctrl_get_cfg_auto_sound(demod,
19999                                               (enum drx_cfg_aud_auto_sound *) config->
20000                                               cfg_data);
20001         case DRX_CFG_AUD_ASS_THRES:
20002                 return aud_ctrl_get_cfg_ass_thres(demod,
20003                                              (struct drx_cfg_aud_ass_thres *) config->
20004                                              cfg_data);
20005         case DRX_CFG_AUD_CARRIER:
20006                 return aud_ctrl_get_cfg_carrier(demod,
20007                                             (struct drx_cfg_aud_carriers *) config->
20008                                             cfg_data);
20009         case DRX_CFG_AUD_DEVIATION:
20010                 return aud_ctrl_get_cfg_dev(demod,
20011                                         (enum drx_cfg_aud_deviation *) config->
20012                                         cfg_data);
20013         case DRX_CFG_AUD_PRESCALE:
20014                 return aud_ctrl_get_cfg_prescale(demod,
20015                                              (struct drx_cfg_aud_prescale *) config->
20016                                              cfg_data);
20017         case DRX_CFG_AUD_MIXER:
20018                 return aud_ctrl_get_cfg_mixer(demod,
20019                                           (struct drx_cfg_aud_mixer *) config->cfg_data);
20020         case DRX_CFG_AUD_AVSYNC:
20021                 return aud_ctrl_get_cfg_av_sync(demod,
20022                                            (enum drx_cfg_aud_av_sync *) config->
20023                                            cfg_data);
20024 #endif
20025
20026         default:
20027                 return -EINVAL;
20028         }
20029
20030         return 0;
20031 rw_error:
20032         return -EIO;
20033 }
20034
20035 /*=============================================================================
20036 ===== EXPORTED FUNCTIONS ====================================================*/
20037 /**
20038 * \fn drxj_open()
20039 * \brief Open the demod instance, configure device, configure drxdriver
20040 * \return Status_t Return status.
20041 *
20042 * drxj_open() can be called with a NULL ucode image => no ucode upload.
20043 * This means that drxj_open() must NOT contain SCU commands or, in general,
20044 * rely on SCU or AUD ucode to be present.
20045 *
20046 */
20047 int drxj_open(struct drx_demod_instance *demod)
20048 {
20049         struct i2c_device_addr *dev_addr = NULL;
20050         struct drxj_data *ext_attr = NULL;
20051         struct drx_common_attr *common_attr = NULL;
20052         u32 driver_version = 0;
20053         struct drxu_code_info ucode_info;
20054         struct drx_cfg_mpeg_output cfg_mpeg_output;
20055         int rc;
20056
20057         /* Check arguments */
20058         if (demod->my_ext_attr == NULL)
20059                 return -EINVAL;
20060
20061         dev_addr = demod->my_i2c_dev_addr;
20062         ext_attr = (struct drxj_data *) demod->my_ext_attr;
20063         common_attr = (struct drx_common_attr *) demod->my_common_attr;
20064
20065         rc = power_up_device(demod);
20066         if (rc != 0) {
20067                 pr_err("error %d\n", rc);
20068                 goto rw_error;
20069         }
20070         common_attr->current_power_mode = DRX_POWER_UP;
20071
20072         /* has to be in front of setIqmAf and setOrxNsuAox */
20073         rc = get_device_capabilities(demod);
20074         if (rc != 0) {
20075                 pr_err("error %d\n", rc);
20076                 goto rw_error;
20077         }
20078
20079         /* Soft reset of sys- and osc-clockdomain */
20080         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_SOFT_RST__A, (SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), 0);
20081         if (rc != 0) {
20082                 pr_err("error %d\n", rc);
20083                 goto rw_error;
20084         }
20085         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
20086         if (rc != 0) {
20087                 pr_err("error %d\n", rc);
20088                 goto rw_error;
20089         }
20090         rc = drxbsp_hst_sleep(1);
20091         if (rc != 0) {
20092                 pr_err("error %d\n", rc);
20093                 goto rw_error;
20094         }
20095
20096         /* TODO first make sure that everything keeps working before enabling this */
20097         /* PowerDownAnalogBlocks() */
20098         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, 0);
20099         if (rc != 0) {
20100                 pr_err("error %d\n", rc);
20101                 goto rw_error;
20102         }
20103
20104         rc = set_iqm_af(demod, false);
20105         if (rc != 0) {
20106                 pr_err("error %d\n", rc);
20107                 goto rw_error;
20108         }
20109         rc = set_orx_nsu_aox(demod, false);
20110         if (rc != 0) {
20111                 pr_err("error %d\n", rc);
20112                 goto rw_error;
20113         }
20114
20115         rc = init_hi(demod);
20116         if (rc != 0) {
20117                 pr_err("error %d\n", rc);
20118                 goto rw_error;
20119         }
20120
20121         /* disable mpegoutput pins */
20122         cfg_mpeg_output.enable_mpeg_output = false;
20123         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
20124         if (rc != 0) {
20125                 pr_err("error %d\n", rc);
20126                 goto rw_error;
20127         }
20128         /* Stop AUD Inform SetAudio it will need to do all setting */
20129         rc = power_down_aud(demod);
20130         if (rc != 0) {
20131                 pr_err("error %d\n", rc);
20132                 goto rw_error;
20133         }
20134         /* Stop SCU */
20135         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
20136         if (rc != 0) {
20137                 pr_err("error %d\n", rc);
20138                 goto rw_error;
20139         }
20140
20141         /* Upload microcode */
20142         if (common_attr->microcode != NULL) {
20143                 /* Dirty trick to use common ucode upload & verify,
20144                    pretend device is already open */
20145                 common_attr->is_opened = true;
20146                 ucode_info.mc_data = common_attr->microcode;
20147
20148 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20149                 /* Upload microcode without audio part */
20150                 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_UPLOAD, false);
20151                 if (rc != 0) {
20152                         pr_err("error %d\n", rc);
20153                         goto rw_error;
20154                 }
20155 #else
20156                 rc = drx_ctrl(demod, DRX_CTRL_LOAD_UCODE, &ucode_info);
20157                 if (rc != 0) {
20158                         pr_err("error %d\n", rc);
20159                         goto rw_error;
20160                 }
20161 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20162                 if (common_attr->verify_microcode == true) {
20163 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20164                         rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_VERIFY, false);
20165                         if (rc != 0) {
20166                                 pr_err("error %d\n", rc);
20167                                 goto rw_error;
20168                         }
20169 #else
20170                         rc = drx_ctrl(demod, DRX_CTRL_VERIFY_UCODE, &ucode_info);
20171                         if (rc != 0) {
20172                                 pr_err("error %d\n", rc);
20173                                 goto rw_error;
20174                         }
20175 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20176                 }
20177                 common_attr->is_opened = false;
20178         }
20179
20180         /* Run SCU for a little while to initialize microcode version numbers */
20181         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
20182         if (rc != 0) {
20183                 pr_err("error %d\n", rc);
20184                 goto rw_error;
20185         }
20186
20187         /* Open tuner instance */
20188         if (demod->my_tuner != NULL) {
20189                 demod->my_tuner->my_common_attr->my_user_data = (void *)demod;
20190
20191                 if (common_attr->tuner_port_nr == 1) {
20192                         bool bridge_closed = true;
20193                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
20194                         if (rc != 0) {
20195                                 pr_err("error %d\n", rc);
20196                                 goto rw_error;
20197                         }
20198                 }
20199
20200                 rc = drxbsp_tuner_open(demod->my_tuner);
20201                 if (rc != 0) {
20202                         pr_err("error %d\n", rc);
20203                         goto rw_error;
20204                 }
20205
20206                 if (common_attr->tuner_port_nr == 1) {
20207                         bool bridge_closed = false;
20208                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
20209                         if (rc != 0) {
20210                                 pr_err("error %d\n", rc);
20211                                 goto rw_error;
20212                         }
20213                 }
20214                 common_attr->tuner_min_freq_rf =
20215                     ((demod->my_tuner)->my_common_attr->min_freq_rf);
20216                 common_attr->tuner_max_freq_rf =
20217                     ((demod->my_tuner)->my_common_attr->max_freq_rf);
20218         }
20219
20220         /* Initialize scan timeout */
20221         common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
20222         common_attr->scan_desired_lock = DRX_LOCKED;
20223
20224         /* Initialize default AFE configuartion for QAM */
20225         if (ext_attr->has_lna) {
20226                 /* IF AGC off, PGA active */
20227 #ifndef DRXJ_VSB_ONLY
20228                 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
20229                 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
20230                 ext_attr->qam_pga_cfg = 140 + (11 * 13);
20231 #endif
20232                 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
20233                 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
20234                 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
20235         } else {
20236                 /* IF AGC on, PGA not active */
20237 #ifndef DRXJ_VSB_ONLY
20238                 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
20239                 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20240                 ext_attr->qam_if_agc_cfg.min_output_level = 0;
20241                 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
20242                 ext_attr->qam_if_agc_cfg.speed = 3;
20243                 ext_attr->qam_if_agc_cfg.top = 1297;
20244                 ext_attr->qam_pga_cfg = 140;
20245 #endif
20246                 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
20247                 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20248                 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
20249                 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
20250                 ext_attr->vsb_if_agc_cfg.speed = 3;
20251                 ext_attr->vsb_if_agc_cfg.top = 1024;
20252                 ext_attr->vsb_pga_cfg = 140;
20253         }
20254         /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
20255         /* mc has not used them */
20256 #ifndef DRXJ_VSB_ONLY
20257         ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
20258         ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20259         ext_attr->qam_rf_agc_cfg.min_output_level = 0;
20260         ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
20261         ext_attr->qam_rf_agc_cfg.speed = 3;
20262         ext_attr->qam_rf_agc_cfg.top = 9500;
20263         ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
20264         ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
20265         ext_attr->qam_pre_saw_cfg.reference = 0x07;
20266         ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
20267 #endif
20268         /* Initialize default AFE configuartion for VSB */
20269         ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
20270         ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20271         ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
20272         ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
20273         ext_attr->vsb_rf_agc_cfg.speed = 3;
20274         ext_attr->vsb_rf_agc_cfg.top = 9500;
20275         ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
20276         ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
20277         ext_attr->vsb_pre_saw_cfg.reference = 0x07;
20278         ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
20279
20280 #ifndef DRXJ_DIGITAL_ONLY
20281         /* Initialize default AFE configuartion for ATV */
20282         ext_attr->atv_rf_agc_cfg.standard = DRX_STANDARD_NTSC;
20283         ext_attr->atv_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20284         ext_attr->atv_rf_agc_cfg.top = 9500;
20285         ext_attr->atv_rf_agc_cfg.cut_off_current = 4000;
20286         ext_attr->atv_rf_agc_cfg.speed = 3;
20287         ext_attr->atv_if_agc_cfg.standard = DRX_STANDARD_NTSC;
20288         ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
20289         ext_attr->atv_if_agc_cfg.speed = 3;
20290         ext_attr->atv_if_agc_cfg.top = 2400;
20291         ext_attr->atv_pre_saw_cfg.reference = 0x0007;
20292         ext_attr->atv_pre_saw_cfg.use_pre_saw = true;
20293         ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
20294 #endif
20295         ext_attr->standard = DRX_STANDARD_UNKNOWN;
20296
20297         rc = smart_ant_init(demod);
20298         if (rc != 0) {
20299                 pr_err("error %d\n", rc);
20300                 goto rw_error;
20301         }
20302
20303         /* Stamp driver version number in SCU data RAM in BCD code
20304            Done to enable field application engineers to retreive drxdriver version
20305            via I2C from SCU RAM
20306          */
20307         driver_version = (VERSION_MAJOR / 100) % 10;
20308         driver_version <<= 4;
20309         driver_version += (VERSION_MAJOR / 10) % 10;
20310         driver_version <<= 4;
20311         driver_version += (VERSION_MAJOR % 10);
20312         driver_version <<= 4;
20313         driver_version += (VERSION_MINOR % 10);
20314         driver_version <<= 4;
20315         driver_version += (VERSION_PATCH / 1000) % 10;
20316         driver_version <<= 4;
20317         driver_version += (VERSION_PATCH / 100) % 10;
20318         driver_version <<= 4;
20319         driver_version += (VERSION_PATCH / 10) % 10;
20320         driver_version <<= 4;
20321         driver_version += (VERSION_PATCH % 10);
20322         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
20323         if (rc != 0) {
20324                 pr_err("error %d\n", rc);
20325                 goto rw_error;
20326         }
20327         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
20328         if (rc != 0) {
20329                 pr_err("error %d\n", rc);
20330                 goto rw_error;
20331         }
20332
20333         /* refresh the audio data structure with default */
20334         ext_attr->aud_data = drxj_default_aud_data_g;
20335
20336         return 0;
20337 rw_error:
20338         common_attr->is_opened = false;
20339         return -EIO;
20340 }
20341
20342 /*============================================================================*/
20343 /**
20344 * \fn drxj_close()
20345 * \brief Close the demod instance, power down the device
20346 * \return Status_t Return status.
20347 *
20348 */
20349 int drxj_close(struct drx_demod_instance *demod)
20350 {
20351         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
20352         struct drx_common_attr *common_attr = demod->my_common_attr;
20353         int rc;
20354         enum drx_power_mode power_mode = DRX_POWER_UP;
20355
20356         /* power up */
20357         rc = ctrl_power_mode(demod, &power_mode);
20358         if (rc != 0) {
20359                 pr_err("error %d\n", rc);
20360                 goto rw_error;
20361         }
20362
20363         if (demod->my_tuner != NULL) {
20364                 /* Check if bridge is used */
20365                 if (common_attr->tuner_port_nr == 1) {
20366                         bool bridge_closed = true;
20367                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
20368                         if (rc != 0) {
20369                                 pr_err("error %d\n", rc);
20370                                 goto rw_error;
20371                         }
20372                 }
20373                 rc = drxbsp_tuner_close(demod->my_tuner);
20374                 if (rc != 0) {
20375                         pr_err("error %d\n", rc);
20376                         goto rw_error;
20377                 }
20378                 if (common_attr->tuner_port_nr == 1) {
20379                         bool bridge_closed = false;
20380                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
20381                         if (rc != 0) {
20382                                 pr_err("error %d\n", rc);
20383                                 goto rw_error;
20384                         }
20385                 }
20386         }
20387
20388         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
20389         if (rc != 0) {
20390                 pr_err("error %d\n", rc);
20391                 goto rw_error;
20392         }
20393         power_mode = DRX_POWER_DOWN;
20394         rc = ctrl_power_mode(demod, &power_mode);
20395         if (rc != 0) {
20396                 pr_err("error %d\n", rc);
20397                 goto rw_error;
20398         }
20399
20400         return 0;
20401 rw_error:
20402         return -EIO;
20403 }
20404
20405 /*============================================================================*/
20406 /**
20407 * \fn drxj_ctrl()
20408 * \brief DRXJ specific control function
20409 * \return Status_t Return status.
20410 */
20411 int
20412 drxj_ctrl(struct drx_demod_instance *demod, u32 ctrl, void *ctrl_data)
20413 {
20414         switch (ctrl) {
20415       /*======================================================================*/
20416         case DRX_CTRL_SET_CHANNEL:
20417                 {
20418                         return ctrl_set_channel(demod, (struct drx_channel *)ctrl_data);
20419                 }
20420                 break;
20421       /*======================================================================*/
20422         case DRX_CTRL_GET_CHANNEL:
20423                 {
20424                         return ctrl_get_channel(demod, (struct drx_channel *)ctrl_data);
20425                 }
20426                 break;
20427       /*======================================================================*/
20428         case DRX_CTRL_SIG_QUALITY:
20429                 {
20430                         return ctrl_sig_quality(demod,
20431                                               (struct drx_sig_quality *) ctrl_data);
20432                 }
20433                 break;
20434       /*======================================================================*/
20435         case DRX_CTRL_SIG_STRENGTH:
20436                 {
20437                         return ctrl_sig_strength(demod, (u16 *)ctrl_data);
20438                 }
20439                 break;
20440       /*======================================================================*/
20441         case DRX_CTRL_CONSTEL:
20442                 {
20443                         return ctrl_constel(demod, (struct drx_complex *)ctrl_data);
20444                 }
20445                 break;
20446       /*======================================================================*/
20447         case DRX_CTRL_SET_CFG:
20448                 {
20449                         return ctrl_set_cfg(demod, (struct drx_cfg *)ctrl_data);
20450                 }
20451                 break;
20452       /*======================================================================*/
20453         case DRX_CTRL_GET_CFG:
20454                 {
20455                         return ctrl_get_cfg(demod, (struct drx_cfg *)ctrl_data);
20456                 }
20457                 break;
20458       /*======================================================================*/
20459         case DRX_CTRL_I2C_BRIDGE:
20460                 {
20461                         return ctrl_i2c_bridge(demod, (bool *)ctrl_data);
20462                 }
20463                 break;
20464       /*======================================================================*/
20465         case DRX_CTRL_LOCK_STATUS:
20466                 {
20467                         return ctrl_lock_status(demod,
20468                                               (enum drx_lock_status *)ctrl_data);
20469                 }
20470                 break;
20471       /*======================================================================*/
20472         case DRX_CTRL_SET_STANDARD:
20473                 {
20474                         return ctrl_set_standard(demod,
20475                                                (enum drx_standard *)ctrl_data);
20476                 }
20477                 break;
20478       /*======================================================================*/
20479         case DRX_CTRL_GET_STANDARD:
20480                 {
20481                         return ctrl_get_standard(demod,
20482                                                (enum drx_standard *)ctrl_data);
20483                 }
20484                 break;
20485       /*======================================================================*/
20486         case DRX_CTRL_POWER_MODE:
20487                 {
20488                         return ctrl_power_mode(demod, (enum drx_power_mode *)ctrl_data);
20489                 }
20490                 break;
20491       /*======================================================================*/
20492         case DRX_CTRL_VERSION:
20493                 {
20494                         return ctrl_version(demod,
20495                                            (struct drx_version_list **)ctrl_data);
20496                 }
20497                 break;
20498       /*======================================================================*/
20499         case DRX_CTRL_PROBE_DEVICE:
20500                 {
20501                         return ctrl_probe_device(demod);
20502                 }
20503                 break;
20504       /*======================================================================*/
20505         case DRX_CTRL_SET_OOB:
20506                 {
20507                         return ctrl_set_oob(demod, (struct drxoob *)ctrl_data);
20508                 }
20509                 break;
20510       /*======================================================================*/
20511         case DRX_CTRL_GET_OOB:
20512                 {
20513                         return ctrl_get_oob(demod, (struct drxoob_status *)ctrl_data);
20514                 }
20515                 break;
20516       /*======================================================================*/
20517         case DRX_CTRL_SET_UIO_CFG:
20518                 {
20519                         return ctrl_set_uio_cfg(demod, (struct drxuio_cfg *)ctrl_data);
20520                 }
20521                 break;
20522       /*======================================================================*/
20523         case DRX_CTRL_GET_UIO_CFG:
20524                 {
20525                         return ctrl_getuio_cfg(demod, (struct drxuio_cfg *)ctrl_data);
20526                 }
20527                 break;
20528       /*======================================================================*/
20529         case DRX_CTRL_UIO_READ:
20530                 {
20531                         return ctrl_uio_read(demod, (struct drxuio_data *)ctrl_data);
20532                 }
20533                 break;
20534       /*======================================================================*/
20535         case DRX_CTRL_UIO_WRITE:
20536                 {
20537                         return ctrl_uio_write(demod, (struct drxuio_data *)ctrl_data);
20538                 }
20539                 break;
20540       /*======================================================================*/
20541         case DRX_CTRL_AUD_SET_STANDARD:
20542                 {
20543                         return aud_ctrl_set_standard(demod,
20544                                                   (enum drx_aud_standard *) ctrl_data);
20545                 }
20546                 break;
20547       /*======================================================================*/
20548         case DRX_CTRL_AUD_GET_STANDARD:
20549                 {
20550                         return aud_ctrl_get_standard(demod,
20551                                                   (enum drx_aud_standard *) ctrl_data);
20552                 }
20553                 break;
20554       /*======================================================================*/
20555         case DRX_CTRL_AUD_GET_STATUS:
20556                 {
20557                         return aud_ctrl_get_status(demod,
20558                                                 (struct drx_aud_status *) ctrl_data);
20559                 }
20560                 break;
20561       /*======================================================================*/
20562         case DRX_CTRL_AUD_BEEP:
20563                 {
20564                         return aud_ctrl_beep(demod, (struct drx_aud_beep *)ctrl_data);
20565                 }
20566                 break;
20567
20568       /*======================================================================*/
20569         case DRX_CTRL_I2C_READWRITE:
20570                 {
20571                         return ctrl_i2c_write_read(demod,
20572                                                 (struct drxi2c_data *) ctrl_data);
20573                 }
20574                 break;
20575 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20576         case DRX_CTRL_LOAD_UCODE:
20577                 {
20578                         return ctrl_u_code_upload(demod,
20579                                                (p_drxu_code_info_t) ctrl_data,
20580                                                UCODE_UPLOAD, false);
20581                 }
20582                 break;
20583         case DRX_CTRL_VERIFY_UCODE:
20584                 {
20585                         return ctrl_u_code_upload(demod,
20586                                                (p_drxu_code_info_t) ctrl_data,
20587                                                UCODE_VERIFY, false);
20588                 }
20589                 break;
20590 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20591         case DRX_CTRL_VALIDATE_UCODE:
20592                 {
20593                         return ctrl_validate_u_code(demod);
20594                 }
20595                 break;
20596         default:
20597                 return -ENOTSUPP;
20598         }
20599         return 0;
20600 }