[media] drx-j: get rid of drx_driver.c
[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 #include "drx_driver.h"
43
44 /*============================================================================*/
45 /*=== DEFINES ================================================================*/
46 /*============================================================================*/
47
48 /**
49 * \brief Maximum u32 value.
50 */
51 #ifndef MAX_U32
52 #define MAX_U32  ((u32) (0xFFFFFFFFL))
53 #endif
54
55 /* Customer configurable hardware settings, etc */
56 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
57 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
58 #endif
59
60 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
61 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
62 #endif
63
64 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
65 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
66 #endif
67
68 #ifndef OOB_CRX_DRIVE_STRENGTH
69 #define OOB_CRX_DRIVE_STRENGTH 0x02
70 #endif
71
72 #ifndef OOB_DRX_DRIVE_STRENGTH
73 #define OOB_DRX_DRIVE_STRENGTH 0x02
74 #endif
75 /**** START DJCOMBO patches to DRXJ registermap constants *********************/
76 /**** registermap 200706071303 from drxj **************************************/
77 #define   ATV_TOP_CR_AMP_TH_FM                                              0x0
78 #define   ATV_TOP_CR_AMP_TH_L                                               0xA
79 #define   ATV_TOP_CR_AMP_TH_LP                                              0xA
80 #define   ATV_TOP_CR_AMP_TH_BG                                              0x8
81 #define   ATV_TOP_CR_AMP_TH_DK                                              0x8
82 #define   ATV_TOP_CR_AMP_TH_I                                               0x8
83 #define     ATV_TOP_CR_CONT_CR_D_MN                                         0x18
84 #define     ATV_TOP_CR_CONT_CR_D_FM                                         0x0
85 #define     ATV_TOP_CR_CONT_CR_D_L                                          0x20
86 #define     ATV_TOP_CR_CONT_CR_D_LP                                         0x20
87 #define     ATV_TOP_CR_CONT_CR_D_BG                                         0x18
88 #define     ATV_TOP_CR_CONT_CR_D_DK                                         0x18
89 #define     ATV_TOP_CR_CONT_CR_D_I                                          0x18
90 #define     ATV_TOP_CR_CONT_CR_I_MN                                         0x80
91 #define     ATV_TOP_CR_CONT_CR_I_FM                                         0x0
92 #define     ATV_TOP_CR_CONT_CR_I_L                                          0x80
93 #define     ATV_TOP_CR_CONT_CR_I_LP                                         0x80
94 #define     ATV_TOP_CR_CONT_CR_I_BG                                         0x80
95 #define     ATV_TOP_CR_CONT_CR_I_DK                                         0x80
96 #define     ATV_TOP_CR_CONT_CR_I_I                                          0x80
97 #define     ATV_TOP_CR_CONT_CR_P_MN                                         0x4
98 #define     ATV_TOP_CR_CONT_CR_P_FM                                         0x0
99 #define     ATV_TOP_CR_CONT_CR_P_L                                          0x4
100 #define     ATV_TOP_CR_CONT_CR_P_LP                                         0x4
101 #define     ATV_TOP_CR_CONT_CR_P_BG                                         0x4
102 #define     ATV_TOP_CR_CONT_CR_P_DK                                         0x4
103 #define     ATV_TOP_CR_CONT_CR_P_I                                          0x4
104 #define   ATV_TOP_CR_OVM_TH_MN                                              0xA0
105 #define   ATV_TOP_CR_OVM_TH_FM                                              0x0
106 #define   ATV_TOP_CR_OVM_TH_L                                               0xA0
107 #define   ATV_TOP_CR_OVM_TH_LP                                              0xA0
108 #define   ATV_TOP_CR_OVM_TH_BG                                              0xA0
109 #define   ATV_TOP_CR_OVM_TH_DK                                              0xA0
110 #define   ATV_TOP_CR_OVM_TH_I                                               0xA0
111 #define     ATV_TOP_EQU0_EQU_C0_FM                                          0x0
112 #define     ATV_TOP_EQU0_EQU_C0_L                                           0x3
113 #define     ATV_TOP_EQU0_EQU_C0_LP                                          0x3
114 #define     ATV_TOP_EQU0_EQU_C0_BG                                          0x7
115 #define     ATV_TOP_EQU0_EQU_C0_DK                                          0x0
116 #define     ATV_TOP_EQU0_EQU_C0_I                                           0x3
117 #define     ATV_TOP_EQU1_EQU_C1_FM                                          0x0
118 #define     ATV_TOP_EQU1_EQU_C1_L                                           0x1F6
119 #define     ATV_TOP_EQU1_EQU_C1_LP                                          0x1F6
120 #define     ATV_TOP_EQU1_EQU_C1_BG                                          0x197
121 #define     ATV_TOP_EQU1_EQU_C1_DK                                          0x198
122 #define     ATV_TOP_EQU1_EQU_C1_I                                           0x1F6
123 #define     ATV_TOP_EQU2_EQU_C2_FM                                          0x0
124 #define     ATV_TOP_EQU2_EQU_C2_L                                           0x28
125 #define     ATV_TOP_EQU2_EQU_C2_LP                                          0x28
126 #define     ATV_TOP_EQU2_EQU_C2_BG                                          0xC5
127 #define     ATV_TOP_EQU2_EQU_C2_DK                                          0xB0
128 #define     ATV_TOP_EQU2_EQU_C2_I                                           0x28
129 #define     ATV_TOP_EQU3_EQU_C3_FM                                          0x0
130 #define     ATV_TOP_EQU3_EQU_C3_L                                           0x192
131 #define     ATV_TOP_EQU3_EQU_C3_LP                                          0x192
132 #define     ATV_TOP_EQU3_EQU_C3_BG                                          0x12E
133 #define     ATV_TOP_EQU3_EQU_C3_DK                                          0x18E
134 #define     ATV_TOP_EQU3_EQU_C3_I                                           0x192
135 #define     ATV_TOP_STD_MODE_MN                                             0x0
136 #define     ATV_TOP_STD_MODE_FM                                             0x1
137 #define     ATV_TOP_STD_MODE_L                                              0x0
138 #define     ATV_TOP_STD_MODE_LP                                             0x0
139 #define     ATV_TOP_STD_MODE_BG                                             0x0
140 #define     ATV_TOP_STD_MODE_DK                                             0x0
141 #define     ATV_TOP_STD_MODE_I                                              0x0
142 #define     ATV_TOP_STD_VID_POL_MN                                          0x0
143 #define     ATV_TOP_STD_VID_POL_FM                                          0x0
144 #define     ATV_TOP_STD_VID_POL_L                                           0x2
145 #define     ATV_TOP_STD_VID_POL_LP                                          0x2
146 #define     ATV_TOP_STD_VID_POL_BG                                          0x0
147 #define     ATV_TOP_STD_VID_POL_DK                                          0x0
148 #define     ATV_TOP_STD_VID_POL_I                                           0x0
149 #define   ATV_TOP_VID_AMP_MN                                                0x380
150 #define   ATV_TOP_VID_AMP_FM                                                0x0
151 #define   ATV_TOP_VID_AMP_L                                                 0xF50
152 #define   ATV_TOP_VID_AMP_LP                                                0xF50
153 #define   ATV_TOP_VID_AMP_BG                                                0x380
154 #define   ATV_TOP_VID_AMP_DK                                                0x394
155 #define   ATV_TOP_VID_AMP_I                                                 0x3D8
156 #define   IQM_CF_OUT_ENA_OFDM__M                                            0x4
157 #define     IQM_FS_ADJ_SEL_B_QAM                                            0x1
158 #define     IQM_FS_ADJ_SEL_B_OFF                                            0x0
159 #define     IQM_FS_ADJ_SEL_B_VSB                                            0x2
160 #define     IQM_RC_ADJ_SEL_B_OFF                                            0x0
161 #define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
162 #define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
163 /**** END DJCOMBO patches to DRXJ registermap *********************************/
164
165 #include "drx_driver_version.h"
166
167 /* #define DRX_DEBUG */
168 #ifdef DRX_DEBUG
169 #include <stdio.h>
170 #endif
171
172 /*-----------------------------------------------------------------------------
173 ENUMS
174 ----------------------------------------------------------------------------*/
175
176 /*-----------------------------------------------------------------------------
177 DEFINES
178 ----------------------------------------------------------------------------*/
179 #ifndef DRXJ_WAKE_UP_KEY
180 #define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
181 #endif
182
183 /**
184 * \def DRXJ_DEF_I2C_ADDR
185 * \brief Default I2C addres of a demodulator instance.
186 */
187 #define DRXJ_DEF_I2C_ADDR (0x52)
188
189 /**
190 * \def DRXJ_DEF_DEMOD_DEV_ID
191 * \brief Default device identifier of a demodultor instance.
192 */
193 #define DRXJ_DEF_DEMOD_DEV_ID      (1)
194
195 /**
196 * \def DRXJ_SCAN_TIMEOUT
197 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
198 */
199 #define DRXJ_SCAN_TIMEOUT    1000
200
201 /**
202 * \def DRXJ_DAP
203 * \brief Name of structure containing all data access protocol functions.
204 */
205 #define DRXJ_DAP drx_dap_drxj_funct_g
206
207 /**
208 * \def HI_I2C_DELAY
209 * \brief HI timing delay for I2C timing (in nano seconds)
210 *
211 *  Used to compute HI_CFG_DIV
212 */
213 #define HI_I2C_DELAY    42
214
215 /**
216 * \def HI_I2C_BRIDGE_DELAY
217 * \brief HI timing delay for I2C timing (in nano seconds)
218 *
219 *  Used to compute HI_CFG_BDL
220 */
221 #define HI_I2C_BRIDGE_DELAY   750
222
223 /**
224 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
225 */
226 #define VSB_TOP_MEASUREMENT_PERIOD  64
227 #define SYMBOLS_PER_SEGMENT         832
228
229 /**
230 * \brief bit rate and segment rate constants used for SER and BER.
231 */
232 /* values taken from the QAM microcode */
233 #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
234 #define DRXJ_QAM_SL_SIG_POWER_QPSK        32768
235 #define DRXJ_QAM_SL_SIG_POWER_QAM8        24576
236 #define DRXJ_QAM_SL_SIG_POWER_QAM16       40960
237 #define DRXJ_QAM_SL_SIG_POWER_QAM32       20480
238 #define DRXJ_QAM_SL_SIG_POWER_QAM64       43008
239 #define DRXJ_QAM_SL_SIG_POWER_QAM128      20992
240 #define DRXJ_QAM_SL_SIG_POWER_QAM256      43520
241 /**
242 * \brief Min supported symbolrates.
243 */
244 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
245 #define DRXJ_QAM_SYMBOLRATE_MIN          (520000)
246 #endif
247
248 /**
249 * \brief Max supported symbolrates.
250 */
251 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
252 #define DRXJ_QAM_SYMBOLRATE_MAX         (7233000)
253 #endif
254
255 /**
256 * \def DRXJ_QAM_MAX_WAITTIME
257 * \brief Maximal wait time for QAM auto constellation in ms
258 */
259 #ifndef DRXJ_QAM_MAX_WAITTIME
260 #define DRXJ_QAM_MAX_WAITTIME 900
261 #endif
262
263 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
264 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
265 #endif
266
267 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
268 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
269 #endif
270
271 /**
272 * \def SCU status and results
273 * \brief SCU
274 */
275 #define DRX_SCU_READY               0
276 #define DRXJ_MAX_WAITTIME           100 /* ms */
277 #define FEC_RS_MEASUREMENT_PERIOD   12894       /* 1 sec */
278 #define FEC_RS_MEASUREMENT_PRESCALE 1   /* n sec */
279
280 /**
281 * \def DRX_AUD_MAX_DEVIATION
282 * \brief Needed for calculation of prescale feature in AUD
283 */
284 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
285 #define DRXJ_AUD_MAX_FM_DEVIATION  100  /* kHz */
286 #endif
287
288 /**
289 * \brief Needed for calculation of NICAM prescale feature in AUD
290 */
291 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
292 #define DRXJ_AUD_MAX_NICAM_PRESCALE  (9)        /* dB */
293 #endif
294
295 /**
296 * \brief Needed for calculation of NICAM prescale feature in AUD
297 */
298 #ifndef DRXJ_AUD_MAX_WAITTIME
299 #define DRXJ_AUD_MAX_WAITTIME  250      /* ms */
300 #endif
301
302 /* ATV config changed flags */
303 #define DRXJ_ATV_CHANGED_COEF          (0x00000001UL)
304 #define DRXJ_ATV_CHANGED_PEAK_FLT      (0x00000008UL)
305 #define DRXJ_ATV_CHANGED_NOISE_FLT     (0x00000010UL)
306 #define DRXJ_ATV_CHANGED_OUTPUT        (0x00000020UL)
307 #define DRXJ_ATV_CHANGED_SIF_ATT       (0x00000040UL)
308
309 /* UIO define */
310 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
311 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
312
313 /*
314  * MICROCODE RELATED DEFINES
315  */
316
317 /* Magic word for checking correct Endianess of microcode data */
318 #define DRX_UCODE_MAGIC_WORD         ((((u16)'H')<<8)+((u16)'L'))
319
320 /* CRC flag in ucode header, flags field. */
321 #define DRX_UCODE_CRC_FLAG           (0x0001)
322
323 /*
324  * Maximum size of buffer used to verify the microcode.
325  * Must be an even number
326  */
327 #define DRX_UCODE_MAX_BUF_SIZE       (DRXDAP_MAX_RCHUNKSIZE)
328
329 #if DRX_UCODE_MAX_BUF_SIZE & 1
330 #error DRX_UCODE_MAX_BUF_SIZE must be an even number
331 #endif
332
333 /*
334  * Power mode macros
335  */
336
337 #define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
338                                        (mode == DRX_POWER_MODE_10) || \
339                                        (mode == DRX_POWER_MODE_11) || \
340                                        (mode == DRX_POWER_MODE_12) || \
341                                        (mode == DRX_POWER_MODE_13) || \
342                                        (mode == DRX_POWER_MODE_14) || \
343                                        (mode == DRX_POWER_MODE_15) || \
344                                        (mode == DRX_POWER_MODE_16) || \
345                                        (mode == DRX_POWER_DOWN))
346
347 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
348 /*============================================================================*/
349 /*=== MICROCODE RELATED DEFINES ==============================================*/
350 /*============================================================================*/
351
352 /**
353 * \def DRXJ_UCODE_MAGIC_WORD
354 * \brief Magic word for checking correct Endianess of microcode data.
355 *
356 */
357
358 #ifndef DRXJ_UCODE_MAGIC_WORD
359 #define DRXJ_UCODE_MAGIC_WORD         ((((u16)'H')<<8)+((u16)'L'))
360 #endif
361
362 /**
363 * \def DRXJ_UCODE_CRC_FLAG
364 * \brief CRC flag in ucode header, flags field.
365 *
366 */
367
368 #ifndef DRXJ_UCODE_CRC_FLAG
369 #define DRXJ_UCODE_CRC_FLAG           (0x0001)
370 #endif
371
372 /**
373 * \def DRXJ_UCODE_COMPRESSION_FLAG
374 * \brief Compression flag in ucode header, flags field.
375 *
376 */
377
378 #ifndef DRXJ_UCODE_COMPRESSION_FLAG
379 #define DRXJ_UCODE_COMPRESSION_FLAG   (0x0002)
380 #endif
381
382 /**
383 * \def DRXJ_UCODE_MAX_BUF_SIZE
384 * \brief Maximum size of buffer used to verify the microcode.Must be an even number.
385 *
386 */
387
388 #ifndef DRXJ_UCODE_MAX_BUF_SIZE
389 #define DRXJ_UCODE_MAX_BUF_SIZE       (DRXDAP_MAX_RCHUNKSIZE)
390 #endif
391 #if DRXJ_UCODE_MAX_BUF_SIZE & 1
392 #error DRXJ_UCODE_MAX_BUF_SIZE must be an even number
393 #endif
394
395 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
396
397 /* Pin safe mode macro */
398 #define DRXJ_PIN_SAFE_MODE 0x0000
399 /*============================================================================*/
400 /*=== GLOBAL VARIABLEs =======================================================*/
401 /*============================================================================*/
402 /**
403 */
404
405 /**
406 * \brief Temporary register definitions.
407 *        (register definitions that are not yet available in register master)
408 */
409
410 /******************************************************************************/
411 /* Audio block 0x103 is write only. To avoid shadowing in driver accessing    */
412 /* RAM adresses directly. This must be READ ONLY to avoid problems.           */
413 /* Writing to the interface adresses is more than only writing the RAM        */
414 /* locations                                                                  */
415 /******************************************************************************/
416 /**
417 * \brief RAM location of MODUS registers
418 */
419 #define AUD_DEM_RAM_MODUS_HI__A              0x10204A3
420 #define AUD_DEM_RAM_MODUS_HI__M              0xF000
421
422 #define AUD_DEM_RAM_MODUS_LO__A              0x10204A4
423 #define AUD_DEM_RAM_MODUS_LO__M              0x0FFF
424
425 /**
426 * \brief RAM location of I2S config registers
427 */
428 #define AUD_DEM_RAM_I2S_CONFIG1__A           0x10204B1
429 #define AUD_DEM_RAM_I2S_CONFIG2__A           0x10204B2
430
431 /**
432 * \brief RAM location of DCO config registers
433 */
434 #define AUD_DEM_RAM_DCO_B_HI__A              0x1020461
435 #define AUD_DEM_RAM_DCO_B_LO__A              0x1020462
436 #define AUD_DEM_RAM_DCO_A_HI__A              0x1020463
437 #define AUD_DEM_RAM_DCO_A_LO__A              0x1020464
438
439 /**
440 * \brief RAM location of Threshold registers
441 */
442 #define AUD_DEM_RAM_NICAM_THRSHLD__A         0x102045A
443 #define AUD_DEM_RAM_A2_THRSHLD__A            0x10204BB
444 #define AUD_DEM_RAM_BTSC_THRSHLD__A          0x10204A6
445
446 /**
447 * \brief RAM location of Carrier Threshold registers
448 */
449 #define AUD_DEM_RAM_CM_A_THRSHLD__A          0x10204AF
450 #define AUD_DEM_RAM_CM_B_THRSHLD__A          0x10204B0
451
452 /**
453 * \brief FM Matrix register fix
454 */
455 #ifdef AUD_DEM_WR_FM_MATRIX__A
456 #undef  AUD_DEM_WR_FM_MATRIX__A
457 #endif
458 #define AUD_DEM_WR_FM_MATRIX__A              0x105006F
459
460 /*============================================================================*/
461 /**
462 * \brief Defines required for audio
463 */
464 #define AUD_VOLUME_ZERO_DB                      115
465 #define AUD_VOLUME_DB_MIN                       -60
466 #define AUD_VOLUME_DB_MAX                       12
467 #define AUD_CARRIER_STRENGTH_QP_0DB             0x4000
468 #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100   421
469 #define AUD_MAX_AVC_REF_LEVEL                   15
470 #define AUD_I2S_FREQUENCY_MAX                   48000UL
471 #define AUD_I2S_FREQUENCY_MIN                   12000UL
472 #define AUD_RDS_ARRAY_SIZE                      18
473
474 /**
475 * \brief Needed for calculation of prescale feature in AUD
476 */
477 #ifndef DRX_AUD_MAX_FM_DEVIATION
478 #define DRX_AUD_MAX_FM_DEVIATION  (100) /* kHz */
479 #endif
480
481 /**
482 * \brief Needed for calculation of NICAM prescale feature in AUD
483 */
484 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
485 #define DRX_AUD_MAX_NICAM_PRESCALE  (9) /* dB */
486 #endif
487
488 /*============================================================================*/
489 /* Values for I2S Master/Slave pin configurations */
490 #define SIO_PDR_I2S_CL_CFG_MODE__MASTER      0x0004
491 #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER     0x0008
492 #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE       0x0004
493 #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE      0x0000
494
495 #define SIO_PDR_I2S_DA_CFG_MODE__MASTER      0x0003
496 #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER     0x0008
497 #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE       0x0003
498 #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE      0x0008
499
500 #define SIO_PDR_I2S_WS_CFG_MODE__MASTER      0x0004
501 #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER     0x0008
502 #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE       0x0004
503 #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE      0x0000
504
505 /*============================================================================*/
506 /*=== REGISTER ACCESS MACROS =================================================*/
507 /*============================================================================*/
508
509 /**
510 * This macro is used to create byte arrays for block writes.
511 * Block writes speed up I2C traffic between host and demod.
512 * The macro takes care of the required byte order in a 16 bits word.
513 * x -> lowbyte(x), highbyte(x)
514 */
515 #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
516                        ((u8)((((u16)x)>>8)&0xFF))
517 /**
518 * This macro is used to convert byte array to 16 bit register value for block read.
519 * Block read speed up I2C traffic between host and demod.
520 * The macro takes care of the required byte order in a 16 bits word.
521 */
522 #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
523
524 /*============================================================================*/
525 /*=== MISC DEFINES ===========================================================*/
526 /*============================================================================*/
527
528 /*============================================================================*/
529 /*=== HI COMMAND RELATED DEFINES =============================================*/
530 /*============================================================================*/
531
532 /**
533 * \brief General maximum number of retries for ucode command interfaces
534 */
535 #define DRXJ_MAX_RETRIES (100)
536
537 /*============================================================================*/
538 /*=== STANDARD RELATED MACROS ================================================*/
539 /*============================================================================*/
540
541 #define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
542                                (std == DRX_STANDARD_PAL_SECAM_DK) || \
543                                (std == DRX_STANDARD_PAL_SECAM_I) || \
544                                (std == DRX_STANDARD_PAL_SECAM_L) || \
545                                (std == DRX_STANDARD_PAL_SECAM_LP) || \
546                                (std == DRX_STANDARD_NTSC) || \
547                                (std == DRX_STANDARD_FM))
548
549 #define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
550                                (std == DRX_STANDARD_ITU_B) || \
551                                (std == DRX_STANDARD_ITU_C) || \
552                                (std == DRX_STANDARD_ITU_D))
553
554 /*-----------------------------------------------------------------------------
555 GLOBAL VARIABLES
556 ----------------------------------------------------------------------------*/
557 /*
558  * DRXJ DAP structures
559  */
560
561 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
562                                       u32 addr,
563                                       u16 datasize,
564                                       u8 *data, u32 flags);
565
566 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
567                                                 u32 waddr,
568                                                 u32 raddr,
569                                                 u8 wdata, u8 *rdata);
570
571 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
572                                                  u32 waddr,
573                                                  u32 raddr,
574                                                  u16 wdata, u16 *rdata);
575
576 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
577                                                  u32 waddr,
578                                                  u32 raddr,
579                                                  u32 wdata, u32 *rdata);
580
581 static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
582                                      u32 addr,
583                                      u8 *data, u32 flags);
584
585 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
586                                       u32 addr,
587                                       u16 *data, u32 flags);
588
589 static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
590                                       u32 addr,
591                                       u32 *data, u32 flags);
592
593 static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
594                                        u32 addr,
595                                        u16 datasize,
596                                        u8 *data, u32 flags);
597
598 static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
599                                       u32 addr,
600                                       u8 data, u32 flags);
601
602 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
603                                        u32 addr,
604                                        u16 data, u32 flags);
605
606 static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
607                                        u32 addr,
608                                        u32 data, u32 flags);
609
610 /* The version structure of this protocol implementation */
611 char drx_dap_drxj_module_name[] = "DRXJ Data Access Protocol";
612 char drx_dap_drxj_version_text[] = "0.0.0";
613
614 struct drx_version drx_dap_drxj_version = {
615         DRX_MODULE_DAP,       /**< type identifier of the module  */
616         drx_dap_drxj_module_name, /**< name or description of module  */
617
618         0,                    /**< major version number           */
619         0,                    /**< minor version number           */
620         0,                    /**< patch version number           */
621         drx_dap_drxj_version_text /**< version as text string         */
622 };
623
624 /* The structure containing the protocol interface */
625 struct drx_access_func drx_dap_drxj_funct_g = {
626         &drx_dap_drxj_version,
627         drxj_dap_write_block,   /* Supported       */
628         drxj_dap_read_block,    /* Supported       */
629         drxj_dap_write_reg8,    /* Not supported   */
630         drxj_dap_read_reg8,     /* Not supported   */
631         drxj_dap_read_modify_write_reg8,        /* Not supported   */
632         drxj_dap_write_reg16,   /* Supported       */
633         drxj_dap_read_reg16,    /* Supported       */
634         drxj_dap_read_modify_write_reg16,       /* Supported       */
635         drxj_dap_write_reg32,   /* Supported       */
636         drxj_dap_read_reg32,    /* Supported       */
637         drxj_dap_read_modify_write_reg32,       /* Not supported   */
638 };
639
640 /**
641 * /var DRXJ_Func_g
642 * /brief The driver functions of the drxj
643 */
644 struct drx_demod_func drxj_functions_g = {
645         DRXJ_TYPE_ID,
646         drxj_open,
647         drxj_close,
648         drxj_ctrl
649 };
650
651 struct drxj_data drxj_data_g = {
652         false,                  /* has_lna : true if LNA (aka PGA) present      */
653         false,                  /* has_oob : true if OOB supported              */
654         false,                  /* has_ntsc: true if NTSC supported             */
655         false,                  /* has_btsc: true if BTSC supported             */
656         false,                  /* has_smatx: true if SMA_TX pin is available   */
657         false,                  /* has_smarx: true if SMA_RX pin is available   */
658         false,                  /* has_gpio : true if GPIO pin is available     */
659         false,                  /* has_irqn : true if IRQN pin is available     */
660         0,                      /* mfx A1/A2/A... */
661
662         /* tuner settings */
663         false,                  /* tuner mirrors RF signal    */
664         /* standard/channel settings */
665         DRX_STANDARD_UNKNOWN,   /* current standard           */
666         DRX_CONSTELLATION_AUTO, /* constellation              */
667         0,                      /* frequency in KHz           */
668         DRX_BANDWIDTH_UNKNOWN,  /* curr_bandwidth              */
669         DRX_MIRROR_NO,          /* mirror                     */
670
671         /* signal quality information: */
672         /* default values taken from the QAM Programming guide */
673         /*   fec_bits_desired should not be less than 4000000    */
674         4000000,                /* fec_bits_desired    */
675         5,                      /* fec_vd_plen         */
676         4,                      /* qam_vd_prescale     */
677         0xFFFF,                 /* qamVDPeriod       */
678         204 * 8,                /* fec_rs_plen annex A */
679         1,                      /* fec_rs_prescale     */
680         FEC_RS_MEASUREMENT_PERIOD,      /* fec_rs_period     */
681         true,                   /* reset_pkt_err_acc    */
682         0,                      /* pkt_err_acc_start    */
683
684         /* HI configuration */
685         0,                      /* hi_cfg_timing_div    */
686         0,                      /* hi_cfg_bridge_delay  */
687         0,                      /* hi_cfg_wake_up_key    */
688         0,                      /* hi_cfg_ctrl         */
689         0,                      /* HICfgTimeout      */
690         /* UIO configuartion */
691         DRX_UIO_MODE_DISABLE,   /* uio_sma_rx_mode      */
692         DRX_UIO_MODE_DISABLE,   /* uio_sma_tx_mode      */
693         DRX_UIO_MODE_DISABLE,   /* uioASELMode       */
694         DRX_UIO_MODE_DISABLE,   /* uio_irqn_mode       */
695         /* FS setting */
696         0UL,                    /* iqm_fs_rate_ofs      */
697         false,                  /* pos_image          */
698         /* RC setting */
699         0UL,                    /* iqm_rc_rate_ofs      */
700         /* AUD information */
701 /*   false,                  * flagSetAUDdone    */
702 /*   false,                  * detectedRDS       */
703 /*   true,                   * flagASDRequest    */
704 /*   false,                  * flagHDevClear     */
705 /*   false,                  * flagHDevSet       */
706 /*   (u16) 0xFFF,          * rdsLastCount      */
707
708 /*#ifdef DRXJ_SPLIT_UCODE_UPLOAD
709    false,                  * flag_aud_mc_uploaded */
710 /*#endif * DRXJ_SPLIT_UCODE_UPLOAD */
711         /* ATV configuartion */
712         0UL,                    /* flags cfg changes */
713         /* shadow of ATV_TOP_EQU0__A */
714         {-5,
715          ATV_TOP_EQU0_EQU_C0_FM,
716          ATV_TOP_EQU0_EQU_C0_L,
717          ATV_TOP_EQU0_EQU_C0_LP,
718          ATV_TOP_EQU0_EQU_C0_BG,
719          ATV_TOP_EQU0_EQU_C0_DK,
720          ATV_TOP_EQU0_EQU_C0_I},
721         /* shadow of ATV_TOP_EQU1__A */
722         {-50,
723          ATV_TOP_EQU1_EQU_C1_FM,
724          ATV_TOP_EQU1_EQU_C1_L,
725          ATV_TOP_EQU1_EQU_C1_LP,
726          ATV_TOP_EQU1_EQU_C1_BG,
727          ATV_TOP_EQU1_EQU_C1_DK,
728          ATV_TOP_EQU1_EQU_C1_I},
729         /* shadow of ATV_TOP_EQU2__A */
730         {210,
731          ATV_TOP_EQU2_EQU_C2_FM,
732          ATV_TOP_EQU2_EQU_C2_L,
733          ATV_TOP_EQU2_EQU_C2_LP,
734          ATV_TOP_EQU2_EQU_C2_BG,
735          ATV_TOP_EQU2_EQU_C2_DK,
736          ATV_TOP_EQU2_EQU_C2_I},
737         /* shadow of ATV_TOP_EQU3__A */
738         {-160,
739          ATV_TOP_EQU3_EQU_C3_FM,
740          ATV_TOP_EQU3_EQU_C3_L,
741          ATV_TOP_EQU3_EQU_C3_LP,
742          ATV_TOP_EQU3_EQU_C3_BG,
743          ATV_TOP_EQU3_EQU_C3_DK,
744          ATV_TOP_EQU3_EQU_C3_I},
745         false,                  /* flag: true=bypass             */
746         ATV_TOP_VID_PEAK__PRE,  /* shadow of ATV_TOP_VID_PEAK__A */
747         ATV_TOP_NOISE_TH__PRE,  /* shadow of ATV_TOP_NOISE_TH__A */
748         true,                   /* flag CVBS ouput enable        */
749         false,                  /* flag SIF ouput enable         */
750         DRXJ_SIF_ATTENUATION_0DB,       /* current SIF att setting       */
751         {                       /* qam_rf_agc_cfg */
752          DRX_STANDARD_ITU_B,    /* standard            */
753          DRX_AGC_CTRL_AUTO,     /* ctrl_mode            */
754          0,                     /* output_level         */
755          0,                     /* min_output_level      */
756          0xFFFF,                /* max_output_level      */
757          0x0000,                /* speed               */
758          0x0000,                /* top                 */
759          0x0000                 /* c.o.c.              */
760          },
761         {                       /* qam_if_agc_cfg */
762          DRX_STANDARD_ITU_B,    /* standard            */
763          DRX_AGC_CTRL_AUTO,     /* ctrl_mode            */
764          0,                     /* output_level         */
765          0,                     /* min_output_level      */
766          0xFFFF,                /* max_output_level      */
767          0x0000,                /* speed               */
768          0x0000,                /* top    (don't care) */
769          0x0000                 /* c.o.c. (don't care) */
770          },
771         {                       /* vsb_rf_agc_cfg */
772          DRX_STANDARD_8VSB,     /* standard       */
773          DRX_AGC_CTRL_AUTO,     /* ctrl_mode       */
774          0,                     /* output_level    */
775          0,                     /* min_output_level */
776          0xFFFF,                /* max_output_level */
777          0x0000,                /* speed          */
778          0x0000,                /* top    (don't care) */
779          0x0000                 /* c.o.c. (don't care) */
780          },
781         {                       /* vsb_if_agc_cfg */
782          DRX_STANDARD_8VSB,     /* standard       */
783          DRX_AGC_CTRL_AUTO,     /* ctrl_mode       */
784          0,                     /* output_level    */
785          0,                     /* min_output_level */
786          0xFFFF,                /* max_output_level */
787          0x0000,                /* speed          */
788          0x0000,                /* top    (don't care) */
789          0x0000                 /* c.o.c. (don't care) */
790          },
791         0,                      /* qam_pga_cfg */
792         0,                      /* vsb_pga_cfg */
793         {                       /* qam_pre_saw_cfg */
794          DRX_STANDARD_ITU_B,    /* standard  */
795          0,                     /* reference */
796          false                  /* use_pre_saw */
797          },
798         {                       /* vsb_pre_saw_cfg */
799          DRX_STANDARD_8VSB,     /* standard  */
800          0,                     /* reference */
801          false                  /* use_pre_saw */
802          },
803
804         /* Version information */
805 #ifndef _CH_
806         {
807          "01234567890",         /* human readable version microcode             */
808          "01234567890"          /* human readable version device specific code  */
809          },
810         {
811          {                      /* struct drx_version for microcode                   */
812           DRX_MODULE_UNKNOWN,
813           (char *)(NULL),
814           0,
815           0,
816           0,
817           (char *)(NULL)
818           },
819          {                      /* struct drx_version for device specific code */
820           DRX_MODULE_UNKNOWN,
821           (char *)(NULL),
822           0,
823           0,
824           0,
825           (char *)(NULL)
826           }
827          },
828         {
829          {                      /* struct drx_version_list for microcode */
830           (struct drx_version *) (NULL),
831           (struct drx_version_list *) (NULL)
832           },
833          {                      /* struct drx_version_list for device specific code */
834           (struct drx_version *) (NULL),
835           (struct drx_version_list *) (NULL)
836           }
837          },
838 #endif
839         false,                  /* smart_ant_inverted */
840         /* Tracking filter setting for OOB  */
841         {
842          12000,
843          9300,
844          6600,
845          5280,
846          3700,
847          3000,
848          2000,
849          0},
850         false,                  /* oob_power_on           */
851         0,                      /* mpeg_ts_static_bitrate  */
852         false,                  /* disable_te_ihandling   */
853         false,                  /* bit_reverse_mpeg_outout */
854         DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO,        /* mpeg_output_clock_rate */
855         DRXJ_MPEG_START_WIDTH_1CLKCYC,  /* mpeg_start_width */
856
857         /* Pre SAW & Agc configuration for ATV */
858         {
859          DRX_STANDARD_NTSC,     /* standard     */
860          7,                     /* reference    */
861          true                   /* use_pre_saw    */
862          },
863         {                       /* ATV RF-AGC */
864          DRX_STANDARD_NTSC,     /* standard              */
865          DRX_AGC_CTRL_AUTO,     /* ctrl_mode              */
866          0,                     /* output_level           */
867          0,                     /* min_output_level (d.c.) */
868          0,                     /* max_output_level (d.c.) */
869          3,                     /* speed                 */
870          9500,                  /* top                   */
871          4000                   /* cut-off current       */
872          },
873         {                       /* ATV IF-AGC */
874          DRX_STANDARD_NTSC,     /* standard              */
875          DRX_AGC_CTRL_AUTO,     /* ctrl_mode              */
876          0,                     /* output_level           */
877          0,                     /* min_output_level (d.c.) */
878          0,                     /* max_output_level (d.c.) */
879          3,                     /* speed                 */
880          2400,                  /* top                   */
881          0                      /* c.o.c.         (d.c.) */
882          },
883         140,                    /* ATV PGA config */
884         0,                      /* curr_symbol_rate */
885
886         false,                  /* pdr_safe_mode     */
887         SIO_PDR_GPIO_CFG__PRE,  /* pdr_safe_restore_val_gpio  */
888         SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
889         SIO_PDR_SMA_RX_CFG__PRE,        /* pdr_safe_restore_val_sma_rx */
890         SIO_PDR_SMA_TX_CFG__PRE,        /* pdr_safe_restore_val_sma_tx */
891
892         4,                      /* oob_pre_saw            */
893         DRXJ_OOB_LO_POW_MINUS10DB,      /* oob_lo_pow             */
894         {
895          false                  /* aud_data, only first member */
896          },
897 };
898
899 /**
900 * \var drxj_default_addr_g
901 * \brief Default I2C address and device identifier.
902 */
903 struct i2c_device_addr drxj_default_addr_g = {
904         DRXJ_DEF_I2C_ADDR,      /* i2c address */
905         DRXJ_DEF_DEMOD_DEV_ID   /* device id */
906 };
907
908 /**
909 * \var drxj_default_comm_attr_g
910 * \brief Default common attributes of a drxj demodulator instance.
911 */
912 struct drx_common_attr drxj_default_comm_attr_g = {
913         NULL,                   /* ucode file           */
914         true,                   /* ucode verify switch  */
915         {0},                    /* version record       */
916
917         44000,                  /* IF in kHz in case no tuner instance is used  */
918         (151875 - 0),           /* system clock frequency in kHz                */
919         0,                      /* oscillator frequency kHz                     */
920         0,                      /* oscillator deviation in ppm, signed          */
921         false,                  /* If true mirror frequency spectrum            */
922         {
923          /* MPEG output configuration */
924          true,                  /* If true, enable MPEG ouput    */
925          false,                 /* If true, insert RS byte       */
926          true,                  /* If true, parallel out otherwise serial */
927          false,                 /* If true, invert DATA signals  */
928          false,                 /* If true, invert ERR signal    */
929          false,                 /* If true, invert STR signals   */
930          false,                 /* If true, invert VAL signals   */
931          false,                 /* If true, invert CLK signals   */
932          true,                  /* If true, static MPEG clockrate will
933                                    be used, otherwise clockrate will
934                                    adapt to the bitrate of the TS */
935          19392658UL,            /* Maximum bitrate in b/s in case
936                                    static clockrate is selected */
937          DRX_MPEG_STR_WIDTH_1   /* MPEG Start width in clock cycles */
938          },
939         /* Initilisations below can be ommited, they require no user input and
940            are initialy 0, NULL or false. The compiler will initialize them to these
941            values when ommited.  */
942         false,                  /* is_opened */
943
944         /* SCAN */
945         NULL,                   /* no scan params yet               */
946         0,                      /* current scan index               */
947         0,                      /* next scan frequency              */
948         false,                  /* scan ready flag                  */
949         0,                      /* max channels to scan             */
950         0,                      /* nr of channels scanned           */
951         NULL,                   /* default scan function            */
952         NULL,                   /* default context pointer          */
953         0,                      /* millisec to wait for demod lock  */
954         DRXJ_DEMOD_LOCK,        /* desired lock               */
955         false,
956
957         /* Power management */
958         DRX_POWER_UP,
959
960         /* Tuner */
961         1,                      /* nr of I2C port to wich tuner is     */
962         0L,                     /* minimum RF input frequency, in kHz  */
963         0L,                     /* maximum RF input frequency, in kHz  */
964         false,                  /* Rf Agc Polarity                     */
965         false,                  /* If Agc Polarity                     */
966         false,                  /* tuner slow mode                     */
967
968         {                       /* current channel (all 0)             */
969          0UL                    /* channel.frequency */
970          },
971         DRX_STANDARD_UNKNOWN,   /* current standard */
972         DRX_STANDARD_UNKNOWN,   /* previous standard */
973         DRX_STANDARD_UNKNOWN,   /* di_cache_standard   */
974         false,                  /* use_bootloader */
975         0UL,                    /* capabilities */
976         0                       /* mfx */
977 };
978
979 /**
980 * \var drxj_default_demod_g
981 * \brief Default drxj demodulator instance.
982 */
983 struct drx_demod_instance drxj_default_demod_g = {
984         &drxj_functions_g,      /* demod functions */
985         &DRXJ_DAP,              /* data access protocol functions */
986         NULL,                   /* tuner instance */
987         &drxj_default_addr_g,   /* i2c address & device id */
988         &drxj_default_comm_attr_g,      /* demod common attributes */
989         &drxj_data_g            /* demod device specific attributes */
990 };
991
992 /**
993 * \brief Default audio data structure for DRK demodulator instance.
994 *
995 * This structure is DRXK specific.
996 *
997 */
998 struct drx_aud_data drxj_default_aud_data_g = {
999         false,                  /* audio_is_active */
1000         DRX_AUD_STANDARD_AUTO,  /* audio_standard  */
1001
1002         /* i2sdata */
1003         {
1004          false,                 /* output_enable   */
1005          48000,                 /* frequency      */
1006          DRX_I2S_MODE_MASTER,   /* mode           */
1007          DRX_I2S_WORDLENGTH_32, /* word_length     */
1008          DRX_I2S_POLARITY_RIGHT,        /* polarity       */
1009          DRX_I2S_FORMAT_WS_WITH_DATA    /* format         */
1010          },
1011         /* volume            */
1012         {
1013          true,                  /* mute;          */
1014          0,                     /* volume         */
1015          DRX_AUD_AVC_OFF,       /* avc_mode        */
1016          0,                     /* avc_ref_level    */
1017          DRX_AUD_AVC_MAX_GAIN_12DB,     /* avc_max_gain     */
1018          DRX_AUD_AVC_MAX_ATTEN_24DB,    /* avc_max_atten    */
1019          0,                     /* strength_left   */
1020          0                      /* strength_right  */
1021          },
1022         DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
1023         /*  ass_thresholds */
1024         {
1025          440,                   /* A2    */
1026          12,                    /* BTSC  */
1027          700,                   /* NICAM */
1028          },
1029         /* carrier */
1030         {
1031          /* a */
1032          {
1033           42,                   /* thres */
1034           DRX_NO_CARRIER_NOISE, /* opt   */
1035           0,                    /* shift */
1036           0                     /* dco   */
1037           },
1038          /* b */
1039          {
1040           42,                   /* thres */
1041           DRX_NO_CARRIER_MUTE,  /* opt   */
1042           0,                    /* shift */
1043           0                     /* dco   */
1044           },
1045
1046          },
1047         /* mixer */
1048         {
1049          DRX_AUD_SRC_STEREO_OR_A,       /* source_i2s */
1050          DRX_AUD_I2S_MATRIX_STEREO,     /* matrix_i2s */
1051          DRX_AUD_FM_MATRIX_SOUND_A      /* matrix_fm  */
1052          },
1053         DRX_AUD_DEVIATION_NORMAL,       /* deviation */
1054         DRX_AUD_AVSYNC_OFF,     /* av_sync */
1055
1056         /* prescale */
1057         {
1058          DRX_AUD_MAX_FM_DEVIATION,      /* fm_deviation */
1059          DRX_AUD_MAX_NICAM_PRESCALE     /* nicam_gain */
1060          },
1061         DRX_AUD_FM_DEEMPH_75US, /* deemph */
1062         DRX_BTSC_STEREO,        /* btsc_detect */
1063         0,                      /* rds_data_counter */
1064         false                   /* rds_data_present */
1065 };
1066
1067 /*-----------------------------------------------------------------------------
1068 STRUCTURES
1069 ----------------------------------------------------------------------------*/
1070 struct drxjeq_stat {
1071         u16 eq_mse;
1072         u8 eq_mode;
1073         u8 eq_ctrl;
1074         u8 eq_stat;
1075 };
1076
1077 /* HI command */
1078 struct drxj_hi_cmd {
1079         u16 cmd;
1080         u16 param1;
1081         u16 param2;
1082         u16 param3;
1083         u16 param4;
1084         u16 param5;
1085         u16 param6;
1086 };
1087
1088 /*============================================================================*/
1089 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
1090 /*============================================================================*/
1091
1092 /**
1093  * struct drxu_code_block_hdr - Structure of the microcode block headers
1094  *
1095  * @addr:       Destination address of the data in this block
1096  * @size:       Size of the block data following this header counted in
1097  *              16 bits words
1098  * @CRC:        CRC value of the data block, only valid if CRC flag is
1099  *              set.
1100  */
1101 struct drxu_code_block_hdr {
1102         u32 addr;
1103         u16 size;
1104         u16 flags;
1105         u16 CRC;
1106 };
1107
1108 /*-----------------------------------------------------------------------------
1109 FUNCTIONS
1110 ----------------------------------------------------------------------------*/
1111 /* Some prototypes */
1112 static int
1113 hi_command(struct i2c_device_addr *dev_addr,
1114            const struct drxj_hi_cmd *cmd, u16 *result);
1115
1116 static int
1117 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
1118
1119 static int
1120 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
1121
1122 static int power_down_aud(struct drx_demod_instance *demod);
1123
1124 #ifndef DRXJ_DIGITAL_ONLY
1125 static int power_up_aud(struct drx_demod_instance *demod, bool set_standard);
1126 #endif
1127
1128 static int
1129 aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard);
1130
1131 static int
1132 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1133
1134 static int
1135 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
1136
1137 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1138 static int
1139 ctrl_u_code_upload(struct drx_demod_instance *demod,
1140                   struct drxu_code_info *mc_info,
1141                 enum drxu_code_actionaction, bool audio_mc_upload);
1142 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1143
1144 /*============================================================================*/
1145 /*============================================================================*/
1146 /*==                          HELPER FUNCTIONS                              ==*/
1147 /*============================================================================*/
1148 /*============================================================================*/
1149
1150 /**
1151 * \fn void mult32(u32 a, u32 b, u32 *h, u32 *l)
1152 * \brief 32bitsx32bits signed multiplication
1153 * \param a 32 bits multiplicant, typecast from signed to unisgned
1154 * \param b 32 bits multiplier, typecast from signed to unisgned
1155 * \param h pointer to high part 64 bits result, typecast from signed to unisgned
1156 * \param l pointer to low part 64 bits result
1157 *
1158 * For the 2n+n addition a + b:
1159 * if a >= 0, then h += 0 (sign extension = 0)
1160 * but if a < 0, then h += 2^n-1 ==> h -= 1.
1161 *
1162 * Also, if a + b < 2^n, then a + b  >= a && a + b >= b
1163 * but if a + b >= 2^n, then R = a + b - 2^n,
1164 * and because a < 2^n && b < 2*n ==> R < a && R < b.
1165 * Therefore, to detect overflow, simply compare the addition result with
1166 * one of the operands; if the result is smaller, overflow has occurred and
1167 * h must be incremented.
1168 *
1169 * Booth multiplication uses additions and subtractions to reduce the number
1170 * of iterations. This is done by taking three subsequent bits abc and calculating
1171 * the following multiplication factor: -2a + b + c. This factor is multiplied
1172 * by the second operand and added to the result. Next, the first operand is
1173 * shifted two bits (hence one of the three bits is reused) and the process
1174 * repeated. The last iteration has only two bits left, but we simply add
1175 * a zero to the end.
1176 *
1177 * Hence: (n=4)
1178 *  1 * a =  0 * 4a + 1 * a
1179 *  2 * a =  1 * 4a - 2 * a
1180 *  3 * a =  1 * 4a - 1 * a
1181 * -1 * a =  0 * 4a - 1 * a
1182 * -5 * a = -1 * 4a - 1 * a
1183 *
1184 * etc.
1185 *
1186 * Note that the function is type size independent. Any unsigned integer type
1187 * can be substituted for booth_t.
1188 *
1189 */
1190
1191 #define DRX_IS_BOOTH_NEGATIVE(__a)  (((__a) & (1 << (sizeof(u32) * 8 - 1))) != 0)
1192
1193 static void mult32(u32 a, u32 b, u32 *h, u32 *l)
1194 {
1195         unsigned int i;
1196         *h = *l = 0;
1197
1198         /* n/2 iterations; shift operand a left two bits after each iteration.      */
1199         /* This automatically appends a zero to the operand for the last iteration. */
1200         for (i = 0; i < sizeof(a) * 8; i += 2, a = a << 2) {
1201                 /* Shift result left two bits */
1202                 *h = (*h << 2) + (*l >> (sizeof(*l) * 8 - 2));
1203                 *l = (*l << 2);
1204
1205                 /* Take the first three bits of operand a for the Booth conversion: */
1206                 /* 0, 7: do nothing  */
1207                 /* 1, 2: add b       */
1208                 /* 3   : add 2b      */
1209                 /* 4   : subtract 2b */
1210                 /* 5, 6: subtract b  */
1211                 switch (a >> (sizeof(a) * 8 - 3)) {
1212                 case 3:
1213                         *l += b;
1214                         *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1215                 case 1:
1216                 case 2:
1217                         *l += b;
1218                         *h = *h - DRX_IS_BOOTH_NEGATIVE(b) + (*l < b);
1219                         break;
1220                 case 4:
1221                         *l -= b;
1222                         *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1223                                                                     ((u32)
1224                                                                      (-
1225                                                                       ((s32)
1226                                                                        b))));
1227                 case 5:
1228                 case 6:
1229                         *l -= b;
1230                         *h = *h - !DRX_IS_BOOTH_NEGATIVE(b) + !b + (*l <
1231                                                                     ((u32)
1232                                                                      (-
1233                                                                       ((s32)
1234                                                                        b))));
1235                         break;
1236                 }
1237         }
1238 }
1239
1240 /*============================================================================*/
1241
1242 /*
1243 * \fn u32 frac28(u32 N, u32 D)
1244 * \brief Compute: (1<<28)*N/D
1245 * \param N 32 bits
1246 * \param D 32 bits
1247 * \return (1<<28)*N/D
1248 * This function is used to avoid floating-point calculations as they may
1249 * not be present on the target platform.
1250
1251 * frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1252 * fraction used for setting the Frequency Shifter registers.
1253 * N and D can hold numbers up to width: 28-bits.
1254 * The 4 bits integer part and the 28 bits fractional part are calculated.
1255
1256 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1257
1258 * N: 0...(1<<28)-1 = 268435454
1259 * D: 0...(1<<28)-1
1260 * Q: 0...(1<<32)-1
1261 */
1262 static u32 frac28(u32 N, u32 D)
1263 {
1264         int i = 0;
1265         u32 Q1 = 0;
1266         u32 R0 = 0;
1267
1268         R0 = (N % D) << 4;      /* 32-28 == 4 shifts possible at max */
1269         Q1 = N / D;             /* integer part, only the 4 least significant bits
1270                                    will be visible in the result */
1271
1272         /* division using radix 16, 7 nibbles in the result */
1273         for (i = 0; i < 7; i++) {
1274                 Q1 = (Q1 << 4) | R0 / D;
1275                 R0 = (R0 % D) << 4;
1276         }
1277         /* rounding */
1278         if ((R0 >> 3) >= D)
1279                 Q1++;
1280
1281         return Q1;
1282 }
1283
1284 /**
1285 * \fn u32 log1_times100( u32 x)
1286 * \brief Compute: 100*log10(x)
1287 * \param x 32 bits
1288 * \return 100*log10(x)
1289 *
1290 * 100*log10(x)
1291 * = 100*(log2(x)/log2(10)))
1292 * = (100*(2^15)*log2(x))/((2^15)*log2(10))
1293 * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1294 * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1295 * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1296 *
1297 * where y = 2^k and 1<= (x/y) < 2
1298 */
1299
1300 static u32 log1_times100(u32 x)
1301 {
1302         static const u8 scale = 15;
1303         static const u8 index_width = 5;
1304         /*
1305            log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1306            0 <= n < ((1<<INDEXWIDTH)+1)
1307          */
1308
1309         static const u32 log2lut[] = {
1310                 0,              /* 0.000000 */
1311                 290941,         /* 290941.300628 */
1312                 573196,         /* 573196.476418 */
1313                 847269,         /* 847269.179851 */
1314                 1113620,        /* 1113620.489452 */
1315                 1372674,        /* 1372673.576986 */
1316                 1624818,        /* 1624817.752104 */
1317                 1870412,        /* 1870411.981536 */
1318                 2109788,        /* 2109787.962654 */
1319                 2343253,        /* 2343252.817465 */
1320                 2571091,        /* 2571091.461923 */
1321                 2793569,        /* 2793568.696416 */
1322                 3010931,        /* 3010931.055901 */
1323                 3223408,        /* 3223408.452106 */
1324                 3431216,        /* 3431215.635215 */
1325                 3634553,        /* 3634553.498355 */
1326                 3833610,        /* 3833610.244726 */
1327                 4028562,        /* 4028562.434393 */
1328                 4219576,        /* 4219575.925308 */
1329                 4406807,        /* 4406806.721144 */
1330                 4590402,        /* 4590401.736809 */
1331                 4770499,        /* 4770499.491025 */
1332                 4947231,        /* 4947230.734179 */
1333                 5120719,        /* 5120719.018555 */
1334                 5291081,        /* 5291081.217197 */
1335                 5458428,        /* 5458427.996830 */
1336                 5622864,        /* 5622864.249668 */
1337                 5784489,        /* 5784489.488298 */
1338                 5943398,        /* 5943398.207380 */
1339                 6099680,        /* 6099680.215452 */
1340                 6253421,        /* 6253420.939751 */
1341                 6404702,        /* 6404701.706649 */
1342                 6553600,        /* 6553600.000000 */
1343         };
1344
1345         u8 i = 0;
1346         u32 y = 0;
1347         u32 d = 0;
1348         u32 k = 0;
1349         u32 r = 0;
1350
1351         if (x == 0)
1352                 return 0;
1353
1354         /* Scale x (normalize) */
1355         /* computing y in log(x/y) = log(x) - log(y) */
1356         if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
1357                 for (k = scale; k > 0; k--) {
1358                         if (x & (((u32) 1) << scale))
1359                                 break;
1360                         x <<= 1;
1361                 }
1362         } else {
1363                 for (k = scale; k < 31; k++) {
1364                         if ((x & (((u32) (-1)) << (scale + 1))) == 0)
1365                                 break;
1366                         x >>= 1;
1367                 }
1368         }
1369         /*
1370            Now x has binary point between bit[scale] and bit[scale-1]
1371            and 1.0 <= x < 2.0 */
1372
1373         /* correction for divison: log(x) = log(x/y)+log(y) */
1374         y = k * ((((u32) 1) << scale) * 200);
1375
1376         /* remove integer part */
1377         x &= ((((u32) 1) << scale) - 1);
1378         /* get index */
1379         i = (u8) (x >> (scale - index_width));
1380         /* compute delta (x-a) */
1381         d = x & ((((u32) 1) << (scale - index_width)) - 1);
1382         /* compute log, multiplication ( d* (.. )) must be within range ! */
1383         y += log2lut[i] +
1384             ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
1385         /* Conver to log10() */
1386         y /= 108853;            /* (log2(10) << scale) */
1387         r = (y >> 1);
1388         /* rounding */
1389         if (y & ((u32)1))
1390                 r++;
1391
1392         return r;
1393
1394 }
1395
1396 /**
1397 * \fn u32 frac_times1e6( u16 N, u32 D)
1398 * \brief Compute: (N/D) * 1000000.
1399 * \param N nominator 16-bits.
1400 * \param D denominator 32-bits.
1401 * \return u32
1402 * \retval ((N/D) * 1000000), 32 bits
1403 *
1404 * No check on D=0!
1405 */
1406 static u32 frac_times1e6(u32 N, u32 D)
1407 {
1408         u32 remainder = 0;
1409         u32 frac = 0;
1410
1411         /*
1412            frac = (N * 1000000) / D
1413            To let it fit in a 32 bits computation:
1414            frac = (N * (1000000 >> 4)) / (D >> 4)
1415            This would result in a problem in case D < 16 (div by 0).
1416            So we do it more elaborate as shown below.
1417          */
1418         frac = (((u32) N) * (1000000 >> 4)) / D;
1419         frac <<= 4;
1420         remainder = (((u32) N) * (1000000 >> 4)) % D;
1421         remainder <<= 4;
1422         frac += remainder / D;
1423         remainder = remainder % D;
1424         if ((remainder * 2) > D)
1425                 frac++;
1426
1427         return frac;
1428 }
1429
1430 /*============================================================================*/
1431
1432 /**
1433 * \brief Compute: 100 * 10^( gd_b / 200 ).
1434 * \param  u32   gd_b      Gain in 0.1dB
1435 * \return u32            Gainfactor in 0.01 resolution
1436 *
1437 */
1438 static u32 d_b2lin_times100(u32 gd_b)
1439 {
1440         u32 result = 0;
1441         u32 nr6d_b_steps = 0;
1442         u32 remainder = 0;
1443         u32 remainder_fac = 0;
1444
1445         /* start with factors 2 (6.02dB) */
1446         nr6d_b_steps = gd_b * 1000UL / 60206UL;
1447         if (nr6d_b_steps > 17) {
1448                 /* Result max overflow if > log2( maxu32 / 2e4 ) ~= 17.7 */
1449                 return MAX_U32;
1450         }
1451         result = (1 << nr6d_b_steps);
1452
1453         /* calculate remaining factor,
1454            poly approximation of 10^(gd_b/200):
1455
1456            y = 1E-04x2 + 0.0106x + 1.0026
1457
1458            max deviation < 0.005 for range x = [0 ... 60]
1459          */
1460         remainder = ((gd_b * 1000UL) % 60206UL) / 1000UL;
1461         /* using 1e-4 for poly calculation  */
1462         remainder_fac = 1 * remainder * remainder;
1463         remainder_fac += 106 * remainder;
1464         remainder_fac += 10026;
1465
1466         /* multiply by remaining factor */
1467         result *= remainder_fac;
1468
1469         /* conversion from 1e-4 to 1e-2 */
1470         return (result + 50) / 100;
1471 }
1472
1473 #ifndef DRXJ_DIGITAL_ONLY
1474 #define FRAC_FLOOR    0
1475 #define FRAC_CEIL     1
1476 #define FRAC_ROUND    2
1477 /**
1478 * \fn u32 frac( u32 N, u32 D, u16 RC )
1479 * \brief Compute: N/D.
1480 * \param N nominator 32-bits.
1481 * \param D denominator 32-bits.
1482 * \param RC-result correction: 0-floor; 1-ceil; 2-round
1483 * \return u32
1484 * \retval N/D, 32 bits
1485 *
1486 * If D=0 returns 0
1487 */
1488 static u32 frac(u32 N, u32 D, u16 RC)
1489 {
1490         u32 remainder = 0;
1491         u32 frac = 0;
1492         u16 bit_cnt = 32;
1493
1494         if (D == 0) {
1495                 frac = 0;
1496                 remainder = 0;
1497
1498                 return frac;
1499         }
1500
1501         if (D > N) {
1502                 frac = 0;
1503                 remainder = N;
1504         } else {
1505                 remainder = 0;
1506                 frac = N;
1507                 while (bit_cnt-- > 0) {
1508                         remainder <<= 1;
1509                         remainder |= ((frac & 0x80000000) >> 31);
1510                         frac <<= 1;
1511                         if (remainder < D) {
1512                                 frac &= 0xFFFFFFFE;
1513                         } else {
1514                                 remainder -= D;
1515                                 frac |= 0x1;
1516                         }
1517                 }
1518
1519                 /* result correction if needed */
1520                 if ((RC == FRAC_CEIL) && (remainder != 0)) {
1521                         /* ceil the result */
1522                         /*(remainder is not zero -> value behind decimal point exists) */
1523                         frac++;
1524                 }
1525                 if ((RC == FRAC_ROUND) && (remainder >= D >> 1)) {
1526                         /* remainder is bigger from D/2 -> round the result */
1527                         frac++;
1528                 }
1529         }
1530
1531         return frac;
1532 }
1533 #endif
1534
1535 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
1536 /*============================================================================*/
1537
1538 /**
1539 * \fn u16 u_code_read16( u8 *addr)
1540 * \brief Read a 16 bits word, expect big endian data.
1541 * \return u16 The data read.
1542 */
1543 static u16 u_code_read16(u8 *addr)
1544 {
1545         /* Works fo any host processor */
1546
1547         u16 word = 0;
1548
1549         word = ((u16) addr[0]);
1550         word <<= 8;
1551         word |= ((u16) addr[1]);
1552
1553         return word;
1554 }
1555
1556 /*============================================================================*/
1557
1558 /**
1559 * \fn u32 u_code_read32( u8 *addr)
1560 * \brief Read a 32 bits word, expect big endian data.
1561 * \return u32 The data read.
1562 */
1563 static u32 u_code_read32(u8 *addr)
1564 {
1565         /* Works fo any host processor */
1566
1567         u32 word = 0;
1568
1569         word = ((u16) addr[0]);
1570         word <<= 8;
1571         word |= ((u16) addr[1]);
1572         word <<= 8;
1573         word |= ((u16) addr[2]);
1574         word <<= 8;
1575         word |= ((u16) addr[3]);
1576
1577         return word;
1578 }
1579
1580 /*============================================================================*/
1581
1582 /**
1583 * \fn u16 u_code_compute_crc (u8 *block_data, u16 nr_words)
1584 * \brief Compute CRC of block of microcode data.
1585 * \param block_data Pointer to microcode data.
1586 * \param nr_words Size of microcode block (number of 16 bits words).
1587 * \return u16 The computed CRC residu.
1588 */
1589 static u16 u_code_compute_crc(u8 *block_data, u16 nr_words)
1590 {
1591         u16 i = 0;
1592         u16 j = 0;
1593         u32 crc_word = 0;
1594         u32 carry = 0;
1595
1596         while (i < nr_words) {
1597                 crc_word |= (u32) u_code_read16(block_data);
1598                 for (j = 0; j < 16; j++) {
1599                         crc_word <<= 1;
1600                         if (carry != 0)
1601                                 crc_word ^= 0x80050000UL;
1602                         carry = crc_word & 0x80000000UL;
1603                 }
1604                 i++;
1605                 block_data += (sizeof(u16));
1606         }
1607         return (u16)(crc_word >> 16);
1608 }
1609 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
1610
1611 /**
1612 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1613 *        and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1614 *
1615 */
1616 static const u16 nicam_presc_table_val[43] = {
1617         1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1618         5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1619         18, 20, 23, 25, 28, 32, 36, 40, 45,
1620         51, 57, 64, 71, 80, 90, 101, 113, 127
1621 };
1622
1623 /*============================================================================*/
1624 /*==                        END HELPER FUNCTIONS                            ==*/
1625 /*============================================================================*/
1626
1627 /*============================================================================*/
1628 /*============================================================================*/
1629 /*==                      DRXJ DAP FUNCTIONS                                ==*/
1630 /*============================================================================*/
1631 /*============================================================================*/
1632
1633 /*
1634    This layer takes care of some device specific register access protocols:
1635    -conversion to short address format
1636    -access to audio block
1637    This layer is placed between the drx_dap_fasi and the rest of the drxj
1638    specific implementation. This layer can use address map knowledge whereas
1639    dap_fasi may not use memory map knowledge.
1640
1641    * For audio currently only 16 bits read and write register access is
1642      supported. More is not needed. RMW and 32 or 8 bit access on audio
1643      registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1644      single/multi master) will be ignored.
1645
1646    TODO: check ignoring single/multimaster is ok for AUD access ?
1647 */
1648
1649 #define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1650 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80     /* millisec */
1651 /*============================================================================*/
1652
1653 /**
1654 * \fn bool is_handled_by_aud_tr_if( u32 addr )
1655 * \brief Check if this address is handled by the audio token ring interface.
1656 * \param addr
1657 * \return bool
1658 * \retval true  Yes, handled by audio token ring interface
1659 * \retval false No, not handled by audio token ring interface
1660 *
1661 */
1662 static
1663 bool is_handled_by_aud_tr_if(u32 addr)
1664 {
1665         bool retval = false;
1666
1667         if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1668             (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1669             (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1670                 retval = true;
1671         }
1672
1673         return retval;
1674 }
1675
1676 /*============================================================================*/
1677
1678 static int drxj_dap_read_block(struct i2c_device_addr *dev_addr,
1679                                       u32 addr,
1680                                       u16 datasize,
1681                                       u8 *data, u32 flags)
1682 {
1683         return drx_dap_fasi_funct_g.read_block_func(dev_addr,
1684                                                addr, datasize, data, flags);
1685 }
1686
1687 /*============================================================================*/
1688
1689 static int drxj_dap_read_modify_write_reg8(struct i2c_device_addr *dev_addr,
1690                                                 u32 waddr,
1691                                                 u32 raddr,
1692                                                 u8 wdata, u8 *rdata)
1693 {
1694         return drx_dap_fasi_funct_g.read_modify_write_reg8func(dev_addr,
1695                                                          waddr,
1696                                                          raddr, wdata, rdata);
1697 }
1698
1699 /*============================================================================*/
1700
1701 /**
1702 * \fn int drxj_dap_rm_write_reg16short
1703 * \brief Read modify write 16 bits audio register using short format only.
1704 * \param dev_addr
1705 * \param waddr    Address to write to
1706 * \param raddr    Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1707 * \param wdata    Data to write
1708 * \param rdata    Buffer for data to read
1709 * \return int
1710 * \retval 0 Succes
1711 * \retval -EIO Timeout, I2C error, illegal bank
1712 *
1713 * 16 bits register read modify write access using short addressing format only.
1714 * Requires knowledge of the registermap, thus device dependent.
1715 * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1716 *
1717 */
1718
1719 /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1720    See comments drxj_dap_read_modify_write_reg16 */
1721 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
1722 static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1723                                               u32 waddr,
1724                                               u32 raddr,
1725                                               u16 wdata, u16 *rdata)
1726 {
1727         int rc;
1728
1729         if (rdata == NULL)
1730                 return -EINVAL;
1731
1732         /* Set RMW flag */
1733         rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1734                                               SIO_HI_RA_RAM_S0_FLG_ACC__A,
1735                                               SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1736                                               0x0000);
1737         if (rc == 0) {
1738                 /* Write new data: triggers RMW */
1739                 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr, waddr, wdata,
1740                                                       0x0000);
1741         }
1742         if (rc == 0) {
1743                 /* Read old data */
1744                 rc = drx_dap_fasi_funct_g.read_reg16func(dev_addr, raddr, rdata,
1745                                                      0x0000);
1746         }
1747         if (rc == 0) {
1748                 /* Reset RMW flag */
1749                 rc = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
1750                                                       SIO_HI_RA_RAM_S0_FLG_ACC__A,
1751                                                       0, 0x0000);
1752         }
1753
1754         return rc;
1755 }
1756 #endif
1757
1758 /*============================================================================*/
1759
1760 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1761                                                  u32 waddr,
1762                                                  u32 raddr,
1763                                                  u16 wdata, u16 *rdata)
1764 {
1765         /* TODO: correct short/long addressing format decision,
1766            now long format has higher prio then short because short also
1767            needs virt bnks (not impl yet) for certain audio registers */
1768 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1769         return drx_dap_fasi_funct_g.read_modify_write_reg16func(dev_addr,
1770                                                           waddr,
1771                                                           raddr, wdata, rdata);
1772 #else
1773         return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
1774 #endif
1775 }
1776
1777 /*============================================================================*/
1778
1779 static int drxj_dap_read_modify_write_reg32(struct i2c_device_addr *dev_addr,
1780                                                  u32 waddr,
1781                                                  u32 raddr,
1782                                                  u32 wdata, u32 *rdata)
1783 {
1784         return drx_dap_fasi_funct_g.read_modify_write_reg32func(dev_addr,
1785                                                           waddr,
1786                                                           raddr, wdata, rdata);
1787 }
1788
1789 /*============================================================================*/
1790
1791 static int drxj_dap_read_reg8(struct i2c_device_addr *dev_addr,
1792                                      u32 addr,
1793                                      u8 *data, u32 flags)
1794 {
1795         return drx_dap_fasi_funct_g.read_reg8func(dev_addr, addr, data, flags);
1796 }
1797
1798 /*============================================================================*/
1799
1800 /**
1801 * \fn int drxj_dap_read_aud_reg16
1802 * \brief Read 16 bits audio register
1803 * \param dev_addr
1804 * \param addr
1805 * \param data
1806 * \return int
1807 * \retval 0 Succes
1808 * \retval -EIO Timeout, I2C error, illegal bank
1809 *
1810 * 16 bits register read access via audio token ring interface.
1811 *
1812 */
1813 static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1814                                          u32 addr, u16 *data)
1815 {
1816         u32 start_timer = 0;
1817         u32 current_timer = 0;
1818         u32 delta_timer = 0;
1819         u16 tr_status = 0;
1820         int stat = -EIO;
1821
1822         /* No read possible for bank 3, return with error */
1823         if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1824                 stat = -EINVAL;
1825         } else {
1826                 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1827
1828                 /* Force reset write bit */
1829                 addr &= (~write_bit);
1830
1831                 /* Set up read */
1832                 start_timer = drxbsp_hst_clock();
1833                 do {
1834                         /* RMW to aud TR IF until request is granted or timeout */
1835                         stat = drxj_dap_read_modify_write_reg16(dev_addr,
1836                                                              addr,
1837                                                              SIO_HI_RA_RAM_S0_RMWBUF__A,
1838                                                              0x0000, &tr_status);
1839
1840                         if (stat != 0)
1841                                 break;
1842
1843                         current_timer = drxbsp_hst_clock();
1844                         delta_timer = current_timer - start_timer;
1845                         if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1846                                 stat = -EIO;
1847                                 break;
1848                         }
1849
1850                 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1851                           AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1852                          ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1853                           AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1854         }                       /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1855
1856         /* Wait for read ready status or timeout */
1857         if (stat == 0) {
1858                 start_timer = drxbsp_hst_clock();
1859
1860                 while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1861                        AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1862                         stat = drxj_dap_read_reg16(dev_addr,
1863                                                   AUD_TOP_TR_CTR__A,
1864                                                   &tr_status, 0x0000);
1865                         if (stat != 0)
1866                                 break;
1867
1868                         current_timer = drxbsp_hst_clock();
1869                         delta_timer = current_timer - start_timer;
1870                         if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1871                                 stat = -EIO;
1872                                 break;
1873                         }
1874                 }               /* while ( ... ) */
1875         }
1876
1877         /* Read value */
1878         if (stat == 0)
1879                 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1880                                                      AUD_TOP_TR_RD_REG__A,
1881                                                      SIO_HI_RA_RAM_S0_RMWBUF__A,
1882                                                      0x0000, data);
1883         return stat;
1884 }
1885
1886 /*============================================================================*/
1887
1888 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1889                                       u32 addr,
1890                                       u16 *data, u32 flags)
1891 {
1892         int stat = -EIO;
1893
1894         /* Check param */
1895         if ((dev_addr == NULL) || (data == NULL))
1896                 return -EINVAL;
1897
1898         if (is_handled_by_aud_tr_if(addr))
1899                 stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
1900         else
1901                 stat = drx_dap_fasi_funct_g.read_reg16func(dev_addr,
1902                                                            addr, data, flags);
1903
1904         return stat;
1905 }
1906
1907 /*============================================================================*/
1908
1909 static int drxj_dap_read_reg32(struct i2c_device_addr *dev_addr,
1910                                       u32 addr,
1911                                       u32 *data, u32 flags)
1912 {
1913         return drx_dap_fasi_funct_g.read_reg32func(dev_addr, addr, data, flags);
1914 }
1915
1916 /*============================================================================*/
1917
1918 static int drxj_dap_write_block(struct i2c_device_addr *dev_addr,
1919                                        u32 addr,
1920                                        u16 datasize,
1921                                        u8 *data, u32 flags)
1922 {
1923         return drx_dap_fasi_funct_g.write_block_func(dev_addr,
1924                                                 addr, datasize, data, flags);
1925 }
1926
1927 /*============================================================================*/
1928
1929 static int drxj_dap_write_reg8(struct i2c_device_addr *dev_addr,
1930                                       u32 addr,
1931                                       u8 data, u32 flags)
1932 {
1933         return drx_dap_fasi_funct_g.write_reg8func(dev_addr, addr, data, flags);
1934 }
1935
1936 /*============================================================================*/
1937
1938 /**
1939 * \fn int drxj_dap_write_aud_reg16
1940 * \brief Write 16 bits audio register
1941 * \param dev_addr
1942 * \param addr
1943 * \param data
1944 * \return int
1945 * \retval 0 Succes
1946 * \retval -EIO Timeout, I2C error, illegal bank
1947 *
1948 * 16 bits register write access via audio token ring interface.
1949 *
1950 */
1951 static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
1952                                           u32 addr, u16 data)
1953 {
1954         int stat = -EIO;
1955
1956         /* No write possible for bank 2, return with error */
1957         if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
1958                 stat = -EINVAL;
1959         } else {
1960                 u32 start_timer = 0;
1961                 u32 current_timer = 0;
1962                 u32 delta_timer = 0;
1963                 u16 tr_status = 0;
1964                 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1965
1966                 /* Force write bit */
1967                 addr |= write_bit;
1968                 start_timer = drxbsp_hst_clock();
1969                 do {
1970                         /* RMW to aud TR IF until request is granted or timeout */
1971                         stat = drxj_dap_read_modify_write_reg16(dev_addr,
1972                                                              addr,
1973                                                              SIO_HI_RA_RAM_S0_RMWBUF__A,
1974                                                              data, &tr_status);
1975                         if (stat != 0)
1976                                 break;
1977
1978                         current_timer = drxbsp_hst_clock();
1979                         delta_timer = current_timer - start_timer;
1980                         if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1981                                 stat = -EIO;
1982                                 break;
1983                         }
1984
1985                 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1986                           AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1987                          ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1988                           AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1989
1990         }                       /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
1991
1992         return stat;
1993 }
1994
1995 /*============================================================================*/
1996
1997 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
1998                                        u32 addr,
1999                                        u16 data, u32 flags)
2000 {
2001         int stat = -EIO;
2002
2003         /* Check param */
2004         if (dev_addr == NULL)
2005                 return -EINVAL;
2006
2007         if (is_handled_by_aud_tr_if(addr))
2008                 stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
2009         else
2010                 stat = drx_dap_fasi_funct_g.write_reg16func(dev_addr,
2011                                                             addr, data, flags);
2012
2013         return stat;
2014 }
2015
2016 /*============================================================================*/
2017
2018 static int drxj_dap_write_reg32(struct i2c_device_addr *dev_addr,
2019                                        u32 addr,
2020                                        u32 data, u32 flags)
2021 {
2022         return drx_dap_fasi_funct_g.write_reg32func(dev_addr, addr, data, flags);
2023 }
2024
2025 /*============================================================================*/
2026
2027 /* Free data ram in SIO HI */
2028 #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2029 #define SIO_HI_RA_RAM_USR_END__A   0x420060
2030
2031 #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2032 #define DRXJ_HI_ATOMIC_BUF_END   (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2033 #define DRXJ_HI_ATOMIC_READ      SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2034 #define DRXJ_HI_ATOMIC_WRITE     SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2035
2036 /**
2037 * \fn int drxj_dap_atomic_read_write_block()
2038 * \brief Basic access routine for atomic read or write access
2039 * \param dev_addr  pointer to i2c dev address
2040 * \param addr     destination/source address
2041 * \param datasize size of data buffer in bytes
2042 * \param data     pointer to data buffer
2043 * \return int
2044 * \retval 0 Succes
2045 * \retval -EIO Timeout, I2C error, illegal bank
2046 *
2047 */
2048 static
2049 int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2050                                           u32 addr,
2051                                           u16 datasize,
2052                                           u8 *data, bool read_flag)
2053 {
2054         struct drxj_hi_cmd hi_cmd;
2055         int rc;
2056         u16 word;
2057         u16 dummy = 0;
2058         u16 i = 0;
2059
2060         /* Parameter check */
2061         if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
2062                 return -EINVAL;
2063
2064         /* Set up HI parameters to read or write n bytes */
2065         hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2066         hi_cmd.param1 =
2067             (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2068                      DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2069         hi_cmd.param2 =
2070             (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2071         hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2072         if (!read_flag)
2073                 hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2074         else
2075                 hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
2076         hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2077                                 DRXDAP_FASI_ADDR2BANK(addr));
2078         hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
2079
2080         if (!read_flag) {
2081                 /* write data to buffer */
2082                 for (i = 0; i < (datasize / 2); i++) {
2083
2084                         word = ((u16) data[2 * i]);
2085                         word += (((u16) data[(2 * i) + 1]) << 8);
2086                         drxj_dap_write_reg16(dev_addr,
2087                                              (DRXJ_HI_ATOMIC_BUF_START + i),
2088                                             word, 0);
2089                 }
2090         }
2091
2092         rc = hi_command(dev_addr, &hi_cmd, &dummy);
2093         if (rc != 0) {
2094                 pr_err("error %d\n", rc);
2095                 goto rw_error;
2096         }
2097
2098         if (read_flag) {
2099                 /* read data from buffer */
2100                 for (i = 0; i < (datasize / 2); i++) {
2101                         drxj_dap_read_reg16(dev_addr,
2102                                             (DRXJ_HI_ATOMIC_BUF_START + i),
2103                                            &word, 0);
2104                         data[2 * i] = (u8) (word & 0xFF);
2105                         data[(2 * i) + 1] = (u8) (word >> 8);
2106                 }
2107         }
2108
2109         return 0;
2110
2111 rw_error:
2112         return -EIO;
2113
2114 }
2115
2116 /*============================================================================*/
2117
2118 /**
2119 * \fn int drxj_dap_atomic_read_reg32()
2120 * \brief Atomic read of 32 bits words
2121 */
2122 static
2123 int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2124                                      u32 addr,
2125                                      u32 *data, u32 flags)
2126 {
2127         u8 buf[sizeof(*data)];
2128         int rc = -EIO;
2129         u32 word = 0;
2130
2131         if (!data)
2132                 return -EINVAL;
2133
2134         rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
2135                                               sizeof(*data), buf, true);
2136
2137         if (rc < 0)
2138                 return 0;
2139
2140         word = (u32) buf[3];
2141         word <<= 8;
2142         word |= (u32) buf[2];
2143         word <<= 8;
2144         word |= (u32) buf[1];
2145         word <<= 8;
2146         word |= (u32) buf[0];
2147
2148         *data = word;
2149
2150         return rc;
2151 }
2152
2153 /*============================================================================*/
2154
2155 /*============================================================================*/
2156 /*==                        END DRXJ DAP FUNCTIONS                          ==*/
2157 /*============================================================================*/
2158
2159 /*============================================================================*/
2160 /*============================================================================*/
2161 /*==                      HOST INTERFACE FUNCTIONS                          ==*/
2162 /*============================================================================*/
2163 /*============================================================================*/
2164
2165 /**
2166 * \fn int hi_cfg_command()
2167 * \brief Configure HI with settings stored in the demod structure.
2168 * \param demod Demodulator.
2169 * \return int.
2170 *
2171 * This routine was created because to much orthogonal settings have
2172 * been put into one HI API function (configure). Especially the I2C bridge
2173 * enable/disable should not need re-configuration of the HI.
2174 *
2175 */
2176 static int hi_cfg_command(const struct drx_demod_instance *demod)
2177 {
2178         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2179         struct drxj_hi_cmd hi_cmd;
2180         u16 result = 0;
2181         int rc;
2182
2183         ext_attr = (struct drxj_data *) demod->my_ext_attr;
2184
2185         hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2186         hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2187         hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2188         hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2189         hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2190         hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2191         hi_cmd.param6 = ext_attr->hi_cfg_transmit;
2192
2193         rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
2194         if (rc != 0) {
2195                 pr_err("error %d\n", rc);
2196                 goto rw_error;
2197         }
2198
2199         /* Reset power down flag (set one call only) */
2200         ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2201
2202         return 0;
2203
2204 rw_error:
2205         return -EIO;
2206 }
2207
2208 /**
2209 * \fn int hi_command()
2210 * \brief Configure HI with settings stored in the demod structure.
2211 * \param dev_addr I2C address.
2212 * \param cmd HI command.
2213 * \param result HI command result.
2214 * \return int.
2215 *
2216 * Sends command to HI
2217 *
2218 */
2219 static int
2220 hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
2221 {
2222         u16 wait_cmd = 0;
2223         u16 nr_retries = 0;
2224         bool powerdown_cmd = false;
2225         int rc;
2226
2227         /* Write parameters */
2228         switch (cmd->cmd) {
2229
2230         case SIO_HI_RA_RAM_CMD_CONFIG:
2231         case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2232                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
2233                 if (rc != 0) {
2234                         pr_err("error %d\n", rc);
2235                         goto rw_error;
2236                 }
2237                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
2238                 if (rc != 0) {
2239                         pr_err("error %d\n", rc);
2240                         goto rw_error;
2241                 }
2242                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
2243                 if (rc != 0) {
2244                         pr_err("error %d\n", rc);
2245                         goto rw_error;
2246                 }
2247                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
2248                 if (rc != 0) {
2249                         pr_err("error %d\n", rc);
2250                         goto rw_error;
2251                 }
2252                 /* fallthrough */
2253         case SIO_HI_RA_RAM_CMD_BRDCTRL:
2254                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
2255                 if (rc != 0) {
2256                         pr_err("error %d\n", rc);
2257                         goto rw_error;
2258                 }
2259                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
2260                 if (rc != 0) {
2261                         pr_err("error %d\n", rc);
2262                         goto rw_error;
2263                 }
2264                 /* fallthrough */
2265         case SIO_HI_RA_RAM_CMD_NULL:
2266                 /* No parameters */
2267                 break;
2268
2269         default:
2270                 return -EINVAL;
2271                 break;
2272         }
2273
2274         /* Write command */
2275         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
2276         if (rc != 0) {
2277                 pr_err("error %d\n", rc);
2278                 goto rw_error;
2279         }
2280
2281         if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
2282                 drxbsp_hst_sleep(1);
2283
2284         /* Detect power down to ommit reading result */
2285         powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2286                                   (((cmd->
2287                                      param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2288                                    == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2289         if (!powerdown_cmd) {
2290                 /* Wait until command rdy */
2291                 do {
2292                         nr_retries++;
2293                         if (nr_retries > DRXJ_MAX_RETRIES) {
2294                                 pr_err("timeout\n");
2295                                 goto rw_error;
2296                         }
2297
2298                         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
2299                         if (rc != 0) {
2300                                 pr_err("error %d\n", rc);
2301                                 goto rw_error;
2302                         }
2303                 } while (wait_cmd != 0);
2304
2305                 /* Read result */
2306                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
2307                 if (rc != 0) {
2308                         pr_err("error %d\n", rc);
2309                         goto rw_error;
2310                 }
2311
2312         }
2313         /* if ( powerdown_cmd == true ) */
2314         return 0;
2315 rw_error:
2316         return -EIO;
2317 }
2318
2319 /**
2320 * \fn int init_hi( const struct drx_demod_instance *demod )
2321 * \brief Initialise and configurate HI.
2322 * \param demod pointer to demod data.
2323 * \return int Return status.
2324 * \retval 0 Success.
2325 * \retval -EIO Failure.
2326 *
2327 * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2328 * Need to store configuration in driver because of the way I2C
2329 * bridging is controlled.
2330 *
2331 */
2332 static int init_hi(const struct drx_demod_instance *demod)
2333 {
2334         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2335         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2336         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2337         int rc;
2338
2339         ext_attr = (struct drxj_data *) demod->my_ext_attr;
2340         common_attr = (struct drx_common_attr *) demod->my_common_attr;
2341         dev_addr = demod->my_i2c_dev_addr;
2342
2343         /* PATCH for bug 5003, HI ucode v3.1.0 */
2344         rc = DRXJ_DAP.write_reg16func(dev_addr, 0x4301D7, 0x801, 0);
2345         if (rc != 0) {
2346                 pr_err("error %d\n", rc);
2347                 goto rw_error;
2348         }
2349
2350         /* Timing div, 250ns/Psys */
2351         /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2352         ext_attr->hi_cfg_timing_div =
2353             (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
2354         /* Clipping */
2355         if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
2356                 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2357         /* Bridge delay, uses oscilator clock */
2358         /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2359         /* SDA brdige delay */
2360         ext_attr->hi_cfg_bridge_delay =
2361             (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
2362             1000;
2363         /* Clipping */
2364         if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
2365                 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2366         /* SCL bridge delay, same as SDA for now */
2367         ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
2368                                       SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2369         /* Wakeup key, setting the read flag (as suggest in the documentation) does
2370            not always result into a working solution (barebones worked VI2C failed).
2371            Not setting the bit works in all cases . */
2372         ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
2373         /* port/bridge/power down ctrl */
2374         ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2375         /* transit mode time out delay and watch dog divider */
2376         ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
2377
2378         rc = hi_cfg_command(demod);
2379         if (rc != 0) {
2380                 pr_err("error %d\n", rc);
2381                 goto rw_error;
2382         }
2383
2384         return 0;
2385
2386 rw_error:
2387         return -EIO;
2388 }
2389
2390 /*============================================================================*/
2391 /*==                   END HOST INTERFACE FUNCTIONS                         ==*/
2392 /*============================================================================*/
2393
2394 /*============================================================================*/
2395 /*============================================================================*/
2396 /*==                        AUXILIARY FUNCTIONS                             ==*/
2397 /*============================================================================*/
2398 /*============================================================================*/
2399
2400 /**
2401 * \fn int get_device_capabilities()
2402 * \brief Get and store device capabilities.
2403 * \param demod  Pointer to demodulator instance.
2404 * \return int.
2405 * \return 0    Success
2406 * \retval -EIO Failure
2407 *
2408 * Depending on pulldowns on MDx pins the following internals are set:
2409 *  * common_attr->osc_clock_freq
2410 *  * ext_attr->has_lna
2411 *  * ext_attr->has_ntsc
2412 *  * ext_attr->has_btsc
2413 *  * ext_attr->has_oob
2414 *
2415 */
2416 static int get_device_capabilities(struct drx_demod_instance *demod)
2417 {
2418         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2419         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
2420         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2421         u16 sio_pdr_ohw_cfg = 0;
2422         u32 sio_top_jtagid_lo = 0;
2423         u16 bid = 0;
2424         int rc;
2425
2426         common_attr = (struct drx_common_attr *) demod->my_common_attr;
2427         ext_attr = (struct drxj_data *) demod->my_ext_attr;
2428         dev_addr = demod->my_i2c_dev_addr;
2429
2430         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2431         if (rc != 0) {
2432                 pr_err("error %d\n", rc);
2433                 goto rw_error;
2434         }
2435         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
2436         if (rc != 0) {
2437                 pr_err("error %d\n", rc);
2438                 goto rw_error;
2439         }
2440         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2441         if (rc != 0) {
2442                 pr_err("error %d\n", rc);
2443                 goto rw_error;
2444         }
2445
2446         switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2447         case 0:
2448                 /* ignore (bypass ?) */
2449                 break;
2450         case 1:
2451                 /* 27 MHz */
2452                 common_attr->osc_clock_freq = 27000;
2453                 break;
2454         case 2:
2455                 /* 20.25 MHz */
2456                 common_attr->osc_clock_freq = 20250;
2457                 break;
2458         case 3:
2459                 /* 4 MHz */
2460                 common_attr->osc_clock_freq = 4000;
2461                 break;
2462         default:
2463                 return -EIO;
2464         }
2465
2466         /*
2467            Determine device capabilities
2468            Based on pinning v47
2469          */
2470         rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
2471         if (rc != 0) {
2472                 pr_err("error %d\n", rc);
2473                 goto rw_error;
2474         }
2475         ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
2476
2477         switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
2478         case 0x31:
2479                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2480                 if (rc != 0) {
2481                         pr_err("error %d\n", rc);
2482                         goto rw_error;
2483                 }
2484                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
2485                 if (rc != 0) {
2486                         pr_err("error %d\n", rc);
2487                         goto rw_error;
2488                 }
2489                 bid = (bid >> 10) & 0xf;
2490                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2491                 if (rc != 0) {
2492                         pr_err("error %d\n", rc);
2493                         goto rw_error;
2494                 }
2495
2496                 ext_attr->has_lna = true;
2497                 ext_attr->has_ntsc = false;
2498                 ext_attr->has_btsc = false;
2499                 ext_attr->has_oob = false;
2500                 ext_attr->has_smatx = true;
2501                 ext_attr->has_smarx = false;
2502                 ext_attr->has_gpio = false;
2503                 ext_attr->has_irqn = false;
2504                 break;
2505         case 0x33:
2506                 ext_attr->has_lna = false;
2507                 ext_attr->has_ntsc = false;
2508                 ext_attr->has_btsc = false;
2509                 ext_attr->has_oob = false;
2510                 ext_attr->has_smatx = true;
2511                 ext_attr->has_smarx = false;
2512                 ext_attr->has_gpio = false;
2513                 ext_attr->has_irqn = false;
2514                 break;
2515         case 0x45:
2516                 ext_attr->has_lna = true;
2517                 ext_attr->has_ntsc = true;
2518                 ext_attr->has_btsc = false;
2519                 ext_attr->has_oob = false;
2520                 ext_attr->has_smatx = true;
2521                 ext_attr->has_smarx = true;
2522                 ext_attr->has_gpio = true;
2523                 ext_attr->has_irqn = false;
2524                 break;
2525         case 0x46:
2526                 ext_attr->has_lna = false;
2527                 ext_attr->has_ntsc = true;
2528                 ext_attr->has_btsc = false;
2529                 ext_attr->has_oob = false;
2530                 ext_attr->has_smatx = true;
2531                 ext_attr->has_smarx = true;
2532                 ext_attr->has_gpio = true;
2533                 ext_attr->has_irqn = false;
2534                 break;
2535         case 0x41:
2536                 ext_attr->has_lna = true;
2537                 ext_attr->has_ntsc = true;
2538                 ext_attr->has_btsc = true;
2539                 ext_attr->has_oob = false;
2540                 ext_attr->has_smatx = true;
2541                 ext_attr->has_smarx = true;
2542                 ext_attr->has_gpio = true;
2543                 ext_attr->has_irqn = false;
2544                 break;
2545         case 0x43:
2546                 ext_attr->has_lna = false;
2547                 ext_attr->has_ntsc = true;
2548                 ext_attr->has_btsc = true;
2549                 ext_attr->has_oob = false;
2550                 ext_attr->has_smatx = true;
2551                 ext_attr->has_smarx = true;
2552                 ext_attr->has_gpio = true;
2553                 ext_attr->has_irqn = false;
2554                 break;
2555         case 0x32:
2556                 ext_attr->has_lna = true;
2557                 ext_attr->has_ntsc = false;
2558                 ext_attr->has_btsc = false;
2559                 ext_attr->has_oob = true;
2560                 ext_attr->has_smatx = true;
2561                 ext_attr->has_smarx = true;
2562                 ext_attr->has_gpio = true;
2563                 ext_attr->has_irqn = true;
2564                 break;
2565         case 0x34:
2566                 ext_attr->has_lna = false;
2567                 ext_attr->has_ntsc = true;
2568                 ext_attr->has_btsc = true;
2569                 ext_attr->has_oob = true;
2570                 ext_attr->has_smatx = true;
2571                 ext_attr->has_smarx = true;
2572                 ext_attr->has_gpio = true;
2573                 ext_attr->has_irqn = true;
2574                 break;
2575         case 0x42:
2576                 ext_attr->has_lna = true;
2577                 ext_attr->has_ntsc = true;
2578                 ext_attr->has_btsc = true;
2579                 ext_attr->has_oob = true;
2580                 ext_attr->has_smatx = true;
2581                 ext_attr->has_smarx = true;
2582                 ext_attr->has_gpio = true;
2583                 ext_attr->has_irqn = true;
2584                 break;
2585         case 0x44:
2586                 ext_attr->has_lna = false;
2587                 ext_attr->has_ntsc = true;
2588                 ext_attr->has_btsc = true;
2589                 ext_attr->has_oob = true;
2590                 ext_attr->has_smatx = true;
2591                 ext_attr->has_smarx = true;
2592                 ext_attr->has_gpio = true;
2593                 ext_attr->has_irqn = true;
2594                 break;
2595         default:
2596                 /* Unknown device variant */
2597                 return -EIO;
2598                 break;
2599         }
2600
2601         return 0;
2602 rw_error:
2603         return -EIO;
2604 }
2605
2606 /**
2607 * \fn int power_up_device()
2608 * \brief Power up device.
2609 * \param demod  Pointer to demodulator instance.
2610 * \return int.
2611 * \return 0    Success
2612 * \retval -EIO Failure, I2C or max retries reached
2613 *
2614 */
2615
2616 #ifndef DRXJ_MAX_RETRIES_POWERUP
2617 #define DRXJ_MAX_RETRIES_POWERUP 10
2618 #endif
2619
2620 static int power_up_device(struct drx_demod_instance *demod)
2621 {
2622         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2623         u8 data = 0;
2624         u16 retry_count = 0;
2625         struct i2c_device_addr wake_up_addr;
2626
2627         dev_addr = demod->my_i2c_dev_addr;
2628         wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2629         wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2630         wake_up_addr.user_data = dev_addr->user_data;
2631         /*
2632          * I2C access may fail in this case: no ack
2633          * dummy write must be used to wake uop device, dummy read must be used to
2634          * reset HI state machine (avoiding actual writes)
2635          */
2636         do {
2637                 data = 0;
2638                 drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
2639                                       (struct i2c_device_addr *)(NULL), 0,
2640                                      (u8 *)(NULL));
2641                 drxbsp_hst_sleep(10);
2642                 retry_count++;
2643         } while ((drxbsp_i2c_write_read
2644                   ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
2645                    &data)
2646                   != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
2647
2648         /* Need some recovery time .... */
2649         drxbsp_hst_sleep(10);
2650
2651         if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
2652                 return -EIO;
2653
2654         return 0;
2655 }
2656
2657 /*----------------------------------------------------------------------------*/
2658 /* MPEG Output Configuration Functions - begin                                */
2659 /*----------------------------------------------------------------------------*/
2660 /**
2661 * \fn int ctrl_set_cfg_mpeg_output()
2662 * \brief Set MPEG output configuration of the device.
2663 * \param devmod  Pointer to demodulator instance.
2664 * \param cfg_data Pointer to mpeg output configuaration.
2665 * \return int.
2666 *
2667 *  Configure MPEG output parameters.
2668 *
2669 */
2670 static int
2671 ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
2672 {
2673         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2674         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2675         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2676         int rc;
2677         u16 fec_oc_reg_mode = 0;
2678         u16 fec_oc_reg_ipr_mode = 0;
2679         u16 fec_oc_reg_ipr_invert = 0;
2680         u32 max_bit_rate = 0;
2681         u32 rcn_rate = 0;
2682         u32 nr_bits = 0;
2683         u16 sio_pdr_md_cfg = 0;
2684         /* data mask for the output data byte */
2685         u16 invert_data_mask =
2686             FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2687             FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2688             FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2689             FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2690
2691         /* check arguments */
2692         if ((demod == NULL) || (cfg_data == NULL))
2693                 return -EINVAL;
2694
2695         dev_addr = demod->my_i2c_dev_addr;
2696         ext_attr = (struct drxj_data *) demod->my_ext_attr;
2697         common_attr = (struct drx_common_attr *) demod->my_common_attr;
2698
2699         if (cfg_data->enable_mpeg_output == true) {
2700                 /* quick and dirty patch to set MPEG incase current std is not
2701                    producing MPEG */
2702                 switch (ext_attr->standard) {
2703                 case DRX_STANDARD_8VSB:
2704                 case DRX_STANDARD_ITU_A:
2705                 case DRX_STANDARD_ITU_B:
2706                 case DRX_STANDARD_ITU_C:
2707                         break;
2708                 default:
2709                         /* not an MPEG producing std, just store MPEG cfg */
2710                         common_attr->mpeg_cfg.enable_mpeg_output =
2711                             cfg_data->enable_mpeg_output;
2712                         common_attr->mpeg_cfg.insert_rs_byte =
2713                             cfg_data->insert_rs_byte;
2714                         common_attr->mpeg_cfg.enable_parallel =
2715                             cfg_data->enable_parallel;
2716                         common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
2717                         common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
2718                         common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
2719                         common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
2720                         common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
2721                         common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
2722                         common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
2723                         return 0;
2724                 }
2725
2726                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
2727                 if (rc != 0) {
2728                         pr_err("error %d\n", rc);
2729                         goto rw_error;
2730                 }
2731                 switch (ext_attr->standard) {
2732                 case DRX_STANDARD_8VSB:
2733                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
2734                         if (rc != 0) {
2735                                 pr_err("error %d\n", rc);
2736                                 goto rw_error;
2737                         }       /* 2048 bytes fifo ram */
2738                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
2739                         if (rc != 0) {
2740                                 pr_err("error %d\n", rc);
2741                                 goto rw_error;
2742                         }
2743                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
2744                         if (rc != 0) {
2745                                 pr_err("error %d\n", rc);
2746                                 goto rw_error;
2747                         }
2748                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
2749                         if (rc != 0) {
2750                                 pr_err("error %d\n", rc);
2751                                 goto rw_error;
2752                         }
2753                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
2754                         if (rc != 0) {
2755                                 pr_err("error %d\n", rc);
2756                                 goto rw_error;
2757                         }
2758                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
2759                         if (rc != 0) {
2760                                 pr_err("error %d\n", rc);
2761                                 goto rw_error;
2762                         }
2763                         /* Low Water Mark for synchronization  */
2764                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
2765                         if (rc != 0) {
2766                                 pr_err("error %d\n", rc);
2767                                 goto rw_error;
2768                         }
2769                         /* High Water Mark for synchronization */
2770                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
2771                         if (rc != 0) {
2772                                 pr_err("error %d\n", rc);
2773                                 goto rw_error;
2774                         }
2775                         break;
2776                 case DRX_STANDARD_ITU_A:
2777                 case DRX_STANDARD_ITU_C:
2778                         switch (ext_attr->constellation) {
2779                         case DRX_CONSTELLATION_QAM256:
2780                                 nr_bits = 8;
2781                                 break;
2782                         case DRX_CONSTELLATION_QAM128:
2783                                 nr_bits = 7;
2784                                 break;
2785                         case DRX_CONSTELLATION_QAM64:
2786                                 nr_bits = 6;
2787                                 break;
2788                         case DRX_CONSTELLATION_QAM32:
2789                                 nr_bits = 5;
2790                                 break;
2791                         case DRX_CONSTELLATION_QAM16:
2792                                 nr_bits = 4;
2793                                 break;
2794                         default:
2795                                 return -EIO;
2796                         }       /* ext_attr->constellation */
2797                         /* max_bit_rate = symbol_rate * nr_bits * coef */
2798                         /* coef = 188/204                          */
2799                         max_bit_rate =
2800                             (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
2801                         /* pass through b/c Annex A/c need following settings */
2802                 case DRX_STANDARD_ITU_B:
2803                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
2804                         if (rc != 0) {
2805                                 pr_err("error %d\n", rc);
2806                                 goto rw_error;
2807                         }
2808                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
2809                         if (rc != 0) {
2810                                 pr_err("error %d\n", rc);
2811                                 goto rw_error;
2812                         }
2813                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
2814                         if (rc != 0) {
2815                                 pr_err("error %d\n", rc);
2816                                 goto rw_error;
2817                         }
2818                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
2819                         if (rc != 0) {
2820                                 pr_err("error %d\n", rc);
2821                                 goto rw_error;
2822                         }
2823                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
2824                         if (rc != 0) {
2825                                 pr_err("error %d\n", rc);
2826                                 goto rw_error;
2827                         }
2828                         if (cfg_data->static_clk == true) {
2829                                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
2830                                 if (rc != 0) {
2831                                         pr_err("error %d\n", rc);
2832                                         goto rw_error;
2833                                 }
2834                         } else {
2835                                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
2836                                 if (rc != 0) {
2837                                         pr_err("error %d\n", rc);
2838                                         goto rw_error;
2839                                 }
2840                         }
2841                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
2842                         if (rc != 0) {
2843                                 pr_err("error %d\n", rc);
2844                                 goto rw_error;
2845                         }
2846                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
2847                         if (rc != 0) {
2848                                 pr_err("error %d\n", rc);
2849                                 goto rw_error;
2850                         }
2851                         break;
2852                 default:
2853                         break;
2854                 }               /* swtich (standard) */
2855
2856                 /* Check insertion of the Reed-Solomon parity bytes */
2857                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
2858                 if (rc != 0) {
2859                         pr_err("error %d\n", rc);
2860                         goto rw_error;
2861                 }
2862                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
2863                 if (rc != 0) {
2864                         pr_err("error %d\n", rc);
2865                         goto rw_error;
2866                 }
2867                 if (cfg_data->insert_rs_byte == true) {
2868                         /* enable parity symbol forward */
2869                         fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
2870                         /* MVAL disable during parity bytes */
2871                         fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2872                         switch (ext_attr->standard) {
2873                         case DRX_STANDARD_8VSB:
2874                                 rcn_rate = 0x004854D3;
2875                                 break;
2876                         case DRX_STANDARD_ITU_B:
2877                                 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2878                                 switch (ext_attr->constellation) {
2879                                 case DRX_CONSTELLATION_QAM256:
2880                                         rcn_rate = 0x008945E7;
2881                                         break;
2882                                 case DRX_CONSTELLATION_QAM64:
2883                                         rcn_rate = 0x005F64D4;
2884                                         break;
2885                                 default:
2886                                         return -EIO;
2887                                 }
2888                                 break;
2889                         case DRX_STANDARD_ITU_A:
2890                         case DRX_STANDARD_ITU_C:
2891                                 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2892                                 rcn_rate =
2893                                     (frac28
2894                                      (max_bit_rate,
2895                                       (u32) (common_attr->sys_clock_freq / 8))) /
2896                                     188;
2897                                 break;
2898                         default:
2899                                 return -EIO;
2900                         }       /* ext_attr->standard */
2901                 } else {        /* insert_rs_byte == false */
2902
2903                         /* disable parity symbol forward */
2904                         fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2905                         /* MVAL enable during parity bytes */
2906                         fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2907                         switch (ext_attr->standard) {
2908                         case DRX_STANDARD_8VSB:
2909                                 rcn_rate = 0x0041605C;
2910                                 break;
2911                         case DRX_STANDARD_ITU_B:
2912                                 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2913                                 switch (ext_attr->constellation) {
2914                                 case DRX_CONSTELLATION_QAM256:
2915                                         rcn_rate = 0x0082D6A0;
2916                                         break;
2917                                 case DRX_CONSTELLATION_QAM64:
2918                                         rcn_rate = 0x005AEC1A;
2919                                         break;
2920                                 default:
2921                                         return -EIO;
2922                                 }
2923                                 break;
2924                         case DRX_STANDARD_ITU_A:
2925                         case DRX_STANDARD_ITU_C:
2926                                 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2927                                 rcn_rate =
2928                                     (frac28
2929                                      (max_bit_rate,
2930                                       (u32) (common_attr->sys_clock_freq / 8))) /
2931                                     204;
2932                                 break;
2933                         default:
2934                                 return -EIO;
2935                         }       /* ext_attr->standard */
2936                 }
2937
2938                 if (cfg_data->enable_parallel == true) {        /* MPEG data output is paralel -> clear ipr_mode[0] */
2939                         fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2940                 } else {        /* MPEG data output is serial -> set ipr_mode[0] */
2941                         fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
2942                 }
2943
2944                 /* Control slective inversion of output bits */
2945                 if (cfg_data->invert_data == true)
2946                         fec_oc_reg_ipr_invert |= invert_data_mask;
2947                 else
2948                         fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2949
2950                 if (cfg_data->invert_err == true)
2951                         fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2952                 else
2953                         fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2954
2955                 if (cfg_data->invert_str == true)
2956                         fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
2957                 else
2958                         fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2959
2960                 if (cfg_data->invert_val == true)
2961                         fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
2962                 else
2963                         fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2964
2965                 if (cfg_data->invert_clk == true)
2966                         fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
2967                 else
2968                         fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2969
2970                 if (cfg_data->static_clk == true) {     /* Static mode */
2971                         u32 dto_rate = 0;
2972                         u32 bit_rate = 0;
2973                         u16 fec_oc_dto_burst_len = 0;
2974                         u16 fec_oc_dto_period = 0;
2975
2976                         fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
2977
2978                         switch (ext_attr->standard) {
2979                         case DRX_STANDARD_8VSB:
2980                                 fec_oc_dto_period = 4;
2981                                 if (cfg_data->insert_rs_byte == true)
2982                                         fec_oc_dto_burst_len = 208;
2983                                 break;
2984                         case DRX_STANDARD_ITU_A:
2985                                 {
2986                                         u32 symbol_rate_th = 6400000;
2987                                         if (cfg_data->insert_rs_byte == true) {
2988                                                 fec_oc_dto_burst_len = 204;
2989                                                 symbol_rate_th = 5900000;
2990                                         }
2991                                         if (ext_attr->curr_symbol_rate >=
2992                                             symbol_rate_th) {
2993                                                 fec_oc_dto_period = 0;
2994                                         } else {
2995                                                 fec_oc_dto_period = 1;
2996                                         }
2997                                 }
2998                                 break;
2999                         case DRX_STANDARD_ITU_B:
3000                                 fec_oc_dto_period = 1;
3001                                 if (cfg_data->insert_rs_byte == true)
3002                                         fec_oc_dto_burst_len = 128;
3003                                 break;
3004                         case DRX_STANDARD_ITU_C:
3005                                 fec_oc_dto_period = 1;
3006                                 if (cfg_data->insert_rs_byte == true)
3007                                         fec_oc_dto_burst_len = 204;
3008                                 break;
3009                         default:
3010                                 return -EIO;
3011                         }
3012                         bit_rate =
3013                             common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
3014                                                                2);
3015                         dto_rate =
3016                             frac28(bit_rate, common_attr->sys_clock_freq * 1000);
3017                         dto_rate >>= 3;
3018                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
3019                         if (rc != 0) {
3020                                 pr_err("error %d\n", rc);
3021                                 goto rw_error;
3022                         }
3023                         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);
3024                         if (rc != 0) {
3025                                 pr_err("error %d\n", rc);
3026                                 goto rw_error;
3027                         }
3028                         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);
3029                         if (rc != 0) {
3030                                 pr_err("error %d\n", rc);
3031                                 goto rw_error;
3032                         }
3033                         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);
3034                         if (rc != 0) {
3035                                 pr_err("error %d\n", rc);
3036                                 goto rw_error;
3037                         }
3038                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
3039                         if (rc != 0) {
3040                                 pr_err("error %d\n", rc);
3041                                 goto rw_error;
3042                         }
3043                         if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3044                                 fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
3045                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
3046                         if (rc != 0) {
3047                                 pr_err("error %d\n", rc);
3048                                 goto rw_error;
3049                         }
3050                 } else {        /* Dynamic mode */
3051
3052                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
3053                         if (rc != 0) {
3054                                 pr_err("error %d\n", rc);
3055                                 goto rw_error;
3056                         }
3057                         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
3058                         if (rc != 0) {
3059                                 pr_err("error %d\n", rc);
3060                                 goto rw_error;
3061                         }
3062                 }
3063
3064                 rc = DRXJ_DAP.write_reg32func(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
3065                 if (rc != 0) {
3066                         pr_err("error %d\n", rc);
3067                         goto rw_error;
3068                 }
3069
3070                 /* Write appropriate registers with requested configuration */
3071                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
3072                 if (rc != 0) {
3073                         pr_err("error %d\n", rc);
3074                         goto rw_error;
3075                 }
3076                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
3077                 if (rc != 0) {
3078                         pr_err("error %d\n", rc);
3079                         goto rw_error;
3080                 }
3081                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
3082                 if (rc != 0) {
3083                         pr_err("error %d\n", rc);
3084                         goto rw_error;
3085                 }
3086
3087                 /* enabling for both parallel and serial now */
3088                 /*  Write magic word to enable pdr reg write */
3089                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3090                 if (rc != 0) {
3091                         pr_err("error %d\n", rc);
3092                         goto rw_error;
3093                 }
3094                 /*  Set MPEG TS pads to outputmode */
3095                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
3096                 if (rc != 0) {
3097                         pr_err("error %d\n", rc);
3098                         goto rw_error;
3099                 }
3100                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
3101                 if (rc != 0) {
3102                         pr_err("error %d\n", rc);
3103                         goto rw_error;
3104                 }
3105                 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);
3106                 if (rc != 0) {
3107                         pr_err("error %d\n", rc);
3108                         goto rw_error;
3109                 }
3110                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
3111                 if (rc != 0) {
3112                         pr_err("error %d\n", rc);
3113                         goto rw_error;
3114                 }
3115                 sio_pdr_md_cfg =
3116                     MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3117                     SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
3118                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3119                 if (rc != 0) {
3120                         pr_err("error %d\n", rc);
3121                         goto rw_error;
3122                 }
3123                 if (cfg_data->enable_parallel == true) {        /* MPEG data output is paralel -> set MD1 to MD7 to output mode */
3124                         sio_pdr_md_cfg =
3125                             MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3126                             SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3127                             SIO_PDR_MD0_CFG_MODE__B;
3128                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3129                         if (rc != 0) {
3130                                 pr_err("error %d\n", rc);
3131                                 goto rw_error;
3132                         }
3133                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
3134                         if (rc != 0) {
3135                                 pr_err("error %d\n", rc);
3136                                 goto rw_error;
3137                         }
3138                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
3139                         if (rc != 0) {
3140                                 pr_err("error %d\n", rc);
3141                                 goto rw_error;
3142                         }
3143                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
3144                         if (rc != 0) {
3145                                 pr_err("error %d\n", rc);
3146                                 goto rw_error;
3147                         }
3148                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
3149                         if (rc != 0) {
3150                                 pr_err("error %d\n", rc);
3151                                 goto rw_error;
3152                         }
3153                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
3154                         if (rc != 0) {
3155                                 pr_err("error %d\n", rc);
3156                                 goto rw_error;
3157                         }
3158                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
3159                         if (rc != 0) {
3160                                 pr_err("error %d\n", rc);
3161                                 goto rw_error;
3162                         }
3163                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
3164                         if (rc != 0) {
3165                                 pr_err("error %d\n", rc);
3166                                 goto rw_error;
3167                         }
3168                 } else {        /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3169                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3170                         if (rc != 0) {
3171                                 pr_err("error %d\n", rc);
3172                                 goto rw_error;
3173                         }
3174                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3175                         if (rc != 0) {
3176                                 pr_err("error %d\n", rc);
3177                                 goto rw_error;
3178                         }
3179                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3180                         if (rc != 0) {
3181                                 pr_err("error %d\n", rc);
3182                                 goto rw_error;
3183                         }
3184                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3185                         if (rc != 0) {
3186                                 pr_err("error %d\n", rc);
3187                                 goto rw_error;
3188                         }
3189                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3190                         if (rc != 0) {
3191                                 pr_err("error %d\n", rc);
3192                                 goto rw_error;
3193                         }
3194                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3195                         if (rc != 0) {
3196                                 pr_err("error %d\n", rc);
3197                                 goto rw_error;
3198                         }
3199                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3200                         if (rc != 0) {
3201                                 pr_err("error %d\n", rc);
3202                                 goto rw_error;
3203                         }
3204                 }
3205                 /*  Enable Monitor Bus output over MPEG pads and ctl input */
3206                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3207                 if (rc != 0) {
3208                         pr_err("error %d\n", rc);
3209                         goto rw_error;
3210                 }
3211                 /*  Write nomagic word to enable pdr reg write */
3212                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3213                 if (rc != 0) {
3214                         pr_err("error %d\n", rc);
3215                         goto rw_error;
3216                 }
3217         } else {
3218                 /*  Write magic word to enable pdr reg write */
3219                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3220                 if (rc != 0) {
3221                         pr_err("error %d\n", rc);
3222                         goto rw_error;
3223                 }
3224                 /*  Set MPEG TS pads to inputmode */
3225                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_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_MERR_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_MCLK_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_MVAL_CFG__A, 0x0000, 0);
3241                 if (rc != 0) {
3242                         pr_err("error %d\n", rc);
3243                         goto rw_error;
3244                 }
3245                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
3246                 if (rc != 0) {
3247                         pr_err("error %d\n", rc);
3248                         goto rw_error;
3249                 }
3250                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3251                 if (rc != 0) {
3252                         pr_err("error %d\n", rc);
3253                         goto rw_error;
3254                 }
3255                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3256                 if (rc != 0) {
3257                         pr_err("error %d\n", rc);
3258                         goto rw_error;
3259                 }
3260                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3261                 if (rc != 0) {
3262                         pr_err("error %d\n", rc);
3263                         goto rw_error;
3264                 }
3265                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3266                 if (rc != 0) {
3267                         pr_err("error %d\n", rc);
3268                         goto rw_error;
3269                 }
3270                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3271                 if (rc != 0) {
3272                         pr_err("error %d\n", rc);
3273                         goto rw_error;
3274                 }
3275                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3276                 if (rc != 0) {
3277                         pr_err("error %d\n", rc);
3278                         goto rw_error;
3279                 }
3280                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3281                 if (rc != 0) {
3282                         pr_err("error %d\n", rc);
3283                         goto rw_error;
3284                 }
3285                 /* Enable Monitor Bus output over MPEG pads and ctl input */
3286                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3287                 if (rc != 0) {
3288                         pr_err("error %d\n", rc);
3289                         goto rw_error;
3290                 }
3291                 /* Write nomagic word to enable pdr reg write */
3292                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3293                 if (rc != 0) {
3294                         pr_err("error %d\n", rc);
3295                         goto rw_error;
3296                 }
3297         }
3298
3299         /* save values for restore after re-acquire */
3300         common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3301         common_attr->mpeg_cfg.insert_rs_byte = cfg_data->insert_rs_byte;
3302         common_attr->mpeg_cfg.enable_parallel = cfg_data->enable_parallel;
3303         common_attr->mpeg_cfg.invert_data = cfg_data->invert_data;
3304         common_attr->mpeg_cfg.invert_err = cfg_data->invert_err;
3305         common_attr->mpeg_cfg.invert_str = cfg_data->invert_str;
3306         common_attr->mpeg_cfg.invert_val = cfg_data->invert_val;
3307         common_attr->mpeg_cfg.invert_clk = cfg_data->invert_clk;
3308         common_attr->mpeg_cfg.static_clk = cfg_data->static_clk;
3309         common_attr->mpeg_cfg.bitrate = cfg_data->bitrate;
3310
3311         return 0;
3312 rw_error:
3313         return -EIO;
3314 }
3315
3316 /*----------------------------------------------------------------------------*/
3317
3318 /**
3319 * \fn int ctrl_get_cfg_mpeg_output()
3320 * \brief Get MPEG output configuration of the device.
3321 * \param devmod  Pointer to demodulator instance.
3322 * \param cfg_data Pointer to MPEG output configuaration struct.
3323 * \return int.
3324 *
3325 *  Retrieve MPEG output configuartion.
3326 *
3327 */
3328 static int
3329 ctrl_get_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
3330 {
3331         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3332         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
3333         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
3334         int rc;
3335         u32 rate_reg = 0;
3336         u32 data64hi = 0;
3337         u32 data64lo = 0;
3338
3339         if (cfg_data == NULL)
3340                 return -EINVAL;
3341
3342         dev_addr = demod->my_i2c_dev_addr;
3343         common_attr = demod->my_common_attr;
3344
3345         cfg_data->enable_mpeg_output = common_attr->mpeg_cfg.enable_mpeg_output;
3346         cfg_data->insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
3347         cfg_data->enable_parallel = common_attr->mpeg_cfg.enable_parallel;
3348         cfg_data->invert_data = common_attr->mpeg_cfg.invert_data;
3349         cfg_data->invert_err = common_attr->mpeg_cfg.invert_err;
3350         cfg_data->invert_str = common_attr->mpeg_cfg.invert_str;
3351         cfg_data->invert_val = common_attr->mpeg_cfg.invert_val;
3352         cfg_data->invert_clk = common_attr->mpeg_cfg.invert_clk;
3353         cfg_data->static_clk = common_attr->mpeg_cfg.static_clk;
3354         cfg_data->bitrate = 0;
3355
3356         rc = ctrl_lock_status(demod, &lock_status);
3357         if (rc != 0) {
3358                 pr_err("error %d\n", rc);
3359                 goto rw_error;
3360         }
3361         if ((lock_status == DRX_LOCKED)) {
3362                 rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_RCN_DYN_RATE_LO__A, &rate_reg, 0);
3363                 if (rc != 0) {
3364                         pr_err("error %d\n", rc);
3365                         goto rw_error;
3366                 }
3367                 /* Frcn_rate = rate_reg * Fsys / 2 ^ 25 */
3368                 mult32(rate_reg, common_attr->sys_clock_freq * 1000, &data64hi,
3369                        &data64lo);
3370                 cfg_data->bitrate = (data64hi << 7) | (data64lo >> 25);
3371         }
3372
3373         return 0;
3374 rw_error:
3375         return -EIO;
3376 }
3377
3378 /*----------------------------------------------------------------------------*/
3379 /* MPEG Output Configuration Functions - end                                  */
3380 /*----------------------------------------------------------------------------*/
3381
3382 /*----------------------------------------------------------------------------*/
3383 /* miscellaneous configuartions - begin                           */
3384 /*----------------------------------------------------------------------------*/
3385
3386 /**
3387 * \fn int set_mpegtei_handling()
3388 * \brief Activate MPEG TEI handling settings.
3389 * \param devmod  Pointer to demodulator instance.
3390 * \return int.
3391 *
3392 * This routine should be called during a set channel of QAM/VSB
3393 *
3394 */
3395 static int set_mpegtei_handling(struct drx_demod_instance *demod)
3396 {
3397         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3398         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3399         int rc;
3400         u16 fec_oc_dpr_mode = 0;
3401         u16 fec_oc_snc_mode = 0;
3402         u16 fec_oc_ems_mode = 0;
3403
3404         dev_addr = demod->my_i2c_dev_addr;
3405         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3406
3407         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
3408         if (rc != 0) {
3409                 pr_err("error %d\n", rc);
3410                 goto rw_error;
3411         }
3412         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
3413         if (rc != 0) {
3414                 pr_err("error %d\n", rc);
3415                 goto rw_error;
3416         }
3417         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
3418         if (rc != 0) {
3419                 pr_err("error %d\n", rc);
3420                 goto rw_error;
3421         }
3422
3423         /* reset to default, allow TEI bit to be changed */
3424         fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3425         fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3426                            FEC_OC_SNC_MODE_CORR_DISABLE__M));
3427         fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
3428
3429         if (ext_attr->disable_te_ihandling) {
3430                 /* do not change TEI bit */
3431                 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3432                 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3433                     ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3434                 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3435         }
3436
3437         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
3438         if (rc != 0) {
3439                 pr_err("error %d\n", rc);
3440                 goto rw_error;
3441         }
3442         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
3443         if (rc != 0) {
3444                 pr_err("error %d\n", rc);
3445                 goto rw_error;
3446         }
3447         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
3448         if (rc != 0) {
3449                 pr_err("error %d\n", rc);
3450                 goto rw_error;
3451         }
3452
3453         return 0;
3454 rw_error:
3455         return -EIO;
3456 }
3457
3458 /*----------------------------------------------------------------------------*/
3459 /**
3460 * \fn int bit_reverse_mpeg_output()
3461 * \brief Set MPEG output bit-endian settings.
3462 * \param devmod  Pointer to demodulator instance.
3463 * \return int.
3464 *
3465 * This routine should be called during a set channel of QAM/VSB
3466 *
3467 */
3468 static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
3469 {
3470         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3471         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3472         int rc;
3473         u16 fec_oc_ipr_mode = 0;
3474
3475         dev_addr = demod->my_i2c_dev_addr;
3476         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3477
3478         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
3479         if (rc != 0) {
3480                 pr_err("error %d\n", rc);
3481                 goto rw_error;
3482         }
3483
3484         /* reset to default (normal bit order) */
3485         fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3486
3487         if (ext_attr->bit_reverse_mpeg_outout)
3488                 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3489
3490         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
3491         if (rc != 0) {
3492                 pr_err("error %d\n", rc);
3493                 goto rw_error;
3494         }
3495
3496         return 0;
3497 rw_error:
3498         return -EIO;
3499 }
3500
3501 /*----------------------------------------------------------------------------*/
3502 /**
3503 * \fn int set_mpeg_output_clock_rate()
3504 * \brief Set MPEG output clock rate.
3505 * \param devmod  Pointer to demodulator instance.
3506 * \return int.
3507 *
3508 * This routine should be called during a set channel of QAM/VSB
3509 *
3510 */
3511 static int set_mpeg_output_clock_rate(struct drx_demod_instance *demod)
3512 {
3513         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3514         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3515         int rc;
3516
3517         dev_addr = demod->my_i2c_dev_addr;
3518         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3519
3520         if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3521                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_DTO_PERIOD__A, ext_attr->mpeg_output_clock_rate - 1, 0);
3522                 if (rc != 0) {
3523                         pr_err("error %d\n", rc);
3524                         goto rw_error;
3525                 }
3526         }
3527
3528         return 0;
3529 rw_error:
3530         return -EIO;
3531 }
3532
3533 /*----------------------------------------------------------------------------*/
3534 /**
3535 * \fn int set_mpeg_start_width()
3536 * \brief Set MPEG start width.
3537 * \param devmod  Pointer to demodulator instance.
3538 * \return int.
3539 *
3540 * This routine should be called during a set channel of QAM/VSB
3541 *
3542 */
3543 static int set_mpeg_start_width(struct drx_demod_instance *demod)
3544 {
3545         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3546         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3547         struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
3548         int rc;
3549         u16 fec_oc_comm_mb = 0;
3550
3551         dev_addr = demod->my_i2c_dev_addr;
3552         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3553         common_attr = demod->my_common_attr;
3554
3555         if ((common_attr->mpeg_cfg.static_clk == true)
3556             && (common_attr->mpeg_cfg.enable_parallel == false)) {
3557                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
3558                 if (rc != 0) {
3559                         pr_err("error %d\n", rc);
3560                         goto rw_error;
3561                 }
3562                 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3563                 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
3564                         fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
3565                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
3566                 if (rc != 0) {
3567                         pr_err("error %d\n", rc);
3568                         goto rw_error;
3569                 }
3570         }
3571
3572         return 0;
3573 rw_error:
3574         return -EIO;
3575 }
3576
3577 /*----------------------------------------------------------------------------*/
3578 /**
3579 * \fn int ctrl_set_cfg_mpeg_output_misc()
3580 * \brief Set miscellaneous configuartions
3581 * \param devmod  Pointer to demodulator instance.
3582 * \param cfg_data pDRXJCfgMisc_t
3583 * \return int.
3584 *
3585 *  This routine can be used to set configuartion options that are DRXJ
3586 *  specific and/or added to the requirements at a late stage.
3587 *
3588 */
3589 static int
3590 ctrl_set_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3591                               struct drxj_cfg_mpeg_output_misc *cfg_data)
3592 {
3593         struct drxj_data *ext_attr = NULL;
3594         int rc;
3595
3596         if (cfg_data == NULL)
3597                 return -EINVAL;
3598
3599         ext_attr = demod->my_ext_attr;
3600
3601         /*
3602            Set disable TEI bit handling flag.
3603            TEI must be left untouched by device in case of BER measurements using
3604            external equipment that is unable to ignore the TEI bit in the TS.
3605            Default will false (enable TEI bit handling).
3606            Reverse output bit order. Default is false (msb on MD7 (parallel) or out first (serial)).
3607            Set clock rate. Default is auto that is derived from symbol rate.
3608            The flags and values will also be used to set registers during a set channel.
3609          */
3610         ext_attr->disable_te_ihandling = cfg_data->disable_tei_handling;
3611         ext_attr->bit_reverse_mpeg_outout = cfg_data->bit_reverse_mpeg_outout;
3612         ext_attr->mpeg_output_clock_rate = cfg_data->mpeg_output_clock_rate;
3613         ext_attr->mpeg_start_width = cfg_data->mpeg_start_width;
3614         /* Don't care what the active standard is, activate setting immediatly */
3615         rc = set_mpegtei_handling(demod);
3616         if (rc != 0) {
3617                 pr_err("error %d\n", rc);
3618                 goto rw_error;
3619         }
3620         rc = bit_reverse_mpeg_output(demod);
3621         if (rc != 0) {
3622                 pr_err("error %d\n", rc);
3623                 goto rw_error;
3624         }
3625         rc = set_mpeg_output_clock_rate(demod);
3626         if (rc != 0) {
3627                 pr_err("error %d\n", rc);
3628                 goto rw_error;
3629         }
3630         rc = set_mpeg_start_width(demod);
3631         if (rc != 0) {
3632                 pr_err("error %d\n", rc);
3633                 goto rw_error;
3634         }
3635
3636         return 0;
3637 rw_error:
3638         return -EIO;
3639 }
3640
3641 /*----------------------------------------------------------------------------*/
3642
3643 /**
3644 * \fn int ctrl_get_cfg_mpeg_output_misc()
3645 * \brief Get miscellaneous configuartions.
3646 * \param devmod  Pointer to demodulator instance.
3647 * \param cfg_data Pointer to DRXJCfgMisc_t.
3648 * \return int.
3649 *
3650 *  This routine can be used to retreive the current setting of the configuartion
3651 *  options that are DRXJ specific and/or added to the requirements at a
3652 *  late stage.
3653 *
3654 */
3655 static int
3656 ctrl_get_cfg_mpeg_output_misc(struct drx_demod_instance *demod,
3657                               struct drxj_cfg_mpeg_output_misc *cfg_data)
3658 {
3659         struct drxj_data *ext_attr = NULL;
3660         int rc;
3661         u16 data = 0;
3662
3663         if (cfg_data == NULL)
3664                 return -EINVAL;
3665
3666         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3667         cfg_data->disable_tei_handling = ext_attr->disable_te_ihandling;
3668         cfg_data->bit_reverse_mpeg_outout = ext_attr->bit_reverse_mpeg_outout;
3669         cfg_data->mpeg_start_width = ext_attr->mpeg_start_width;
3670         if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO) {
3671                 cfg_data->mpeg_output_clock_rate = ext_attr->mpeg_output_clock_rate;
3672         } else {
3673                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, FEC_OC_DTO_PERIOD__A, &data, 0);
3674                 if (rc != 0) {
3675                         pr_err("error %d\n", rc);
3676                         goto rw_error;
3677                 }
3678                 cfg_data->mpeg_output_clock_rate =
3679                     (enum drxj_mpeg_output_clock_rate) (data + 1);
3680         }
3681
3682         return 0;
3683 rw_error:
3684         return -EIO;
3685 }
3686
3687 /*----------------------------------------------------------------------------*/
3688
3689 /**
3690 * \fn int ctrl_get_cfg_hw_cfg()
3691 * \brief Get HW configuartions.
3692 * \param devmod  Pointer to demodulator instance.
3693 * \param cfg_data Pointer to Bool.
3694 * \return int.
3695 *
3696 *  This routine can be used to retreive the current setting of the configuartion
3697 *  options that are DRXJ specific and/or added to the requirements at a
3698 *  late stage.
3699 *
3700 */
3701 static int
3702 ctrl_get_cfg_hw_cfg(struct drx_demod_instance *demod, struct drxj_cfg_hw_cfg *cfg_data)
3703 {
3704         int rc;
3705         u16 data = 0;
3706
3707         if (cfg_data == NULL)
3708                 return -EINVAL;
3709
3710         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3711         if (rc != 0) {
3712                 pr_err("error %d\n", rc);
3713                 goto rw_error;
3714         }
3715         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_OHW_CFG__A, &data, 0);
3716         if (rc != 0) {
3717                 pr_err("error %d\n", rc);
3718                 goto rw_error;
3719         }
3720         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3721         if (rc != 0) {
3722                 pr_err("error %d\n", rc);
3723                 goto rw_error;
3724         }
3725
3726         cfg_data->i2c_speed = (enum drxji2c_speed) ((data >> 6) & 0x1);
3727         cfg_data->xtal_freq = (enum drxj_xtal_freq) (data & 0x3);
3728
3729         return 0;
3730 rw_error:
3731         return -EIO;
3732 }
3733
3734 /*----------------------------------------------------------------------------*/
3735 /* miscellaneous configuartions - end                             */
3736 /*----------------------------------------------------------------------------*/
3737
3738 /*----------------------------------------------------------------------------*/
3739 /* UIO Configuration Functions - begin                                        */
3740 /*----------------------------------------------------------------------------*/
3741 /**
3742 * \fn int ctrl_set_uio_cfg()
3743 * \brief Configure modus oprandi UIO.
3744 * \param demod Pointer to demodulator instance.
3745 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3746 * \return int.
3747 */
3748 static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3749 {
3750         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3751         int rc;
3752
3753         if ((uio_cfg == NULL) || (demod == NULL))
3754                 return -EINVAL;
3755
3756         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3757
3758         /*  Write magic word to enable pdr reg write               */
3759         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3760         if (rc != 0) {
3761                 pr_err("error %d\n", rc);
3762                 goto rw_error;
3763         }
3764         switch (uio_cfg->uio) {
3765       /*====================================================================*/
3766         case DRX_UIO1:
3767                 /* DRX_UIO1: SMA_TX UIO-1 */
3768                 if (!ext_attr->has_smatx)
3769                         return -EIO;
3770                 switch (uio_cfg->mode) {
3771                 case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
3772                 case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
3773                 case DRX_UIO_MODE_READWRITE:
3774                         ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3775                         break;
3776                 case DRX_UIO_MODE_DISABLE:
3777                         ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3778                         /* pad configuration register is set 0 - input mode */
3779                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
3780                         if (rc != 0) {
3781                                 pr_err("error %d\n", rc);
3782                                 goto rw_error;
3783                         }
3784                         break;
3785                 default:
3786                         return -EINVAL;
3787                 }               /* switch ( uio_cfg->mode ) */
3788                 break;
3789       /*====================================================================*/
3790         case DRX_UIO2:
3791                 /* DRX_UIO2: SMA_RX UIO-2 */
3792                 if (!ext_attr->has_smarx)
3793                         return -EIO;
3794                 switch (uio_cfg->mode) {
3795                 case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
3796                 case DRX_UIO_MODE_READWRITE:
3797                         ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3798                         break;
3799                 case DRX_UIO_MODE_DISABLE:
3800                         ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3801                         /* pad configuration register is set 0 - input mode */
3802                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
3803                         if (rc != 0) {
3804                                 pr_err("error %d\n", rc);
3805                                 goto rw_error;
3806                         }
3807                         break;
3808                 default:
3809                         return -EINVAL;
3810                         break;
3811                 }               /* switch ( uio_cfg->mode ) */
3812                 break;
3813       /*====================================================================*/
3814         case DRX_UIO3:
3815                 /* DRX_UIO3: GPIO UIO-3 */
3816                 if (!ext_attr->has_gpio)
3817                         return -EIO;
3818                 switch (uio_cfg->mode) {
3819                 case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
3820                 case DRX_UIO_MODE_READWRITE:
3821                         ext_attr->uio_gpio_mode = uio_cfg->mode;
3822                         break;
3823                 case DRX_UIO_MODE_DISABLE:
3824                         ext_attr->uio_gpio_mode = uio_cfg->mode;
3825                         /* pad configuration register is set 0 - input mode */
3826                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
3827                         if (rc != 0) {
3828                                 pr_err("error %d\n", rc);
3829                                 goto rw_error;
3830                         }
3831                         break;
3832                 default:
3833                         return -EINVAL;
3834                         break;
3835                 }               /* switch ( uio_cfg->mode ) */
3836                 break;
3837       /*====================================================================*/
3838         case DRX_UIO4:
3839                 /* DRX_UIO4: IRQN UIO-4 */
3840                 if (!ext_attr->has_irqn)
3841                         return -EIO;
3842                 switch (uio_cfg->mode) {
3843                 case DRX_UIO_MODE_READWRITE:
3844                         ext_attr->uio_irqn_mode = uio_cfg->mode;
3845                         break;
3846                 case DRX_UIO_MODE_DISABLE:
3847                         /* pad configuration register is set 0 - input mode */
3848                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
3849                         if (rc != 0) {
3850                                 pr_err("error %d\n", rc);
3851                                 goto rw_error;
3852                         }
3853                         ext_attr->uio_irqn_mode = uio_cfg->mode;
3854                         break;
3855                 case DRX_UIO_MODE_FIRMWARE0:    /* falltrough */
3856                 default:
3857                         return -EINVAL;
3858                         break;
3859                 }               /* switch ( uio_cfg->mode ) */
3860                 break;
3861       /*====================================================================*/
3862         default:
3863                 return -EINVAL;
3864         }                       /* switch ( uio_cfg->uio ) */
3865
3866         /*  Write magic word to disable pdr reg write               */
3867         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3868         if (rc != 0) {
3869                 pr_err("error %d\n", rc);
3870                 goto rw_error;
3871         }
3872
3873         return 0;
3874 rw_error:
3875         return -EIO;
3876 }
3877
3878 /*============================================================================*/
3879 /**
3880 * \fn int ctrl_getuio_cfg()
3881 * \brief Get modus oprandi UIO.
3882 * \param demod Pointer to demodulator instance.
3883 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3884 * \return int.
3885 */
3886 static int ctrl_getuio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3887 {
3888
3889         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
3890         enum drxuio_mode *uio_mode[4] = { NULL };
3891         bool *uio_available[4] = { NULL };
3892
3893         ext_attr = demod->my_ext_attr;
3894
3895         uio_mode[DRX_UIO1] = &ext_attr->uio_sma_tx_mode;
3896         uio_mode[DRX_UIO2] = &ext_attr->uio_sma_rx_mode;
3897         uio_mode[DRX_UIO3] = &ext_attr->uio_gpio_mode;
3898         uio_mode[DRX_UIO4] = &ext_attr->uio_irqn_mode;
3899
3900         uio_available[DRX_UIO1] = &ext_attr->has_smatx;
3901         uio_available[DRX_UIO2] = &ext_attr->has_smarx;
3902         uio_available[DRX_UIO3] = &ext_attr->has_gpio;
3903         uio_available[DRX_UIO4] = &ext_attr->has_irqn;
3904
3905         if (uio_cfg == NULL)
3906                 return -EINVAL;
3907
3908         if ((uio_cfg->uio > DRX_UIO4) || (uio_cfg->uio < DRX_UIO1))
3909                 return -EINVAL;
3910
3911         if (!*uio_available[uio_cfg->uio])
3912                 return -EIO;
3913
3914         uio_cfg->mode = *uio_mode[uio_cfg->uio];
3915
3916         return 0;
3917 }
3918
3919 /**
3920 * \fn int ctrl_uio_write()
3921 * \brief Write to a UIO.
3922 * \param demod Pointer to demodulator instance.
3923 * \param uio_data Pointer to data container for a certain UIO.
3924 * \return int.
3925 */
3926 static int
3927 ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
3928 {
3929         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3930         int rc;
3931         u16 pin_cfg_value = 0;
3932         u16 value = 0;
3933
3934         if ((uio_data == NULL) || (demod == NULL))
3935                 return -EINVAL;
3936
3937         ext_attr = (struct drxj_data *) demod->my_ext_attr;
3938
3939         /*  Write magic word to enable pdr reg write               */
3940         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3941         if (rc != 0) {
3942                 pr_err("error %d\n", rc);
3943                 goto rw_error;
3944         }
3945         switch (uio_data->uio) {
3946       /*====================================================================*/
3947         case DRX_UIO1:
3948                 /* DRX_UIO1: SMA_TX UIO-1 */
3949                 if (!ext_attr->has_smatx)
3950                         return -EIO;
3951                 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3952                     && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3953                         return -EIO;
3954                 }
3955                 pin_cfg_value = 0;
3956                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3957                 pin_cfg_value |= 0x0113;
3958                 /* io_pad_cfg_mode output mode is drive always */
3959                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3960
3961                 /* write to io pad configuration register - output mode */
3962                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
3963                 if (rc != 0) {
3964                         pr_err("error %d\n", rc);
3965                         goto rw_error;
3966                 }
3967
3968                 /* use corresponding bit in io data output registar */
3969                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3970                 if (rc != 0) {
3971                         pr_err("error %d\n", rc);
3972                         goto rw_error;
3973                 }
3974                 if (!uio_data->value)
3975                         value &= 0x7FFF;        /* write zero to 15th bit - 1st UIO */
3976                 else
3977                         value |= 0x8000;        /* write one to 15th bit - 1st UIO */
3978
3979                 /* write back to io data output register */
3980                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3981                 if (rc != 0) {
3982                         pr_err("error %d\n", rc);
3983                         goto rw_error;
3984                 }
3985                 break;
3986    /*======================================================================*/
3987         case DRX_UIO2:
3988                 /* DRX_UIO2: SMA_RX UIO-2 */
3989                 if (!ext_attr->has_smarx)
3990                         return -EIO;
3991                 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
3992                         return -EIO;
3993
3994                 pin_cfg_value = 0;
3995                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3996                 pin_cfg_value |= 0x0113;
3997                 /* io_pad_cfg_mode output mode is drive always */
3998                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3999
4000                 /* write to io pad configuration register - output mode */
4001                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
4002                 if (rc != 0) {
4003                         pr_err("error %d\n", rc);
4004                         goto rw_error;
4005                 }
4006
4007                 /* use corresponding bit in io data output registar */
4008                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
4009                 if (rc != 0) {
4010                         pr_err("error %d\n", rc);
4011                         goto rw_error;
4012                 }
4013                 if (!uio_data->value)
4014                         value &= 0xBFFF;        /* write zero to 14th bit - 2nd UIO */
4015                 else
4016                         value |= 0x4000;        /* write one to 14th bit - 2nd UIO */
4017
4018                 /* write back to io data output register */
4019                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
4020                 if (rc != 0) {
4021                         pr_err("error %d\n", rc);
4022                         goto rw_error;
4023                 }
4024                 break;
4025    /*====================================================================*/
4026         case DRX_UIO3:
4027                 /* DRX_UIO3: ASEL UIO-3 */
4028                 if (!ext_attr->has_gpio)
4029                         return -EIO;
4030                 if (ext_attr->uio_gpio_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_GPIO_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_HI__A, &value, 0);
4048                 if (rc != 0) {
4049                         pr_err("error %d\n", rc);
4050                         goto rw_error;
4051                 }
4052                 if (!uio_data->value)
4053                         value &= 0xFFFB;        /* write zero to 2nd bit - 3rd UIO */
4054                 else
4055                         value |= 0x0004;        /* write one to 2nd bit - 3rd 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_HI__A, value, 0);
4059                 if (rc != 0) {
4060                         pr_err("error %d\n", rc);
4061                         goto rw_error;
4062                 }
4063                 break;
4064    /*=====================================================================*/
4065         case DRX_UIO4:
4066                 /* DRX_UIO4: IRQN UIO-4 */
4067                 if (!ext_attr->has_irqn)
4068                         return -EIO;
4069
4070                 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
4071                         return -EIO;
4072
4073                 pin_cfg_value = 0;
4074                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4075                 pin_cfg_value |= 0x0113;
4076                 /* io_pad_cfg_mode output mode is drive always */
4077                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4078
4079                 /* write to io pad configuration register - output mode */
4080                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
4081                 if (rc != 0) {
4082                         pr_err("error %d\n", rc);
4083                         goto rw_error;
4084                 }
4085
4086                 /* use corresponding bit in io data output registar */
4087                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
4088                 if (rc != 0) {
4089                         pr_err("error %d\n", rc);
4090                         goto rw_error;
4091                 }
4092                 if (uio_data->value == false)
4093                         value &= 0xEFFF;        /* write zero to 12th bit - 4th UIO */
4094                 else
4095                         value |= 0x1000;        /* write one to 12th bit - 4th UIO */
4096
4097                 /* write back to io data output register */
4098                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
4099                 if (rc != 0) {
4100                         pr_err("error %d\n", rc);
4101                         goto rw_error;
4102                 }
4103                 break;
4104       /*=====================================================================*/
4105         default:
4106                 return -EINVAL;
4107         }                       /* switch ( uio_data->uio ) */
4108
4109         /*  Write magic word to disable pdr reg write               */
4110         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4111         if (rc != 0) {
4112                 pr_err("error %d\n", rc);
4113                 goto rw_error;
4114         }
4115
4116         return 0;
4117 rw_error:
4118         return -EIO;
4119 }
4120
4121 /**
4122 *\fn int ctrl_uio_read
4123 *\brief Read from a UIO.
4124 * \param demod Pointer to demodulator instance.
4125 * \param uio_data Pointer to data container for a certain UIO.
4126 * \return int.
4127 */
4128 static int ctrl_uio_read(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
4129 {
4130         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
4131         int rc;
4132         u16 pin_cfg_value = 0;
4133         u16 value = 0;
4134
4135         if ((uio_data == NULL) || (demod == NULL))
4136                 return -EINVAL;
4137
4138         ext_attr = (struct drxj_data *) demod->my_ext_attr;
4139
4140         /*  Write magic word to enable pdr reg write               */
4141         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4142         if (rc != 0) {
4143                 pr_err("error %d\n", rc);
4144                 goto rw_error;
4145         }
4146         switch (uio_data->uio) {
4147       /*====================================================================*/
4148         case DRX_UIO1:
4149                 /* DRX_UIO1: SMA_TX UIO-1 */
4150                 if (!ext_attr->has_smatx)
4151                         return -EIO;
4152
4153                 if (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
4154                         return -EIO;
4155
4156                 pin_cfg_value = 0;
4157                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4158                 pin_cfg_value |= 0x0110;
4159                 /* io_pad_cfg_mode output mode is drive always */
4160                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4161
4162                 /* write to io pad configuration register - input mode */
4163                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
4164                 if (rc != 0) {
4165                         pr_err("error %d\n", rc);
4166                         goto rw_error;
4167                 }
4168
4169                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4170                 if (rc != 0) {
4171                         pr_err("error %d\n", rc);
4172                         goto rw_error;
4173                 }
4174                 if ((value & 0x8000) != 0) {    /* check 15th bit - 1st UIO */
4175                         uio_data->value = true;
4176                 } else {
4177                         uio_data->value = false;
4178                 }
4179                 break;
4180    /*======================================================================*/
4181         case DRX_UIO2:
4182                 /* DRX_UIO2: SMA_RX UIO-2 */
4183                 if (!ext_attr->has_smarx)
4184                         return -EIO;
4185
4186                 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
4187                         return -EIO;
4188
4189                 pin_cfg_value = 0;
4190                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4191                 pin_cfg_value |= 0x0110;
4192                 /* io_pad_cfg_mode output mode is drive always */
4193                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4194
4195                 /* write to io pad configuration register - input mode */
4196                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
4197                 if (rc != 0) {
4198                         pr_err("error %d\n", rc);
4199                         goto rw_error;
4200                 }
4201
4202                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4203                 if (rc != 0) {
4204                         pr_err("error %d\n", rc);
4205                         goto rw_error;
4206                 }
4207
4208                 if ((value & 0x4000) != 0)      /* check 14th bit - 2nd UIO */
4209                         uio_data->value = true;
4210                 else
4211                         uio_data->value = false;
4212
4213                 break;
4214    /*=====================================================================*/
4215         case DRX_UIO3:
4216                 /* DRX_UIO3: GPIO UIO-3 */
4217                 if (!ext_attr->has_gpio)
4218                         return -EIO;
4219
4220                 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
4221                         return -EIO;
4222
4223                 pin_cfg_value = 0;
4224                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4225                 pin_cfg_value |= 0x0110;
4226                 /* io_pad_cfg_mode output mode is drive always */
4227                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4228
4229                 /* write to io pad configuration register - input mode */
4230                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
4231                 if (rc != 0) {
4232                         pr_err("error %d\n", rc);
4233                         goto rw_error;
4234                 }
4235
4236                 /* read io input data registar */
4237                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_HI__A, &value, 0);
4238                 if (rc != 0) {
4239                         pr_err("error %d\n", rc);
4240                         goto rw_error;
4241                 }
4242                 if ((value & 0x0004) != 0) {    /* check 2nd bit - 3rd UIO */
4243                         uio_data->value = true;
4244                 } else {
4245                         uio_data->value = false;
4246                 }
4247                 break;
4248    /*=====================================================================*/
4249         case DRX_UIO4:
4250                 /* DRX_UIO4: IRQN UIO-4 */
4251                 if (!ext_attr->has_irqn)
4252                         return -EIO;
4253
4254                 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
4255                         return -EIO;
4256
4257                 pin_cfg_value = 0;
4258                 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
4259                 pin_cfg_value |= 0x0110;
4260                 /* io_pad_cfg_mode output mode is drive always */
4261                 /* io_pad_cfg_drive is set to power 2 (23 mA) */
4262
4263                 /* write to io pad configuration register - input mode */
4264                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
4265                 if (rc != 0) {
4266                         pr_err("error %d\n", rc);
4267                         goto rw_error;
4268                 }
4269
4270                 /* read io input data registar */
4271                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SIO_PDR_UIO_IN_LO__A, &value, 0);
4272                 if (rc != 0) {
4273                         pr_err("error %d\n", rc);
4274                         goto rw_error;
4275                 }
4276                 if ((value & 0x1000) != 0)      /* check 12th bit - 4th UIO */
4277                         uio_data->value = true;
4278                 else
4279                         uio_data->value = false;
4280
4281                 break;
4282       /*====================================================================*/
4283         default:
4284                 return -EINVAL;
4285         }                       /* switch ( uio_data->uio ) */
4286
4287         /*  Write magic word to disable pdr reg write               */
4288         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4289         if (rc != 0) {
4290                 pr_err("error %d\n", rc);
4291                 goto rw_error;
4292         }
4293
4294         return 0;
4295 rw_error:
4296         return -EIO;
4297 }
4298
4299 /*---------------------------------------------------------------------------*/
4300 /* UIO Configuration Functions - end                                         */
4301 /*---------------------------------------------------------------------------*/
4302
4303 /*----------------------------------------------------------------------------*/
4304 /* I2C Bridge Functions - begin                                               */
4305 /*----------------------------------------------------------------------------*/
4306 /**
4307 * \fn int ctrl_i2c_bridge()
4308 * \brief Open or close the I2C switch to tuner.
4309 * \param demod Pointer to demodulator instance.
4310 * \param bridge_closed Pointer to bool indication if bridge is closed not.
4311 * \return int.
4312
4313 */
4314 static int
4315 ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
4316 {
4317         struct drxj_hi_cmd hi_cmd;
4318         u16 result = 0;
4319
4320         /* check arguments */
4321         if (bridge_closed == NULL)
4322                 return -EINVAL;
4323
4324         hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
4325         hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
4326         if (*bridge_closed)
4327                 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
4328         else
4329                 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
4330
4331         return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
4332 }
4333
4334 /*----------------------------------------------------------------------------*/
4335 /* I2C Bridge Functions - end                                                 */
4336 /*----------------------------------------------------------------------------*/
4337
4338 /*----------------------------------------------------------------------------*/
4339 /* Smart antenna Functions - begin                                            */
4340 /*----------------------------------------------------------------------------*/
4341 /**
4342 * \fn int smart_ant_init()
4343 * \brief Initialize Smart Antenna.
4344 * \param pointer to struct drx_demod_instance.
4345 * \return int.
4346 *
4347 */
4348 static int smart_ant_init(struct drx_demod_instance *demod)
4349 {
4350         struct drxj_data *ext_attr = NULL;
4351         struct i2c_device_addr *dev_addr = NULL;
4352         struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
4353         int rc;
4354         u16 data = 0;
4355
4356         dev_addr = demod->my_i2c_dev_addr;
4357         ext_attr = (struct drxj_data *) demod->my_ext_attr;
4358
4359         /*  Write magic word to enable pdr reg write               */
4360         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4361         if (rc != 0) {
4362                 pr_err("error %d\n", rc);
4363                 goto rw_error;
4364         }
4365         /* init smart antenna */
4366         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
4367         if (rc != 0) {
4368                 pr_err("error %d\n", rc);
4369                 goto rw_error;
4370         }
4371         if (ext_attr->smart_ant_inverted) {
4372                 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);
4373                 if (rc != 0) {
4374                         pr_err("error %d\n", rc);
4375                         goto rw_error;
4376                 }
4377         } else {
4378                 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);
4379                 if (rc != 0) {
4380                         pr_err("error %d\n", rc);
4381                         goto rw_error;
4382                 }
4383         }
4384
4385         /* config SMA_TX pin to smart antenna mode */
4386         rc = ctrl_set_uio_cfg(demod, &uio_cfg);
4387         if (rc != 0) {
4388                 pr_err("error %d\n", rc);
4389                 goto rw_error;
4390         }
4391         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
4392         if (rc != 0) {
4393                 pr_err("error %d\n", rc);
4394                 goto rw_error;
4395         }
4396         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
4397         if (rc != 0) {
4398                 pr_err("error %d\n", rc);
4399                 goto rw_error;
4400         }
4401
4402         /*  Write magic word to disable pdr reg write               */
4403         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4404         if (rc != 0) {
4405                 pr_err("error %d\n", rc);
4406                 goto rw_error;
4407         }
4408
4409         return 0;
4410 rw_error:
4411         return -EIO;
4412 }
4413
4414 /**
4415 * \fn int ctrl_set_cfg_smart_ant()
4416 * \brief Set Smart Antenna.
4417 * \param pointer to struct drxj_cfg_smart_ant.
4418 * \return int.
4419 *
4420 */
4421 static int
4422 ctrl_set_cfg_smart_ant(struct drx_demod_instance *demod, struct drxj_cfg_smart_ant *smart_ant)
4423 {
4424         struct drxj_data *ext_attr = NULL;
4425         struct i2c_device_addr *dev_addr = NULL;
4426         int rc;
4427         u32 start_time = 0;
4428         u16 data = 0;
4429         static bool bit_inverted;
4430
4431         dev_addr = demod->my_i2c_dev_addr;
4432         ext_attr = (struct drxj_data *) demod->my_ext_attr;
4433
4434         /* check arguments */
4435         if (smart_ant == NULL)
4436                 return -EINVAL;
4437
4438         if (bit_inverted != ext_attr->smart_ant_inverted
4439             || ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SMA) {
4440                 rc = smart_ant_init(demod);
4441                 if (rc != 0) {
4442                         pr_err("error %d\n", rc);
4443                         goto rw_error;
4444                 }
4445                 bit_inverted = ext_attr->smart_ant_inverted;
4446         }
4447
4448         /*  Write magic word to enable pdr reg write               */
4449         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4450         if (rc != 0) {
4451                 pr_err("error %d\n", rc);
4452                 goto rw_error;
4453         }
4454
4455         switch (smart_ant->io) {
4456         case DRXJ_SMT_ANT_OUTPUT:
4457                 /* enable Tx if Mode B (input) is supported */
4458                 /*
4459                    RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4460                    WR16( dev_addr, SIO_SA_TX_COMMAND__A, data | SIO_SA_TX_COMMAND_TX_ENABLE__M );
4461                  */
4462                 start_time = drxbsp_hst_clock();
4463                 do {
4464                         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_SA_TX_STATUS__A, &data, 0);
4465                         if (rc != 0) {
4466                                 pr_err("error %d\n", rc);
4467                                 goto rw_error;
4468                         }
4469                 } while ((data & SIO_SA_TX_STATUS_BUSY__M) && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
4470
4471                 if (data & SIO_SA_TX_STATUS_BUSY__M)
4472                         return -EIO;
4473
4474                 /* write to smart antenna configuration register */
4475                 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);
4476                 if (rc != 0) {
4477                         pr_err("error %d\n", rc);
4478                         goto rw_error;
4479                 }
4480                 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);
4481                 if (rc != 0) {
4482                         pr_err("error %d\n", rc);
4483                         goto rw_error;
4484                 }
4485                 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);
4486                 if (rc != 0) {
4487                         pr_err("error %d\n", rc);
4488                         goto rw_error;
4489                 }
4490                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_DATA3__A, 0xff8d, 0);
4491                 if (rc != 0) {
4492                         pr_err("error %d\n", rc);
4493                         goto rw_error;
4494                 }
4495
4496                 /* trigger the sending */
4497                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_SA_TX_LENGTH__A, 56, 0);
4498                 if (rc != 0) {
4499                         pr_err("error %d\n", rc);
4500                         goto rw_error;
4501                 }
4502
4503                 break;
4504         case DRXJ_SMT_ANT_INPUT:
4505                 /* disable Tx if Mode B (input) is supported */
4506                 /*
4507                    RR16( dev_addr, SIO_SA_TX_COMMAND__A, &data );
4508                    WR16( dev_addr, SIO_SA_TX_COMMAND__A, data & (~SIO_SA_TX_COMMAND_TX_ENABLE__M) );
4509                  */
4510         default:
4511                 return -EINVAL;
4512         }
4513         /*  Write magic word to enable pdr reg write               */
4514         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
4515         if (rc != 0) {
4516                 pr_err("error %d\n", rc);
4517                 goto rw_error;
4518         }
4519
4520         return 0;
4521 rw_error:
4522         return -EIO;
4523 }
4524
4525 static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
4526 {
4527         int rc;
4528         u32 start_time = 0;
4529         u16 cur_cmd = 0;
4530
4531         /* Check param */
4532         if (cmd == NULL)
4533                 return -EINVAL;
4534
4535         /* Wait until SCU command interface is ready to receive command */
4536         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4537         if (rc != 0) {
4538                 pr_err("error %d\n", rc);
4539                 goto rw_error;
4540         }
4541         if (cur_cmd != DRX_SCU_READY)
4542                 return -EIO;
4543
4544         switch (cmd->parameter_len) {
4545         case 5:
4546                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
4547                 if (rc != 0) {
4548                         pr_err("error %d\n", rc);
4549                         goto rw_error;
4550                 }       /* fallthrough */
4551         case 4:
4552                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
4553                 if (rc != 0) {
4554                         pr_err("error %d\n", rc);
4555                         goto rw_error;
4556                 }       /* fallthrough */
4557         case 3:
4558                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
4559                 if (rc != 0) {
4560                         pr_err("error %d\n", rc);
4561                         goto rw_error;
4562                 }       /* fallthrough */
4563         case 2:
4564                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
4565                 if (rc != 0) {
4566                         pr_err("error %d\n", rc);
4567                         goto rw_error;
4568                 }       /* fallthrough */
4569         case 1:
4570                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
4571                 if (rc != 0) {
4572                         pr_err("error %d\n", rc);
4573                         goto rw_error;
4574                 }       /* fallthrough */
4575         case 0:
4576                 /* do nothing */
4577                 break;
4578         default:
4579                 /* this number of parameters is not supported */
4580                 return -EIO;
4581         }
4582         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
4583         if (rc != 0) {
4584                 pr_err("error %d\n", rc);
4585                 goto rw_error;
4586         }
4587
4588         /* Wait until SCU has processed command */
4589         start_time = drxbsp_hst_clock();
4590         do {
4591                 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4592                 if (rc != 0) {
4593                         pr_err("error %d\n", rc);
4594                         goto rw_error;
4595                 }
4596         } while (!(cur_cmd == DRX_SCU_READY)
4597                  && ((drxbsp_hst_clock() - start_time) < DRXJ_MAX_WAITTIME));
4598
4599         if (cur_cmd != DRX_SCU_READY)
4600                 return -EIO;
4601
4602         /* read results */
4603         if ((cmd->result_len > 0) && (cmd->result != NULL)) {
4604                 s16 err;
4605
4606                 switch (cmd->result_len) {
4607                 case 4:
4608                         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
4609                         if (rc != 0) {
4610                                 pr_err("error %d\n", rc);
4611                                 goto rw_error;
4612                         }       /* fallthrough */
4613                 case 3:
4614                         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
4615                         if (rc != 0) {
4616                                 pr_err("error %d\n", rc);
4617                                 goto rw_error;
4618                         }       /* fallthrough */
4619                 case 2:
4620                         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
4621                         if (rc != 0) {
4622                                 pr_err("error %d\n", rc);
4623                                 goto rw_error;
4624                         }       /* fallthrough */
4625                 case 1:
4626                         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
4627                         if (rc != 0) {
4628                                 pr_err("error %d\n", rc);
4629                                 goto rw_error;
4630                         }       /* fallthrough */
4631                 case 0:
4632                         /* do nothing */
4633                         break;
4634                 default:
4635                         /* this number of parameters is not supported */
4636                         return -EIO;
4637                 }
4638
4639                 /* Check if an error was reported by SCU */
4640                 err = cmd->result[0];
4641
4642                 /* check a few fixed error codes */
4643                 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4644                     || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4645                     || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4646                     || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
4647                     ) {
4648                         return -EINVAL;
4649                 }
4650                 /* here it is assumed that negative means error, and positive no error */
4651                 else if (err < 0)
4652                         return -EIO;
4653                 else
4654                         return 0;
4655         }
4656
4657         return 0;
4658
4659 rw_error:
4660         return -EIO;
4661 }
4662
4663 /**
4664 * \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4665 * \brief Basic access routine for SCU atomic read or write access
4666 * \param dev_addr  pointer to i2c dev address
4667 * \param addr     destination/source address
4668 * \param datasize size of data buffer in bytes
4669 * \param data     pointer to data buffer
4670 * \return int
4671 * \retval 0 Succes
4672 * \retval -EIO Timeout, I2C error, illegal bank
4673 *
4674 */
4675 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4676 static
4677 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 */
4678                                               u8 *data, bool read_flag)
4679 {
4680         struct drxjscu_cmd scu_cmd;
4681         int rc;
4682         u16 set_param_parameters[15];
4683         u16 cmd_result[15];
4684
4685         /* Parameter check */
4686         if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
4687                 return -EINVAL;
4688
4689         set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4690         if (read_flag) {                /* read */
4691                 set_param_parameters[0] = ((~(0x0080)) & datasize);
4692                 scu_cmd.parameter_len = 2;
4693                 scu_cmd.result_len = datasize / 2 + 2;
4694         } else {
4695                 int i = 0;
4696
4697                 set_param_parameters[0] = 0x0080 | datasize;
4698                 for (i = 0; i < (datasize / 2); i++) {
4699                         set_param_parameters[i + 2] =
4700                             (data[2 * i] | (data[(2 * i) + 1] << 8));
4701                 }
4702                 scu_cmd.parameter_len = datasize / 2 + 2;
4703                 scu_cmd.result_len = 1;
4704         }
4705
4706         scu_cmd.command =
4707             SCU_RAM_COMMAND_STANDARD_TOP |
4708             SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4709         scu_cmd.result = cmd_result;
4710         scu_cmd.parameter = set_param_parameters;
4711         rc = scu_command(dev_addr, &scu_cmd);
4712         if (rc != 0) {
4713                 pr_err("error %d\n", rc);
4714                 goto rw_error;
4715         }
4716
4717         if (read_flag) {
4718                 int i = 0;
4719                 /* read data from buffer */
4720                 for (i = 0; i < (datasize / 2); i++) {
4721                         data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4722                         data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
4723                 }
4724         }
4725
4726         return 0;
4727
4728 rw_error:
4729         return -EIO;
4730
4731 }
4732
4733 /*============================================================================*/
4734
4735 /**
4736 * \fn int DRXJ_DAP_AtomicReadReg16()
4737 * \brief Atomic read of 16 bits words
4738 */
4739 static
4740 int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4741                                          u32 addr,
4742                                          u16 *data, u32 flags)
4743 {
4744         u8 buf[2];
4745         int rc = -EIO;
4746         u16 word = 0;
4747
4748         if (!data)
4749                 return -EINVAL;
4750
4751         rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
4752         if (rc < 0)
4753                 return rc;
4754
4755         word = (u16) (buf[0] + (buf[1] << 8));
4756
4757         *data = word;
4758
4759         return rc;
4760 }
4761
4762 /*============================================================================*/
4763 /**
4764 * \fn int drxj_dap_scu_atomic_write_reg16()
4765 * \brief Atomic read of 16 bits words
4766 */
4767 static
4768 int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4769                                           u32 addr,
4770                                           u16 data, u32 flags)
4771 {
4772         u8 buf[2];
4773         int rc = -EIO;
4774
4775         buf[0] = (u8) (data & 0xff);
4776         buf[1] = (u8) ((data >> 8) & 0xff);
4777
4778         rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
4779
4780         return rc;
4781 }
4782
4783 static int
4784 ctrl_i2c_write_read(struct drx_demod_instance *demod, struct drxi2c_data *i2c_data)
4785 {
4786         return -ENOTSUPP;
4787 }
4788
4789 /* -------------------------------------------------------------------------- */
4790 /**
4791 * \brief Measure result of ADC synchronisation
4792 * \param demod demod instance
4793 * \param count (returned) count
4794 * \return int.
4795 * \retval 0    Success
4796 * \retval -EIO Failure: I2C error
4797 *
4798 */
4799 static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
4800 {
4801         struct i2c_device_addr *dev_addr = NULL;
4802         int rc;
4803         u16 data = 0;
4804
4805         dev_addr = demod->my_i2c_dev_addr;
4806
4807         /* Start measurement */
4808         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
4809         if (rc != 0) {
4810                 pr_err("error %d\n", rc);
4811                 goto rw_error;
4812         }
4813         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
4814         if (rc != 0) {
4815                 pr_err("error %d\n", rc);
4816                 goto rw_error;
4817         }
4818
4819         /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4820         rc = drxbsp_hst_sleep(1);
4821         if (rc != 0) {
4822                 pr_err("error %d\n", rc);
4823                 goto rw_error;
4824         }
4825
4826         *count = 0;
4827         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE0__A, &data, 0);
4828         if (rc != 0) {
4829                 pr_err("error %d\n", rc);
4830                 goto rw_error;
4831         }
4832         if (data == 127)
4833                 *count = *count + 1;
4834         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE1__A, &data, 0);
4835         if (rc != 0) {
4836                 pr_err("error %d\n", rc);
4837                 goto rw_error;
4838         }
4839         if (data == 127)
4840                 *count = *count + 1;
4841         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_PHASE2__A, &data, 0);
4842         if (rc != 0) {
4843                 pr_err("error %d\n", rc);
4844                 goto rw_error;
4845         }
4846         if (data == 127)
4847                 *count = *count + 1;
4848
4849         return 0;
4850 rw_error:
4851         return -EIO;
4852 }
4853
4854 /**
4855 * \brief Synchronize analog and digital clock domains
4856 * \param demod demod instance
4857 * \return int.
4858 * \retval 0    Success
4859 * \retval -EIO Failure: I2C error or failure to synchronize
4860 *
4861 * An IQM reset will also reset the results of this synchronization.
4862 * After an IQM reset this routine needs to be called again.
4863 *
4864 */
4865
4866 static int adc_synchronization(struct drx_demod_instance *demod)
4867 {
4868         struct i2c_device_addr *dev_addr = NULL;
4869         int rc;
4870         u16 count = 0;
4871
4872         dev_addr = demod->my_i2c_dev_addr;
4873
4874         rc = adc_sync_measurement(demod, &count);
4875         if (rc != 0) {
4876                 pr_err("error %d\n", rc);
4877                 goto rw_error;
4878         }
4879
4880         if (count == 1) {
4881                 /* Try sampling on a diffrent edge */
4882                 u16 clk_neg = 0;
4883
4884                 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
4885                 if (rc != 0) {
4886                         pr_err("error %d\n", rc);
4887                         goto rw_error;
4888                 }
4889
4890                 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4891                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
4892                 if (rc != 0) {
4893                         pr_err("error %d\n", rc);
4894                         goto rw_error;
4895                 }
4896
4897                 rc = adc_sync_measurement(demod, &count);
4898                 if (rc != 0) {
4899                         pr_err("error %d\n", rc);
4900                         goto rw_error;
4901                 }
4902         }
4903
4904         /* TODO: implement fallback scenarios */
4905         if (count < 2)
4906                 return -EIO;
4907
4908         return 0;
4909 rw_error:
4910         return -EIO;
4911 }
4912
4913 /**
4914 * \brief Configure IQM AF registers
4915 * \param demod instance of demodulator.
4916 * \param active
4917 * \return int.
4918 */
4919 static int iqm_set_af(struct drx_demod_instance *demod, bool active)
4920 {
4921         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
4922         int rc;
4923         u16 data = 0;
4924
4925         /* Configure IQM */
4926         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
4927         if (rc != 0) {
4928                 pr_err("error %d\n", rc);
4929                 goto rw_error;
4930         }
4931         if (!active)
4932                 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));
4933         else
4934                 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);
4935         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
4936         if (rc != 0) {
4937                 pr_err("error %d\n", rc);
4938                 goto rw_error;
4939         }
4940
4941         return 0;
4942 rw_error:
4943         return -EIO;
4944 }
4945
4946 /* -------------------------------------------------------------------------- */
4947 static int
4948 ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg);
4949
4950 /**
4951 * \brief set configuration of pin-safe mode
4952 * \param demod instance of demodulator.
4953 * \param enable boolean; true: activate pin-safe mode, false: de-activate p.s.m.
4954 * \return int.
4955 */
4956 static int
4957 ctrl_set_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enable)
4958 {
4959         struct drxj_data *ext_attr = NULL;
4960         struct i2c_device_addr *dev_addr = NULL;
4961         int rc;
4962
4963         if (enable == NULL)
4964                 return -EINVAL;
4965
4966         dev_addr = demod->my_i2c_dev_addr;
4967         ext_attr = (struct drxj_data *) demod->my_ext_attr;
4968
4969         /*  Write magic word to enable pdr reg write  */
4970         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
4971         if (rc != 0) {
4972                 pr_err("error %d\n", rc);
4973                 goto rw_error;
4974         }
4975
4976         if (*enable) {
4977                 bool bridge_enabled = false;
4978
4979                 /* MPEG pins to input */
4980                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MSTRT_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_MERR_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_MCLK_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_MVAL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
4996                 if (rc != 0) {
4997                         pr_err("error %d\n", rc);
4998                         goto rw_error;
4999                 }
5000                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD0_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5001                 if (rc != 0) {
5002                         pr_err("error %d\n", rc);
5003                         goto rw_error;
5004                 }
5005                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD1_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5006                 if (rc != 0) {
5007                         pr_err("error %d\n", rc);
5008                         goto rw_error;
5009                 }
5010                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5011                 if (rc != 0) {
5012                         pr_err("error %d\n", rc);
5013                         goto rw_error;
5014                 }
5015                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD3_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5016                 if (rc != 0) {
5017                         pr_err("error %d\n", rc);
5018                         goto rw_error;
5019                 }
5020                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD4_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5021                 if (rc != 0) {
5022                         pr_err("error %d\n", rc);
5023                         goto rw_error;
5024                 }
5025                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD5_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5026                 if (rc != 0) {
5027                         pr_err("error %d\n", rc);
5028                         goto rw_error;
5029                 }
5030                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD6_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5031                 if (rc != 0) {
5032                         pr_err("error %d\n", rc);
5033                         goto rw_error;
5034                 }
5035                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_MD7_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5036                 if (rc != 0) {
5037                         pr_err("error %d\n", rc);
5038                         goto rw_error;
5039                 }
5040
5041                 /* PD_I2C_SDA2 Bridge off, Port2 Inactive
5042                    PD_I2C_SCL2 Bridge off, Port2 Inactive */
5043                 rc = ctrl_i2c_bridge(demod, &bridge_enabled);
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_I2C_SDA2_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_I2C_SCL2_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5054                 if (rc != 0) {
5055                         pr_err("error %d\n", rc);
5056                         goto rw_error;
5057                 }
5058
5059                 /*  PD_GPIO     Store and set to input
5060                    PD_VSYNC    Store and set to input
5061                    PD_SMA_RX   Store and set to input
5062                    PD_SMA_TX   Store and set to input */
5063                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, &ext_attr->pdr_safe_restore_val_gpio, 0);
5064                 if (rc != 0) {
5065                         pr_err("error %d\n", rc);
5066                         goto rw_error;
5067                 }
5068                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, &ext_attr->pdr_safe_restore_val_v_sync, 0);
5069                 if (rc != 0) {
5070                         pr_err("error %d\n", rc);
5071                         goto rw_error;
5072                 }
5073                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_rx, 0);
5074                 if (rc != 0) {
5075                         pr_err("error %d\n", rc);
5076                         goto rw_error;
5077                 }
5078                 rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, &ext_attr->pdr_safe_restore_val_sma_tx, 0);
5079                 if (rc != 0) {
5080                         pr_err("error %d\n", rc);
5081                         goto rw_error;
5082                 }
5083                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_GPIO_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_VSYNC_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_SMA_RX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5094                 if (rc != 0) {
5095                         pr_err("error %d\n", rc);
5096                         goto rw_error;
5097                 }
5098                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5099                 if (rc != 0) {
5100                         pr_err("error %d\n", rc);
5101                         goto rw_error;
5102                 }
5103
5104                 /*  PD_RF_AGC   Analog DAC outputs, cannot be set to input or tristate!
5105                    PD_IF_AGC   Analog DAC outputs, cannot be set to input or tristate! */
5106                 rc = iqm_set_af(demod, false);
5107                 if (rc != 0) {
5108                         pr_err("error %d\n", rc);
5109                         goto rw_error;
5110                 }
5111
5112                 /*  PD_CVBS     Analog DAC output, standby mode
5113                    PD_SIF      Analog DAC output, standby mode */
5114                 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);
5115                 if (rc != 0) {
5116                         pr_err("error %d\n", rc);
5117                         goto rw_error;
5118                 }
5119
5120                 /*  PD_I2S_CL   Input
5121                    PD_I2S_DA   Input
5122                    PD_I2S_WS   Input */
5123                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_CL_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5124                 if (rc != 0) {
5125                         pr_err("error %d\n", rc);
5126                         goto rw_error;
5127                 }
5128                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_DA_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5129                 if (rc != 0) {
5130                         pr_err("error %d\n", rc);
5131                         goto rw_error;
5132                 }
5133                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_WS_CFG__A, DRXJ_PIN_SAFE_MODE, 0);
5134                 if (rc != 0) {
5135                         pr_err("error %d\n", rc);
5136                         goto rw_error;
5137                 }
5138         } else {
5139                 /* No need to restore MPEG pins;
5140                    is done in SetStandard/SetChannel */
5141
5142                 /* PD_I2C_SDA2 Port2 active
5143                    PD_I2C_SCL2 Port2 active */
5144                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SDA2_CFG__A, SIO_PDR_I2C_SDA2_CFG__PRE, 0);
5145                 if (rc != 0) {
5146                         pr_err("error %d\n", rc);
5147                         goto rw_error;
5148                 }
5149                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2C_SCL2_CFG__A, SIO_PDR_I2C_SCL2_CFG__PRE, 0);
5150                 if (rc != 0) {
5151                         pr_err("error %d\n", rc);
5152                         goto rw_error;
5153                 }
5154
5155                 /*  PD_GPIO     Restore
5156                    PD_VSYNC    Restore
5157                    PD_SMA_RX   Restore
5158                    PD_SMA_TX   Restore */
5159                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_GPIO_CFG__A, ext_attr->pdr_safe_restore_val_gpio, 0);
5160                 if (rc != 0) {
5161                         pr_err("error %d\n", rc);
5162                         goto rw_error;
5163                 }
5164                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_VSYNC_CFG__A, ext_attr->pdr_safe_restore_val_v_sync, 0);
5165                 if (rc != 0) {
5166                         pr_err("error %d\n", rc);
5167                         goto rw_error;
5168                 }
5169                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_RX_CFG__A, ext_attr->pdr_safe_restore_val_sma_rx, 0);
5170                 if (rc != 0) {
5171                         pr_err("error %d\n", rc);
5172                         goto rw_error;
5173                 }
5174                 rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_SMA_TX_CFG__A, ext_attr->pdr_safe_restore_val_sma_tx, 0);
5175                 if (rc != 0) {
5176                         pr_err("error %d\n", rc);
5177                         goto rw_error;
5178                 }
5179
5180                 /*  PD_RF_AGC, PD_IF_AGC
5181                    No need to restore; will be restored in SetStandard/SetChannel */
5182
5183                 /*  PD_CVBS, PD_SIF
5184                    No need to restore; will be restored in SetStandard/SetChannel */
5185
5186                 /*  PD_I2S_CL, PD_I2S_DA, PD_I2S_WS
5187                    Should be restored via DRX_CTRL_SET_AUD */
5188         }
5189
5190         /*  Write magic word to disable pdr reg write */
5191         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
5192         if (rc != 0) {
5193                 pr_err("error %d\n", rc);
5194                 goto rw_error;
5195         }
5196         ext_attr->pdr_safe_mode = *enable;
5197
5198         return 0;
5199
5200 rw_error:
5201         return -EIO;
5202 }
5203
5204 /* -------------------------------------------------------------------------- */
5205
5206 /**
5207 * \brief get configuration of pin-safe mode
5208 * \param demod instance of demodulator.
5209 * \param enable boolean indicating whether pin-safe mode is active
5210 * \return int.
5211 */
5212 static int
5213 ctrl_get_cfg_pdr_safe_mode(struct drx_demod_instance *demod, bool *enabled)
5214 {
5215         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
5216
5217         if (enabled == NULL)
5218                 return -EINVAL;
5219
5220         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5221         *enabled = ext_attr->pdr_safe_mode;
5222
5223         return 0;
5224 }
5225
5226 /**
5227 * \brief Verifies whether microcode can be loaded.
5228 * \param demod Demodulator instance.
5229 * \return int.
5230 */
5231 static int ctrl_validate_u_code(struct drx_demod_instance *demod)
5232 {
5233         u32 mc_dev, mc_patch;
5234         u16 ver_type;
5235
5236         /* Check device.
5237          *  Disallow microcode if:
5238          *   - MC has version record AND
5239          *   - device ID in version record is not 0 AND
5240          *   - product ID in version record's device ID does not
5241          *     match DRXJ1 product IDs - 0x393 or 0x394
5242          */
5243         ver_type = DRX_ATTR_MCRECORD(demod).aux_type;
5244         mc_dev = DRX_ATTR_MCRECORD(demod).mc_dev_type;
5245         mc_patch = DRX_ATTR_MCRECORD(demod).mc_base_version;
5246
5247         if (DRX_ISMCVERTYPE(ver_type)) {
5248                 if ((mc_dev != 0) &&
5249                     (((mc_dev >> 16) & 0xFFF) != 0x393) &&
5250                     (((mc_dev >> 16) & 0xFFF) != 0x394)) {
5251                         /* Microcode is marked for another device - error */
5252                         return -EINVAL;
5253                 } else if (mc_patch != 0) {
5254                         /* Patch not allowed because there is no ROM */
5255                         return -EINVAL;
5256                 }
5257         }
5258
5259         /* Everything else: OK */
5260         return 0;
5261 }
5262
5263 /*============================================================================*/
5264 /*==                      END AUXILIARY FUNCTIONS                           ==*/
5265 /*============================================================================*/
5266
5267 /*============================================================================*/
5268 /*============================================================================*/
5269 /*==                8VSB & QAM COMMON DATAPATH FUNCTIONS                    ==*/
5270 /*============================================================================*/
5271 /*============================================================================*/
5272 /**
5273 * \fn int init_agc ()
5274 * \brief Initialize AGC for all standards.
5275 * \param demod instance of demodulator.
5276 * \param channel pointer to channel data.
5277 * \return int.
5278 */
5279 static int init_agc(struct drx_demod_instance *demod)
5280 {
5281         struct i2c_device_addr *dev_addr = NULL;
5282         struct drx_common_attr *common_attr = NULL;
5283         struct drxj_data *ext_attr = NULL;
5284         struct drxj_cfg_agc *p_agc_rf_settings = NULL;
5285         struct drxj_cfg_agc *p_agc_if_settings = NULL;
5286         int rc;
5287         u16 ingain_tgt_max = 0;
5288         u16 clp_dir_to = 0;
5289         u16 sns_sum_max = 0;
5290         u16 clp_sum_max = 0;
5291         u16 sns_dir_to = 0;
5292         u16 ki_innergain_min = 0;
5293         u16 agc_ki = 0;
5294         u16 ki_max = 0;
5295         u16 if_iaccu_hi_tgt_min = 0;
5296         u16 data = 0;
5297         u16 agc_ki_dgain = 0;
5298         u16 ki_min = 0;
5299         u16 clp_ctrl_mode = 0;
5300         u16 agc_rf = 0;
5301         u16 agc_if = 0;
5302
5303         dev_addr = demod->my_i2c_dev_addr;
5304         common_attr = (struct drx_common_attr *) demod->my_common_attr;
5305         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5306
5307         switch (ext_attr->standard) {
5308         case DRX_STANDARD_8VSB:
5309                 clp_sum_max = 1023;
5310                 clp_dir_to = (u16) (-9);
5311                 sns_sum_max = 1023;
5312                 sns_dir_to = (u16) (-9);
5313                 ki_innergain_min = (u16) (-32768);
5314                 ki_max = 0x032C;
5315                 agc_ki_dgain = 0xC;
5316                 if_iaccu_hi_tgt_min = 2047;
5317                 ki_min = 0x0117;
5318                 ingain_tgt_max = 16383;
5319                 clp_ctrl_mode = 0;
5320                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 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_KI_MAXGAIN__A, 0x0, 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_CLP_SUM__A, 0, 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_AGC_CLP_CYCCNT__A, 0, 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_CLP_DIR_WD__A, 0, 0);
5341                 if (rc != 0) {
5342                         pr_err("error %d\n", rc);
5343                         goto rw_error;
5344                 }
5345                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
5346                 if (rc != 0) {
5347                         pr_err("error %d\n", rc);
5348                         goto rw_error;
5349                 }
5350                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
5351                 if (rc != 0) {
5352                         pr_err("error %d\n", rc);
5353                         goto rw_error;
5354                 }
5355                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
5356                 if (rc != 0) {
5357                         pr_err("error %d\n", rc);
5358                         goto rw_error;
5359                 }
5360                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
5361                 if (rc != 0) {
5362                         pr_err("error %d\n", rc);
5363                         goto rw_error;
5364                 }
5365                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
5366                 if (rc != 0) {
5367                         pr_err("error %d\n", rc);
5368                         goto rw_error;
5369                 }
5370                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
5371                 if (rc != 0) {
5372                         pr_err("error %d\n", rc);
5373                         goto rw_error;
5374                 }
5375                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
5376                 if (rc != 0) {
5377                         pr_err("error %d\n", rc);
5378                         goto rw_error;
5379                 }
5380                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
5381                 if (rc != 0) {
5382                         pr_err("error %d\n", rc);
5383                         goto rw_error;
5384                 }
5385                 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
5386                 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
5387                 break;
5388 #ifndef DRXJ_VSB_ONLY
5389         case DRX_STANDARD_ITU_A:
5390         case DRX_STANDARD_ITU_C:
5391         case DRX_STANDARD_ITU_B:
5392                 ingain_tgt_max = 5119;
5393                 clp_sum_max = 1023;
5394                 clp_dir_to = (u16) (-5);
5395                 sns_sum_max = 127;
5396                 sns_dir_to = (u16) (-3);
5397                 ki_innergain_min = 0;
5398                 ki_max = 0x0657;
5399                 if_iaccu_hi_tgt_min = 2047;
5400                 agc_ki_dgain = 0x7;
5401                 ki_min = 0x0117;
5402                 clp_ctrl_mode = 0;
5403                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 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_KI_MAXGAIN__A, 0x0, 0);
5409                 if (rc != 0) {
5410                         pr_err("error %d\n", rc);
5411                         goto rw_error;
5412                 }
5413                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
5414                 if (rc != 0) {
5415                         pr_err("error %d\n", rc);
5416                         goto rw_error;
5417                 }
5418                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
5419                 if (rc != 0) {
5420                         pr_err("error %d\n", rc);
5421                         goto rw_error;
5422                 }
5423                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
5424                 if (rc != 0) {
5425                         pr_err("error %d\n", rc);
5426                         goto rw_error;
5427                 }
5428                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
5429                 if (rc != 0) {
5430                         pr_err("error %d\n", rc);
5431                         goto rw_error;
5432                 }
5433                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
5434                 if (rc != 0) {
5435                         pr_err("error %d\n", rc);
5436                         goto rw_error;
5437                 }
5438                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
5439                 if (rc != 0) {
5440                         pr_err("error %d\n", rc);
5441                         goto rw_error;
5442                 }
5443                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
5444                 if (rc != 0) {
5445                         pr_err("error %d\n", rc);
5446                         goto rw_error;
5447                 }
5448                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
5449                 if (rc != 0) {
5450                         pr_err("error %d\n", rc);
5451                         goto rw_error;
5452                 }
5453                 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
5454                 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
5455                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5456                 if (rc != 0) {
5457                         pr_err("error %d\n", rc);
5458                         goto rw_error;
5459                 }
5460
5461                 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
5462                 if (rc != 0) {
5463                         pr_err("error %d\n", rc);
5464                         goto rw_error;
5465                 }
5466                 agc_ki &= 0xf000;
5467                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
5468                 if (rc != 0) {
5469                         pr_err("error %d\n", rc);
5470                         goto rw_error;
5471                 }
5472                 break;
5473 #endif
5474 #ifndef DRXJ_DIGITAL_ONLY
5475         case DRX_STANDARD_FM:
5476                 clp_sum_max = 1023;
5477                 sns_sum_max = 1023;
5478                 ki_innergain_min = (u16) (-32768);
5479                 if_iaccu_hi_tgt_min = 2047;
5480                 agc_ki_dgain = 0x7;
5481                 ki_min = 0x0225;
5482                 ki_max = 0x0547;
5483                 clp_dir_to = (u16) (-9);
5484                 sns_dir_to = (u16) (-9);
5485                 ingain_tgt_max = 9000;
5486                 clp_ctrl_mode = 1;
5487                 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5488                 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5489                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5490                 if (rc != 0) {
5491                         pr_err("error %d\n", rc);
5492                         goto rw_error;
5493                 }
5494                 break;
5495         case DRX_STANDARD_NTSC:
5496         case DRX_STANDARD_PAL_SECAM_BG:
5497         case DRX_STANDARD_PAL_SECAM_DK:
5498         case DRX_STANDARD_PAL_SECAM_I:
5499                 clp_sum_max = 1023;
5500                 sns_sum_max = 1023;
5501                 ki_innergain_min = (u16) (-32768);
5502                 if_iaccu_hi_tgt_min = 2047;
5503                 agc_ki_dgain = 0x7;
5504                 ki_min = 0x0225;
5505                 ki_max = 0x0547;
5506                 clp_dir_to = (u16) (-9);
5507                 ingain_tgt_max = 9000;
5508                 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5509                 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5510                 sns_dir_to = (u16) (-9);
5511                 clp_ctrl_mode = 1;
5512                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5513                 if (rc != 0) {
5514                         pr_err("error %d\n", rc);
5515                         goto rw_error;
5516                 }
5517                 break;
5518         case DRX_STANDARD_PAL_SECAM_L:
5519         case DRX_STANDARD_PAL_SECAM_LP:
5520                 clp_sum_max = 1023;
5521                 sns_sum_max = 1023;
5522                 ki_innergain_min = (u16) (-32768);
5523                 if_iaccu_hi_tgt_min = 2047;
5524                 agc_ki_dgain = 0x7;
5525                 ki_min = 0x0225;
5526                 ki_max = 0x0547;
5527                 clp_dir_to = (u16) (-9);
5528                 sns_dir_to = (u16) (-9);
5529                 ingain_tgt_max = 9000;
5530                 clp_ctrl_mode = 1;
5531                 p_agc_if_settings = &(ext_attr->atv_if_agc_cfg);
5532                 p_agc_rf_settings = &(ext_attr->atv_rf_agc_cfg);
5533                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
5534                 if (rc != 0) {
5535                         pr_err("error %d\n", rc);
5536                         goto rw_error;
5537                 }
5538                 break;
5539 #endif
5540         default:
5541                 return -EINVAL;
5542         }
5543
5544         /* for new AGC interface */
5545         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 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_INGAIN__A, p_agc_if_settings->top, 0);
5551         if (rc != 0) {
5552                 pr_err("error %d\n", rc);
5553                 goto rw_error;
5554         }       /* Gain fed from inner to outer AGC */
5555         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_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_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_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_IF_IACCU_HI__A, 0, 0);
5566         if (rc != 0) {
5567                 pr_err("error %d\n", rc);
5568                 goto rw_error;
5569         }       /* set to p_agc_settings->top before */
5570         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 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_RF_IACCU_HI__A, 0, 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_RF_IACCU_LO__A, 0, 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_RF_MAX__A, 32767, 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_CLP_SUM_MAX__A, clp_sum_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_SNS_SUM_MAX__A, sns_sum_max, 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_KI_INNERGAIN_MIN__A, ki_innergain_min, 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_FAST_SNS_CTRL_DELAY__A, 50, 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_KI_CYCLEN__A, 500, 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_CYCLEN__A, 500, 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_KI_MAXMINGAIN_TH__A, 20, 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_KI_MIN__A, ki_min, 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_KI_MAX__A, ki_max, 0);
5631         if (rc != 0) {
5632                 pr_err("error %d\n", rc);
5633                 goto rw_error;
5634         }
5635         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
5636         if (rc != 0) {
5637                 pr_err("error %d\n", rc);
5638                 goto rw_error;
5639         }
5640         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
5641         if (rc != 0) {
5642                 pr_err("error %d\n", rc);
5643                 goto rw_error;
5644         }
5645         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
5646         if (rc != 0) {
5647                 pr_err("error %d\n", rc);
5648                 goto rw_error;
5649         }
5650         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
5651         if (rc != 0) {
5652                 pr_err("error %d\n", rc);
5653                 goto rw_error;
5654         }
5655         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
5656         if (rc != 0) {
5657                 pr_err("error %d\n", rc);
5658                 goto rw_error;
5659         }
5660         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
5661         if (rc != 0) {
5662                 pr_err("error %d\n", rc);
5663                 goto rw_error;
5664         }
5665         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
5666         if (rc != 0) {
5667                 pr_err("error %d\n", rc);
5668                 goto rw_error;
5669         }
5670         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
5671         if (rc != 0) {
5672                 pr_err("error %d\n", rc);
5673                 goto rw_error;
5674         }
5675
5676         agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
5677         if (common_attr->tuner_rf_agc_pol == true)
5678                 agc_rf = 0x87ff - agc_rf;
5679
5680         agc_if = 0x800;
5681         if (common_attr->tuner_if_agc_pol == true)
5682                 agc_rf = 0x87ff - agc_rf;
5683
5684         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
5685         if (rc != 0) {
5686                 pr_err("error %d\n", rc);
5687                 goto rw_error;
5688         }
5689         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
5690         if (rc != 0) {
5691                 pr_err("error %d\n", rc);
5692                 goto rw_error;
5693         }
5694
5695         /* Set/restore Ki DGAIN factor */
5696         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5697         if (rc != 0) {
5698                 pr_err("error %d\n", rc);
5699                 goto rw_error;
5700         }
5701         data &= ~SCU_RAM_AGC_KI_DGAIN__M;
5702         data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
5703         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5704         if (rc != 0) {
5705                 pr_err("error %d\n", rc);
5706                 goto rw_error;
5707         }
5708
5709         return 0;
5710 rw_error:
5711         return -EIO;
5712 }
5713
5714 /**
5715 * \fn int set_frequency ()
5716 * \brief Set frequency shift.
5717 * \param demod instance of demodulator.
5718 * \param channel pointer to channel data.
5719 * \param tuner_freq_offset residual frequency from tuner.
5720 * \return int.
5721 */
5722 static int
5723 set_frequency(struct drx_demod_instance *demod,
5724               struct drx_channel *channel, s32 tuner_freq_offset)
5725 {
5726         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5727         struct drxj_data *ext_attr = demod->my_ext_attr;
5728         int rc;
5729         s32 sampling_frequency = 0;
5730         s32 frequency_shift = 0;
5731         s32 if_freq_actual = 0;
5732         s32 rf_freq_residual = -1 * tuner_freq_offset;
5733         s32 adc_freq = 0;
5734         s32 intermediate_freq = 0;
5735         u32 iqm_fs_rate_ofs = 0;
5736         bool adc_flip = true;
5737         bool select_pos_image = false;
5738         bool rf_mirror;
5739         bool tuner_mirror;
5740         bool image_to_select = true;
5741         s32 fm_frequency_shift = 0;
5742
5743         rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
5744         tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
5745         /*
5746            Program frequency shifter
5747            No need to account for mirroring on RF
5748          */
5749         switch (ext_attr->standard) {
5750         case DRX_STANDARD_ITU_A:        /* fallthrough */
5751         case DRX_STANDARD_ITU_C:        /* fallthrough */
5752         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
5753         case DRX_STANDARD_8VSB:
5754                 select_pos_image = true;
5755                 break;
5756         case DRX_STANDARD_FM:
5757                 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
5758                    Sound carrier is already 3Mhz above centre frequency due
5759                    to tuner setting so now add an extra shift of 1MHz... */
5760                 fm_frequency_shift = 1000;
5761         case DRX_STANDARD_ITU_B:        /* fallthrough */
5762         case DRX_STANDARD_NTSC: /* fallthrough */
5763         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
5764         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
5765         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
5766         case DRX_STANDARD_PAL_SECAM_L:
5767                 select_pos_image = false;
5768                 break;
5769         default:
5770                 return -EINVAL;
5771         }
5772         intermediate_freq = demod->my_common_attr->intermediate_freq;
5773         sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
5774         if (tuner_mirror)
5775                 if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
5776         else
5777                 if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
5778         if (if_freq_actual > sampling_frequency / 2) {
5779                 /* adc mirrors */
5780                 adc_freq = sampling_frequency - if_freq_actual;
5781                 adc_flip = true;
5782         } else {
5783                 /* adc doesn't mirror */
5784                 adc_freq = if_freq_actual;
5785                 adc_flip = false;
5786         }
5787
5788         frequency_shift = adc_freq;
5789         image_to_select =
5790             (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
5791         iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
5792
5793         if (image_to_select)
5794                 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
5795
5796         /* Program frequency shifter with tuner offset compensation */
5797         /* frequency_shift += tuner_freq_offset; TODO */
5798         rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
5799         if (rc != 0) {
5800                 pr_err("error %d\n", rc);
5801                 goto rw_error;
5802         }
5803         ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
5804         ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
5805
5806         return 0;
5807 rw_error:
5808         return -EIO;
5809 }
5810
5811 /**
5812 * \fn int get_sig_strength()
5813 * \brief Retrieve signal strength for VSB and QAM.
5814 * \param demod Pointer to demod instance
5815 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
5816 * \return int.
5817 * \retval 0 sig_strength contains valid data.
5818 * \retval -EINVAL sig_strength is NULL.
5819 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5820 */
5821 #define DRXJ_AGC_TOP    0x2800
5822 #define DRXJ_AGC_SNS    0x1600
5823 #define DRXJ_RFAGC_MAX  0x3fff
5824 #define DRXJ_RFAGC_MIN  0x800
5825
5826 static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
5827 {
5828         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5829         int rc;
5830         u16 rf_gain = 0;
5831         u16 if_gain = 0;
5832         u16 if_agc_sns = 0;
5833         u16 if_agc_top = 0;
5834         u16 rf_agc_max = 0;
5835         u16 rf_agc_min = 0;
5836
5837         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
5838         if (rc != 0) {
5839                 pr_err("error %d\n", rc);
5840                 goto rw_error;
5841         }
5842         if_gain &= IQM_AF_AGC_IF__M;
5843         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
5844         if (rc != 0) {
5845                 pr_err("error %d\n", rc);
5846                 goto rw_error;
5847         }
5848         rf_gain &= IQM_AF_AGC_RF__M;
5849
5850         if_agc_sns = DRXJ_AGC_SNS;
5851         if_agc_top = DRXJ_AGC_TOP;
5852         rf_agc_max = DRXJ_RFAGC_MAX;
5853         rf_agc_min = DRXJ_RFAGC_MIN;
5854
5855         if (if_gain > if_agc_top) {
5856                 if (rf_gain > rf_agc_max)
5857                         *sig_strength = 100;
5858                 else if (rf_gain > rf_agc_min) {
5859                         if (rf_agc_max == rf_agc_min) {
5860                                 pr_err("error: rf_agc_max == rf_agc_min\n");
5861                                 return -EIO;
5862                         }
5863                         *sig_strength =
5864                             75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
5865                                                              rf_agc_min);
5866                 } else
5867                         *sig_strength = 75;
5868         } else if (if_gain > if_agc_sns) {
5869                 if (if_agc_top == if_agc_sns) {
5870                         pr_err("error: if_agc_top == if_agc_sns\n");
5871                         return -EIO;
5872                 }
5873                 *sig_strength =
5874                     20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
5875         } else {
5876                 if (!if_agc_sns) {
5877                         pr_err("error: if_agc_sns is zero!\n");
5878                         return -EIO;
5879                 }
5880                 *sig_strength = (20 * if_gain / if_agc_sns);
5881         }
5882
5883         return 0;
5884 rw_error:
5885         return -EIO;
5886 }
5887
5888 /**
5889 * \fn int get_acc_pkt_err()
5890 * \brief Retrieve signal strength for VSB and QAM.
5891 * \param demod Pointer to demod instance
5892 * \param packet_err Pointer to packet error
5893 * \return int.
5894 * \retval 0 sig_strength contains valid data.
5895 * \retval -EINVAL sig_strength is NULL.
5896 * \retval -EIO Erroneous data, sig_strength contains invalid data.
5897 */
5898 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5899 static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
5900 {
5901         int rc;
5902         static u16 pkt_err;
5903         static u16 last_pkt_err;
5904         u16 data = 0;
5905         struct drxj_data *ext_attr = NULL;
5906         struct i2c_device_addr *dev_addr = NULL;
5907
5908         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5909         dev_addr = demod->my_i2c_dev_addr;
5910
5911         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
5912         if (rc != 0) {
5913                 pr_err("error %d\n", rc);
5914                 goto rw_error;
5915         }
5916         if (ext_attr->reset_pkt_err_acc) {
5917                 last_pkt_err = data;
5918                 pkt_err = 0;
5919                 ext_attr->reset_pkt_err_acc = false;
5920         }
5921
5922         if (data < last_pkt_err) {
5923                 pkt_err += 0xffff - last_pkt_err;
5924                 pkt_err += data;
5925         } else {
5926                 pkt_err += (data - last_pkt_err);
5927         }
5928         *packet_err = pkt_err;
5929         last_pkt_err = data;
5930
5931         return 0;
5932 rw_error:
5933         return -EIO;
5934 }
5935 #endif
5936
5937 /**
5938 * \fn int ResetAccPktErr()
5939 * \brief Reset Accumulating packet error count.
5940 * \param demod Pointer to demod instance
5941 * \return int.
5942 * \retval 0.
5943 * \retval -EIO Erroneous data.
5944 */
5945 static int ctrl_set_cfg_reset_pkt_err(struct drx_demod_instance *demod)
5946 {
5947 #ifdef DRXJ_SIGNAL_ACCUM_ERR
5948         struct drxj_data *ext_attr = NULL;
5949         int rc;
5950         u16 packet_error = 0;
5951
5952         ext_attr = (struct drxj_data *) demod->my_ext_attr;
5953         ext_attr->reset_pkt_err_acc = true;
5954         /* call to reset counter */
5955         rc = get_acc_pkt_err(demod, &packet_error);
5956         if (rc != 0) {
5957                 pr_err("error %d\n", rc);
5958                 goto rw_error;
5959         }
5960
5961         return 0;
5962 rw_error:
5963 #endif
5964         return -EIO;
5965 }
5966
5967 /**
5968 * \fn static short get_str_freq_offset()
5969 * \brief Get symbol rate offset in QAM & 8VSB mode
5970 * \return Error code
5971 */
5972 static int get_str_freq_offset(struct drx_demod_instance *demod, s32 *str_freq)
5973 {
5974         int rc;
5975         u32 symbol_frequency_ratio = 0;
5976         u32 symbol_nom_frequency_ratio = 0;
5977
5978         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5979         struct drxj_data *ext_attr = demod->my_ext_attr;
5980
5981         rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &symbol_frequency_ratio, 0);
5982         if (rc != 0) {
5983                 pr_err("error %d\n", rc);
5984                 goto rw_error;
5985         }
5986         symbol_nom_frequency_ratio = ext_attr->iqm_rc_rate_ofs;
5987
5988         if (symbol_frequency_ratio > symbol_nom_frequency_ratio)
5989                 *str_freq =
5990                     -1 *
5991                     frac_times1e6((symbol_frequency_ratio -
5992                                   symbol_nom_frequency_ratio),
5993                                  (symbol_frequency_ratio + (1 << 23)));
5994         else
5995                 *str_freq =
5996                     frac_times1e6((symbol_nom_frequency_ratio -
5997                                   symbol_frequency_ratio),
5998                                  (symbol_frequency_ratio + (1 << 23)));
5999
6000         return 0;
6001 rw_error:
6002         return -EIO;
6003 }
6004
6005 /**
6006 * \fn static short get_ctl_freq_offset
6007 * \brief Get the value of ctl_freq in QAM & ATSC mode
6008 * \return Error code
6009 */
6010 static int get_ctl_freq_offset(struct drx_demod_instance *demod, s32 *ctl_freq)
6011 {
6012         s32 sampling_frequency = 0;
6013         s32 current_frequency = 0;
6014         s32 nominal_frequency = 0;
6015         s32 carrier_frequency_shift = 0;
6016         s32 sign = 1;
6017         u32 data64hi = 0;
6018         u32 data64lo = 0;
6019         struct drxj_data *ext_attr = NULL;
6020         struct drx_common_attr *common_attr = NULL;
6021         struct i2c_device_addr *dev_addr = NULL;
6022         int rc;
6023
6024         dev_addr = demod->my_i2c_dev_addr;
6025         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6026         common_attr = (struct drx_common_attr *) demod->my_common_attr;
6027
6028         sampling_frequency = common_attr->sys_clock_freq / 3;
6029
6030         /* both registers are sign extended */
6031         nominal_frequency = ext_attr->iqm_fs_rate_ofs;
6032         rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, (u32 *)&current_frequency, 0);
6033         if (rc != 0) {
6034                 pr_err("error %d\n", rc);
6035                 goto rw_error;
6036         }
6037
6038         if (ext_attr->pos_image) {
6039                 /* negative image */
6040                 carrier_frequency_shift = nominal_frequency - current_frequency;
6041         } else {
6042                 /* positive image */
6043                 carrier_frequency_shift = current_frequency - nominal_frequency;
6044         }
6045
6046         /* carrier Frequency Shift In Hz */
6047         if (carrier_frequency_shift < 0) {
6048                 sign = -1;
6049                 carrier_frequency_shift *= sign;
6050         }
6051
6052         /* *ctl_freq = carrier_frequency_shift * 50.625e6 / (1 << 28); */
6053         mult32(carrier_frequency_shift, sampling_frequency, &data64hi, &data64lo);
6054         *ctl_freq =
6055             (s32) ((((data64lo >> 28) & 0xf) | (data64hi << 4)) * sign);
6056
6057         return 0;
6058 rw_error:
6059         return -EIO;
6060 }
6061
6062 /*============================================================================*/
6063
6064 /**
6065 * \fn int set_agc_rf ()
6066 * \brief Configure RF AGC
6067 * \param demod instance of demodulator.
6068 * \param agc_settings AGC configuration structure
6069 * \return int.
6070 */
6071 static int
6072 set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
6073 {
6074         struct i2c_device_addr *dev_addr = NULL;
6075         struct drxj_data *ext_attr = NULL;
6076         struct drxj_cfg_agc *p_agc_settings = NULL;
6077         struct drx_common_attr *common_attr = NULL;
6078         int rc;
6079         drx_write_reg16func_t scu_wr16 = NULL;
6080         drx_read_reg16func_t scu_rr16 = NULL;
6081
6082         common_attr = (struct drx_common_attr *) demod->my_common_attr;
6083         dev_addr = demod->my_i2c_dev_addr;
6084         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6085
6086         if (atomic) {
6087                 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
6088                 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
6089         } else {
6090                 scu_rr16 = DRXJ_DAP.read_reg16func;
6091                 scu_wr16 = DRXJ_DAP.write_reg16func;
6092         }
6093
6094         /* Configure AGC only if standard is currently active */
6095         if ((ext_attr->standard == agc_settings->standard) ||
6096             (DRXJ_ISQAMSTD(ext_attr->standard) &&
6097              DRXJ_ISQAMSTD(agc_settings->standard)) ||
6098             (DRXJ_ISATVSTD(ext_attr->standard) &&
6099              DRXJ_ISATVSTD(agc_settings->standard))) {
6100                 u16 data = 0;
6101
6102                 switch (agc_settings->ctrl_mode) {
6103                 case DRX_AGC_CTRL_AUTO:
6104
6105                         /* Enable RF AGC DAC */
6106                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6107                         if (rc != 0) {
6108                                 pr_err("error %d\n", rc);
6109                                 goto rw_error;
6110                         }
6111                         data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
6112                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6113                         if (rc != 0) {
6114                                 pr_err("error %d\n", rc);
6115                                 goto rw_error;
6116                         }
6117
6118                         /* Enable SCU RF AGC loop */
6119                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6120                         if (rc != 0) {
6121                                 pr_err("error %d\n", rc);
6122                                 goto rw_error;
6123                         }
6124                         data &= ~SCU_RAM_AGC_KI_RF__M;
6125                         if (ext_attr->standard == DRX_STANDARD_8VSB)
6126                                 data |= (2 << SCU_RAM_AGC_KI_RF__B);
6127                         else if (DRXJ_ISQAMSTD(ext_attr->standard))
6128                                 data |= (5 << SCU_RAM_AGC_KI_RF__B);
6129                         else
6130                                 data |= (4 << SCU_RAM_AGC_KI_RF__B);
6131
6132                         if (common_attr->tuner_rf_agc_pol)
6133                                 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
6134                         else
6135                                 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
6136                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6137                         if (rc != 0) {
6138                                 pr_err("error %d\n", rc);
6139                                 goto rw_error;
6140                         }
6141
6142                         /* Set speed ( using complementary reduction value ) */
6143                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
6144                         if (rc != 0) {
6145                                 pr_err("error %d\n", rc);
6146                                 goto rw_error;
6147                         }
6148                         data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
6149                         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);
6150                         if (rc != 0) {
6151                                 pr_err("error %d\n", rc);
6152                                 goto rw_error;
6153                         }
6154
6155                         if (agc_settings->standard == DRX_STANDARD_8VSB)
6156                                 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
6157                         else if (DRXJ_ISQAMSTD(agc_settings->standard))
6158                                 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
6159                         else if (DRXJ_ISATVSTD(agc_settings->standard))
6160                                 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
6161                         else
6162                                 return -EINVAL;
6163
6164                         /* Set TOP, only if IF-AGC is in AUTO mode */
6165                         if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
6166                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
6167                                 if (rc != 0) {
6168                                         pr_err("error %d\n", rc);
6169                                         goto rw_error;
6170                                 }
6171                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
6172                                 if (rc != 0) {
6173                                         pr_err("error %d\n", rc);
6174                                         goto rw_error;
6175                                 }
6176                         }
6177
6178                         /* Cut-Off current */
6179                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
6180                         if (rc != 0) {
6181                                 pr_err("error %d\n", rc);
6182                                 goto rw_error;
6183                         }
6184                         break;
6185                 case DRX_AGC_CTRL_USER:
6186
6187                         /* Enable RF AGC DAC */
6188                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6189                         if (rc != 0) {
6190                                 pr_err("error %d\n", rc);
6191                                 goto rw_error;
6192                         }
6193                         data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
6194                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6195                         if (rc != 0) {
6196                                 pr_err("error %d\n", rc);
6197                                 goto rw_error;
6198                         }
6199
6200                         /* Disable SCU RF AGC loop */
6201                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6202                         if (rc != 0) {
6203                                 pr_err("error %d\n", rc);
6204                                 goto rw_error;
6205                         }
6206                         data &= ~SCU_RAM_AGC_KI_RF__M;
6207                         if (common_attr->tuner_rf_agc_pol)
6208                                 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
6209                         else
6210                                 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
6211                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6212                         if (rc != 0) {
6213                                 pr_err("error %d\n", rc);
6214                                 goto rw_error;
6215                         }
6216
6217                         /* Write value to output pin */
6218                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
6219                         if (rc != 0) {
6220                                 pr_err("error %d\n", rc);
6221                                 goto rw_error;
6222                         }
6223                         break;
6224                 case DRX_AGC_CTRL_OFF:
6225
6226                         /* Disable RF AGC DAC */
6227                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6228                         if (rc != 0) {
6229                                 pr_err("error %d\n", rc);
6230                                 goto rw_error;
6231                         }
6232                         data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
6233                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6234                         if (rc != 0) {
6235                                 pr_err("error %d\n", rc);
6236                                 goto rw_error;
6237                         }
6238
6239                         /* Disable SCU RF AGC loop */
6240                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6241                         if (rc != 0) {
6242                                 pr_err("error %d\n", rc);
6243                                 goto rw_error;
6244                         }
6245                         data &= ~SCU_RAM_AGC_KI_RF__M;
6246                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6247                         if (rc != 0) {
6248                                 pr_err("error %d\n", rc);
6249                                 goto rw_error;
6250                         }
6251                         break;
6252                 default:
6253                         return -EINVAL;
6254                 }               /* switch ( agcsettings->ctrl_mode ) */
6255         }
6256
6257         /* Store rf agc settings */
6258         switch (agc_settings->standard) {
6259         case DRX_STANDARD_8VSB:
6260                 ext_attr->vsb_rf_agc_cfg = *agc_settings;
6261                 break;
6262 #ifndef DRXJ_VSB_ONLY
6263         case DRX_STANDARD_ITU_A:
6264         case DRX_STANDARD_ITU_B:
6265         case DRX_STANDARD_ITU_C:
6266                 ext_attr->qam_rf_agc_cfg = *agc_settings;
6267                 break;
6268 #endif
6269 #ifndef DRXJ_DIGITAL_ONLY
6270         case DRX_STANDARD_PAL_SECAM_BG:
6271         case DRX_STANDARD_PAL_SECAM_DK:
6272         case DRX_STANDARD_PAL_SECAM_I:
6273         case DRX_STANDARD_PAL_SECAM_L:
6274         case DRX_STANDARD_PAL_SECAM_LP:
6275         case DRX_STANDARD_NTSC:
6276         case DRX_STANDARD_FM:
6277                 ext_attr->atv_rf_agc_cfg = *agc_settings;
6278                 break;
6279 #endif
6280         default:
6281                 return -EIO;
6282         }
6283
6284         return 0;
6285 rw_error:
6286         return -EIO;
6287 }
6288
6289 /**
6290 * \fn int get_agc_rf ()
6291 * \brief get configuration of RF AGC
6292 * \param demod instance of demodulator.
6293 * \param agc_settings AGC configuration structure
6294 * \return int.
6295 */
6296 static int
6297 get_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6298 {
6299         struct i2c_device_addr *dev_addr = NULL;
6300         struct drxj_data *ext_attr = NULL;
6301         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6302         int rc;
6303
6304         dev_addr = demod->my_i2c_dev_addr;
6305         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6306
6307         /* Return stored AGC settings */
6308         standard = agc_settings->standard;
6309         switch (agc_settings->standard) {
6310         case DRX_STANDARD_8VSB:
6311                 *agc_settings = ext_attr->vsb_rf_agc_cfg;
6312                 break;
6313 #ifndef DRXJ_VSB_ONLY
6314         case DRX_STANDARD_ITU_A:
6315         case DRX_STANDARD_ITU_B:
6316         case DRX_STANDARD_ITU_C:
6317                 *agc_settings = ext_attr->qam_rf_agc_cfg;
6318                 break;
6319 #endif
6320 #ifndef DRXJ_DIGITAL_ONLY
6321         case DRX_STANDARD_PAL_SECAM_BG:
6322         case DRX_STANDARD_PAL_SECAM_DK:
6323         case DRX_STANDARD_PAL_SECAM_I:
6324         case DRX_STANDARD_PAL_SECAM_L:
6325         case DRX_STANDARD_PAL_SECAM_LP:
6326         case DRX_STANDARD_NTSC:
6327         case DRX_STANDARD_FM:
6328                 *agc_settings = ext_attr->atv_rf_agc_cfg;
6329                 break;
6330 #endif
6331         default:
6332                 return -EIO;
6333         }
6334         agc_settings->standard = standard;
6335
6336         /* Get AGC output only if standard is currently active. */
6337         if ((ext_attr->standard == agc_settings->standard) ||
6338             (DRXJ_ISQAMSTD(ext_attr->standard) &&
6339              DRXJ_ISQAMSTD(agc_settings->standard)) ||
6340             (DRXJ_ISATVSTD(ext_attr->standard) &&
6341              DRXJ_ISATVSTD(agc_settings->standard))) {
6342                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, &(agc_settings->output_level), 0);
6343                 if (rc != 0) {
6344                         pr_err("error %d\n", rc);
6345                         goto rw_error;
6346                 }
6347         }
6348
6349         return 0;
6350 rw_error:
6351         return -EIO;
6352 }
6353
6354 /**
6355 * \fn int set_agc_if ()
6356 * \brief Configure If AGC
6357 * \param demod instance of demodulator.
6358 * \param agc_settings AGC configuration structure
6359 * \return int.
6360 */
6361 static int
6362 set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
6363 {
6364         struct i2c_device_addr *dev_addr = NULL;
6365         struct drxj_data *ext_attr = NULL;
6366         struct drxj_cfg_agc *p_agc_settings = NULL;
6367         struct drx_common_attr *common_attr = NULL;
6368         drx_write_reg16func_t scu_wr16 = NULL;
6369         drx_read_reg16func_t scu_rr16 = NULL;
6370         int rc;
6371
6372         common_attr = (struct drx_common_attr *) demod->my_common_attr;
6373         dev_addr = demod->my_i2c_dev_addr;
6374         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6375
6376         if (atomic) {
6377                 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
6378                 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
6379         } else {
6380                 scu_rr16 = DRXJ_DAP.read_reg16func;
6381                 scu_wr16 = DRXJ_DAP.write_reg16func;
6382         }
6383
6384         /* Configure AGC only if standard is currently active */
6385         if ((ext_attr->standard == agc_settings->standard) ||
6386             (DRXJ_ISQAMSTD(ext_attr->standard) &&
6387              DRXJ_ISQAMSTD(agc_settings->standard)) ||
6388             (DRXJ_ISATVSTD(ext_attr->standard) &&
6389              DRXJ_ISATVSTD(agc_settings->standard))) {
6390                 u16 data = 0;
6391
6392                 switch (agc_settings->ctrl_mode) {
6393                 case DRX_AGC_CTRL_AUTO:
6394                         /* Enable IF AGC DAC */
6395                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6396                         if (rc != 0) {
6397                                 pr_err("error %d\n", rc);
6398                                 goto rw_error;
6399                         }
6400                         data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
6401                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6402                         if (rc != 0) {
6403                                 pr_err("error %d\n", rc);
6404                                 goto rw_error;
6405                         }
6406
6407                         /* Enable SCU IF AGC loop */
6408                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6409                         if (rc != 0) {
6410                                 pr_err("error %d\n", rc);
6411                                 goto rw_error;
6412                         }
6413                         data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6414                         data &= ~SCU_RAM_AGC_KI_IF__M;
6415                         if (ext_attr->standard == DRX_STANDARD_8VSB)
6416                                 data |= (3 << SCU_RAM_AGC_KI_IF__B);
6417                         else if (DRXJ_ISQAMSTD(ext_attr->standard))
6418                                 data |= (6 << SCU_RAM_AGC_KI_IF__B);
6419                         else
6420                                 data |= (5 << SCU_RAM_AGC_KI_IF__B);
6421
6422                         if (common_attr->tuner_if_agc_pol)
6423                                 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
6424                         else
6425                                 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
6426                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6427                         if (rc != 0) {
6428                                 pr_err("error %d\n", rc);
6429                                 goto rw_error;
6430                         }
6431
6432                         /* Set speed (using complementary reduction value) */
6433                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
6434                         if (rc != 0) {
6435                                 pr_err("error %d\n", rc);
6436                                 goto rw_error;
6437                         }
6438                         data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
6439                         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);
6440                         if (rc != 0) {
6441                                 pr_err("error %d\n", rc);
6442                                 goto rw_error;
6443                         }
6444
6445                         if (agc_settings->standard == DRX_STANDARD_8VSB)
6446                                 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
6447                         else if (DRXJ_ISQAMSTD(agc_settings->standard))
6448                                 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
6449                         else if (DRXJ_ISATVSTD(agc_settings->standard))
6450                                 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
6451                         else
6452                                 return -EINVAL;
6453
6454                         /* Restore TOP */
6455                         if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
6456                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
6457                                 if (rc != 0) {
6458                                         pr_err("error %d\n", rc);
6459                                         goto rw_error;
6460                                 }
6461                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
6462                                 if (rc != 0) {
6463                                         pr_err("error %d\n", rc);
6464                                         goto rw_error;
6465                                 }
6466                         } else {
6467                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
6468                                 if (rc != 0) {
6469                                         pr_err("error %d\n", rc);
6470                                         goto rw_error;
6471                                 }
6472                                 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
6473                                 if (rc != 0) {
6474                                         pr_err("error %d\n", rc);
6475                                         goto rw_error;
6476                                 }
6477                         }
6478                         break;
6479
6480                 case DRX_AGC_CTRL_USER:
6481
6482                         /* Enable IF AGC DAC */
6483                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6484                         if (rc != 0) {
6485                                 pr_err("error %d\n", rc);
6486                                 goto rw_error;
6487                         }
6488                         data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
6489                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6490                         if (rc != 0) {
6491                                 pr_err("error %d\n", rc);
6492                                 goto rw_error;
6493                         }
6494
6495                         /* Disable SCU IF AGC loop */
6496                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6497                         if (rc != 0) {
6498                                 pr_err("error %d\n", rc);
6499                                 goto rw_error;
6500                         }
6501                         data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6502                         data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6503                         if (common_attr->tuner_if_agc_pol)
6504                                 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
6505                         else
6506                                 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
6507                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6508                         if (rc != 0) {
6509                                 pr_err("error %d\n", rc);
6510                                 goto rw_error;
6511                         }
6512
6513                         /* Write value to output pin */
6514                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
6515                         if (rc != 0) {
6516                                 pr_err("error %d\n", rc);
6517                                 goto rw_error;
6518                         }
6519                         break;
6520
6521                 case DRX_AGC_CTRL_OFF:
6522
6523                         /* Disable If AGC DAC */
6524                         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6525                         if (rc != 0) {
6526                                 pr_err("error %d\n", rc);
6527                                 goto rw_error;
6528                         }
6529                         data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
6530                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6531                         if (rc != 0) {
6532                                 pr_err("error %d\n", rc);
6533                                 goto rw_error;
6534                         }
6535
6536                         /* Disable SCU IF AGC loop */
6537                         rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
6538                         if (rc != 0) {
6539                                 pr_err("error %d\n", rc);
6540                                 goto rw_error;
6541                         }
6542                         data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6543                         data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
6544                         rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
6545                         if (rc != 0) {
6546                                 pr_err("error %d\n", rc);
6547                                 goto rw_error;
6548                         }
6549                         break;
6550                 default:
6551                         return -EINVAL;
6552                 }               /* switch ( agcsettings->ctrl_mode ) */
6553
6554                 /* always set the top to support configurations without if-loop */
6555                 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
6556                 if (rc != 0) {
6557                         pr_err("error %d\n", rc);
6558                         goto rw_error;
6559                 }
6560         }
6561
6562         /* Store if agc settings */
6563         switch (agc_settings->standard) {
6564         case DRX_STANDARD_8VSB:
6565                 ext_attr->vsb_if_agc_cfg = *agc_settings;
6566                 break;
6567 #ifndef DRXJ_VSB_ONLY
6568         case DRX_STANDARD_ITU_A:
6569         case DRX_STANDARD_ITU_B:
6570         case DRX_STANDARD_ITU_C:
6571                 ext_attr->qam_if_agc_cfg = *agc_settings;
6572                 break;
6573 #endif
6574 #ifndef DRXJ_DIGITAL_ONLY
6575         case DRX_STANDARD_PAL_SECAM_BG:
6576         case DRX_STANDARD_PAL_SECAM_DK:
6577         case DRX_STANDARD_PAL_SECAM_I:
6578         case DRX_STANDARD_PAL_SECAM_L:
6579         case DRX_STANDARD_PAL_SECAM_LP:
6580         case DRX_STANDARD_NTSC:
6581         case DRX_STANDARD_FM:
6582                 ext_attr->atv_if_agc_cfg = *agc_settings;
6583                 break;
6584 #endif
6585         default:
6586                 return -EIO;
6587         }
6588
6589         return 0;
6590 rw_error:
6591         return -EIO;
6592 }
6593
6594 /**
6595 * \fn int get_agc_if ()
6596 * \brief get configuration of If AGC
6597 * \param demod instance of demodulator.
6598 * \param agc_settings AGC configuration structure
6599 * \return int.
6600 */
6601 static int
6602 get_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
6603 {
6604         struct i2c_device_addr *dev_addr = NULL;
6605         struct drxj_data *ext_attr = NULL;
6606         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
6607         int rc;
6608
6609         dev_addr = demod->my_i2c_dev_addr;
6610         ext_attr = (struct drxj_data *) demod->my_ext_attr;
6611
6612         /* Return stored ATV AGC settings */
6613         standard = agc_settings->standard;
6614         switch (agc_settings->standard) {
6615         case DRX_STANDARD_8VSB:
6616                 *agc_settings = ext_attr->vsb_if_agc_cfg;
6617                 break;
6618 #ifndef DRXJ_VSB_ONLY
6619         case DRX_STANDARD_ITU_A:
6620         case DRX_STANDARD_ITU_B:
6621         case DRX_STANDARD_ITU_C:
6622                 *agc_settings = ext_attr->qam_if_agc_cfg;
6623                 break;
6624 #endif
6625 #ifndef DRXJ_DIGITAL_ONLY
6626         case DRX_STANDARD_PAL_SECAM_BG:
6627         case DRX_STANDARD_PAL_SECAM_DK:
6628         case DRX_STANDARD_PAL_SECAM_I:
6629         case DRX_STANDARD_PAL_SECAM_L:
6630         case DRX_STANDARD_PAL_SECAM_LP:
6631         case DRX_STANDARD_NTSC:
6632         case DRX_STANDARD_FM:
6633                 *agc_settings = ext_attr->atv_if_agc_cfg;
6634                 break;
6635 #endif
6636         default:
6637                 return -EIO;
6638         }
6639         agc_settings->standard = standard;
6640
6641         /* Get AGC output only if standard is currently active */
6642         if ((ext_attr->standard == agc_settings->standard) ||
6643             (DRXJ_ISQAMSTD(ext_attr->standard) &&
6644              DRXJ_ISQAMSTD(agc_settings->standard)) ||
6645             (DRXJ_ISATVSTD(ext_attr->standard) &&
6646              DRXJ_ISATVSTD(agc_settings->standard))) {
6647                 /* read output level */
6648                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, &(agc_settings->output_level), 0);
6649                 if (rc != 0) {
6650                         pr_err("error %d\n", rc);
6651                         goto rw_error;
6652                 }
6653         }
6654
6655         return 0;
6656 rw_error:
6657         return -EIO;
6658 }
6659
6660 /**
6661 * \fn int set_iqm_af ()
6662 * \brief Configure IQM AF registers
6663 * \param demod instance of demodulator.
6664 * \param active
6665 * \return int.
6666 */
6667 static int set_iqm_af(struct drx_demod_instance *demod, bool active)
6668 {
6669         u16 data = 0;
6670         struct i2c_device_addr *dev_addr = NULL;
6671         int rc;
6672
6673         dev_addr = demod->my_i2c_dev_addr;
6674
6675         /* Configure IQM */
6676         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_STDBY__A, &data, 0);
6677         if (rc != 0) {
6678                 pr_err("error %d\n", rc);
6679                 goto rw_error;
6680         }
6681         if (!active)
6682                 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));
6683         else
6684                 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);
6685         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, data, 0);
6686         if (rc != 0) {
6687                 pr_err("error %d\n", rc);
6688                 goto rw_error;
6689         }
6690
6691         return 0;
6692 rw_error:
6693         return -EIO;
6694 }
6695
6696 /*============================================================================*/
6697 /*==              END 8VSB & QAM COMMON DATAPATH FUNCTIONS                  ==*/
6698 /*============================================================================*/
6699
6700 /*============================================================================*/
6701 /*============================================================================*/
6702 /*==                       8VSB DATAPATH FUNCTIONS                          ==*/
6703 /*============================================================================*/
6704 /*============================================================================*/
6705
6706 /**
6707 * \fn int power_down_vsb ()
6708 * \brief Powr down QAM related blocks.
6709 * \param demod instance of demodulator.
6710 * \param channel pointer to channel data.
6711 * \return int.
6712 */
6713 static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
6714 {
6715         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6716         struct drxjscu_cmd cmd_scu = { /* command     */ 0,
6717                 /* parameter_len */ 0,
6718                 /* result_len    */ 0,
6719                 /* *parameter   */ NULL,
6720                 /* *result      */ NULL
6721         };
6722         struct drx_cfg_mpeg_output cfg_mpeg_output;
6723         int rc;
6724         u16 cmd_result = 0;
6725
6726         /*
6727            STOP demodulator
6728            reset of FEC and VSB HW
6729          */
6730         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
6731             SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6732         cmd_scu.parameter_len = 0;
6733         cmd_scu.result_len = 1;
6734         cmd_scu.parameter = NULL;
6735         cmd_scu.result = &cmd_result;
6736         rc = scu_command(dev_addr, &cmd_scu);
6737         if (rc != 0) {
6738                 pr_err("error %d\n", rc);
6739                 goto rw_error;
6740         }
6741
6742         /* stop all comm_exec */
6743         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
6744         if (rc != 0) {
6745                 pr_err("error %d\n", rc);
6746                 goto rw_error;
6747         }
6748         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
6749         if (rc != 0) {
6750                 pr_err("error %d\n", rc);
6751                 goto rw_error;
6752         }
6753         if (primary) {
6754                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
6755                 if (rc != 0) {
6756                         pr_err("error %d\n", rc);
6757                         goto rw_error;
6758                 }
6759                 rc = set_iqm_af(demod, false);
6760                 if (rc != 0) {
6761                         pr_err("error %d\n", rc);
6762                         goto rw_error;
6763                 }
6764         } else {
6765                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
6766                 if (rc != 0) {
6767                         pr_err("error %d\n", rc);
6768                         goto rw_error;
6769                 }
6770                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
6771                 if (rc != 0) {
6772                         pr_err("error %d\n", rc);
6773                         goto rw_error;
6774                 }
6775                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
6776                 if (rc != 0) {
6777                         pr_err("error %d\n", rc);
6778                         goto rw_error;
6779                 }
6780                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
6781                 if (rc != 0) {
6782                         pr_err("error %d\n", rc);
6783                         goto rw_error;
6784                 }
6785                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
6786                 if (rc != 0) {
6787                         pr_err("error %d\n", rc);
6788                         goto rw_error;
6789                 }
6790         }
6791
6792         cfg_mpeg_output.enable_mpeg_output = false;
6793         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6794         if (rc != 0) {
6795                 pr_err("error %d\n", rc);
6796                 goto rw_error;
6797         }
6798
6799         return 0;
6800 rw_error:
6801         return -EIO;
6802 }
6803
6804 /**
6805 * \fn int set_vsb_leak_n_gain ()
6806 * \brief Set ATSC demod.
6807 * \param demod instance of demodulator.
6808 * \return int.
6809 */
6810 static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
6811 {
6812         struct i2c_device_addr *dev_addr = NULL;
6813         int rc;
6814
6815         const u8 vsb_ffe_leak_gain_ram0[] = {
6816                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO1  */
6817                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO2  */
6818                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO3  */
6819                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO4  */
6820                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO5  */
6821                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO6  */
6822                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO7  */
6823                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO8  */
6824                 DRXJ_16TO8(0xf),        /* FFETRAINLKRATIO9  */
6825                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO10  */
6826                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO11 */
6827                 DRXJ_16TO8(0x8),        /* FFETRAINLKRATIO12 */
6828                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO1 */
6829                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO2 */
6830                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO3 */
6831                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO4 */
6832                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO5 */
6833                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO6 */
6834                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO7 */
6835                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO8 */
6836                 DRXJ_16TO8(0x20),       /* FFERCA1TRAINLKRATIO9 */
6837                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO10 */
6838                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO11 */
6839                 DRXJ_16TO8(0x10),       /* FFERCA1TRAINLKRATIO12 */
6840                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO1 */
6841                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO2 */
6842                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO3 */
6843                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO4 */
6844                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO5 */
6845                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO6 */
6846                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO7 */
6847                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO8 */
6848                 DRXJ_16TO8(0x20),       /* FFERCA1DATALKRATIO9 */
6849                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO10 */
6850                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO11 */
6851                 DRXJ_16TO8(0x10),       /* FFERCA1DATALKRATIO12 */
6852                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO1 */
6853                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO2 */
6854                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO3 */
6855                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO4 */
6856                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO5 */
6857                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO6 */
6858                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO7 */
6859                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO8 */
6860                 DRXJ_16TO8(0x20),       /* FFERCA2TRAINLKRATIO9 */
6861                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO10 */
6862                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO11 */
6863                 DRXJ_16TO8(0x10),       /* FFERCA2TRAINLKRATIO12 */
6864                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO1 */
6865                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO2 */
6866                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO3 */
6867                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO4 */
6868                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO5 */
6869                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO6 */
6870                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO7 */
6871                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO8 */
6872                 DRXJ_16TO8(0x20),       /* FFERCA2DATALKRATIO9 */
6873                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO10 */
6874                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO11 */
6875                 DRXJ_16TO8(0x10),       /* FFERCA2DATALKRATIO12 */
6876                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO1 */
6877                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO2 */
6878                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO3 */
6879                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO4 */
6880                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO5 */
6881                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO6 */
6882                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO7 */
6883                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO8 */
6884                 DRXJ_16TO8(0x0e),       /* FFEDDM1TRAINLKRATIO9 */
6885                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO10 */
6886                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO11 */
6887                 DRXJ_16TO8(0x07),       /* FFEDDM1TRAINLKRATIO12 */
6888                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO1 */
6889                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO2 */
6890                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO3 */
6891                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO4 */
6892                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO5 */
6893                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO6 */
6894                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO7 */
6895                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO8 */
6896                 DRXJ_16TO8(0x0e),       /* FFEDDM1DATALKRATIO9 */
6897                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO10 */
6898                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO11 */
6899                 DRXJ_16TO8(0x07),       /* FFEDDM1DATALKRATIO12 */
6900                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO1 */
6901                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO2 */
6902                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO3 */
6903                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO4 */
6904                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO5 */
6905                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO6 */
6906                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO7 */
6907                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO8 */
6908                 DRXJ_16TO8(0x0c),       /* FFEDDM2TRAINLKRATIO9 */
6909                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO10 */
6910                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO11 */
6911                 DRXJ_16TO8(0x06),       /* FFEDDM2TRAINLKRATIO12 */
6912                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO1 */
6913                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO2 */
6914                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO3 */
6915                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO4 */
6916                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO5 */
6917                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO6 */
6918                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO7 */
6919                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO8 */
6920                 DRXJ_16TO8(0x0c),       /* FFEDDM2DATALKRATIO9 */
6921                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO10 */
6922                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO11 */
6923                 DRXJ_16TO8(0x06),       /* FFEDDM2DATALKRATIO12 */
6924                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN1 */
6925                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN2 */
6926                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN3 */
6927                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN4 */
6928                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN5 */
6929                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN6 */
6930                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN7 */
6931                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN8 */
6932                 DRXJ_16TO8(0x4040),     /* FIRTRAINGAIN9 */
6933                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN10 */
6934                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN11 */
6935                 DRXJ_16TO8(0x2020),     /* FIRTRAINGAIN12 */
6936                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN1 */
6937                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN2 */
6938                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN3 */
6939                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN4 */
6940                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN5 */
6941                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN6 */
6942                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN7 */
6943                 DRXJ_16TO8(0x1010)      /* FIRRCA1GAIN8 */
6944         };
6945
6946         const u8 vsb_ffe_leak_gain_ram1[] = {
6947                 DRXJ_16TO8(0x1010),     /* FIRRCA1GAIN9 */
6948                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN10 */
6949                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN11 */
6950                 DRXJ_16TO8(0x0808),     /* FIRRCA1GAIN12 */
6951                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN1 */
6952                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN2 */
6953                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN3 */
6954                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN4 */
6955                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN5 */
6956                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN6 */
6957                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN7 */
6958                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN8 */
6959                 DRXJ_16TO8(0x1010),     /* FIRRCA2GAIN9 */
6960                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN10 */
6961                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN11 */
6962                 DRXJ_16TO8(0x0808),     /* FIRRCA2GAIN12 */
6963                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN1 */
6964                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN2 */
6965                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN3 */
6966                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN4 */
6967                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN5 */
6968                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN6 */
6969                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN7 */
6970                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN8 */
6971                 DRXJ_16TO8(0x0606),     /* FIRDDM1GAIN9 */
6972                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN10 */
6973                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN11 */
6974                 DRXJ_16TO8(0x0303),     /* FIRDDM1GAIN12 */
6975                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN1 */
6976                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN2 */
6977                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN3 */
6978                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN4 */
6979                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN5 */
6980                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN6 */
6981                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN7 */
6982                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN8 */
6983                 DRXJ_16TO8(0x0505),     /* FIRDDM2GAIN9 */
6984                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN10 */
6985                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN11 */
6986                 DRXJ_16TO8(0x0303),     /* FIRDDM2GAIN12 */
6987                 DRXJ_16TO8(0x001f),     /* DFETRAINLKRATIO */
6988                 DRXJ_16TO8(0x01ff),     /* DFERCA1TRAINLKRATIO */
6989                 DRXJ_16TO8(0x01ff),     /* DFERCA1DATALKRATIO */
6990                 DRXJ_16TO8(0x004f),     /* DFERCA2TRAINLKRATIO */
6991                 DRXJ_16TO8(0x004f),     /* DFERCA2DATALKRATIO */
6992                 DRXJ_16TO8(0x01ff),     /* DFEDDM1TRAINLKRATIO */
6993                 DRXJ_16TO8(0x01ff),     /* DFEDDM1DATALKRATIO */
6994                 DRXJ_16TO8(0x0352),     /* DFEDDM2TRAINLKRATIO */
6995                 DRXJ_16TO8(0x0352),     /* DFEDDM2DATALKRATIO */
6996                 DRXJ_16TO8(0x0000),     /* DFETRAINGAIN */
6997                 DRXJ_16TO8(0x2020),     /* DFERCA1GAIN */
6998                 DRXJ_16TO8(0x1010),     /* DFERCA2GAIN */
6999                 DRXJ_16TO8(0x1818),     /* DFEDDM1GAIN */
7000                 DRXJ_16TO8(0x1212)      /* DFEDDM2GAIN */
7001         };
7002
7003         dev_addr = demod->my_i2c_dev_addr;
7004         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);
7005         if (rc != 0) {
7006                 pr_err("error %d\n", rc);
7007                 goto rw_error;
7008         }
7009         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);
7010         if (rc != 0) {
7011                 pr_err("error %d\n", rc);
7012                 goto rw_error;
7013         }
7014
7015         return 0;
7016 rw_error:
7017         return -EIO;
7018 }
7019
7020 /**
7021 * \fn int set_vsb()
7022 * \brief Set 8VSB demod.
7023 * \param demod instance of demodulator.
7024 * \return int.
7025 *
7026 */
7027 static int set_vsb(struct drx_demod_instance *demod)
7028 {
7029         struct i2c_device_addr *dev_addr = NULL;
7030         int rc;
7031         struct drx_common_attr *common_attr = NULL;
7032         struct drxjscu_cmd cmd_scu;
7033         struct drxj_data *ext_attr = NULL;
7034         u16 cmd_result = 0;
7035         u16 cmd_param = 0;
7036         const u8 vsb_taps_re[] = {
7037                 DRXJ_16TO8(-2), /* re0  */
7038                 DRXJ_16TO8(4),  /* re1  */
7039                 DRXJ_16TO8(1),  /* re2  */
7040                 DRXJ_16TO8(-4), /* re3  */
7041                 DRXJ_16TO8(1),  /* re4  */
7042                 DRXJ_16TO8(4),  /* re5  */
7043                 DRXJ_16TO8(-3), /* re6  */
7044                 DRXJ_16TO8(-3), /* re7  */
7045                 DRXJ_16TO8(6),  /* re8  */
7046                 DRXJ_16TO8(1),  /* re9  */
7047                 DRXJ_16TO8(-9), /* re10 */
7048                 DRXJ_16TO8(3),  /* re11 */
7049                 DRXJ_16TO8(12), /* re12 */
7050                 DRXJ_16TO8(-9), /* re13 */
7051                 DRXJ_16TO8(-15),        /* re14 */
7052                 DRXJ_16TO8(17), /* re15 */
7053                 DRXJ_16TO8(19), /* re16 */
7054                 DRXJ_16TO8(-29),        /* re17 */
7055                 DRXJ_16TO8(-22),        /* re18 */
7056                 DRXJ_16TO8(45), /* re19 */
7057                 DRXJ_16TO8(25), /* re20 */
7058                 DRXJ_16TO8(-70),        /* re21 */
7059                 DRXJ_16TO8(-28),        /* re22 */
7060                 DRXJ_16TO8(111),        /* re23 */
7061                 DRXJ_16TO8(30), /* re24 */
7062                 DRXJ_16TO8(-201),       /* re25 */
7063                 DRXJ_16TO8(-31),        /* re26 */
7064                 DRXJ_16TO8(629) /* re27 */
7065         };
7066
7067         dev_addr = demod->my_i2c_dev_addr;
7068         common_attr = (struct drx_common_attr *) demod->my_common_attr;
7069         ext_attr = (struct drxj_data *) demod->my_ext_attr;
7070
7071         /* stop all comm_exec */
7072         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
7073         if (rc != 0) {
7074                 pr_err("error %d\n", rc);
7075                 goto rw_error;
7076         }
7077         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
7078         if (rc != 0) {
7079                 pr_err("error %d\n", rc);
7080                 goto rw_error;
7081         }
7082         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
7083         if (rc != 0) {
7084                 pr_err("error %d\n", rc);
7085                 goto rw_error;
7086         }
7087         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
7088         if (rc != 0) {
7089                 pr_err("error %d\n", rc);
7090                 goto rw_error;
7091         }
7092         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
7093         if (rc != 0) {
7094                 pr_err("error %d\n", rc);
7095                 goto rw_error;
7096         }
7097         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 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, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
7103         if (rc != 0) {
7104                 pr_err("error %d\n", rc);
7105                 goto rw_error;
7106         }
7107
7108         /* reset demodulator */
7109         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7110             | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
7111         cmd_scu.parameter_len = 0;
7112         cmd_scu.result_len = 1;
7113         cmd_scu.parameter = NULL;
7114         cmd_scu.result = &cmd_result;
7115         rc = scu_command(dev_addr, &cmd_scu);
7116         if (rc != 0) {
7117                 pr_err("error %d\n", rc);
7118                 goto rw_error;
7119         }
7120
7121         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
7122         if (rc != 0) {
7123                 pr_err("error %d\n", rc);
7124                 goto rw_error;
7125         }
7126         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
7127         if (rc != 0) {
7128                 pr_err("error %d\n", rc);
7129                 goto rw_error;
7130         }
7131         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
7132         if (rc != 0) {
7133                 pr_err("error %d\n", rc);
7134                 goto rw_error;
7135         }
7136         ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
7137         rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
7138         if (rc != 0) {
7139                 pr_err("error %d\n", rc);
7140                 goto rw_error;
7141         }
7142         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
7143         if (rc != 0) {
7144                 pr_err("error %d\n", rc);
7145                 goto rw_error;
7146         }
7147         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
7148         if (rc != 0) {
7149                 pr_err("error %d\n", rc);
7150                 goto rw_error;
7151         }
7152
7153         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
7154         if (rc != 0) {
7155                 pr_err("error %d\n", rc);
7156                 goto rw_error;
7157         }
7158         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, 28, 0);
7159         if (rc != 0) {
7160                 pr_err("error %d\n", rc);
7161                 goto rw_error;
7162         }
7163         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
7164         if (rc != 0) {
7165                 pr_err("error %d\n", rc);
7166                 goto rw_error;
7167         }
7168         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
7169         if (rc != 0) {
7170                 pr_err("error %d\n", rc);
7171                 goto rw_error;
7172         }
7173         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
7174         if (rc != 0) {
7175                 pr_err("error %d\n", rc);
7176                 goto rw_error;
7177         }
7178         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
7179         if (rc != 0) {
7180                 pr_err("error %d\n", rc);
7181                 goto rw_error;
7182         }
7183         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE__A, 1393, 0);
7184         if (rc != 0) {
7185                 pr_err("error %d\n", rc);
7186                 goto rw_error;
7187         }
7188         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
7189         if (rc != 0) {
7190                 pr_err("error %d\n", rc);
7191                 goto rw_error;
7192         }
7193         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
7194         if (rc != 0) {
7195                 pr_err("error %d\n", rc);
7196                 goto rw_error;
7197         }
7198
7199         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
7200         if (rc != 0) {
7201                 pr_err("error %d\n", rc);
7202                 goto rw_error;
7203         }
7204         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
7205         if (rc != 0) {
7206                 pr_err("error %d\n", rc);
7207                 goto rw_error;
7208         }
7209
7210         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
7211         if (rc != 0) {
7212                 pr_err("error %d\n", rc);
7213                 goto rw_error;
7214         }       /* set higher threshold */
7215         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
7216         if (rc != 0) {
7217                 pr_err("error %d\n", rc);
7218                 goto rw_error;
7219         }       /* burst detection on   */
7220         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
7221         if (rc != 0) {
7222                 pr_err("error %d\n", rc);
7223                 goto rw_error;
7224         }       /* drop thresholds by 1 dB */
7225         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
7226         if (rc != 0) {
7227                 pr_err("error %d\n", rc);
7228                 goto rw_error;
7229         }       /* drop thresholds by 2 dB */
7230         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
7231         if (rc != 0) {
7232                 pr_err("error %d\n", rc);
7233                 goto rw_error;
7234         }       /* cma on               */
7235         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
7236         if (rc != 0) {
7237                 pr_err("error %d\n", rc);
7238                 goto rw_error;
7239         }       /* GPIO               */
7240
7241         /* Initialize the FEC Subsystem */
7242         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
7243         if (rc != 0) {
7244                 pr_err("error %d\n", rc);
7245                 goto rw_error;
7246         }
7247         {
7248                 u16 fec_oc_snc_mode = 0;
7249                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
7250                 if (rc != 0) {
7251                         pr_err("error %d\n", rc);
7252                         goto rw_error;
7253                 }
7254                 /* output data even when not locked */
7255                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
7256                 if (rc != 0) {
7257                         pr_err("error %d\n", rc);
7258                         goto rw_error;
7259                 }
7260         }
7261
7262         /* set clip */
7263         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, 0, 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, IQM_AF_CLP_TH__A, 470, 0);
7269         if (rc != 0) {
7270                 pr_err("error %d\n", rc);
7271                 goto rw_error;
7272         }
7273         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
7274         if (rc != 0) {
7275                 pr_err("error %d\n", rc);
7276                 goto rw_error;
7277         }
7278         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
7279         if (rc != 0) {
7280                 pr_err("error %d\n", rc);
7281                 goto rw_error;
7282         }
7283         /* no transparent, no A&C framing; parity is set in mpegoutput */
7284         {
7285                 u16 fec_oc_reg_mode = 0;
7286                 rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
7287                 if (rc != 0) {
7288                         pr_err("error %d\n", rc);
7289                         goto rw_error;
7290                 }
7291                 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);
7292                 if (rc != 0) {
7293                         pr_err("error %d\n", rc);
7294                         goto rw_error;
7295                 }
7296         }
7297
7298         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
7299         if (rc != 0) {
7300                 pr_err("error %d\n", rc);
7301                 goto rw_error;
7302         }       /* timeout counter for restarting */
7303         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
7304         if (rc != 0) {
7305                 pr_err("error %d\n", rc);
7306                 goto rw_error;
7307         }
7308         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MODE__A, 0, 0);
7309         if (rc != 0) {
7310                 pr_err("error %d\n", rc);
7311                 goto rw_error;
7312         }       /* bypass disabled */
7313         /* initialize RS packet error measurement parameters */
7314         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
7315         if (rc != 0) {
7316                 pr_err("error %d\n", rc);
7317                 goto rw_error;
7318         }
7319         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
7320         if (rc != 0) {
7321                 pr_err("error %d\n", rc);
7322                 goto rw_error;
7323         }
7324
7325         /* init measurement period of MER/SER */
7326         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
7327         if (rc != 0) {
7328                 pr_err("error %d\n", rc);
7329                 goto rw_error;
7330         }
7331         rc = DRXJ_DAP.write_reg32func(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
7332         if (rc != 0) {
7333                 pr_err("error %d\n", rc);
7334                 goto rw_error;
7335         }
7336         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
7337         if (rc != 0) {
7338                 pr_err("error %d\n", rc);
7339                 goto rw_error;
7340         }
7341         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
7342         if (rc != 0) {
7343                 pr_err("error %d\n", rc);
7344                 goto rw_error;
7345         }
7346
7347         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
7348         if (rc != 0) {
7349                 pr_err("error %d\n", rc);
7350                 goto rw_error;
7351         }
7352         /* B-Input to ADC, PGA+filter in standby */
7353         if (!ext_attr->has_lna) {
7354                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
7355                 if (rc != 0) {
7356                         pr_err("error %d\n", rc);
7357                         goto rw_error;
7358                 }
7359         }
7360
7361         /* turn on IQMAF. It has to be in front of setAgc**() */
7362         rc = set_iqm_af(demod, true);
7363         if (rc != 0) {
7364                 pr_err("error %d\n", rc);
7365                 goto rw_error;
7366         }
7367         rc = adc_synchronization(demod);
7368         if (rc != 0) {
7369                 pr_err("error %d\n", rc);
7370                 goto rw_error;
7371         }
7372
7373         rc = init_agc(demod);
7374         if (rc != 0) {
7375                 pr_err("error %d\n", rc);
7376                 goto rw_error;
7377         }
7378         rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
7379         if (rc != 0) {
7380                 pr_err("error %d\n", rc);
7381                 goto rw_error;
7382         }
7383         rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
7384         if (rc != 0) {
7385                 pr_err("error %d\n", rc);
7386                 goto rw_error;
7387         }
7388         {
7389                 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
7390                    of only the gain */
7391                 struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
7392
7393                 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
7394                 rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
7395                 if (rc != 0) {
7396                         pr_err("error %d\n", rc);
7397                         goto rw_error;
7398                 }
7399         }
7400         rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
7401         if (rc != 0) {
7402                 pr_err("error %d\n", rc);
7403                 goto rw_error;
7404         }
7405
7406         /* Mpeg output has to be in front of FEC active */
7407         rc = set_mpegtei_handling(demod);
7408         if (rc != 0) {
7409                 pr_err("error %d\n", rc);
7410                 goto rw_error;
7411         }
7412         rc = bit_reverse_mpeg_output(demod);
7413         if (rc != 0) {
7414                 pr_err("error %d\n", rc);
7415                 goto rw_error;
7416         }
7417         rc = set_mpeg_start_width(demod);
7418         if (rc != 0) {
7419                 pr_err("error %d\n", rc);
7420                 goto rw_error;
7421         }
7422         {
7423                 /* TODO: move to set_standard after hardware reset value problem is solved */
7424                 /* Configure initial MPEG output */
7425                 struct drx_cfg_mpeg_output cfg_mpeg_output;
7426                 cfg_mpeg_output.enable_mpeg_output = true;
7427                 cfg_mpeg_output.insert_rs_byte = common_attr->mpeg_cfg.insert_rs_byte;
7428                 cfg_mpeg_output.enable_parallel =
7429                     common_attr->mpeg_cfg.enable_parallel;
7430                 cfg_mpeg_output.invert_data = common_attr->mpeg_cfg.invert_data;
7431                 cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
7432                 cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
7433                 cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
7434                 cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
7435                 cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
7436                 cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
7437                 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
7438                 if (rc != 0) {
7439                         pr_err("error %d\n", rc);
7440                         goto rw_error;
7441                 }
7442         }
7443
7444         /* TBD: what parameters should be set */
7445         cmd_param = 0x00;       /* Default mode AGC on, etc */
7446         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7447             | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
7448         cmd_scu.parameter_len = 1;
7449         cmd_scu.result_len = 1;
7450         cmd_scu.parameter = &cmd_param;
7451         cmd_scu.result = &cmd_result;
7452         rc = scu_command(dev_addr, &cmd_scu);
7453         if (rc != 0) {
7454                 pr_err("error %d\n", rc);
7455                 goto rw_error;
7456         }
7457
7458         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
7459         if (rc != 0) {
7460                 pr_err("error %d\n", rc);
7461                 goto rw_error;
7462         }
7463         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
7464         if (rc != 0) {
7465                 pr_err("error %d\n", rc);
7466                 goto rw_error;
7467         }
7468         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
7469         if (rc != 0) {
7470                 pr_err("error %d\n", rc);
7471                 goto rw_error;
7472         }
7473         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
7474         if (rc != 0) {
7475                 pr_err("error %d\n", rc);
7476                 goto rw_error;
7477         }
7478         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
7479         if (rc != 0) {
7480                 pr_err("error %d\n", rc);
7481                 goto rw_error;
7482         }
7483         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
7484         if (rc != 0) {
7485                 pr_err("error %d\n", rc);
7486                 goto rw_error;
7487         }
7488         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
7489         if (rc != 0) {
7490                 pr_err("error %d\n", rc);
7491                 goto rw_error;
7492         }
7493         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
7494         if (rc != 0) {
7495                 pr_err("error %d\n", rc);
7496                 goto rw_error;
7497         }
7498
7499         /* start demodulator */
7500         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
7501             | SCU_RAM_COMMAND_CMD_DEMOD_START;
7502         cmd_scu.parameter_len = 0;
7503         cmd_scu.result_len = 1;
7504         cmd_scu.parameter = NULL;
7505         cmd_scu.result = &cmd_result;
7506         rc = scu_command(dev_addr, &cmd_scu);
7507         if (rc != 0) {
7508                 pr_err("error %d\n", rc);
7509                 goto rw_error;
7510         }
7511
7512         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
7513         if (rc != 0) {
7514                 pr_err("error %d\n", rc);
7515                 goto rw_error;
7516         }
7517         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
7518         if (rc != 0) {
7519                 pr_err("error %d\n", rc);
7520                 goto rw_error;
7521         }
7522         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
7523         if (rc != 0) {
7524                 pr_err("error %d\n", rc);
7525                 goto rw_error;
7526         }
7527
7528         return 0;
7529 rw_error:
7530         return -EIO;
7531 }
7532
7533 /**
7534 * \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
7535 * \brief Get the values of packet error in 8VSB mode
7536 * \return Error code
7537 */
7538 static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *pck_errs)
7539 {
7540         int rc;
7541         u16 data = 0;
7542         u16 period = 0;
7543         u16 prescale = 0;
7544         u16 packet_errors_mant = 0;
7545         u16 packet_errors_exp = 0;
7546
7547         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
7548         if (rc != 0) {
7549                 pr_err("error %d\n", rc);
7550                 goto rw_error;
7551         }
7552         packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
7553         packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
7554             >> FEC_RS_NR_FAILURES_EXP__B;
7555         period = FEC_RS_MEASUREMENT_PERIOD;
7556         prescale = FEC_RS_MEASUREMENT_PRESCALE;
7557         /* packet error rate = (error packet number) per second */
7558         /* 77.3 us is time for per packet */
7559         if (period * prescale == 0) {
7560                 pr_err("error: period and/or prescale is zero!\n");
7561                 return -EIO;
7562         }
7563         *pck_errs =
7564             (u16) frac_times1e6(packet_errors_mant * (1 << packet_errors_exp),
7565                                  (period * prescale * 77));
7566
7567         return 0;
7568 rw_error:
7569         return -EIO;
7570 }
7571
7572 /**
7573 * \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
7574 * \brief Get the values of ber in VSB mode
7575 * \return Error code
7576 */
7577 static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7578 {
7579         int rc;
7580         u16 data = 0;
7581         u16 period = 0;
7582         u16 prescale = 0;
7583         u16 bit_errors_mant = 0;
7584         u16 bit_errors_exp = 0;
7585
7586         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
7587         if (rc != 0) {
7588                 pr_err("error %d\n", rc);
7589                 goto rw_error;
7590         }
7591         period = FEC_RS_MEASUREMENT_PERIOD;
7592         prescale = FEC_RS_MEASUREMENT_PRESCALE;
7593
7594         bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
7595         bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
7596             >> FEC_RS_NR_BIT_ERRORS_EXP__B;
7597
7598         if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
7599                 *ber = 26570;
7600         else {
7601                 if (period * prescale == 0) {
7602                         pr_err("error: period and/or prescale is zero!\n");
7603                         return -EIO;
7604                 }
7605                 *ber =
7606                     frac_times1e6(bit_errors_mant <<
7607                                  ((bit_errors_exp >
7608                                    2) ? (bit_errors_exp - 3) : bit_errors_exp),
7609                                  period * prescale * 207 *
7610                                  ((bit_errors_exp > 2) ? 1 : 8));
7611         }
7612
7613         return 0;
7614 rw_error:
7615         return -EIO;
7616 }
7617
7618 /**
7619 * \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7620 * \brief Get the values of ber in VSB mode
7621 * \return Error code
7622 */
7623 static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
7624 {
7625         u16 data = 0;
7626         int rc;
7627
7628         rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
7629         if (rc != 0) {
7630                 pr_err("error %d\n", rc);
7631                 goto rw_error;
7632         }
7633         *ber =
7634             frac_times1e6(data,
7635                          VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT);
7636
7637         return 0;
7638 rw_error:
7639         return -EIO;
7640 }
7641
7642 /**
7643 * \fn static short get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ber)
7644 * \brief Get the values of ber in VSB mode
7645 * \return Error code
7646 */
7647 static int get_vsb_symb_err(struct i2c_device_addr *dev_addr, u32 *ser)
7648 {
7649         int rc;
7650         u16 data = 0;
7651         u16 period = 0;
7652         u16 prescale = 0;
7653         u16 symb_errors_mant = 0;
7654         u16 symb_errors_exp = 0;
7655
7656         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &data, 0);
7657         if (rc != 0) {
7658                 pr_err("error %d\n", rc);
7659                 goto rw_error;
7660         }
7661         period = FEC_RS_MEASUREMENT_PERIOD;
7662         prescale = FEC_RS_MEASUREMENT_PRESCALE;
7663
7664         symb_errors_mant = data & FEC_RS_NR_SYMBOL_ERRORS_FIXED_MANT__M;
7665         symb_errors_exp = (data & FEC_RS_NR_SYMBOL_ERRORS_EXP__M)
7666             >> FEC_RS_NR_SYMBOL_ERRORS_EXP__B;
7667
7668         if (period * prescale == 0) {
7669                 pr_err("error: period and/or prescale is zero!\n");
7670                 return -EIO;
7671         }
7672         *ser = (u32) frac_times1e6((symb_errors_mant << symb_errors_exp) * 1000,
7673                                     (period * prescale * 77318));
7674
7675         return 0;
7676 rw_error:
7677         return -EIO;
7678 }
7679
7680 /**
7681 * \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7682 * \brief Get the values of MER
7683 * \return Error code
7684 */
7685 static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
7686 {
7687         int rc;
7688         u16 data_hi = 0;
7689
7690         rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
7691         if (rc != 0) {
7692                 pr_err("error %d\n", rc);
7693                 goto rw_error;
7694         }
7695         *mer =
7696             (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
7697
7698         return 0;
7699 rw_error:
7700         return -EIO;
7701 }
7702
7703 /*============================================================================*/
7704 /**
7705 * \fn int ctrl_get_vsb_constel()
7706 * \brief Retreive a VSB constellation point via I2C.
7707 * \param demod Pointer to demodulator instance.
7708 * \param complex_nr Pointer to the structure in which to store the
7709                    constellation point.
7710 * \return int.
7711 */
7712 static int
7713 ctrl_get_vsb_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
7714 {
7715         struct i2c_device_addr *dev_addr = NULL;
7716         int rc;
7717                                        /**< device address                    */
7718         u16 vsb_top_comm_mb = 0;               /**< VSB SL MB configuration           */
7719         u16 vsb_top_comm_mb_init = 0;    /**< VSB SL MB intial configuration    */
7720         u16 re = 0;                    /**< constellation Re part             */
7721         u32 data = 0;
7722
7723         /* read device info */
7724         dev_addr = demod->my_i2c_dev_addr;
7725
7726         /* TODO: */
7727         /* Monitor bus grabbing is an open external interface issue  */
7728         /* Needs to be checked when external interface PG is updated */
7729
7730         /* Configure MB (Monitor bus) */
7731         rc = DRXJ_DAP.read_reg16func(dev_addr, VSB_TOP_COMM_MB__A, &vsb_top_comm_mb_init, 0);
7732         if (rc != 0) {
7733                 pr_err("error %d\n", rc);
7734                 goto rw_error;
7735         }
7736         /* set observe flag & MB mux */
7737         vsb_top_comm_mb = (vsb_top_comm_mb_init |
7738                         VSB_TOP_COMM_MB_OBS_OBS_ON |
7739                         VSB_TOP_COMM_MB_MUX_OBS_VSB_TCMEQ_2);
7740         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb, 0);
7741         if (rc != 0) {
7742                 pr_err("error %d\n", rc);
7743                 goto rw_error;
7744         }
7745
7746         /* Enable MB grabber in the FEC OC */
7747         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, FEC_OC_OCR_MODE_GRAB_ENABLE__M, 0);
7748         if (rc != 0) {
7749                 pr_err("error %d\n", rc);
7750                 goto rw_error;
7751         }
7752
7753         /* Disable MB grabber in the FEC OC */
7754         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, 0x0, 0);
7755         if (rc != 0) {
7756                 pr_err("error %d\n", rc);
7757                 goto rw_error;
7758         }
7759
7760         /* read data */
7761         rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_OCR_GRAB_RD1__A, &data, 0);
7762         if (rc != 0) {
7763                 pr_err("error %d\n", rc);
7764                 goto rw_error;
7765         }
7766         re = (u16) (((data >> 10) & 0x300) | ((data >> 2) & 0xff));
7767         if (re & 0x0200)
7768                 re |= 0xfc00;
7769         complex_nr->re = re;
7770         complex_nr->im = 0;
7771
7772         /* Restore MB (Monitor bus) */
7773         rc = DRXJ_DAP.write_reg16func(dev_addr, VSB_TOP_COMM_MB__A, vsb_top_comm_mb_init, 0);
7774         if (rc != 0) {
7775                 pr_err("error %d\n", rc);
7776                 goto rw_error;
7777         }
7778
7779         return 0;
7780 rw_error:
7781         return -EIO;
7782 }
7783
7784 /*============================================================================*/
7785 /*==                     END 8VSB DATAPATH FUNCTIONS                        ==*/
7786 /*============================================================================*/
7787
7788 /*============================================================================*/
7789 /*============================================================================*/
7790 /*==                       QAM DATAPATH FUNCTIONS                           ==*/
7791 /*============================================================================*/
7792 /*============================================================================*/
7793
7794 /**
7795 * \fn int power_down_qam ()
7796 * \brief Powr down QAM related blocks.
7797 * \param demod instance of demodulator.
7798 * \param channel pointer to channel data.
7799 * \return int.
7800 */
7801 static int power_down_qam(struct drx_demod_instance *demod, bool primary)
7802 {
7803         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
7804                 /* parameter_len */ 0,
7805                 /* result_len    */ 0,
7806                 /* *parameter   */ NULL,
7807                 /* *result      */ NULL
7808         };
7809         int rc;
7810         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7811         struct drx_cfg_mpeg_output cfg_mpeg_output;
7812         u16 cmd_result = 0;
7813
7814         /*
7815            STOP demodulator
7816            resets IQM, QAM and FEC HW blocks
7817          */
7818         /* stop all comm_exec */
7819         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_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, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
7825         if (rc != 0) {
7826                 pr_err("error %d\n", rc);
7827                 goto rw_error;
7828         }
7829
7830         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
7831             SCU_RAM_COMMAND_CMD_DEMOD_STOP;
7832         cmd_scu.parameter_len = 0;
7833         cmd_scu.result_len = 1;
7834         cmd_scu.parameter = NULL;
7835         cmd_scu.result = &cmd_result;
7836         rc = scu_command(dev_addr, &cmd_scu);
7837         if (rc != 0) {
7838                 pr_err("error %d\n", rc);
7839                 goto rw_error;
7840         }
7841
7842         if (primary) {
7843                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
7844                 if (rc != 0) {
7845                         pr_err("error %d\n", rc);
7846                         goto rw_error;
7847                 }
7848                 rc = set_iqm_af(demod, false);
7849                 if (rc != 0) {
7850                         pr_err("error %d\n", rc);
7851                         goto rw_error;
7852                 }
7853         } else {
7854                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
7855                 if (rc != 0) {
7856                         pr_err("error %d\n", rc);
7857                         goto rw_error;
7858                 }
7859                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
7860                 if (rc != 0) {
7861                         pr_err("error %d\n", rc);
7862                         goto rw_error;
7863                 }
7864                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
7865                 if (rc != 0) {
7866                         pr_err("error %d\n", rc);
7867                         goto rw_error;
7868                 }
7869                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
7870                 if (rc != 0) {
7871                         pr_err("error %d\n", rc);
7872                         goto rw_error;
7873                 }
7874                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
7875                 if (rc != 0) {
7876                         pr_err("error %d\n", rc);
7877                         goto rw_error;
7878                 }
7879         }
7880
7881         cfg_mpeg_output.enable_mpeg_output = false;
7882         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
7883         if (rc != 0) {
7884                 pr_err("error %d\n", rc);
7885                 goto rw_error;
7886         }
7887
7888         return 0;
7889 rw_error:
7890         return -EIO;
7891 }
7892
7893 /*============================================================================*/
7894
7895 /**
7896 * \fn int set_qam_measurement ()
7897 * \brief Setup of the QAM Measuremnt intervals for signal quality
7898 * \param demod instance of demod.
7899 * \param constellation current constellation.
7900 * \return int.
7901 *
7902 *  NOTE:
7903 *  Take into account that for certain settings the errorcounters can overflow.
7904 *  The implementation does not check this.
7905 *
7906 *  TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
7907 *  constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
7908 *  field ?
7909 *
7910 */
7911 #ifndef DRXJ_VSB_ONLY
7912 static int
7913 set_qam_measurement(struct drx_demod_instance *demod,
7914                     enum drx_modulation constellation, u32 symbol_rate)
7915 {
7916         struct i2c_device_addr *dev_addr = NULL;        /* device address for I2C writes */
7917         struct drxj_data *ext_attr = NULL;      /* Global data container for DRXJ specif data */
7918         int rc;
7919         u32 fec_bits_desired = 0;       /* BER accounting period */
7920         u16 fec_rs_plen = 0;    /* defines RS BER measurement period */
7921         u16 fec_rs_prescale = 0;        /* ReedSolomon Measurement Prescale */
7922         u32 fec_rs_period = 0;  /* Value for corresponding I2C register */
7923         u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
7924         u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
7925         u32 qam_vd_period = 0;  /* Value for corresponding I2C register */
7926         u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
7927         u16 fec_vd_plen = 0;    /* no of trellis symbols: VD SER measur period */
7928         u16 qam_vd_prescale = 0;        /* Viterbi Measurement Prescale */
7929
7930         dev_addr = demod->my_i2c_dev_addr;
7931         ext_attr = (struct drxj_data *) demod->my_ext_attr;
7932
7933         fec_bits_desired = ext_attr->fec_bits_desired;
7934         fec_rs_prescale = ext_attr->fec_rs_prescale;
7935
7936         switch (constellation) {
7937         case DRX_CONSTELLATION_QAM16:
7938                 fec_bits_desired = 4 * symbol_rate;
7939                 break;
7940         case DRX_CONSTELLATION_QAM32:
7941                 fec_bits_desired = 5 * symbol_rate;
7942                 break;
7943         case DRX_CONSTELLATION_QAM64:
7944                 fec_bits_desired = 6 * symbol_rate;
7945                 break;
7946         case DRX_CONSTELLATION_QAM128:
7947                 fec_bits_desired = 7 * symbol_rate;
7948                 break;
7949         case DRX_CONSTELLATION_QAM256:
7950                 fec_bits_desired = 8 * symbol_rate;
7951                 break;
7952         default:
7953                 return -EINVAL;
7954         }
7955
7956         /* Parameters for Reed-Solomon Decoder */
7957         /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
7958         /* rs_bit_cnt   = fecrs_period*fecrs_prescale*plen                  */
7959         /*     result is within 32 bit arithmetic ->                        */
7960         /*     no need for mult or frac functions                           */
7961
7962         /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
7963         switch (ext_attr->standard) {
7964         case DRX_STANDARD_ITU_A:
7965         case DRX_STANDARD_ITU_C:
7966                 fec_rs_plen = 204 * 8;
7967                 break;
7968         case DRX_STANDARD_ITU_B:
7969                 fec_rs_plen = 128 * 7;
7970                 break;
7971         default:
7972                 return -EINVAL;
7973         }
7974
7975         ext_attr->fec_rs_plen = fec_rs_plen;    /* for getSigQual */
7976         fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage   */
7977         if (fec_rs_bit_cnt == 0) {
7978                 pr_err("error: fec_rs_bit_cnt is zero!\n");
7979                 return -EIO;
7980         }
7981         fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1;  /* ceil */
7982         if (ext_attr->standard != DRX_STANDARD_ITU_B)
7983                 fec_oc_snc_fail_period = fec_rs_period;
7984
7985         /* limit to max 16 bit value (I2C register width) if needed */
7986         if (fec_rs_period > 0xFFFF)
7987                 fec_rs_period = 0xFFFF;
7988
7989         /* write corresponding registers */
7990         switch (ext_attr->standard) {
7991         case DRX_STANDARD_ITU_A:
7992         case DRX_STANDARD_ITU_C:
7993                 break;
7994         case DRX_STANDARD_ITU_B:
7995                 switch (constellation) {
7996                 case DRX_CONSTELLATION_QAM64:
7997                         fec_rs_period = 31581;
7998                         fec_oc_snc_fail_period = 17932;
7999                         break;
8000                 case DRX_CONSTELLATION_QAM256:
8001                         fec_rs_period = 45446;
8002                         fec_oc_snc_fail_period = 25805;
8003                         break;
8004                 default:
8005                         return -EINVAL;
8006                 }
8007                 break;
8008         default:
8009                 return -EINVAL;
8010         }
8011
8012         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
8013         if (rc != 0) {
8014                 pr_err("error %d\n", rc);
8015                 goto rw_error;
8016         }
8017         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
8018         if (rc != 0) {
8019                 pr_err("error %d\n", rc);
8020                 goto rw_error;
8021         }
8022         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
8023         if (rc != 0) {
8024                 pr_err("error %d\n", rc);
8025                 goto rw_error;
8026         }
8027         ext_attr->fec_rs_period = (u16) fec_rs_period;
8028         ext_attr->fec_rs_prescale = fec_rs_prescale;
8029         rc = DRXJ_DAP.write_reg32func(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
8030         if (rc != 0) {
8031                 pr_err("error %d\n", rc);
8032                 goto rw_error;
8033         }
8034         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
8035         if (rc != 0) {
8036                 pr_err("error %d\n", rc);
8037                 goto rw_error;
8038         }
8039         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
8040         if (rc != 0) {
8041                 pr_err("error %d\n", rc);
8042                 goto rw_error;
8043         }
8044
8045         if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8046                 /* Parameters for Viterbi Decoder */
8047                 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/                      */
8048                 /*                    (qamvd_prescale*plen*(qam_constellation+1))) */
8049                 /* vd_bit_cnt   = qamvd_period*qamvd_prescale*plen                 */
8050                 /*     result is within 32 bit arithmetic ->                       */
8051                 /*     no need for mult or frac functions                          */
8052
8053                 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
8054                 fec_vd_plen = ext_attr->fec_vd_plen;
8055                 qam_vd_prescale = ext_attr->qam_vd_prescale;
8056                 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
8057
8058                 switch (constellation) {
8059                 case DRX_CONSTELLATION_QAM64:
8060                         /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
8061                         qam_vd_period =
8062                             qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
8063                             * (QAM_TOP_CONSTELLATION_QAM64 + 1);
8064                         break;
8065                 case DRX_CONSTELLATION_QAM256:
8066                         /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
8067                         qam_vd_period =
8068                             qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
8069                             * (QAM_TOP_CONSTELLATION_QAM256 + 1);
8070                         break;
8071                 default:
8072                         return -EINVAL;
8073                 }
8074                 if (qam_vd_period == 0) {
8075                         pr_err("error: qam_vd_period is zero!\n");
8076                         return -EIO;
8077                 }
8078                 qam_vd_period = fec_bits_desired / qam_vd_period;
8079                 /* limit to max 16 bit value (I2C register width) if needed */
8080                 if (qam_vd_period > 0xFFFF)
8081                         qam_vd_period = 0xFFFF;
8082
8083                 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
8084                 qam_vd_bit_cnt *= qam_vd_period;
8085
8086                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
8087                 if (rc != 0) {
8088                         pr_err("error %d\n", rc);
8089                         goto rw_error;
8090                 }
8091                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
8092                 if (rc != 0) {
8093                         pr_err("error %d\n", rc);
8094                         goto rw_error;
8095                 }
8096                 ext_attr->qam_vd_period = (u16) qam_vd_period;
8097                 ext_attr->qam_vd_prescale = qam_vd_prescale;
8098         }
8099
8100         return 0;
8101 rw_error:
8102         return -EIO;
8103 }
8104
8105 /*============================================================================*/
8106
8107 /**
8108 * \fn int set_qam16 ()
8109 * \brief QAM16 specific setup
8110 * \param demod instance of demod.
8111 * \return int.
8112 */
8113 static int set_qam16(struct drx_demod_instance *demod)
8114 {
8115         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8116         int rc;
8117         const u8 qam_dq_qual_fun[] = {
8118                 DRXJ_16TO8(2),  /* fun0  */
8119                 DRXJ_16TO8(2),  /* fun1  */
8120                 DRXJ_16TO8(2),  /* fun2  */
8121                 DRXJ_16TO8(2),  /* fun3  */
8122                 DRXJ_16TO8(3),  /* fun4  */
8123                 DRXJ_16TO8(3),  /* fun5  */
8124         };
8125         const u8 qam_eq_cma_rad[] = {
8126                 DRXJ_16TO8(13517),      /* RAD0  */
8127                 DRXJ_16TO8(13517),      /* RAD1  */
8128                 DRXJ_16TO8(13517),      /* RAD2  */
8129                 DRXJ_16TO8(13517),      /* RAD3  */
8130                 DRXJ_16TO8(13517),      /* RAD4  */
8131                 DRXJ_16TO8(13517),      /* RAD5  */
8132         };
8133
8134         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8135         if (rc != 0) {
8136                 pr_err("error %d\n", rc);
8137                 goto rw_error;
8138         }
8139         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);
8140         if (rc != 0) {
8141                 pr_err("error %d\n", rc);
8142                 goto rw_error;
8143         }
8144
8145         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
8146         if (rc != 0) {
8147                 pr_err("error %d\n", rc);
8148                 goto rw_error;
8149         }
8150         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
8151         if (rc != 0) {
8152                 pr_err("error %d\n", rc);
8153                 goto rw_error;
8154         }
8155         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
8156         if (rc != 0) {
8157                 pr_err("error %d\n", rc);
8158                 goto rw_error;
8159         }
8160         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
8161         if (rc != 0) {
8162                 pr_err("error %d\n", rc);
8163                 goto rw_error;
8164         }
8165         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
8166         if (rc != 0) {
8167                 pr_err("error %d\n", rc);
8168                 goto rw_error;
8169         }
8170         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
8171         if (rc != 0) {
8172                 pr_err("error %d\n", rc);
8173                 goto rw_error;
8174         }
8175
8176         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8177         if (rc != 0) {
8178                 pr_err("error %d\n", rc);
8179                 goto rw_error;
8180         }
8181         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
8182         if (rc != 0) {
8183                 pr_err("error %d\n", rc);
8184                 goto rw_error;
8185         }
8186         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8187         if (rc != 0) {
8188                 pr_err("error %d\n", rc);
8189                 goto rw_error;
8190         }
8191
8192         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
8193         if (rc != 0) {
8194                 pr_err("error %d\n", rc);
8195                 goto rw_error;
8196         }
8197         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
8198         if (rc != 0) {
8199                 pr_err("error %d\n", rc);
8200                 goto rw_error;
8201         }
8202         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
8203         if (rc != 0) {
8204                 pr_err("error %d\n", rc);
8205                 goto rw_error;
8206         }
8207         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
8208         if (rc != 0) {
8209                 pr_err("error %d\n", rc);
8210                 goto rw_error;
8211         }
8212         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
8213         if (rc != 0) {
8214                 pr_err("error %d\n", rc);
8215                 goto rw_error;
8216         }
8217         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
8218         if (rc != 0) {
8219                 pr_err("error %d\n", rc);
8220                 goto rw_error;
8221         }
8222         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
8223         if (rc != 0) {
8224                 pr_err("error %d\n", rc);
8225                 goto rw_error;
8226         }
8227
8228         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 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_CA_COARSE__A, 40, 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_CP_FINE__A, 2, 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_CP_MEDIUM__A, 20, 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_CP_COARSE__A, 255, 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_CI_FINE__A, 2, 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_CI_MEDIUM__A, 10, 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_CI_COARSE__A, 50, 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_EP_FINE__A, 12, 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_EP_MEDIUM__A, 24, 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_EP_COARSE__A, 24, 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_EI_FINE__A, 12, 0);
8284         if (rc != 0) {
8285                 pr_err("error %d\n", rc);
8286                 goto rw_error;
8287         }
8288         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8289         if (rc != 0) {
8290                 pr_err("error %d\n", rc);
8291                 goto rw_error;
8292         }
8293         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8294         if (rc != 0) {
8295                 pr_err("error %d\n", rc);
8296                 goto rw_error;
8297         }
8298         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8299         if (rc != 0) {
8300                 pr_err("error %d\n", rc);
8301                 goto rw_error;
8302         }
8303         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8304         if (rc != 0) {
8305                 pr_err("error %d\n", rc);
8306                 goto rw_error;
8307         }
8308         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
8309         if (rc != 0) {
8310                 pr_err("error %d\n", rc);
8311                 goto rw_error;
8312         }
8313         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8314         if (rc != 0) {
8315                 pr_err("error %d\n", rc);
8316                 goto rw_error;
8317         }
8318         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8319         if (rc != 0) {
8320                 pr_err("error %d\n", rc);
8321                 goto rw_error;
8322         }
8323         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
8324         if (rc != 0) {
8325                 pr_err("error %d\n", rc);
8326                 goto rw_error;
8327         }
8328
8329         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
8330         if (rc != 0) {
8331                 pr_err("error %d\n", rc);
8332                 goto rw_error;
8333         }
8334
8335         return 0;
8336 rw_error:
8337         return -EIO;
8338 }
8339
8340 /*============================================================================*/
8341
8342 /**
8343 * \fn int set_qam32 ()
8344 * \brief QAM32 specific setup
8345 * \param demod instance of demod.
8346 * \return int.
8347 */
8348 static int set_qam32(struct drx_demod_instance *demod)
8349 {
8350         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8351         int rc;
8352         const u8 qam_dq_qual_fun[] = {
8353                 DRXJ_16TO8(3),  /* fun0  */
8354                 DRXJ_16TO8(3),  /* fun1  */
8355                 DRXJ_16TO8(3),  /* fun2  */
8356                 DRXJ_16TO8(3),  /* fun3  */
8357                 DRXJ_16TO8(4),  /* fun4  */
8358                 DRXJ_16TO8(4),  /* fun5  */
8359         };
8360         const u8 qam_eq_cma_rad[] = {
8361                 DRXJ_16TO8(6707),       /* RAD0  */
8362                 DRXJ_16TO8(6707),       /* RAD1  */
8363                 DRXJ_16TO8(6707),       /* RAD2  */
8364                 DRXJ_16TO8(6707),       /* RAD3  */
8365                 DRXJ_16TO8(6707),       /* RAD4  */
8366                 DRXJ_16TO8(6707),       /* RAD5  */
8367         };
8368
8369         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8370         if (rc != 0) {
8371                 pr_err("error %d\n", rc);
8372                 goto rw_error;
8373         }
8374         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);
8375         if (rc != 0) {
8376                 pr_err("error %d\n", rc);
8377                 goto rw_error;
8378         }
8379
8380         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
8381         if (rc != 0) {
8382                 pr_err("error %d\n", rc);
8383                 goto rw_error;
8384         }
8385         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
8386         if (rc != 0) {
8387                 pr_err("error %d\n", rc);
8388                 goto rw_error;
8389         }
8390         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8391         if (rc != 0) {
8392                 pr_err("error %d\n", rc);
8393                 goto rw_error;
8394         }
8395         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
8396         if (rc != 0) {
8397                 pr_err("error %d\n", rc);
8398                 goto rw_error;
8399         }
8400         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8401         if (rc != 0) {
8402                 pr_err("error %d\n", rc);
8403                 goto rw_error;
8404         }
8405         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
8406         if (rc != 0) {
8407                 pr_err("error %d\n", rc);
8408                 goto rw_error;
8409         }
8410
8411         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8412         if (rc != 0) {
8413                 pr_err("error %d\n", rc);
8414                 goto rw_error;
8415         }
8416         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
8417         if (rc != 0) {
8418                 pr_err("error %d\n", rc);
8419                 goto rw_error;
8420         }
8421         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8422         if (rc != 0) {
8423                 pr_err("error %d\n", rc);
8424                 goto rw_error;
8425         }
8426
8427         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
8428         if (rc != 0) {
8429                 pr_err("error %d\n", rc);
8430                 goto rw_error;
8431         }
8432         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
8433         if (rc != 0) {
8434                 pr_err("error %d\n", rc);
8435                 goto rw_error;
8436         }
8437         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
8438         if (rc != 0) {
8439                 pr_err("error %d\n", rc);
8440                 goto rw_error;
8441         }
8442         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
8443         if (rc != 0) {
8444                 pr_err("error %d\n", rc);
8445                 goto rw_error;
8446         }
8447         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
8448         if (rc != 0) {
8449                 pr_err("error %d\n", rc);
8450                 goto rw_error;
8451         }
8452         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
8453         if (rc != 0) {
8454                 pr_err("error %d\n", rc);
8455                 goto rw_error;
8456         }
8457         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
8458         if (rc != 0) {
8459                 pr_err("error %d\n", rc);
8460                 goto rw_error;
8461         }
8462
8463         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 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_CA_COARSE__A, 40, 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_CP_FINE__A, 2, 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_CP_MEDIUM__A, 20, 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_CP_COARSE__A, 255, 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_CI_FINE__A, 2, 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_CI_MEDIUM__A, 10, 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_CI_COARSE__A, 50, 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_EP_FINE__A, 12, 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_EP_MEDIUM__A, 24, 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_EP_COARSE__A, 24, 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_EI_FINE__A, 12, 0);
8519         if (rc != 0) {
8520                 pr_err("error %d\n", rc);
8521                 goto rw_error;
8522         }
8523         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8524         if (rc != 0) {
8525                 pr_err("error %d\n", rc);
8526                 goto rw_error;
8527         }
8528         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8529         if (rc != 0) {
8530                 pr_err("error %d\n", rc);
8531                 goto rw_error;
8532         }
8533         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8534         if (rc != 0) {
8535                 pr_err("error %d\n", rc);
8536                 goto rw_error;
8537         }
8538         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
8539         if (rc != 0) {
8540                 pr_err("error %d\n", rc);
8541                 goto rw_error;
8542         }
8543         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
8544         if (rc != 0) {
8545                 pr_err("error %d\n", rc);
8546                 goto rw_error;
8547         }
8548         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8549         if (rc != 0) {
8550                 pr_err("error %d\n", rc);
8551                 goto rw_error;
8552         }
8553         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8554         if (rc != 0) {
8555                 pr_err("error %d\n", rc);
8556                 goto rw_error;
8557         }
8558         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
8559         if (rc != 0) {
8560                 pr_err("error %d\n", rc);
8561                 goto rw_error;
8562         }
8563
8564         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
8565         if (rc != 0) {
8566                 pr_err("error %d\n", rc);
8567                 goto rw_error;
8568         }
8569
8570         return 0;
8571 rw_error:
8572         return -EIO;
8573 }
8574
8575 /*============================================================================*/
8576
8577 /**
8578 * \fn int set_qam64 ()
8579 * \brief QAM64 specific setup
8580 * \param demod instance of demod.
8581 * \return int.
8582 */
8583 static int set_qam64(struct drx_demod_instance *demod)
8584 {
8585         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8586         int rc;
8587         const u8 qam_dq_qual_fun[] = {  /* this is hw reset value. no necessary to re-write */
8588                 DRXJ_16TO8(4),  /* fun0  */
8589                 DRXJ_16TO8(4),  /* fun1  */
8590                 DRXJ_16TO8(4),  /* fun2  */
8591                 DRXJ_16TO8(4),  /* fun3  */
8592                 DRXJ_16TO8(6),  /* fun4  */
8593                 DRXJ_16TO8(6),  /* fun5  */
8594         };
8595         const u8 qam_eq_cma_rad[] = {
8596                 DRXJ_16TO8(13336),      /* RAD0  */
8597                 DRXJ_16TO8(12618),      /* RAD1  */
8598                 DRXJ_16TO8(11988),      /* RAD2  */
8599                 DRXJ_16TO8(13809),      /* RAD3  */
8600                 DRXJ_16TO8(13809),      /* RAD4  */
8601                 DRXJ_16TO8(15609),      /* RAD5  */
8602         };
8603
8604         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8605         if (rc != 0) {
8606                 pr_err("error %d\n", rc);
8607                 goto rw_error;
8608         }
8609         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);
8610         if (rc != 0) {
8611                 pr_err("error %d\n", rc);
8612                 goto rw_error;
8613         }
8614
8615         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
8616         if (rc != 0) {
8617                 pr_err("error %d\n", rc);
8618                 goto rw_error;
8619         }
8620         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
8621         if (rc != 0) {
8622                 pr_err("error %d\n", rc);
8623                 goto rw_error;
8624         }
8625         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8626         if (rc != 0) {
8627                 pr_err("error %d\n", rc);
8628                 goto rw_error;
8629         }
8630         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
8631         if (rc != 0) {
8632                 pr_err("error %d\n", rc);
8633                 goto rw_error;
8634         }
8635         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8636         if (rc != 0) {
8637                 pr_err("error %d\n", rc);
8638                 goto rw_error;
8639         }
8640         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
8641         if (rc != 0) {
8642                 pr_err("error %d\n", rc);
8643                 goto rw_error;
8644         }
8645
8646         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8647         if (rc != 0) {
8648                 pr_err("error %d\n", rc);
8649                 goto rw_error;
8650         }
8651         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
8652         if (rc != 0) {
8653                 pr_err("error %d\n", rc);
8654                 goto rw_error;
8655         }
8656         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8657         if (rc != 0) {
8658                 pr_err("error %d\n", rc);
8659                 goto rw_error;
8660         }
8661
8662         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
8663         if (rc != 0) {
8664                 pr_err("error %d\n", rc);
8665                 goto rw_error;
8666         }
8667         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
8668         if (rc != 0) {
8669                 pr_err("error %d\n", rc);
8670                 goto rw_error;
8671         }
8672         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
8673         if (rc != 0) {
8674                 pr_err("error %d\n", rc);
8675                 goto rw_error;
8676         }
8677         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
8678         if (rc != 0) {
8679                 pr_err("error %d\n", rc);
8680                 goto rw_error;
8681         }
8682         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
8683         if (rc != 0) {
8684                 pr_err("error %d\n", rc);
8685                 goto rw_error;
8686         }
8687         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
8688         if (rc != 0) {
8689                 pr_err("error %d\n", rc);
8690                 goto rw_error;
8691         }
8692         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
8693         if (rc != 0) {
8694                 pr_err("error %d\n", rc);
8695                 goto rw_error;
8696         }
8697
8698         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 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_CA_COARSE__A, 40, 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_CP_FINE__A, 2, 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_CP_MEDIUM__A, 30, 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_CP_COARSE__A, 255, 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_CI_FINE__A, 2, 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_CI_MEDIUM__A, 15, 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_CI_COARSE__A, 80, 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_EP_FINE__A, 12, 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_EP_MEDIUM__A, 24, 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_EP_COARSE__A, 24, 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_EI_FINE__A, 12, 0);
8754         if (rc != 0) {
8755                 pr_err("error %d\n", rc);
8756                 goto rw_error;
8757         }
8758         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8759         if (rc != 0) {
8760                 pr_err("error %d\n", rc);
8761                 goto rw_error;
8762         }
8763         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8764         if (rc != 0) {
8765                 pr_err("error %d\n", rc);
8766                 goto rw_error;
8767         }
8768         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
8769         if (rc != 0) {
8770                 pr_err("error %d\n", rc);
8771                 goto rw_error;
8772         }
8773         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
8774         if (rc != 0) {
8775                 pr_err("error %d\n", rc);
8776                 goto rw_error;
8777         }
8778         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
8779         if (rc != 0) {
8780                 pr_err("error %d\n", rc);
8781                 goto rw_error;
8782         }
8783         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
8784         if (rc != 0) {
8785                 pr_err("error %d\n", rc);
8786                 goto rw_error;
8787         }
8788         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
8789         if (rc != 0) {
8790                 pr_err("error %d\n", rc);
8791                 goto rw_error;
8792         }
8793         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
8794         if (rc != 0) {
8795                 pr_err("error %d\n", rc);
8796                 goto rw_error;
8797         }
8798
8799         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
8800         if (rc != 0) {
8801                 pr_err("error %d\n", rc);
8802                 goto rw_error;
8803         }
8804
8805         return 0;
8806 rw_error:
8807         return -EIO;
8808 }
8809
8810 /*============================================================================*/
8811
8812 /**
8813 * \fn int set_qam128 ()
8814 * \brief QAM128 specific setup
8815 * \param demod: instance of demod.
8816 * \return int.
8817 */
8818 static int set_qam128(struct drx_demod_instance *demod)
8819 {
8820         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8821         int rc;
8822         const u8 qam_dq_qual_fun[] = {
8823                 DRXJ_16TO8(6),  /* fun0  */
8824                 DRXJ_16TO8(6),  /* fun1  */
8825                 DRXJ_16TO8(6),  /* fun2  */
8826                 DRXJ_16TO8(6),  /* fun3  */
8827                 DRXJ_16TO8(9),  /* fun4  */
8828                 DRXJ_16TO8(9),  /* fun5  */
8829         };
8830         const u8 qam_eq_cma_rad[] = {
8831                 DRXJ_16TO8(6164),       /* RAD0  */
8832                 DRXJ_16TO8(6598),       /* RAD1  */
8833                 DRXJ_16TO8(6394),       /* RAD2  */
8834                 DRXJ_16TO8(6409),       /* RAD3  */
8835                 DRXJ_16TO8(6656),       /* RAD4  */
8836                 DRXJ_16TO8(7238),       /* RAD5  */
8837         };
8838
8839         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
8840         if (rc != 0) {
8841                 pr_err("error %d\n", rc);
8842                 goto rw_error;
8843         }
8844         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);
8845         if (rc != 0) {
8846                 pr_err("error %d\n", rc);
8847                 goto rw_error;
8848         }
8849
8850         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
8851         if (rc != 0) {
8852                 pr_err("error %d\n", rc);
8853                 goto rw_error;
8854         }
8855         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
8856         if (rc != 0) {
8857                 pr_err("error %d\n", rc);
8858                 goto rw_error;
8859         }
8860         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
8861         if (rc != 0) {
8862                 pr_err("error %d\n", rc);
8863                 goto rw_error;
8864         }
8865         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
8866         if (rc != 0) {
8867                 pr_err("error %d\n", rc);
8868                 goto rw_error;
8869         }
8870         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
8871         if (rc != 0) {
8872                 pr_err("error %d\n", rc);
8873                 goto rw_error;
8874         }
8875         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
8876         if (rc != 0) {
8877                 pr_err("error %d\n", rc);
8878                 goto rw_error;
8879         }
8880
8881         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
8882         if (rc != 0) {
8883                 pr_err("error %d\n", rc);
8884                 goto rw_error;
8885         }
8886         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
8887         if (rc != 0) {
8888                 pr_err("error %d\n", rc);
8889                 goto rw_error;
8890         }
8891         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
8892         if (rc != 0) {
8893                 pr_err("error %d\n", rc);
8894                 goto rw_error;
8895         }
8896
8897         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
8898         if (rc != 0) {
8899                 pr_err("error %d\n", rc);
8900                 goto rw_error;
8901         }
8902         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
8903         if (rc != 0) {
8904                 pr_err("error %d\n", rc);
8905                 goto rw_error;
8906         }
8907         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
8908         if (rc != 0) {
8909                 pr_err("error %d\n", rc);
8910                 goto rw_error;
8911         }
8912         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
8913         if (rc != 0) {
8914                 pr_err("error %d\n", rc);
8915                 goto rw_error;
8916         }
8917         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
8918         if (rc != 0) {
8919                 pr_err("error %d\n", rc);
8920                 goto rw_error;
8921         }
8922         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
8923         if (rc != 0) {
8924                 pr_err("error %d\n", rc);
8925                 goto rw_error;
8926         }
8927         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
8928         if (rc != 0) {
8929                 pr_err("error %d\n", rc);
8930                 goto rw_error;
8931         }
8932
8933         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 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_CA_COARSE__A, 40, 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_CP_FINE__A, 2, 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_CP_MEDIUM__A, 40, 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_CP_COARSE__A, 255, 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_CI_FINE__A, 2, 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_CI_MEDIUM__A, 20, 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_CI_COARSE__A, 80, 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_EP_FINE__A, 12, 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_EP_MEDIUM__A, 24, 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_EP_COARSE__A, 24, 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_EI_FINE__A, 12, 0);
8989         if (rc != 0) {
8990                 pr_err("error %d\n", rc);
8991                 goto rw_error;
8992         }
8993         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
8994         if (rc != 0) {
8995                 pr_err("error %d\n", rc);
8996                 goto rw_error;
8997         }
8998         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
8999         if (rc != 0) {
9000                 pr_err("error %d\n", rc);
9001                 goto rw_error;
9002         }
9003         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9004         if (rc != 0) {
9005                 pr_err("error %d\n", rc);
9006                 goto rw_error;
9007         }
9008         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
9009         if (rc != 0) {
9010                 pr_err("error %d\n", rc);
9011                 goto rw_error;
9012         }
9013         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
9014         if (rc != 0) {
9015                 pr_err("error %d\n", rc);
9016                 goto rw_error;
9017         }
9018         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9019         if (rc != 0) {
9020                 pr_err("error %d\n", rc);
9021                 goto rw_error;
9022         }
9023         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9024         if (rc != 0) {
9025                 pr_err("error %d\n", rc);
9026                 goto rw_error;
9027         }
9028         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9029         if (rc != 0) {
9030                 pr_err("error %d\n", rc);
9031                 goto rw_error;
9032         }
9033
9034         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
9035         if (rc != 0) {
9036                 pr_err("error %d\n", rc);
9037                 goto rw_error;
9038         }
9039
9040         return 0;
9041 rw_error:
9042         return -EIO;
9043 }
9044
9045 /*============================================================================*/
9046
9047 /**
9048 * \fn int set_qam256 ()
9049 * \brief QAM256 specific setup
9050 * \param demod: instance of demod.
9051 * \return int.
9052 */
9053 static int set_qam256(struct drx_demod_instance *demod)
9054 {
9055         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9056         int rc;
9057         const u8 qam_dq_qual_fun[] = {
9058                 DRXJ_16TO8(8),  /* fun0  */
9059                 DRXJ_16TO8(8),  /* fun1  */
9060                 DRXJ_16TO8(8),  /* fun2  */
9061                 DRXJ_16TO8(8),  /* fun3  */
9062                 DRXJ_16TO8(12), /* fun4  */
9063                 DRXJ_16TO8(12), /* fun5  */
9064         };
9065         const u8 qam_eq_cma_rad[] = {
9066                 DRXJ_16TO8(12345),      /* RAD0  */
9067                 DRXJ_16TO8(12345),      /* RAD1  */
9068                 DRXJ_16TO8(13626),      /* RAD2  */
9069                 DRXJ_16TO8(12931),      /* RAD3  */
9070                 DRXJ_16TO8(14719),      /* RAD4  */
9071                 DRXJ_16TO8(15356),      /* RAD5  */
9072         };
9073
9074         rc = DRXJ_DAP.write_block_func(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
9075         if (rc != 0) {
9076                 pr_err("error %d\n", rc);
9077                 goto rw_error;
9078         }
9079         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);
9080         if (rc != 0) {
9081                 pr_err("error %d\n", rc);
9082                 goto rw_error;
9083         }
9084
9085         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
9086         if (rc != 0) {
9087                 pr_err("error %d\n", rc);
9088                 goto rw_error;
9089         }
9090         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
9091         if (rc != 0) {
9092                 pr_err("error %d\n", rc);
9093                 goto rw_error;
9094         }
9095         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
9096         if (rc != 0) {
9097                 pr_err("error %d\n", rc);
9098                 goto rw_error;
9099         }
9100         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
9101         if (rc != 0) {
9102                 pr_err("error %d\n", rc);
9103                 goto rw_error;
9104         }
9105         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
9106         if (rc != 0) {
9107                 pr_err("error %d\n", rc);
9108                 goto rw_error;
9109         }
9110         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
9111         if (rc != 0) {
9112                 pr_err("error %d\n", rc);
9113                 goto rw_error;
9114         }
9115
9116         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
9117         if (rc != 0) {
9118                 pr_err("error %d\n", rc);
9119                 goto rw_error;
9120         }
9121         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
9122         if (rc != 0) {
9123                 pr_err("error %d\n", rc);
9124                 goto rw_error;
9125         }
9126         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
9127         if (rc != 0) {
9128                 pr_err("error %d\n", rc);
9129                 goto rw_error;
9130         }
9131
9132         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
9133         if (rc != 0) {
9134                 pr_err("error %d\n", rc);
9135                 goto rw_error;
9136         }
9137         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
9138         if (rc != 0) {
9139                 pr_err("error %d\n", rc);
9140                 goto rw_error;
9141         }
9142         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
9143         if (rc != 0) {
9144                 pr_err("error %d\n", rc);
9145                 goto rw_error;
9146         }
9147         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
9148         if (rc != 0) {
9149                 pr_err("error %d\n", rc);
9150                 goto rw_error;
9151         }
9152         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
9153         if (rc != 0) {
9154                 pr_err("error %d\n", rc);
9155                 goto rw_error;
9156         }
9157         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
9158         if (rc != 0) {
9159                 pr_err("error %d\n", rc);
9160                 goto rw_error;
9161         }
9162         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
9163         if (rc != 0) {
9164                 pr_err("error %d\n", rc);
9165                 goto rw_error;
9166         }
9167
9168         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 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_CA_COARSE__A, 40, 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_CP_FINE__A, 2, 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_CP_MEDIUM__A, 50, 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_CP_COARSE__A, 255, 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_CI_FINE__A, 2, 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_CI_MEDIUM__A, 25, 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_CI_COARSE__A, 80, 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_EP_FINE__A, 12, 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_EP_MEDIUM__A, 24, 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_EP_COARSE__A, 24, 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_EI_FINE__A, 12, 0);
9224         if (rc != 0) {
9225                 pr_err("error %d\n", rc);
9226                 goto rw_error;
9227         }
9228         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
9229         if (rc != 0) {
9230                 pr_err("error %d\n", rc);
9231                 goto rw_error;
9232         }
9233         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
9234         if (rc != 0) {
9235                 pr_err("error %d\n", rc);
9236                 goto rw_error;
9237         }
9238         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
9239         if (rc != 0) {
9240                 pr_err("error %d\n", rc);
9241                 goto rw_error;
9242         }
9243         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
9244         if (rc != 0) {
9245                 pr_err("error %d\n", rc);
9246                 goto rw_error;
9247         }
9248         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
9249         if (rc != 0) {
9250                 pr_err("error %d\n", rc);
9251                 goto rw_error;
9252         }
9253         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
9254         if (rc != 0) {
9255                 pr_err("error %d\n", rc);
9256                 goto rw_error;
9257         }
9258         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
9259         if (rc != 0) {
9260                 pr_err("error %d\n", rc);
9261                 goto rw_error;
9262         }
9263         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
9264         if (rc != 0) {
9265                 pr_err("error %d\n", rc);
9266                 goto rw_error;
9267         }
9268
9269         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
9270         if (rc != 0) {
9271                 pr_err("error %d\n", rc);
9272                 goto rw_error;
9273         }
9274
9275         return 0;
9276 rw_error:
9277         return -EIO;
9278 }
9279
9280 /*============================================================================*/
9281 #define QAM_SET_OP_ALL 0x1
9282 #define QAM_SET_OP_CONSTELLATION 0x2
9283 #define QAM_SET_OP_SPECTRUM 0X4
9284
9285 /**
9286 * \fn int set_qam ()
9287 * \brief Set QAM demod.
9288 * \param demod:   instance of demod.
9289 * \param channel: pointer to channel data.
9290 * \return int.
9291 */
9292 static int
9293 set_qam(struct drx_demod_instance *demod,
9294         struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
9295 {
9296         struct i2c_device_addr *dev_addr = NULL;
9297         struct drxj_data *ext_attr = NULL;
9298         struct drx_common_attr *common_attr = NULL;
9299         int rc;
9300         u32 adc_frequency = 0;
9301         u32 iqm_rc_rate = 0;
9302         u16 cmd_result = 0;
9303         u16 lc_symbol_freq = 0;
9304         u16 iqm_rc_stretch = 0;
9305         u16 set_env_parameters = 0;
9306         u16 set_param_parameters[2] = { 0 };
9307         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
9308                 /* parameter_len */ 0,
9309                 /* result_len    */ 0,
9310                 /* parameter    */ NULL,
9311                 /* result       */ NULL
9312         };
9313         const u8 qam_a_taps[] = {
9314                 DRXJ_16TO8(-1), /* re0  */
9315                 DRXJ_16TO8(1),  /* re1  */
9316                 DRXJ_16TO8(1),  /* re2  */
9317                 DRXJ_16TO8(-1), /* re3  */
9318                 DRXJ_16TO8(-1), /* re4  */
9319                 DRXJ_16TO8(2),  /* re5  */
9320                 DRXJ_16TO8(1),  /* re6  */
9321                 DRXJ_16TO8(-2), /* re7  */
9322                 DRXJ_16TO8(0),  /* re8  */
9323                 DRXJ_16TO8(3),  /* re9  */
9324                 DRXJ_16TO8(-1), /* re10 */
9325                 DRXJ_16TO8(-3), /* re11 */
9326                 DRXJ_16TO8(4),  /* re12 */
9327                 DRXJ_16TO8(1),  /* re13 */
9328                 DRXJ_16TO8(-8), /* re14 */
9329                 DRXJ_16TO8(4),  /* re15 */
9330                 DRXJ_16TO8(13), /* re16 */
9331                 DRXJ_16TO8(-13),        /* re17 */
9332                 DRXJ_16TO8(-19),        /* re18 */
9333                 DRXJ_16TO8(28), /* re19 */
9334                 DRXJ_16TO8(25), /* re20 */
9335                 DRXJ_16TO8(-53),        /* re21 */
9336                 DRXJ_16TO8(-31),        /* re22 */
9337                 DRXJ_16TO8(96), /* re23 */
9338                 DRXJ_16TO8(37), /* re24 */
9339                 DRXJ_16TO8(-190),       /* re25 */
9340                 DRXJ_16TO8(-40),        /* re26 */
9341                 DRXJ_16TO8(619) /* re27 */
9342         };
9343         const u8 qam_b64_taps[] = {
9344                 DRXJ_16TO8(0),  /* re0  */
9345                 DRXJ_16TO8(-2), /* re1  */
9346                 DRXJ_16TO8(1),  /* re2  */
9347                 DRXJ_16TO8(2),  /* re3  */
9348                 DRXJ_16TO8(-2), /* re4  */
9349                 DRXJ_16TO8(0),  /* re5  */
9350                 DRXJ_16TO8(4),  /* re6  */
9351                 DRXJ_16TO8(-2), /* re7  */
9352                 DRXJ_16TO8(-4), /* re8  */
9353                 DRXJ_16TO8(4),  /* re9  */
9354                 DRXJ_16TO8(3),  /* re10 */
9355                 DRXJ_16TO8(-6), /* re11 */
9356                 DRXJ_16TO8(0),  /* re12 */
9357                 DRXJ_16TO8(6),  /* re13 */
9358                 DRXJ_16TO8(-5), /* re14 */
9359                 DRXJ_16TO8(-3), /* re15 */
9360                 DRXJ_16TO8(11), /* re16 */
9361                 DRXJ_16TO8(-4), /* re17 */
9362                 DRXJ_16TO8(-19),        /* re18 */
9363                 DRXJ_16TO8(19), /* re19 */
9364                 DRXJ_16TO8(28), /* re20 */
9365                 DRXJ_16TO8(-45),        /* re21 */
9366                 DRXJ_16TO8(-36),        /* re22 */
9367                 DRXJ_16TO8(90), /* re23 */
9368                 DRXJ_16TO8(42), /* re24 */
9369                 DRXJ_16TO8(-185),       /* re25 */
9370                 DRXJ_16TO8(-46),        /* re26 */
9371                 DRXJ_16TO8(614) /* re27 */
9372         };
9373         const u8 qam_b256_taps[] = {
9374                 DRXJ_16TO8(-2), /* re0  */
9375                 DRXJ_16TO8(4),  /* re1  */
9376                 DRXJ_16TO8(1),  /* re2  */
9377                 DRXJ_16TO8(-4), /* re3  */
9378                 DRXJ_16TO8(0),  /* re4  */
9379                 DRXJ_16TO8(4),  /* re5  */
9380                 DRXJ_16TO8(-2), /* re6  */
9381                 DRXJ_16TO8(-4), /* re7  */
9382                 DRXJ_16TO8(5),  /* re8  */
9383                 DRXJ_16TO8(2),  /* re9  */
9384                 DRXJ_16TO8(-8), /* re10 */
9385                 DRXJ_16TO8(2),  /* re11 */
9386                 DRXJ_16TO8(11), /* re12 */
9387                 DRXJ_16TO8(-8), /* re13 */
9388                 DRXJ_16TO8(-15),        /* re14 */
9389                 DRXJ_16TO8(16), /* re15 */
9390                 DRXJ_16TO8(19), /* re16 */
9391                 DRXJ_16TO8(-27),        /* re17 */
9392                 DRXJ_16TO8(-22),        /* re18 */
9393                 DRXJ_16TO8(44), /* re19 */
9394                 DRXJ_16TO8(26), /* re20 */
9395                 DRXJ_16TO8(-69),        /* re21 */
9396                 DRXJ_16TO8(-28),        /* re22 */
9397                 DRXJ_16TO8(110),        /* re23 */
9398                 DRXJ_16TO8(31), /* re24 */
9399                 DRXJ_16TO8(-201),       /* re25 */
9400                 DRXJ_16TO8(-32),        /* re26 */
9401                 DRXJ_16TO8(628) /* re27 */
9402         };
9403         const u8 qam_c_taps[] = {
9404                 DRXJ_16TO8(-3), /* re0  */
9405                 DRXJ_16TO8(3),  /* re1  */
9406                 DRXJ_16TO8(2),  /* re2  */
9407                 DRXJ_16TO8(-4), /* re3  */
9408                 DRXJ_16TO8(0),  /* re4  */
9409                 DRXJ_16TO8(4),  /* re5  */
9410                 DRXJ_16TO8(-1), /* re6  */
9411                 DRXJ_16TO8(-4), /* re7  */
9412                 DRXJ_16TO8(3),  /* re8  */
9413                 DRXJ_16TO8(3),  /* re9  */
9414                 DRXJ_16TO8(-5), /* re10 */
9415                 DRXJ_16TO8(0),  /* re11 */
9416                 DRXJ_16TO8(9),  /* re12 */
9417                 DRXJ_16TO8(-4), /* re13 */
9418                 DRXJ_16TO8(-12),        /* re14 */
9419                 DRXJ_16TO8(10), /* re15 */
9420                 DRXJ_16TO8(16), /* re16 */
9421                 DRXJ_16TO8(-21),        /* re17 */
9422                 DRXJ_16TO8(-20),        /* re18 */
9423                 DRXJ_16TO8(37), /* re19 */
9424                 DRXJ_16TO8(25), /* re20 */
9425                 DRXJ_16TO8(-62),        /* re21 */
9426                 DRXJ_16TO8(-28),        /* re22 */
9427                 DRXJ_16TO8(105),        /* re23 */
9428                 DRXJ_16TO8(31), /* re24 */
9429                 DRXJ_16TO8(-197),       /* re25 */
9430                 DRXJ_16TO8(-33),        /* re26 */
9431                 DRXJ_16TO8(626) /* re27 */
9432         };
9433
9434         dev_addr = demod->my_i2c_dev_addr;
9435         ext_attr = (struct drxj_data *) demod->my_ext_attr;
9436         common_attr = (struct drx_common_attr *) demod->my_common_attr;
9437
9438         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9439                 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9440                         switch (channel->constellation) {
9441                         case DRX_CONSTELLATION_QAM256:
9442                                 iqm_rc_rate = 0x00AE3562;
9443                                 lc_symbol_freq =
9444                                     QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
9445                                 channel->symbolrate = 5360537;
9446                                 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
9447                                 break;
9448                         case DRX_CONSTELLATION_QAM64:
9449                                 iqm_rc_rate = 0x00C05A0E;
9450                                 lc_symbol_freq = 409;
9451                                 channel->symbolrate = 5056941;
9452                                 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
9453                                 break;
9454                         default:
9455                                 return -EINVAL;
9456                         }
9457                 } else {
9458                         adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
9459                         if (channel->symbolrate == 0) {
9460                                 pr_err("error: channel symbolrate is zero!\n");
9461                                 return -EIO;
9462                         }
9463                         iqm_rc_rate =
9464                             (adc_frequency / channel->symbolrate) * (1 << 21) +
9465                             (frac28
9466                              ((adc_frequency % channel->symbolrate),
9467                               channel->symbolrate) >> 7) - (1 << 23);
9468                         lc_symbol_freq =
9469                             (u16) (frac28
9470                                      (channel->symbolrate +
9471                                       (adc_frequency >> 13),
9472                                       adc_frequency) >> 16);
9473                         if (lc_symbol_freq > 511)
9474                                 lc_symbol_freq = 511;
9475
9476                         iqm_rc_stretch = 21;
9477                 }
9478
9479                 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
9480                         set_env_parameters = QAM_TOP_ANNEX_A;   /* annex             */
9481                         set_param_parameters[0] = channel->constellation;       /* constellation     */
9482                         set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
9483                 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9484                         set_env_parameters = QAM_TOP_ANNEX_B;   /* annex             */
9485                         set_param_parameters[0] = channel->constellation;       /* constellation     */
9486                         set_param_parameters[1] = channel->interleavemode;      /* interleave mode   */
9487                 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9488                         set_env_parameters = QAM_TOP_ANNEX_C;   /* annex             */
9489                         set_param_parameters[0] = channel->constellation;       /* constellation     */
9490                         set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17;   /* interleave mode   */
9491                 } else {
9492                         return -EINVAL;
9493                 }
9494         }
9495
9496         if (op & QAM_SET_OP_ALL) {
9497                 /*
9498                    STEP 1: reset demodulator
9499                    resets IQM, QAM and FEC HW blocks
9500                    resets SCU variables
9501                  */
9502                 /* stop all comm_exec */
9503                 rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
9504                 if (rc != 0) {
9505                         pr_err("error %d\n", rc);
9506                         goto rw_error;
9507                 }
9508                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
9509                 if (rc != 0) {
9510                         pr_err("error %d\n", rc);
9511                         goto rw_error;
9512                 }
9513                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9514                 if (rc != 0) {
9515                         pr_err("error %d\n", rc);
9516                         goto rw_error;
9517                 }
9518                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9519                 if (rc != 0) {
9520                         pr_err("error %d\n", rc);
9521                         goto rw_error;
9522                 }
9523                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9524                 if (rc != 0) {
9525                         pr_err("error %d\n", rc);
9526                         goto rw_error;
9527                 }
9528                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9529                 if (rc != 0) {
9530                         pr_err("error %d\n", rc);
9531                         goto rw_error;
9532                 }
9533                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9534                 if (rc != 0) {
9535                         pr_err("error %d\n", rc);
9536                         goto rw_error;
9537                 }
9538
9539                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9540                     SCU_RAM_COMMAND_CMD_DEMOD_RESET;
9541                 cmd_scu.parameter_len = 0;
9542                 cmd_scu.result_len = 1;
9543                 cmd_scu.parameter = NULL;
9544                 cmd_scu.result = &cmd_result;
9545                 rc = scu_command(dev_addr, &cmd_scu);
9546                 if (rc != 0) {
9547                         pr_err("error %d\n", rc);
9548                         goto rw_error;
9549                 }
9550         }
9551
9552         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9553                 /*
9554                    STEP 2: configure demodulator
9555                    -set env
9556                    -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
9557                  */
9558                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9559                     SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
9560                 cmd_scu.parameter_len = 1;
9561                 cmd_scu.result_len = 1;
9562                 cmd_scu.parameter = &set_env_parameters;
9563                 cmd_scu.result = &cmd_result;
9564                 rc = scu_command(dev_addr, &cmd_scu);
9565                 if (rc != 0) {
9566                         pr_err("error %d\n", rc);
9567                         goto rw_error;
9568                 }
9569
9570                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
9571                     SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
9572                 cmd_scu.parameter_len = 2;
9573                 cmd_scu.result_len = 1;
9574                 cmd_scu.parameter = set_param_parameters;
9575                 cmd_scu.result = &cmd_result;
9576                 rc = scu_command(dev_addr, &cmd_scu);
9577                 if (rc != 0) {
9578                         pr_err("error %d\n", rc);
9579                         goto rw_error;
9580                 }
9581                 /* set symbol rate */
9582                 rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
9583                 if (rc != 0) {
9584                         pr_err("error %d\n", rc);
9585                         goto rw_error;
9586                 }
9587                 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
9588                 rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
9589                 if (rc != 0) {
9590                         pr_err("error %d\n", rc);
9591                         goto rw_error;
9592                 }
9593         }
9594         /* STEP 3: enable the system in a mode where the ADC provides valid signal
9595            setup constellation independent registers */
9596         /* from qam_cmd.py script (qam_driver_b) */
9597         /* TODO: remove re-writes of HW reset values */
9598         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
9599                 rc = set_frequency(demod, channel, tuner_freq_offset);
9600                 if (rc != 0) {
9601                         pr_err("error %d\n", rc);
9602                         goto rw_error;
9603                 }
9604         }
9605
9606         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9607
9608                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
9609                 if (rc != 0) {
9610                         pr_err("error %d\n", rc);
9611                         goto rw_error;
9612                 }
9613                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
9614                 if (rc != 0) {
9615                         pr_err("error %d\n", rc);
9616                         goto rw_error;
9617                 }
9618         }
9619
9620         if (op & QAM_SET_OP_ALL) {
9621                 if (!ext_attr->has_lna) {
9622                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
9623                         if (rc != 0) {
9624                                 pr_err("error %d\n", rc);
9625                                 goto rw_error;
9626                         }
9627                 }
9628                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
9629                 if (rc != 0) {
9630                         pr_err("error %d\n", rc);
9631                         goto rw_error;
9632                 }
9633                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
9634                 if (rc != 0) {
9635                         pr_err("error %d\n", rc);
9636                         goto rw_error;
9637                 }
9638                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
9639                 if (rc != 0) {
9640                         pr_err("error %d\n", rc);
9641                         goto rw_error;
9642                 }
9643
9644                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
9645                 if (rc != 0) {
9646                         pr_err("error %d\n", rc);
9647                         goto rw_error;
9648                 }       /* scu temporary shut down agc */
9649
9650                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
9651                 if (rc != 0) {
9652                         pr_err("error %d\n", rc);
9653                         goto rw_error;
9654                 }
9655                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
9656                 if (rc != 0) {
9657                         pr_err("error %d\n", rc);
9658                         goto rw_error;
9659                 }
9660                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
9661                 if (rc != 0) {
9662                         pr_err("error %d\n", rc);
9663                         goto rw_error;
9664                 }
9665                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
9666                 if (rc != 0) {
9667                         pr_err("error %d\n", rc);
9668                         goto rw_error;
9669                 }
9670                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PDREF__A, 4, 0);
9671                 if (rc != 0) {
9672                         pr_err("error %d\n", rc);
9673                         goto rw_error;
9674                 }
9675                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
9676                 if (rc != 0) {
9677                         pr_err("error %d\n", rc);
9678                         goto rw_error;
9679                 }
9680                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
9681                 if (rc != 0) {
9682                         pr_err("error %d\n", rc);
9683                         goto rw_error;
9684                 }
9685
9686                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
9687                 if (rc != 0) {
9688                         pr_err("error %d\n", rc);
9689                         goto rw_error;
9690                 }
9691                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
9692                 if (rc != 0) {
9693                         pr_err("error %d\n", rc);
9694                         goto rw_error;
9695                 }       /*! reset default val ! */
9696
9697                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
9698                 if (rc != 0) {
9699                         pr_err("error %d\n", rc);
9700                         goto rw_error;
9701                 }       /*! reset default val ! */
9702                 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9703                         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
9704                         if (rc != 0) {
9705                                 pr_err("error %d\n", rc);
9706                                 goto rw_error;
9707                         }       /*! reset default val ! */
9708                         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
9709                         if (rc != 0) {
9710                                 pr_err("error %d\n", rc);
9711                                 goto rw_error;
9712                         }       /*! reset default val ! */
9713                         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9714                         if (rc != 0) {
9715                                 pr_err("error %d\n", rc);
9716                                 goto rw_error;
9717                         }       /*! reset default val ! */
9718                 } else {
9719                         switch (channel->constellation) {
9720                         case DRX_CONSTELLATION_QAM16:
9721                         case DRX_CONSTELLATION_QAM64:
9722                         case DRX_CONSTELLATION_QAM256:
9723                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9724                                 if (rc != 0) {
9725                                         pr_err("error %d\n", rc);
9726                                         goto rw_error;
9727                                 }
9728                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
9729                                 if (rc != 0) {
9730                                         pr_err("error %d\n", rc);
9731                                         goto rw_error;
9732                                 }
9733                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
9734                                 if (rc != 0) {
9735                                         pr_err("error %d\n", rc);
9736                                         goto rw_error;
9737                                 }       /*! reset default val ! */
9738                                 break;
9739                         case DRX_CONSTELLATION_QAM32:
9740                         case DRX_CONSTELLATION_QAM128:
9741                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
9742                                 if (rc != 0) {
9743                                         pr_err("error %d\n", rc);
9744                                         goto rw_error;
9745                                 }
9746                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
9747                                 if (rc != 0) {
9748                                         pr_err("error %d\n", rc);
9749                                         goto rw_error;
9750                                 }
9751                                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
9752                                 if (rc != 0) {
9753                                         pr_err("error %d\n", rc);
9754                                         goto rw_error;
9755                                 }
9756                                 break;
9757                         default:
9758                                 return -EIO;
9759                         }       /* switch */
9760                 }
9761
9762                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
9763                 if (rc != 0) {
9764                         pr_err("error %d\n", rc);
9765                         goto rw_error;
9766                 }       /*! reset default val ! */
9767                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 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_LPF_FACTORP__A, 4, 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_LPF_FACTORI__A, 4, 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_MODE__A, 7, 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_TAB0__A, 1, 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_TAB1__A, 1, 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_TAB2__A, 1, 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_TAB3__A, 1, 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_TAB4__A, 2, 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_TAB5__A, 2, 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_TAB6__A, 2, 0);
9818                 if (rc != 0) {
9819                         pr_err("error %d\n", rc);
9820                         goto rw_error;
9821                 }
9822                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
9823                 if (rc != 0) {
9824                         pr_err("error %d\n", rc);
9825                         goto rw_error;
9826                 }
9827                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
9828                 if (rc != 0) {
9829                         pr_err("error %d\n", rc);
9830                         goto rw_error;
9831                 }
9832                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
9833                 if (rc != 0) {
9834                         pr_err("error %d\n", rc);
9835                         goto rw_error;
9836                 }
9837                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
9838                 if (rc != 0) {
9839                         pr_err("error %d\n", rc);
9840                         goto rw_error;
9841                 }
9842                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
9843                 if (rc != 0) {
9844                         pr_err("error %d\n", rc);
9845                         goto rw_error;
9846                 }
9847                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
9848                 if (rc != 0) {
9849                         pr_err("error %d\n", rc);
9850                         goto rw_error;
9851                 }
9852                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
9853                 if (rc != 0) {
9854                         pr_err("error %d\n", rc);
9855                         goto rw_error;
9856                 }
9857                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
9858                 if (rc != 0) {
9859                         pr_err("error %d\n", rc);
9860                         goto rw_error;
9861                 }
9862
9863                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
9864                 if (rc != 0) {
9865                         pr_err("error %d\n", rc);
9866                         goto rw_error;
9867                 }
9868                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
9869                 if (rc != 0) {
9870                         pr_err("error %d\n", rc);
9871                         goto rw_error;
9872                 }
9873                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
9874                 if (rc != 0) {
9875                         pr_err("error %d\n", rc);
9876                         goto rw_error;
9877                 }
9878                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
9879                 if (rc != 0) {
9880                         pr_err("error %d\n", rc);
9881                         goto rw_error;
9882                 }
9883                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
9884                 if (rc != 0) {
9885                         pr_err("error %d\n", rc);
9886                         goto rw_error;
9887                 }
9888
9889                 /* No more resets of the IQM, current standard correctly set =>
9890                    now AGCs can be configured. */
9891                 /* turn on IQMAF. It has to be in front of setAgc**() */
9892                 rc = set_iqm_af(demod, true);
9893                 if (rc != 0) {
9894                         pr_err("error %d\n", rc);
9895                         goto rw_error;
9896                 }
9897                 rc = adc_synchronization(demod);
9898                 if (rc != 0) {
9899                         pr_err("error %d\n", rc);
9900                         goto rw_error;
9901                 }
9902
9903                 rc = init_agc(demod);
9904                 if (rc != 0) {
9905                         pr_err("error %d\n", rc);
9906                         goto rw_error;
9907                 }
9908                 rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
9909                 if (rc != 0) {
9910                         pr_err("error %d\n", rc);
9911                         goto rw_error;
9912                 }
9913                 rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
9914                 if (rc != 0) {
9915                         pr_err("error %d\n", rc);
9916                         goto rw_error;
9917                 }
9918                 {
9919                         /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
9920                            of only the gain */
9921                         struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
9922
9923                         qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
9924                         rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
9925                         if (rc != 0) {
9926                                 pr_err("error %d\n", rc);
9927                                 goto rw_error;
9928                         }
9929                 }
9930                 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
9931                 if (rc != 0) {
9932                         pr_err("error %d\n", rc);
9933                         goto rw_error;
9934                 }
9935         }
9936
9937         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
9938                 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
9939                         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_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_a_taps), ((u8 *)qam_a_taps), 0);
9945                         if (rc != 0) {
9946                                 pr_err("error %d\n", rc);
9947                                 goto rw_error;
9948                         }
9949                 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9950                         switch (channel->constellation) {
9951                         case DRX_CONSTELLATION_QAM64:
9952                                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9953                                 if (rc != 0) {
9954                                         pr_err("error %d\n", rc);
9955                                         goto rw_error;
9956                                 }
9957                                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
9958                                 if (rc != 0) {
9959                                         pr_err("error %d\n", rc);
9960                                         goto rw_error;
9961                                 }
9962                                 break;
9963                         case DRX_CONSTELLATION_QAM256:
9964                                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9965                                 if (rc != 0) {
9966                                         pr_err("error %d\n", rc);
9967                                         goto rw_error;
9968                                 }
9969                                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
9970                                 if (rc != 0) {
9971                                         pr_err("error %d\n", rc);
9972                                         goto rw_error;
9973                                 }
9974                                 break;
9975                         default:
9976                                 return -EIO;
9977                         }
9978                 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9979                         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9980                         if (rc != 0) {
9981                                 pr_err("error %d\n", rc);
9982                                 goto rw_error;
9983                         }
9984                         rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
9985                         if (rc != 0) {
9986                                 pr_err("error %d\n", rc);
9987                                 goto rw_error;
9988                         }
9989                 }
9990
9991                 /* SETP 4: constellation specific setup */
9992                 switch (channel->constellation) {
9993                 case DRX_CONSTELLATION_QAM16:
9994                         rc = set_qam16(demod);
9995                         if (rc != 0) {
9996                                 pr_err("error %d\n", rc);
9997                                 goto rw_error;
9998                         }
9999                         break;
10000                 case DRX_CONSTELLATION_QAM32:
10001                         rc = set_qam32(demod);
10002                         if (rc != 0) {
10003                                 pr_err("error %d\n", rc);
10004                                 goto rw_error;
10005                         }
10006                         break;
10007                 case DRX_CONSTELLATION_QAM64:
10008                         rc = set_qam64(demod);
10009                         if (rc != 0) {
10010                                 pr_err("error %d\n", rc);
10011                                 goto rw_error;
10012                         }
10013                         break;
10014                 case DRX_CONSTELLATION_QAM128:
10015                         rc = set_qam128(demod);
10016                         if (rc != 0) {
10017                                 pr_err("error %d\n", rc);
10018                                 goto rw_error;
10019                         }
10020                         break;
10021                 case DRX_CONSTELLATION_QAM256:
10022                         rc = set_qam256(demod);
10023                         if (rc != 0) {
10024                                 pr_err("error %d\n", rc);
10025                                 goto rw_error;
10026                         }
10027                         break;
10028                 default:
10029                         return -EIO;
10030                 }               /* switch */
10031         }
10032
10033         if ((op & QAM_SET_OP_ALL)) {
10034                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
10035                 if (rc != 0) {
10036                         pr_err("error %d\n", rc);
10037                         goto rw_error;
10038                 }
10039
10040                 /* Mpeg output has to be in front of FEC active */
10041                 rc = set_mpegtei_handling(demod);
10042                 if (rc != 0) {
10043                         pr_err("error %d\n", rc);
10044                         goto rw_error;
10045                 }
10046                 rc = bit_reverse_mpeg_output(demod);
10047                 if (rc != 0) {
10048                         pr_err("error %d\n", rc);
10049                         goto rw_error;
10050                 }
10051                 rc = set_mpeg_start_width(demod);
10052                 if (rc != 0) {
10053                         pr_err("error %d\n", rc);
10054                         goto rw_error;
10055                 }
10056                 {
10057                         /* TODO: move to set_standard after hardware reset value problem is solved */
10058                         /* Configure initial MPEG output */
10059                         struct drx_cfg_mpeg_output cfg_mpeg_output;
10060
10061                         cfg_mpeg_output.enable_mpeg_output = true;
10062                         cfg_mpeg_output.insert_rs_byte =
10063                             common_attr->mpeg_cfg.insert_rs_byte;
10064                         cfg_mpeg_output.enable_parallel =
10065                             common_attr->mpeg_cfg.enable_parallel;
10066                         cfg_mpeg_output.invert_data =
10067                             common_attr->mpeg_cfg.invert_data;
10068                         cfg_mpeg_output.invert_err = common_attr->mpeg_cfg.invert_err;
10069                         cfg_mpeg_output.invert_str = common_attr->mpeg_cfg.invert_str;
10070                         cfg_mpeg_output.invert_val = common_attr->mpeg_cfg.invert_val;
10071                         cfg_mpeg_output.invert_clk = common_attr->mpeg_cfg.invert_clk;
10072                         cfg_mpeg_output.static_clk = common_attr->mpeg_cfg.static_clk;
10073                         cfg_mpeg_output.bitrate = common_attr->mpeg_cfg.bitrate;
10074                         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
10075                         if (rc != 0) {
10076                                 pr_err("error %d\n", rc);
10077                                 goto rw_error;
10078                         }
10079                 }
10080         }
10081
10082         if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
10083
10084                 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
10085                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10086                     SCU_RAM_COMMAND_CMD_DEMOD_START;
10087                 cmd_scu.parameter_len = 0;
10088                 cmd_scu.result_len = 1;
10089                 cmd_scu.parameter = NULL;
10090                 cmd_scu.result = &cmd_result;
10091                 rc = scu_command(dev_addr, &cmd_scu);
10092                 if (rc != 0) {
10093                         pr_err("error %d\n", rc);
10094                         goto rw_error;
10095                 }
10096         }
10097
10098         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
10099         if (rc != 0) {
10100                 pr_err("error %d\n", rc);
10101                 goto rw_error;
10102         }
10103         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
10104         if (rc != 0) {
10105                 pr_err("error %d\n", rc);
10106                 goto rw_error;
10107         }
10108         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
10109         if (rc != 0) {
10110                 pr_err("error %d\n", rc);
10111                 goto rw_error;
10112         }
10113
10114         return 0;
10115 rw_error:
10116         return -EIO;
10117 }
10118
10119 /*============================================================================*/
10120 static int
10121 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality);
10122 static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
10123 {
10124         int rc;
10125         u32 iqm_fs_rate_ofs = 0;
10126         u32 iqm_fs_rate_lo = 0;
10127         u16 qam_ctl_ena = 0;
10128         u16 data = 0;
10129         u16 equ_mode = 0;
10130         u16 fsm_state = 0;
10131         int i = 0;
10132         int ofsofs = 0;
10133         struct i2c_device_addr *dev_addr = NULL;
10134         struct drxj_data *ext_attr = NULL;
10135
10136         dev_addr = demod->my_i2c_dev_addr;
10137         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10138
10139         /* Silence the controlling of lc, equ, and the acquisition state machine */
10140         rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10141         if (rc != 0) {
10142                 pr_err("error %d\n", rc);
10143                 goto rw_error;
10144         }
10145         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);
10146         if (rc != 0) {
10147                 pr_err("error %d\n", rc);
10148                 goto rw_error;
10149         }
10150
10151         /* freeze the frequency control loop */
10152         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CF__A, 0, 0);
10153         if (rc != 0) {
10154                 pr_err("error %d\n", rc);
10155                 goto rw_error;
10156         }
10157         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CF1__A, 0, 0);
10158         if (rc != 0) {
10159                 pr_err("error %d\n", rc);
10160                 goto rw_error;
10161         }
10162
10163         rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
10164         if (rc != 0) {
10165                 pr_err("error %d\n", rc);
10166                 goto rw_error;
10167         }
10168         rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
10169         if (rc != 0) {
10170                 pr_err("error %d\n", rc);
10171                 goto rw_error;
10172         }
10173         ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
10174         iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
10175         iqm_fs_rate_ofs -= 2 * ofsofs;
10176
10177         /* freeze dq/fq updating */
10178         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_MODE__A, &data, 0);
10179         if (rc != 0) {
10180                 pr_err("error %d\n", rc);
10181                 goto rw_error;
10182         }
10183         data = (data & 0xfff9);
10184         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10185         if (rc != 0) {
10186                 pr_err("error %d\n", rc);
10187                 goto rw_error;
10188         }
10189         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10190         if (rc != 0) {
10191                 pr_err("error %d\n", rc);
10192                 goto rw_error;
10193         }
10194
10195         /* lc_cp / _ci / _ca */
10196         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_CI__A, 0, 0);
10197         if (rc != 0) {
10198                 pr_err("error %d\n", rc);
10199                 goto rw_error;
10200         }
10201         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_LC_EP__A, 0, 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_FQ_LA_FACTOR__A, 0, 0);
10207         if (rc != 0) {
10208                 pr_err("error %d\n", rc);
10209                 goto rw_error;
10210         }
10211
10212         /* flip the spec */
10213         rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
10214         if (rc != 0) {
10215                 pr_err("error %d\n", rc);
10216                 goto rw_error;
10217         }
10218         ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
10219         ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
10220
10221         /* freeze dq/fq updating */
10222         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_MODE__A, &data, 0);
10223         if (rc != 0) {
10224                 pr_err("error %d\n", rc);
10225                 goto rw_error;
10226         }
10227         equ_mode = data;
10228         data = (data & 0xfff9);
10229         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10230         if (rc != 0) {
10231                 pr_err("error %d\n", rc);
10232                 goto rw_error;
10233         }
10234         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10235         if (rc != 0) {
10236                 pr_err("error %d\n", rc);
10237                 goto rw_error;
10238         }
10239
10240         for (i = 0; i < 28; i++) {
10241                 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
10242                 if (rc != 0) {
10243                         pr_err("error %d\n", rc);
10244                         goto rw_error;
10245                 }
10246                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
10247                 if (rc != 0) {
10248                         pr_err("error %d\n", rc);
10249                         goto rw_error;
10250                 }
10251         }
10252
10253         for (i = 0; i < 24; i++) {
10254                 rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
10255                 if (rc != 0) {
10256                         pr_err("error %d\n", rc);
10257                         goto rw_error;
10258                 }
10259                 rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
10260                 if (rc != 0) {
10261                         pr_err("error %d\n", rc);
10262                         goto rw_error;
10263                 }
10264         }
10265
10266         data = equ_mode;
10267         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_DQ_MODE__A, data, 0);
10268         if (rc != 0) {
10269                 pr_err("error %d\n", rc);
10270                 goto rw_error;
10271         }
10272         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_FQ_MODE__A, data, 0);
10273         if (rc != 0) {
10274                 pr_err("error %d\n", rc);
10275                 goto rw_error;
10276         }
10277
10278         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
10279         if (rc != 0) {
10280                 pr_err("error %d\n", rc);
10281                 goto rw_error;
10282         }
10283
10284         i = 0;
10285         while ((fsm_state != 4) && (i++ < 100)) {
10286                 rc = DRXJ_DAP.read_reg16func(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
10287                 if (rc != 0) {
10288                         pr_err("error %d\n", rc);
10289                         goto rw_error;
10290                 }
10291         }
10292         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
10293         if (rc != 0) {
10294                 pr_err("error %d\n", rc);
10295                 goto rw_error;
10296         }
10297
10298         return 0;
10299 rw_error:
10300         return -EIO;
10301
10302 }
10303
10304 #define  NO_LOCK        0x0
10305 #define  DEMOD_LOCKED   0x1
10306 #define  SYNC_FLIPPED   0x2
10307 #define  SPEC_MIRRORED  0x4
10308 /**
10309 * \fn int qam64auto ()
10310 * \brief auto do sync pattern switching and mirroring.
10311 * \param demod:   instance of demod.
10312 * \param channel: pointer to channel data.
10313 * \param tuner_freq_offset: tuner frequency offset.
10314 * \param lock_status: pointer to lock status.
10315 * \return int.
10316 */
10317 static int
10318 qam64auto(struct drx_demod_instance *demod,
10319           struct drx_channel *channel,
10320           s32 tuner_freq_offset, enum drx_lock_status *lock_status)
10321 {
10322         struct drx_sig_quality sig_quality;
10323         struct drxj_data *ext_attr = NULL;
10324         int rc;
10325         u32 state = NO_LOCK;
10326         u32 start_time = 0;
10327         u32 d_locked_time = 0;
10328         u32 timeout_ofs = 0;
10329         u16 data = 0;
10330
10331         /* external attributes for storing aquired channel constellation */
10332         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10333         *lock_status = DRX_NOT_LOCKED;
10334         start_time = drxbsp_hst_clock();
10335         state = NO_LOCK;
10336         do {
10337                 rc = ctrl_lock_status(demod, lock_status);
10338                 if (rc != 0) {
10339                         pr_err("error %d\n", rc);
10340                         goto rw_error;
10341                 }
10342
10343                 switch (state) {
10344                 case NO_LOCK:
10345                         if (*lock_status == DRXJ_DEMOD_LOCK) {
10346                                 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10347                                 if (rc != 0) {
10348                                         pr_err("error %d\n", rc);
10349                                         goto rw_error;
10350                                 }
10351                                 if (sig_quality.MER > 208) {
10352                                         state = DEMOD_LOCKED;
10353                                         /* some delay to see if fec_lock possible TODO find the right value */
10354                                         timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;        /* see something, waiting longer */
10355                                         d_locked_time = drxbsp_hst_clock();
10356                                 }
10357                         }
10358                         break;
10359                 case DEMOD_LOCKED:
10360                         if ((*lock_status == DRXJ_DEMOD_LOCK) &&        /* still demod_lock in 150ms */
10361                             ((drxbsp_hst_clock() - d_locked_time) >
10362                              DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10363                                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10364                                 if (rc != 0) {
10365                                         pr_err("error %d\n", rc);
10366                                         goto rw_error;
10367                                 }
10368                                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
10369                                 if (rc != 0) {
10370                                         pr_err("error %d\n", rc);
10371                                         goto rw_error;
10372                                 }
10373                                 state = SYNC_FLIPPED;
10374                                 drxbsp_hst_sleep(10);
10375                         }
10376                         break;
10377                 case SYNC_FLIPPED:
10378                         if (*lock_status == DRXJ_DEMOD_LOCK) {
10379                                 if (channel->mirror == DRX_MIRROR_AUTO) {
10380                                         /* flip sync pattern back */
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 & 0xFFFE, 0);
10387                                         if (rc != 0) {
10388                                                 pr_err("error %d\n", rc);
10389                                                 goto rw_error;
10390                                         }
10391                                         /* flip spectrum */
10392                                         ext_attr->mirror = DRX_MIRROR_YES;
10393                                         rc = qam_flip_spec(demod, channel);
10394                                         if (rc != 0) {
10395                                                 pr_err("error %d\n", rc);
10396                                                 goto rw_error;
10397                                         }
10398                                         state = SPEC_MIRRORED;
10399                                         /* reset timer TODO: still need 500ms? */
10400                                         start_time = d_locked_time =
10401                                             drxbsp_hst_clock();
10402                                         timeout_ofs = 0;
10403                                 } else {        /* no need to wait lock */
10404
10405                                         start_time =
10406                                             drxbsp_hst_clock() -
10407                                             DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
10408                                 }
10409                         }
10410                         break;
10411                 case SPEC_MIRRORED:
10412                         if ((*lock_status == DRXJ_DEMOD_LOCK) &&        /* still demod_lock in 150ms */
10413                             ((drxbsp_hst_clock() - d_locked_time) >
10414                              DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10415                                 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10416                                 if (rc != 0) {
10417                                         pr_err("error %d\n", rc);
10418                                         goto rw_error;
10419                                 }
10420                                 if (sig_quality.MER > 208) {
10421                                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
10422                                         if (rc != 0) {
10423                                                 pr_err("error %d\n", rc);
10424                                                 goto rw_error;
10425                                         }
10426                                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
10427                                         if (rc != 0) {
10428                                                 pr_err("error %d\n", rc);
10429                                                 goto rw_error;
10430                                         }
10431                                         /* no need to wait lock */
10432                                         start_time =
10433                                             drxbsp_hst_clock() -
10434                                             DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
10435                                 }
10436                         }
10437                         break;
10438                 default:
10439                         break;
10440                 }
10441                 drxbsp_hst_sleep(10);
10442         } while
10443             ((*lock_status != DRX_LOCKED) &&
10444              (*lock_status != DRX_NEVER_LOCK) &&
10445              ((drxbsp_hst_clock() - start_time) <
10446               (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
10447             );
10448         /* Returning control to apllication ... */
10449
10450         return 0;
10451 rw_error:
10452         return -EIO;
10453 }
10454
10455 /**
10456 * \fn int qam256auto ()
10457 * \brief auto do sync pattern switching and mirroring.
10458 * \param demod:   instance of demod.
10459 * \param channel: pointer to channel data.
10460 * \param tuner_freq_offset: tuner frequency offset.
10461 * \param lock_status: pointer to lock status.
10462 * \return int.
10463 */
10464 static int
10465 qam256auto(struct drx_demod_instance *demod,
10466            struct drx_channel *channel,
10467            s32 tuner_freq_offset, enum drx_lock_status *lock_status)
10468 {
10469         struct drx_sig_quality sig_quality;
10470         struct drxj_data *ext_attr = NULL;
10471         int rc;
10472         u32 state = NO_LOCK;
10473         u32 start_time = 0;
10474         u32 d_locked_time = 0;
10475         u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
10476
10477         /* external attributes for storing aquired channel constellation */
10478         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10479         *lock_status = DRX_NOT_LOCKED;
10480         start_time = drxbsp_hst_clock();
10481         state = NO_LOCK;
10482         do {
10483                 rc = ctrl_lock_status(demod, lock_status);
10484                 if (rc != 0) {
10485                         pr_err("error %d\n", rc);
10486                         goto rw_error;
10487                 }
10488                 switch (state) {
10489                 case NO_LOCK:
10490                         if (*lock_status == DRXJ_DEMOD_LOCK) {
10491                                 rc = ctrl_get_qam_sig_quality(demod, &sig_quality);
10492                                 if (rc != 0) {
10493                                         pr_err("error %d\n", rc);
10494                                         goto rw_error;
10495                                 }
10496                                 if (sig_quality.MER > 268) {
10497                                         state = DEMOD_LOCKED;
10498                                         timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;        /* see something, wait longer */
10499                                         d_locked_time = drxbsp_hst_clock();
10500                                 }
10501                         }
10502                         break;
10503                 case DEMOD_LOCKED:
10504                         if (*lock_status == DRXJ_DEMOD_LOCK) {
10505                                 if ((channel->mirror == DRX_MIRROR_AUTO) &&
10506                                     ((drxbsp_hst_clock() - d_locked_time) >
10507                                      DRXJ_QAM_FEC_LOCK_WAITTIME)) {
10508                                         ext_attr->mirror = DRX_MIRROR_YES;
10509                                         rc = qam_flip_spec(demod, channel);
10510                                         if (rc != 0) {
10511                                                 pr_err("error %d\n", rc);
10512                                                 goto rw_error;
10513                                         }
10514                                         state = SPEC_MIRRORED;
10515                                         /* reset timer TODO: still need 300ms? */
10516                                         start_time = drxbsp_hst_clock();
10517                                         timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
10518                                 }
10519                         }
10520                         break;
10521                 case SPEC_MIRRORED:
10522                         break;
10523                 default:
10524                         break;
10525                 }
10526                 drxbsp_hst_sleep(10);
10527         } while
10528             ((*lock_status < DRX_LOCKED) &&
10529              (*lock_status != DRX_NEVER_LOCK) &&
10530              ((drxbsp_hst_clock() - start_time) <
10531               (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
10532
10533         return 0;
10534 rw_error:
10535         return -EIO;
10536 }
10537
10538 /**
10539 * \fn int set_qam_channel ()
10540 * \brief Set QAM channel according to the requested constellation.
10541 * \param demod:   instance of demod.
10542 * \param channel: pointer to channel data.
10543 * \return int.
10544 */
10545 static int
10546 set_qam_channel(struct drx_demod_instance *demod,
10547                struct drx_channel *channel, s32 tuner_freq_offset)
10548 {
10549         struct drxj_data *ext_attr = NULL;
10550         int rc;
10551         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
10552         bool auto_flag = false;
10553
10554         /* external attributes for storing aquired channel constellation */
10555         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10556
10557         /* set QAM channel constellation */
10558         switch (channel->constellation) {
10559         case DRX_CONSTELLATION_QAM16:
10560         case DRX_CONSTELLATION_QAM32:
10561         case DRX_CONSTELLATION_QAM64:
10562         case DRX_CONSTELLATION_QAM128:
10563         case DRX_CONSTELLATION_QAM256:
10564                 ext_attr->constellation = channel->constellation;
10565                 if (channel->mirror == DRX_MIRROR_AUTO)
10566                         ext_attr->mirror = DRX_MIRROR_NO;
10567                 else
10568                         ext_attr->mirror = channel->mirror;
10569                 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
10570                 if (rc != 0) {
10571                         pr_err("error %d\n", rc);
10572                         goto rw_error;
10573                 }
10574
10575                 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
10576                     (channel->constellation == DRX_CONSTELLATION_QAM64)) {
10577                         rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10578                         if (rc != 0) {
10579                                 pr_err("error %d\n", rc);
10580                                 goto rw_error;
10581                         }
10582                 }
10583
10584                 if ((ext_attr->standard == DRX_STANDARD_ITU_B) &&
10585                     (channel->mirror == DRX_MIRROR_AUTO) &&
10586                     (channel->constellation == DRX_CONSTELLATION_QAM256)) {
10587                         rc = qam256auto(demod, channel, tuner_freq_offset, &lock_status);
10588                         if (rc != 0) {
10589                                 pr_err("error %d\n", rc);
10590                                 goto rw_error;
10591                         }
10592                 }
10593                 break;
10594         case DRX_CONSTELLATION_AUTO:    /* for channel scan */
10595                 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
10596                         auto_flag = true;
10597                         /* try to lock default QAM constellation: QAM64 */
10598                         channel->constellation = DRX_CONSTELLATION_QAM256;
10599                         ext_attr->constellation = DRX_CONSTELLATION_QAM256;
10600                         if (channel->mirror == DRX_MIRROR_AUTO)
10601                                 ext_attr->mirror = DRX_MIRROR_NO;
10602                         else
10603                                 ext_attr->mirror = channel->mirror;
10604                         rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
10605                         if (rc != 0) {
10606                                 pr_err("error %d\n", rc);
10607                                 goto rw_error;
10608                         }
10609                         rc = qam256auto(demod, channel, tuner_freq_offset, &lock_status);
10610                         if (rc != 0) {
10611                                 pr_err("error %d\n", rc);
10612                                 goto rw_error;
10613                         }
10614
10615                         if (lock_status < DRX_LOCKED) {
10616                                 /* QAM254 not locked -> try to lock QAM64 constellation */
10617                                 channel->constellation =
10618                                     DRX_CONSTELLATION_QAM64;
10619                                 ext_attr->constellation =
10620                                     DRX_CONSTELLATION_QAM64;
10621                                 if (channel->mirror == DRX_MIRROR_AUTO)
10622                                         ext_attr->mirror = DRX_MIRROR_NO;
10623                                 else
10624                                         ext_attr->mirror = channel->mirror;
10625                                 {
10626                                         u16 qam_ctl_ena = 0;
10627                                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10628                                         if (rc != 0) {
10629                                                 pr_err("error %d\n", rc);
10630                                                 goto rw_error;
10631                                         }
10632                                         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);
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_FSM_STATE_TGT__A, 0x2, 0);
10638                                         if (rc != 0) {
10639                                                 pr_err("error %d\n", rc);
10640                                                 goto rw_error;
10641                                         }       /* force to rate hunting */
10642
10643                                         rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_CONSTELLATION);
10644                                         if (rc != 0) {
10645                                                 pr_err("error %d\n", rc);
10646                                                 goto rw_error;
10647                                         }
10648                                         rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena, 0);
10649                                         if (rc != 0) {
10650                                                 pr_err("error %d\n", rc);
10651                                                 goto rw_error;
10652                                         }
10653                                 }
10654                                 rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10655                                 if (rc != 0) {
10656                                         pr_err("error %d\n", rc);
10657                                         goto rw_error;
10658                                 }
10659                         }
10660                         channel->constellation = DRX_CONSTELLATION_AUTO;
10661                 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
10662                         channel->constellation = DRX_CONSTELLATION_QAM64;
10663                         ext_attr->constellation = DRX_CONSTELLATION_QAM64;
10664                         auto_flag = true;
10665
10666                         if (channel->mirror == DRX_MIRROR_AUTO)
10667                                 ext_attr->mirror = DRX_MIRROR_NO;
10668                         else
10669                                 ext_attr->mirror = channel->mirror;
10670                         {
10671                                 u16 qam_ctl_ena = 0;
10672                                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
10673                                 if (rc != 0) {
10674                                         pr_err("error %d\n", rc);
10675                                         goto rw_error;
10676                                 }
10677                                 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);
10678                                 if (rc != 0) {
10679                                         pr_err("error %d\n", rc);
10680                                         goto rw_error;
10681                                 }
10682                                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 0x2, 0);
10683                                 if (rc != 0) {
10684                                         pr_err("error %d\n", rc);
10685                                         goto rw_error;
10686                                 }       /* force to rate hunting */
10687
10688                                 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_CONSTELLATION);
10689                                 if (rc != 0) {
10690                                         pr_err("error %d\n", rc);
10691                                         goto rw_error;
10692                                 }
10693                                 rc = DRXJ_DAP.write_reg16func(demod->my_i2c_dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena, 0);
10694                                 if (rc != 0) {
10695                                         pr_err("error %d\n", rc);
10696                                         goto rw_error;
10697                                 }
10698                         }
10699                         rc = qam64auto(demod, channel, tuner_freq_offset, &lock_status);
10700                         if (rc != 0) {
10701                                 pr_err("error %d\n", rc);
10702                                 goto rw_error;
10703                         }
10704                         channel->constellation = DRX_CONSTELLATION_AUTO;
10705                 } else {
10706                         channel->constellation = DRX_CONSTELLATION_AUTO;
10707                         return -EINVAL;
10708                 }
10709                 break;
10710         default:
10711                 return -EINVAL;
10712         }
10713
10714         return 0;
10715 rw_error:
10716         /* restore starting value */
10717         if (auto_flag)
10718                 channel->constellation = DRX_CONSTELLATION_AUTO;
10719         return -EIO;
10720 }
10721
10722 /*============================================================================*/
10723
10724 /**
10725 * \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
10726 * \brief Get RS error count in QAM mode (used for post RS BER calculation)
10727 * \return Error code
10728 *
10729 * precondition: measurement period & measurement prescale must be set
10730 *
10731 */
10732 static int
10733 get_qamrs_err_count(struct i2c_device_addr *dev_addr, struct drxjrs_errors *rs_errors)
10734 {
10735         int rc;
10736         u16 nr_bit_errors = 0,
10737             nr_symbol_errors = 0,
10738             nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
10739
10740         /* check arguments */
10741         if (dev_addr == NULL)
10742                 return -EINVAL;
10743
10744         /* all reported errors are received in the  */
10745         /* most recently finished measurment period */
10746         /*   no of pre RS bit errors */
10747         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
10748         if (rc != 0) {
10749                 pr_err("error %d\n", rc);
10750                 goto rw_error;
10751         }
10752         /*   no of symbol errors      */
10753         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
10754         if (rc != 0) {
10755                 pr_err("error %d\n", rc);
10756                 goto rw_error;
10757         }
10758         /*   no of packet errors      */
10759         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
10760         if (rc != 0) {
10761                 pr_err("error %d\n", rc);
10762                 goto rw_error;
10763         }
10764         /*   no of failures to decode */
10765         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
10766         if (rc != 0) {
10767                 pr_err("error %d\n", rc);
10768                 goto rw_error;
10769         }
10770         /*   no of post RS bit erros  */
10771         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
10772         if (rc != 0) {
10773                 pr_err("error %d\n", rc);
10774                 goto rw_error;
10775         }
10776         /* TODO: NOTE */
10777         /* These register values are fetched in non-atomic fashion           */
10778         /* It is possible that the read values contain unrelated information */
10779
10780         rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
10781         rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
10782         rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
10783         rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
10784         rs_errors->nr_snc_par_fail_count =
10785             nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
10786
10787         return 0;
10788 rw_error:
10789         return -EIO;
10790 }
10791
10792 /*============================================================================*/
10793
10794 /**
10795 * \fn int ctrl_get_qam_sig_quality()
10796 * \brief Retreive QAM signal quality from device.
10797 * \param devmod Pointer to demodulator instance.
10798 * \param sig_quality Pointer to signal quality data.
10799 * \return int.
10800 * \retval 0 sig_quality contains valid data.
10801 * \retval -EINVAL sig_quality is NULL.
10802 * \retval -EIO Erroneous data, sig_quality contains invalid data.
10803
10804 *  Pre-condition: Device must be started and in lock.
10805 */
10806 static int
10807 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
10808 {
10809         struct i2c_device_addr *dev_addr = NULL;
10810         struct drxj_data *ext_attr = NULL;
10811         int rc;
10812         enum drx_modulation constellation = DRX_CONSTELLATION_UNKNOWN;
10813         struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
10814
10815         u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
10816         u32 post_bit_err_rs = 0;        /* post RedSolomon Bit Error Rate */
10817         u32 pkt_errs = 0;       /* no of packet errors in RS */
10818         u16 qam_sl_err_power = 0;       /* accumulated error between raw and sliced symbols */
10819         u16 qsym_err_vd = 0;    /* quadrature symbol errors in QAM_VD */
10820         u16 fec_oc_period = 0;  /* SNC sync failure measurement period */
10821         u16 fec_rs_prescale = 0;        /* ReedSolomon Measurement Prescale */
10822         u16 fec_rs_period = 0;  /* Value for corresponding I2C register */
10823         /* calculation constants */
10824         u32 rs_bit_cnt = 0;     /* RedSolomon Bit Count */
10825         u32 qam_sl_sig_power = 0;       /* used for MER, depends of QAM constellation */
10826         /* intermediate results */
10827         u32 e = 0;              /* exponent value used for QAM BER/SER */
10828         u32 m = 0;              /* mantisa value used for QAM BER/SER */
10829         u32 ber_cnt = 0;        /* BER count */
10830         /* signal quality info */
10831         u32 qam_sl_mer = 0;     /* QAM MER */
10832         u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
10833         u32 qam_post_rs_ber = 0;        /* Post RedSolomon BER */
10834         u32 qam_vd_ser = 0;     /* ViterbiDecoder SER */
10835         u16 qam_vd_prescale = 0;        /* Viterbi Measurement Prescale */
10836         u16 qam_vd_period = 0;  /* Viterbi Measurement period */
10837         u32 vd_bit_cnt = 0;     /* ViterbiDecoder Bit Count */
10838
10839         /* get device basic information */
10840         dev_addr = demod->my_i2c_dev_addr;
10841         ext_attr = (struct drxj_data *) demod->my_ext_attr;
10842         constellation = ext_attr->constellation;
10843
10844         /* read the physical registers */
10845         /*   Get the RS error data */
10846         rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
10847         if (rc != 0) {
10848                 pr_err("error %d\n", rc);
10849                 goto rw_error;
10850         }
10851         /* get the register value needed for MER */
10852         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
10853         if (rc != 0) {
10854                 pr_err("error %d\n", rc);
10855                 goto rw_error;
10856         }
10857         /* get the register value needed for post RS BER */
10858         rc = DRXJ_DAP.read_reg16func(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
10859         if (rc != 0) {
10860                 pr_err("error %d\n", rc);
10861                 goto rw_error;
10862         }
10863
10864         /* get constants needed for signal quality calculation */
10865         fec_rs_period = ext_attr->fec_rs_period;
10866         fec_rs_prescale = ext_attr->fec_rs_prescale;
10867         rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
10868         qam_vd_period = ext_attr->qam_vd_period;
10869         qam_vd_prescale = ext_attr->qam_vd_prescale;
10870         vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
10871
10872         /* DRXJ_QAM_SL_SIG_POWER_QAMxxx  * 4     */
10873         switch (constellation) {
10874         case DRX_CONSTELLATION_QAM16:
10875                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
10876                 break;
10877         case DRX_CONSTELLATION_QAM32:
10878                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
10879                 break;
10880         case DRX_CONSTELLATION_QAM64:
10881                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
10882                 break;
10883         case DRX_CONSTELLATION_QAM128:
10884                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
10885                 break;
10886         case DRX_CONSTELLATION_QAM256:
10887                 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
10888                 break;
10889         default:
10890                 return -EIO;
10891         }
10892
10893         /* ------------------------------ */
10894         /* MER Calculation                */
10895         /* ------------------------------ */
10896         /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
10897
10898         /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
10899         if (qam_sl_err_power == 0)
10900                 qam_sl_mer = 0;
10901         else
10902                 qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
10903
10904         /* ----------------------------------------- */
10905         /* Pre Viterbi Symbol Error Rate Calculation */
10906         /* ----------------------------------------- */
10907         /* pre viterbi SER is good if it is bellow 0.025 */
10908
10909         /* get the register value */
10910         /*   no of quadrature symbol errors */
10911         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
10912         if (rc != 0) {
10913                 pr_err("error %d\n", rc);
10914                 goto rw_error;
10915         }
10916         /* Extract the Exponent and the Mantisa  */
10917         /* of number of quadrature symbol errors */
10918         e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
10919             QAM_VD_NR_QSYM_ERRORS_EXP__B;
10920         m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
10921             QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
10922
10923         if ((m << e) >> 3 > 549752)
10924                 qam_vd_ser = 500000;
10925         else
10926                 qam_vd_ser = frac_times1e6(m << ((e > 2) ? (e - 3) : e), vd_bit_cnt * ((e > 2) ? 1 : 8) / 8);
10927
10928         /* --------------------------------------- */
10929         /* pre and post RedSolomon BER Calculation */
10930         /* --------------------------------------- */
10931         /* pre RS BER is good if it is below 3.5e-4 */
10932
10933         /* get the register values */
10934         pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
10935         pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
10936
10937         /* Extract the Exponent and the Mantisa of the */
10938         /* pre Reed-Solomon bit error count            */
10939         e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
10940             FEC_RS_NR_BIT_ERRORS_EXP__B;
10941         m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
10942             FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
10943
10944         ber_cnt = m << e;
10945
10946         /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
10947         if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
10948                 qam_pre_rs_ber = 500000;
10949         else
10950                 qam_pre_rs_ber = frac_times1e6(m, rs_bit_cnt >> e);
10951
10952         /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) /  */
10953         /*               (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A)  */
10954         /*
10955            => c = (1000000*100*11.17)/1504 =
10956            post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
10957            (100 * FEC_OC_SNC_FAIL_PERIOD__A)
10958            *100 and /100 is for more precision.
10959            => (20 bits * 12 bits) /(16 bits * 7 bits)  => safe in 32 bits computation
10960
10961            Precision errors still possible.
10962          */
10963         e = post_bit_err_rs * 742686;
10964         m = fec_oc_period * 100;
10965         if (fec_oc_period == 0)
10966                 qam_post_rs_ber = 0xFFFFFFFF;
10967         else
10968                 qam_post_rs_ber = e / m;
10969
10970         /* fill signal quality data structure */
10971         sig_quality->MER = ((u16) qam_sl_mer);
10972         if (ext_attr->standard == DRX_STANDARD_ITU_B)
10973                 sig_quality->pre_viterbi_ber = qam_vd_ser;
10974         else
10975                 sig_quality->pre_viterbi_ber = qam_pre_rs_ber;
10976         sig_quality->post_viterbi_ber = qam_pre_rs_ber;
10977         sig_quality->post_reed_solomon_ber = qam_post_rs_ber;
10978         sig_quality->scale_factor_ber = ((u32) 1000000);
10979 #ifdef DRXJ_SIGNAL_ACCUM_ERR
10980         rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
10981         if (rc != 0) {
10982                 pr_err("error %d\n", rc);
10983                 goto rw_error;
10984         }
10985 #else
10986         sig_quality->packet_error = ((u16) pkt_errs);
10987 #endif
10988
10989         return 0;
10990 rw_error:
10991         return -EIO;
10992 }
10993
10994 /**
10995 * \fn int ctrl_get_qam_constel()
10996 * \brief Retreive a QAM constellation point via I2C.
10997 * \param demod Pointer to demodulator instance.
10998 * \param complex_nr Pointer to the structure in which to store the
10999                    constellation point.
11000 * \return int.
11001 */
11002 static int
11003 ctrl_get_qam_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
11004 {
11005         struct i2c_device_addr *dev_addr = NULL;
11006         int rc;
11007         u32 data = 0;
11008         u16 fec_oc_ocr_mode = 0;
11009                               /**< FEC OCR grabber configuration        */
11010         u16 qam_sl_comm_mb = 0;/**< QAM SL MB configuration              */
11011         u16 qam_sl_comm_mb_init = 0;
11012                               /**< QAM SL MB intial configuration       */
11013         u16 im = 0;           /**< constellation Im part                */
11014         u16 re = 0;           /**< constellation Re part                */
11015                                      /**< device address */
11016
11017         /* read device info */
11018         dev_addr = demod->my_i2c_dev_addr;
11019
11020         /* TODO: */
11021         /* Monitor bus grabbing is an open external interface issue  */
11022         /* Needs to be checked when external interface PG is updated */
11023
11024         /* Configure MB (Monitor bus) */
11025         rc = DRXJ_DAP.read_reg16func(dev_addr, QAM_SL_COMM_MB__A, &qam_sl_comm_mb_init, 0);
11026         if (rc != 0) {
11027                 pr_err("error %d\n", rc);
11028                 goto rw_error;
11029         }
11030         /* set observe flag & MB mux */
11031         qam_sl_comm_mb = qam_sl_comm_mb_init & (~(QAM_SL_COMM_MB_OBS__M +
11032                                            QAM_SL_COMM_MB_MUX_OBS__M));
11033         qam_sl_comm_mb |= (QAM_SL_COMM_MB_OBS_ON +
11034                         QAM_SL_COMM_MB_MUX_OBS_CONST_CORR);
11035         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb, 0);
11036         if (rc != 0) {
11037                 pr_err("error %d\n", rc);
11038                 goto rw_error;
11039         }
11040
11041         /* Enable MB grabber in the FEC OC */
11042         fec_oc_ocr_mode = (/* output select:  observe bus */
11043                                (FEC_OC_OCR_MODE_MB_SELECT__M &
11044                                 (0x0 << FEC_OC_OCR_MODE_MB_SELECT__B)) |
11045                                /* grabber enable: on          */
11046                                (FEC_OC_OCR_MODE_GRAB_ENABLE__M &
11047                                 (0x1 << FEC_OC_OCR_MODE_GRAB_ENABLE__B)) |
11048                                /* grabber select: observe bus */
11049                                (FEC_OC_OCR_MODE_GRAB_SELECT__M &
11050                                 (0x0 << FEC_OC_OCR_MODE_GRAB_SELECT__B)) |
11051                                /* grabber mode:   continuous  */
11052                                (FEC_OC_OCR_MODE_GRAB_COUNTED__M &
11053                                 (0x0 << FEC_OC_OCR_MODE_GRAB_COUNTED__B)));
11054         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, fec_oc_ocr_mode, 0);
11055         if (rc != 0) {
11056                 pr_err("error %d\n", rc);
11057                 goto rw_error;
11058         }
11059
11060         /* Disable MB grabber in the FEC OC */
11061         rc = DRXJ_DAP.write_reg16func(dev_addr, FEC_OC_OCR_MODE__A, 0x00, 0);
11062         if (rc != 0) {
11063                 pr_err("error %d\n", rc);
11064                 goto rw_error;
11065         }
11066
11067         /* read data */
11068         rc = DRXJ_DAP.read_reg32func(dev_addr, FEC_OC_OCR_GRAB_RD0__A, &data, 0);
11069         if (rc != 0) {
11070                 pr_err("error %d\n", rc);
11071                 goto rw_error;
11072         }
11073         re = (u16) (data & FEC_OC_OCR_GRAB_RD0__M);
11074         im = (u16) ((data >> 16) & FEC_OC_OCR_GRAB_RD1__M);
11075
11076         /* TODO: */
11077         /* interpret data (re & im) according to the Monitor bus mapping ?? */
11078
11079         /* sign extension, 10th bit is sign bit */
11080         if ((re & 0x0200) == 0x0200)
11081                 re |= 0xFC00;
11082         if ((im & 0x0200) == 0x0200)
11083                 im |= 0xFC00;
11084         complex_nr->re = ((s16) re);
11085         complex_nr->im = ((s16) im);
11086
11087         /* Restore MB (Monitor bus) */
11088         rc = DRXJ_DAP.write_reg16func(dev_addr, QAM_SL_COMM_MB__A, qam_sl_comm_mb_init, 0);
11089         if (rc != 0) {
11090                 pr_err("error %d\n", rc);
11091                 goto rw_error;
11092         }
11093
11094         return 0;
11095 rw_error:
11096         return -EIO;
11097 }
11098 #endif /* #ifndef DRXJ_VSB_ONLY */
11099
11100 /*============================================================================*/
11101 /*==                     END QAM DATAPATH FUNCTIONS                         ==*/
11102 /*============================================================================*/
11103
11104 /*============================================================================*/
11105 /*============================================================================*/
11106 /*==                       ATV DATAPATH FUNCTIONS                           ==*/
11107 /*============================================================================*/
11108 /*============================================================================*/
11109
11110 /*
11111    Implementation notes.
11112
11113    NTSC/FM AGCs
11114
11115       Four AGCs are used for NTSC:
11116       (1) RF (used to attenuate the input signal in case of to much power)
11117       (2) IF (used to attenuate the input signal in case of to much power)
11118       (3) Video AGC (used to amplify the output signal in case input to low)
11119       (4) SIF AGC (used to amplify the output signal in case input to low)
11120
11121       Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
11122       that the coupling between Video AGC and the RF and IF AGCs also works in
11123       favor of the SIF AGC.
11124
11125       Three AGCs are used for FM:
11126       (1) RF (used to attenuate the input signal in case of to much power)
11127       (2) IF (used to attenuate the input signal in case of to much power)
11128       (3) SIF AGC (used to amplify the output signal in case input to low)
11129
11130       The SIF AGC is now coupled to the RF/IF AGCs.
11131       The SIF AGC is needed for both SIF ouput and the internal SIF signal to
11132       the AUD block.
11133
11134       RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
11135       the ATV block. The AGC control algorithms are all implemented in
11136       microcode.
11137
11138    ATV SETTINGS
11139
11140       (Shadow settings will not be used for now, they will be implemented
11141        later on because of the schedule)
11142
11143       Several HW/SCU "settings" can be used for ATV. The standard selection
11144       will reset most of these settings. To avoid that the end user apllication
11145       has to perform these settings each time the ATV or FM standards is
11146       selected the driver will shadow these settings. This enables the end user
11147       to perform the settings only once after a drx_open(). The driver must
11148       write the shadow settings to HW/SCU incase:
11149          ( setstandard FM/ATV) ||
11150          ( settings have changed && FM/ATV standard is active)
11151       The shadow settings will be stored in the device specific data container.
11152       A set of flags will be defined to flag changes in shadow settings.
11153       A routine will be implemented to write all changed shadow settings to
11154       HW/SCU.
11155
11156       The "settings" will consist of: AGC settings, filter settings etc.
11157
11158       Disadvantage of use of shadow settings:
11159       Direct changes in HW/SCU registers will not be reflected in the
11160       shadow settings and these changes will be overwritten during a next
11161       update. This can happen during evaluation. This will not be a problem
11162       for normal customer usage.
11163 */
11164 /* -------------------------------------------------------------------------- */
11165
11166 /**
11167 * \brief Get array index for atv coef (ext_attr->atvTopCoefX[index])
11168 * \param standard
11169 * \param pointer to index
11170 * \return int.
11171 *
11172 */
11173 static int atv_equ_coef_index(enum drx_standard standard, int *index)
11174 {
11175         switch (standard) {
11176         case DRX_STANDARD_PAL_SECAM_BG:
11177                 *index = (int)DRXJ_COEF_IDX_BG;
11178                 break;
11179         case DRX_STANDARD_PAL_SECAM_DK:
11180                 *index = (int)DRXJ_COEF_IDX_DK;
11181                 break;
11182         case DRX_STANDARD_PAL_SECAM_I:
11183                 *index = (int)DRXJ_COEF_IDX_I;
11184                 break;
11185         case DRX_STANDARD_PAL_SECAM_L:
11186                 *index = (int)DRXJ_COEF_IDX_L;
11187                 break;
11188         case DRX_STANDARD_PAL_SECAM_LP:
11189                 *index = (int)DRXJ_COEF_IDX_LP;
11190                 break;
11191         case DRX_STANDARD_NTSC:
11192                 *index = (int)DRXJ_COEF_IDX_MN;
11193                 break;
11194         case DRX_STANDARD_FM:
11195                 *index = (int)DRXJ_COEF_IDX_FM;
11196                 break;
11197         default:
11198                 *index = (int)DRXJ_COEF_IDX_MN; /* still return a valid index */
11199                 return -EIO;
11200                 break;
11201         }
11202
11203         return 0;
11204 }
11205
11206 /* -------------------------------------------------------------------------- */
11207 /**
11208 * \fn int atv_update_config ()
11209 * \brief Flush changes in ATV shadow registers to physical registers.
11210 * \param demod instance of demodulator
11211 * \param force_update don't look at standard or change flags, flush all.
11212 * \return int.
11213 *
11214 */
11215 static int
11216 atv_update_config(struct drx_demod_instance *demod, bool force_update)
11217 {
11218         struct i2c_device_addr *dev_addr = NULL;
11219         struct drxj_data *ext_attr = NULL;
11220         int rc;
11221
11222         dev_addr = demod->my_i2c_dev_addr;
11223         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11224
11225         /* equalizer coefficients */
11226         if (force_update ||
11227             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_COEF) != 0)) {
11228                 int index = 0;
11229
11230                 rc = atv_equ_coef_index(ext_attr->standard, &index);
11231                 if (rc != 0) {
11232                         pr_err("error %d\n", rc);
11233                         goto rw_error;
11234                 }
11235                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU0__A, ext_attr->atv_top_equ0[index], 0);
11236                 if (rc != 0) {
11237                         pr_err("error %d\n", rc);
11238                         goto rw_error;
11239                 }
11240                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU1__A, ext_attr->atv_top_equ1[index], 0);
11241                 if (rc != 0) {
11242                         pr_err("error %d\n", rc);
11243                         goto rw_error;
11244                 }
11245                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU2__A, ext_attr->atv_top_equ2[index], 0);
11246                 if (rc != 0) {
11247                         pr_err("error %d\n", rc);
11248                         goto rw_error;
11249                 }
11250                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_EQU3__A, ext_attr->atv_top_equ3[index], 0);
11251                 if (rc != 0) {
11252                         pr_err("error %d\n", rc);
11253                         goto rw_error;
11254                 }
11255         }
11256
11257         /* bypass fast carrier recovery */
11258         if (force_update) {
11259                 u16 data = 0;
11260
11261                 rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_RT_ROT_BP__A, &data, 0);
11262                 if (rc != 0) {
11263                         pr_err("error %d\n", rc);
11264                         goto rw_error;
11265                 }
11266                 data &= (~((u16) IQM_RT_ROT_BP_ROT_OFF__M));
11267                 if (ext_attr->phase_correction_bypass)
11268                         data |= IQM_RT_ROT_BP_ROT_OFF_OFF;
11269                 else
11270                         data |= IQM_RT_ROT_BP_ROT_OFF_ACTIVE;
11271                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ROT_BP__A, data, 0);
11272                 if (rc != 0) {
11273                         pr_err("error %d\n", rc);
11274                         goto rw_error;
11275                 }
11276         }
11277
11278         /* peak filter setting */
11279         if (force_update ||
11280             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_PEAK_FLT) != 0)) {
11281                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_PEAK__A, ext_attr->atv_top_vid_peak, 0);
11282                 if (rc != 0) {
11283                         pr_err("error %d\n", rc);
11284                         goto rw_error;
11285                 }
11286         }
11287
11288         /* noise filter setting */
11289         if (force_update ||
11290             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_NOISE_FLT) != 0)) {
11291                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_NOISE_TH__A, ext_attr->atv_top_noise_th, 0);
11292                 if (rc != 0) {
11293                         pr_err("error %d\n", rc);
11294                         goto rw_error;
11295                 }
11296         }
11297
11298         /* SIF attenuation */
11299         if (force_update ||
11300             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_SIF_ATT) != 0)) {
11301                 u16 attenuation = 0;
11302
11303                 switch (ext_attr->sif_attenuation) {
11304                 case DRXJ_SIF_ATTENUATION_0DB:
11305                         attenuation = ATV_TOP_AF_SIF_ATT_0DB;
11306                         break;
11307                 case DRXJ_SIF_ATTENUATION_3DB:
11308                         attenuation = ATV_TOP_AF_SIF_ATT_M3DB;
11309                         break;
11310                 case DRXJ_SIF_ATTENUATION_6DB:
11311                         attenuation = ATV_TOP_AF_SIF_ATT_M6DB;
11312                         break;
11313                 case DRXJ_SIF_ATTENUATION_9DB:
11314                         attenuation = ATV_TOP_AF_SIF_ATT_M9DB;
11315                         break;
11316                 default:
11317                         return -EIO;
11318                         break;
11319                 }
11320                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_AF_SIF_ATT__A, attenuation, 0);
11321                 if (rc != 0) {
11322                         pr_err("error %d\n", rc);
11323                         goto rw_error;
11324                 }
11325         }
11326
11327         /* SIF & CVBS enable */
11328         if (force_update ||
11329             ((ext_attr->atv_cfg_changed_flags & DRXJ_ATV_CHANGED_OUTPUT) != 0)) {
11330                 u16 data = 0;
11331
11332                 rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_STDBY__A, &data, 0);
11333                 if (rc != 0) {
11334                         pr_err("error %d\n", rc);
11335                         goto rw_error;
11336                 }
11337                 if (ext_attr->enable_cvbs_output)
11338                         data |= ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE;
11339                 else
11340                         data &= (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE);
11341
11342                 if (ext_attr->enable_sif_output)
11343                         data &= (~ATV_TOP_STDBY_SIF_STDBY_STANDBY);
11344                 else
11345                         data |= ATV_TOP_STDBY_SIF_STDBY_STANDBY;
11346                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STDBY__A, data, 0);
11347                 if (rc != 0) {
11348                         pr_err("error %d\n", rc);
11349                         goto rw_error;
11350                 }
11351         }
11352
11353         ext_attr->atv_cfg_changed_flags = 0;
11354
11355         return 0;
11356 rw_error:
11357         return -EIO;
11358 }
11359
11360 /* -------------------------------------------------------------------------- */
11361 /**
11362 * \fn int ctrl_set_cfg_atv_output()
11363 * \brief Configure ATV ouputs
11364 * \param demod instance of demodulator
11365 * \param output_cfg output configuaration
11366 * \return int.
11367 *
11368 */
11369 static int
11370 ctrl_set_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11371 {
11372         struct drxj_data *ext_attr = NULL;
11373         int rc;
11374
11375         /* Check arguments */
11376         if (output_cfg == NULL)
11377                 return -EINVAL;
11378
11379         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11380         if (output_cfg->enable_sif_output) {
11381                 switch (output_cfg->sif_attenuation) {
11382                 case DRXJ_SIF_ATTENUATION_0DB:  /* fallthrough */
11383                 case DRXJ_SIF_ATTENUATION_3DB:  /* fallthrough */
11384                 case DRXJ_SIF_ATTENUATION_6DB:  /* fallthrough */
11385                 case DRXJ_SIF_ATTENUATION_9DB:
11386                         /* Do nothing */
11387                         break;
11388                 default:
11389                         return -EINVAL;
11390                         break;
11391                 }
11392
11393                 if (ext_attr->sif_attenuation != output_cfg->sif_attenuation) {
11394                         ext_attr->sif_attenuation = output_cfg->sif_attenuation;
11395                         ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_SIF_ATT;
11396                 }
11397         }
11398
11399         if (ext_attr->enable_cvbs_output != output_cfg->enable_cvbs_output) {
11400                 ext_attr->enable_cvbs_output = output_cfg->enable_cvbs_output;
11401                 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11402         }
11403
11404         if (ext_attr->enable_sif_output != output_cfg->enable_sif_output) {
11405                 ext_attr->enable_sif_output = output_cfg->enable_sif_output;
11406                 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_OUTPUT;
11407         }
11408
11409         rc = atv_update_config(demod, false);
11410         if (rc != 0) {
11411                 pr_err("error %d\n", rc);
11412                 goto rw_error;
11413         }
11414
11415         return 0;
11416 rw_error:
11417         return -EIO;
11418 }
11419
11420 /* -------------------------------------------------------------------------- */
11421 #ifndef DRXJ_DIGITAL_ONLY
11422 /**
11423 * \fn int ctrl_set_cfg_atv_equ_coef()
11424 * \brief Set ATV equalizer coefficients
11425 * \param demod instance of demodulator
11426 * \param coef  the equalizer coefficients
11427 * \return int.
11428 *
11429 */
11430 static int
11431 ctrl_set_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11432 {
11433         struct drxj_data *ext_attr = NULL;
11434         int rc;
11435         int index;
11436
11437         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11438
11439         /* current standard needs to be an ATV standard */
11440         if (!DRXJ_ISATVSTD(ext_attr->standard))
11441                 return -EIO;
11442
11443         /* Check arguments */
11444         if ((coef == NULL) ||
11445             (coef->coef0 > (ATV_TOP_EQU0_EQU_C0__M / 2)) ||
11446             (coef->coef1 > (ATV_TOP_EQU1_EQU_C1__M / 2)) ||
11447             (coef->coef2 > (ATV_TOP_EQU2_EQU_C2__M / 2)) ||
11448             (coef->coef3 > (ATV_TOP_EQU3_EQU_C3__M / 2)) ||
11449             (coef->coef0 < ((s16) ~(ATV_TOP_EQU0_EQU_C0__M >> 1))) ||
11450             (coef->coef1 < ((s16) ~(ATV_TOP_EQU1_EQU_C1__M >> 1))) ||
11451             (coef->coef2 < ((s16) ~(ATV_TOP_EQU2_EQU_C2__M >> 1))) ||
11452             (coef->coef3 < ((s16) ~(ATV_TOP_EQU3_EQU_C3__M >> 1)))) {
11453                 return -EINVAL;
11454         }
11455
11456         rc = atv_equ_coef_index(ext_attr->standard, &index);
11457         if (rc != 0) {
11458                 pr_err("error %d\n", rc);
11459                 goto rw_error;
11460         }
11461         ext_attr->atv_top_equ0[index] = coef->coef0;
11462         ext_attr->atv_top_equ1[index] = coef->coef1;
11463         ext_attr->atv_top_equ2[index] = coef->coef2;
11464         ext_attr->atv_top_equ3[index] = coef->coef3;
11465         ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_COEF;
11466
11467         rc = atv_update_config(demod, false);
11468         if (rc != 0) {
11469                 pr_err("error %d\n", rc);
11470                 goto rw_error;
11471         }
11472
11473         return 0;
11474 rw_error:
11475         return -EIO;
11476 }
11477
11478 /* -------------------------------------------------------------------------- */
11479 /**
11480 * \fn int ctrl_get_cfg_atv_equ_coef()
11481 * \brief Get ATV equ coef settings
11482 * \param demod instance of demodulator
11483 * \param coef The ATV equ coefficients
11484 * \return int.
11485 *
11486 * The values are read from the shadow registers maintained by the drxdriver
11487 * If registers are manipulated outside of the drxdriver scope the reported
11488 * settings will not reflect these changes because of the use of shadow
11489 * regitsers.
11490 *
11491 */
11492 static int
11493 ctrl_get_cfg_atv_equ_coef(struct drx_demod_instance *demod, struct drxj_cfg_atv_equ_coef *coef)
11494 {
11495         struct drxj_data *ext_attr = NULL;
11496         int rc;
11497         int index = 0;
11498
11499         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11500
11501         /* current standard needs to be an ATV standard */
11502         if (!DRXJ_ISATVSTD(ext_attr->standard))
11503                 return -EIO;
11504
11505         /* Check arguments */
11506         if (coef == NULL)
11507                 return -EINVAL;
11508
11509         rc = atv_equ_coef_index(ext_attr->standard, &index);
11510         if (rc != 0) {
11511                 pr_err("error %d\n", rc);
11512                 goto rw_error;
11513         }
11514         coef->coef0 = ext_attr->atv_top_equ0[index];
11515         coef->coef1 = ext_attr->atv_top_equ1[index];
11516         coef->coef2 = ext_attr->atv_top_equ2[index];
11517         coef->coef3 = ext_attr->atv_top_equ3[index];
11518
11519         return 0;
11520 rw_error:
11521         return -EIO;
11522 }
11523
11524 /* -------------------------------------------------------------------------- */
11525 /**
11526 * \fn int ctrl_set_cfg_atv_misc()
11527 * \brief Set misc. settings for ATV.
11528 * \param demod instance of demodulator
11529 * \param
11530 * \return int.
11531 *
11532 */
11533 static int
11534 ctrl_set_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11535 {
11536         struct drxj_data *ext_attr = NULL;
11537         int rc;
11538
11539         /* Check arguments */
11540         if ((settings == NULL) ||
11541             ((settings->peak_filter) < (s16) (-8)) ||
11542             ((settings->peak_filter) > (s16) (15)) ||
11543             ((settings->noise_filter) > 15)) {
11544                 return -EINVAL;
11545         }
11546         /* if */
11547         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11548
11549         if (settings->peak_filter != ext_attr->atv_top_vid_peak) {
11550                 ext_attr->atv_top_vid_peak = settings->peak_filter;
11551                 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_PEAK_FLT;
11552         }
11553
11554         if (settings->noise_filter != ext_attr->atv_top_noise_th) {
11555                 ext_attr->atv_top_noise_th = settings->noise_filter;
11556                 ext_attr->atv_cfg_changed_flags |= DRXJ_ATV_CHANGED_NOISE_FLT;
11557         }
11558
11559         rc = atv_update_config(demod, false);
11560         if (rc != 0) {
11561                 pr_err("error %d\n", rc);
11562                 goto rw_error;
11563         }
11564
11565         return 0;
11566 rw_error:
11567         return -EIO;
11568 }
11569
11570 /* -------------------------------------------------------------------------- */
11571 /**
11572 * \fn int  ctrl_get_cfg_atv_misc()
11573 * \brief Get misc settings of ATV.
11574 * \param demod instance of demodulator
11575 * \param settings misc. ATV settings
11576 * \return int.
11577 *
11578 * The values are read from the shadow registers maintained by the drxdriver
11579 * If registers are manipulated outside of the drxdriver scope the reported
11580 * settings will not reflect these changes because of the use of shadow
11581 * regitsers.
11582 */
11583 static int
11584 ctrl_get_cfg_atv_misc(struct drx_demod_instance *demod, struct drxj_cfg_atv_misc *settings)
11585 {
11586         struct drxj_data *ext_attr = NULL;
11587
11588         /* Check arguments */
11589         if (settings == NULL)
11590                 return -EINVAL;
11591
11592         ext_attr = (struct drxj_data *) demod->my_ext_attr;
11593
11594         settings->peak_filter = ext_attr->atv_top_vid_peak;
11595         settings->noise_filter = ext_attr->atv_top_noise_th;
11596
11597         return 0;
11598 }
11599
11600 /* -------------------------------------------------------------------------- */
11601
11602 /* -------------------------------------------------------------------------- */
11603 /**
11604 * \fn int  ctrl_get_cfg_atv_output()
11605 * \brief
11606 * \param demod instance of demodulator
11607 * \param output_cfg output configuaration
11608 * \return int.
11609 *
11610 */
11611 static int
11612 ctrl_get_cfg_atv_output(struct drx_demod_instance *demod, struct drxj_cfg_atv_output *output_cfg)
11613 {
11614         int rc;
11615         u16 data = 0;
11616
11617         /* Check arguments */
11618         if (output_cfg == NULL)
11619                 return -EINVAL;
11620
11621         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, ATV_TOP_STDBY__A, &data, 0);
11622         if (rc != 0) {
11623                 pr_err("error %d\n", rc);
11624                 goto rw_error;
11625         }
11626         if (data & ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)
11627                 output_cfg->enable_cvbs_output = true;
11628         else
11629                 output_cfg->enable_cvbs_output = false;
11630
11631         if (data & ATV_TOP_STDBY_SIF_STDBY_STANDBY) {
11632                 output_cfg->enable_sif_output = false;
11633         } else {
11634                 output_cfg->enable_sif_output = true;
11635                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, ATV_TOP_AF_SIF_ATT__A, &data, 0);
11636                 if (rc != 0) {
11637                         pr_err("error %d\n", rc);
11638                         goto rw_error;
11639                 }
11640                 output_cfg->sif_attenuation = (enum drxjsif_attenuation) data;
11641         }
11642
11643         return 0;
11644 rw_error:
11645         return -EIO;
11646 }
11647
11648 /* -------------------------------------------------------------------------- */
11649 /**
11650 * \fn int  ctrl_get_cfg_atv_agc_status()
11651 * \brief
11652 * \param demod instance of demodulator
11653 * \param agc_status agc status
11654 * \return int.
11655 *
11656 */
11657 static int
11658 ctrl_get_cfg_atv_agc_status(struct drx_demod_instance *demod,
11659                             struct drxj_cfg_atv_agc_status *agc_status)
11660 {
11661         struct i2c_device_addr *dev_addr = NULL;
11662         int rc;
11663         u16 data = 0;
11664         u32 tmp = 0;
11665
11666         /* Check arguments */
11667         if (agc_status == NULL)
11668                 return -EINVAL;
11669
11670         dev_addr = demod->my_i2c_dev_addr;
11671
11672         /*
11673            RFgain = (IQM_AF_AGC_RF__A * 26.75)/1000 (uA)
11674            = ((IQM_AF_AGC_RF__A * 27) - (0.25*IQM_AF_AGC_RF__A))/1000
11675
11676            IQM_AF_AGC_RF__A * 27 is 20 bits worst case.
11677          */
11678         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &data, 0);
11679         if (rc != 0) {
11680                 pr_err("error %d\n", rc);
11681                 goto rw_error;
11682         }
11683         tmp = ((u32) data) * 27 - ((u32) (data >> 2));  /* nA */
11684         agc_status->rf_agc_gain = (u16) (tmp / 1000);   /* uA */
11685         /* rounding */
11686         if (tmp % 1000 >= 500)
11687                 (agc_status->rf_agc_gain)++;
11688
11689         /*
11690            IFgain = (IQM_AF_AGC_IF__A * 26.75)/1000 (uA)
11691            = ((IQM_AF_AGC_IF__A * 27) - (0.25*IQM_AF_AGC_IF__A))/1000
11692
11693            IQM_AF_AGC_IF__A * 27 is 20 bits worst case.
11694          */
11695         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &data, 0);
11696         if (rc != 0) {
11697                 pr_err("error %d\n", rc);
11698                 goto rw_error;
11699         }
11700         tmp = ((u32) data) * 27 - ((u32) (data >> 2));  /* nA */
11701         agc_status->if_agc_gain = (u16) (tmp / 1000);   /* uA */
11702         /* rounding */
11703         if (tmp % 1000 >= 500)
11704                 (agc_status->if_agc_gain)++;
11705
11706         /*
11707            videoGain = (ATV_TOP_SFR_VID_GAIN__A/16 -150)* 0.05 (dB)
11708            = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (dB)
11709            = 10*(ATV_TOP_SFR_VID_GAIN__A/16 -150)/20 (in 0.1 dB)
11710            = (ATV_TOP_SFR_VID_GAIN__A/16 -150)/2 (in 0.1 dB)
11711            = (ATV_TOP_SFR_VID_GAIN__A/32) - 75 (in 0.1 dB)
11712          */
11713
11714         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &data, 0);
11715         if (rc != 0) {
11716                 pr_err("error %d\n", rc);
11717                 goto rw_error;
11718         }
11719         /* dividing by 32 inclusive rounding */
11720         data >>= 4;
11721         if ((data & 1) != 0)
11722                 data++;
11723         data >>= 1;
11724         agc_status->video_agc_gain = ((s16) data) - 75; /* 0.1 dB */
11725
11726         /*
11727            audioGain = (SCU_RAM_ATV_SIF_GAIN__A -8)* 0.05 (dB)
11728            = (SCU_RAM_ATV_SIF_GAIN__A -8)/20 (dB)
11729            = 10*(SCU_RAM_ATV_SIF_GAIN__A -8)/20 (in 0.1 dB)
11730            = (SCU_RAM_ATV_SIF_GAIN__A -8)/2 (in 0.1 dB)
11731            = (SCU_RAM_ATV_SIF_GAIN__A/2) - 4 (in 0.1 dB)
11732          */
11733
11734         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &data, 0);
11735         if (rc != 0) {
11736                 pr_err("error %d\n", rc);
11737                 goto rw_error;
11738         }
11739         data &= SCU_RAM_ATV_SIF_GAIN__M;
11740         /* dividing by 2 inclusive rounding */
11741         if ((data & 1) != 0)
11742                 data++;
11743         data >>= 1;
11744         agc_status->audio_agc_gain = ((s16) data) - 4;  /* 0.1 dB */
11745
11746         /* Loop gain's */
11747         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
11748         if (rc != 0) {
11749                 pr_err("error %d\n", rc);
11750                 goto rw_error;
11751         }
11752         agc_status->video_agc_loop_gain =
11753             ((data & SCU_RAM_AGC_KI_DGAIN__M) >> SCU_RAM_AGC_KI_DGAIN__B);
11754         agc_status->rf_agc_loop_gain =
11755             ((data & SCU_RAM_AGC_KI_RF__M) >> SCU_RAM_AGC_KI_RF__B);
11756         agc_status->if_agc_loop_gain =
11757             ((data & SCU_RAM_AGC_KI_IF__M) >> SCU_RAM_AGC_KI_IF__B);
11758
11759         return 0;
11760 rw_error:
11761         return -EIO;
11762 }
11763
11764 /* -------------------------------------------------------------------------- */
11765
11766 /**
11767 * \fn int power_up_atv ()
11768 * \brief Power up ATV.
11769 * \param demod instance of demodulator
11770 * \param standard either NTSC or FM (sub strandard for ATV )
11771 * \return int.
11772 *
11773 * * Starts ATV and IQM
11774 * * AUdio already started during standard init for ATV.
11775 */
11776 static int power_up_atv(struct drx_demod_instance *demod, enum drx_standard standard)
11777 {
11778         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11779         int rc;
11780
11781         /* ATV NTSC */
11782         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_ACTIVE, 0);
11783         if (rc != 0) {
11784                 pr_err("error %d\n", rc);
11785                 goto rw_error;
11786         }
11787         /* turn on IQM_AF */
11788         rc = set_iqm_af(demod, true);
11789         if (rc != 0) {
11790                 pr_err("error %d\n", rc);
11791                 goto rw_error;
11792         }
11793         rc = adc_synchronization(demod);
11794         if (rc != 0) {
11795                 pr_err("error %d\n", rc);
11796                 goto rw_error;
11797         }
11798
11799         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
11800         if (rc != 0) {
11801                 pr_err("error %d\n", rc);
11802                 goto rw_error;
11803         }
11804
11805         /* Audio, already done during set standard */
11806
11807         return 0;
11808 rw_error:
11809         return -EIO;
11810 }
11811 #endif /* #ifndef DRXJ_DIGITAL_ONLY */
11812
11813 /* -------------------------------------------------------------------------- */
11814
11815 /**
11816 * \fn int power_down_atv ()
11817 * \brief Power down ATV.
11818 * \param demod instance of demodulator
11819 * \param standard either NTSC or FM (sub strandard for ATV )
11820 * \return int.
11821 *
11822 *  Stops and thus resets ATV and IQM block
11823 *  SIF and CVBS ADC are powered down
11824 *  Calls audio power down
11825 */
11826 static int
11827 power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
11828 {
11829         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11830         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
11831                 /* parameter_len */ 0,
11832                 /* result_len    */ 0,
11833                 /* *parameter   */ NULL,
11834                 /* *result      */ NULL
11835         };
11836         int rc;
11837         u16 cmd_result = 0;
11838
11839         /* ATV NTSC */
11840
11841         /* Stop ATV SCU (will reset ATV and IQM hardware */
11842         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
11843             SCU_RAM_COMMAND_CMD_DEMOD_STOP;
11844         cmd_scu.parameter_len = 0;
11845         cmd_scu.result_len = 1;
11846         cmd_scu.parameter = NULL;
11847         cmd_scu.result = &cmd_result;
11848         rc = scu_command(dev_addr, &cmd_scu);
11849         if (rc != 0) {
11850                 pr_err("error %d\n", rc);
11851                 goto rw_error;
11852         }
11853         /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
11854         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);
11855         if (rc != 0) {
11856                 pr_err("error %d\n", rc);
11857                 goto rw_error;
11858         }
11859
11860         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
11861         if (rc != 0) {
11862                 pr_err("error %d\n", rc);
11863                 goto rw_error;
11864         }
11865         if (primary) {
11866                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
11867                 if (rc != 0) {
11868                         pr_err("error %d\n", rc);
11869                         goto rw_error;
11870                 }
11871                 rc = set_iqm_af(demod, false);
11872                 if (rc != 0) {
11873                         pr_err("error %d\n", rc);
11874                         goto rw_error;
11875                 }
11876         } else {
11877                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
11878                 if (rc != 0) {
11879                         pr_err("error %d\n", rc);
11880                         goto rw_error;
11881                 }
11882                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
11883                 if (rc != 0) {
11884                         pr_err("error %d\n", rc);
11885                         goto rw_error;
11886                 }
11887                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
11888                 if (rc != 0) {
11889                         pr_err("error %d\n", rc);
11890                         goto rw_error;
11891                 }
11892                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
11893                 if (rc != 0) {
11894                         pr_err("error %d\n", rc);
11895                         goto rw_error;
11896                 }
11897                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
11898                 if (rc != 0) {
11899                         pr_err("error %d\n", rc);
11900                         goto rw_error;
11901                 }
11902         }
11903         rc = power_down_aud(demod);
11904         if (rc != 0) {
11905                 pr_err("error %d\n", rc);
11906                 goto rw_error;
11907         }
11908
11909         return 0;
11910 rw_error:
11911         return -EIO;
11912 }
11913
11914 /* -------------------------------------------------------------------------- */
11915 /**
11916 * \fn int set_atv_standard ()
11917 * \brief Set up ATV demodulator.
11918 * \param demod instance of demodulator
11919 * \param standard either NTSC or FM (sub strandard for ATV )
11920 * \return int.
11921 *
11922 * Init all channel independent registers.
11923 * Assuming that IQM, ATV and AUD blocks have been reset and are in STOP mode
11924 *
11925 */
11926 #ifndef DRXJ_DIGITAL_ONLY
11927 #define SCU_RAM_ATV_ENABLE_IIR_WA__A 0x831F6D   /* TODO remove after done with reg import */
11928 static int
11929 set_atv_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
11930 {
11931 /* TODO: enable alternative for tap settings via external file
11932
11933 something like:
11934 #ifdef   DRXJ_ATV_COEF_FILE
11935 #include DRXJ_ATV_COEF_FILE
11936 #else
11937 ... code defining fixed coef's ...
11938 #endif
11939
11940 Cutsomer must create file "customer_coefs.c.inc" containing
11941 modified copy off the constants below, and define the compiler
11942 switch DRXJ_ATV_COEF_FILE="customer_coefs.c.inc".
11943
11944 Still to check if this will work; DRXJ_16TO8 macro may cause
11945 trouble ?
11946 */
11947         const u8 ntsc_taps_re[] = {
11948                 DRXJ_16TO8(-12),        /* re0  */
11949                 DRXJ_16TO8(-9), /* re1  */
11950                 DRXJ_16TO8(9),  /* re2  */
11951                 DRXJ_16TO8(19), /* re3  */
11952                 DRXJ_16TO8(-4), /* re4  */
11953                 DRXJ_16TO8(-24),        /* re5  */
11954                 DRXJ_16TO8(-6), /* re6  */
11955                 DRXJ_16TO8(16), /* re7  */
11956                 DRXJ_16TO8(6),  /* re8  */
11957                 DRXJ_16TO8(-16),        /* re9  */
11958                 DRXJ_16TO8(-5), /* re10 */
11959                 DRXJ_16TO8(13), /* re11 */
11960                 DRXJ_16TO8(-2), /* re12 */
11961                 DRXJ_16TO8(-20),        /* re13 */
11962                 DRXJ_16TO8(4),  /* re14 */
11963                 DRXJ_16TO8(25), /* re15 */
11964                 DRXJ_16TO8(-6), /* re16 */
11965                 DRXJ_16TO8(-36),        /* re17 */
11966                 DRXJ_16TO8(2),  /* re18 */
11967                 DRXJ_16TO8(38), /* re19 */
11968                 DRXJ_16TO8(-10),        /* re20 */
11969                 DRXJ_16TO8(-48),        /* re21 */
11970                 DRXJ_16TO8(35), /* re22 */
11971                 DRXJ_16TO8(94), /* re23 */
11972                 DRXJ_16TO8(-59),        /* re24 */
11973                 DRXJ_16TO8(-217),       /* re25 */
11974                 DRXJ_16TO8(50), /* re26 */
11975                 DRXJ_16TO8(679) /* re27 */
11976         };
11977         const u8 ntsc_taps_im[] = {
11978                 DRXJ_16TO8(11), /* im0  */
11979                 DRXJ_16TO8(1),  /* im1  */
11980                 DRXJ_16TO8(-10),        /* im2  */
11981                 DRXJ_16TO8(2),  /* im3  */
11982                 DRXJ_16TO8(24), /* im4  */
11983                 DRXJ_16TO8(21), /* im5  */
11984                 DRXJ_16TO8(1),  /* im6  */
11985                 DRXJ_16TO8(-4), /* im7  */
11986                 DRXJ_16TO8(7),  /* im8  */
11987                 DRXJ_16TO8(14), /* im9  */
11988                 DRXJ_16TO8(27), /* im10 */
11989                 DRXJ_16TO8(42), /* im11 */
11990                 DRXJ_16TO8(22), /* im12 */
11991                 DRXJ_16TO8(-20),        /* im13 */
11992                 DRXJ_16TO8(2),  /* im14 */
11993                 DRXJ_16TO8(98), /* im15 */
11994                 DRXJ_16TO8(122),        /* im16 */
11995                 DRXJ_16TO8(0),  /* im17 */
11996                 DRXJ_16TO8(-85),        /* im18 */
11997                 DRXJ_16TO8(51), /* im19 */
11998                 DRXJ_16TO8(247),        /* im20 */
11999                 DRXJ_16TO8(192),        /* im21 */
12000                 DRXJ_16TO8(-55),        /* im22 */
12001                 DRXJ_16TO8(-95),        /* im23 */
12002                 DRXJ_16TO8(217),        /* im24 */
12003                 DRXJ_16TO8(544),        /* im25 */
12004                 DRXJ_16TO8(553),        /* im26 */
12005                 DRXJ_16TO8(302) /* im27 */
12006         };
12007         const u8 bg_taps_re[] = {
12008                 DRXJ_16TO8(-18),        /* re0  */
12009                 DRXJ_16TO8(18), /* re1  */
12010                 DRXJ_16TO8(19), /* re2  */
12011                 DRXJ_16TO8(-26),        /* re3  */
12012                 DRXJ_16TO8(-20),        /* re4  */
12013                 DRXJ_16TO8(36), /* re5  */
12014                 DRXJ_16TO8(5),  /* re6  */
12015                 DRXJ_16TO8(-51),        /* re7  */
12016                 DRXJ_16TO8(15), /* re8  */
12017                 DRXJ_16TO8(45), /* re9  */
12018                 DRXJ_16TO8(-46),        /* re10 */
12019                 DRXJ_16TO8(-24),        /* re11 */
12020                 DRXJ_16TO8(71), /* re12 */
12021                 DRXJ_16TO8(-17),        /* re13 */
12022                 DRXJ_16TO8(-83),        /* re14 */
12023                 DRXJ_16TO8(74), /* re15 */
12024                 DRXJ_16TO8(75), /* re16 */
12025                 DRXJ_16TO8(-134),       /* re17 */
12026                 DRXJ_16TO8(-40),        /* re18 */
12027                 DRXJ_16TO8(191),        /* re19 */
12028                 DRXJ_16TO8(-11),        /* re20 */
12029                 DRXJ_16TO8(-233),       /* re21 */
12030                 DRXJ_16TO8(74), /* re22 */
12031                 DRXJ_16TO8(271),        /* re23 */
12032                 DRXJ_16TO8(-132),       /* re24 */
12033                 DRXJ_16TO8(-341),       /* re25 */
12034                 DRXJ_16TO8(172),        /* re26 */
12035                 DRXJ_16TO8(801) /* re27 */
12036         };
12037         const u8 bg_taps_im[] = {
12038                 DRXJ_16TO8(-24),        /* im0  */
12039                 DRXJ_16TO8(-10),        /* im1  */
12040                 DRXJ_16TO8(9),  /* im2  */
12041                 DRXJ_16TO8(-5), /* im3  */
12042                 DRXJ_16TO8(-51),        /* im4  */
12043                 DRXJ_16TO8(-17),        /* im5  */
12044                 DRXJ_16TO8(31), /* im6  */
12045                 DRXJ_16TO8(-48),        /* im7  */
12046                 DRXJ_16TO8(-95),        /* im8  */
12047                 DRXJ_16TO8(25), /* im9  */
12048                 DRXJ_16TO8(37), /* im10 */
12049                 DRXJ_16TO8(-123),       /* im11 */
12050                 DRXJ_16TO8(-77),        /* im12 */
12051                 DRXJ_16TO8(94), /* im13 */
12052                 DRXJ_16TO8(-10),        /* im14 */
12053                 DRXJ_16TO8(-149),       /* im15 */
12054                 DRXJ_16TO8(10), /* im16 */
12055                 DRXJ_16TO8(108),        /* im17 */
12056                 DRXJ_16TO8(-49),        /* im18 */
12057                 DRXJ_16TO8(-59),        /* im19 */
12058                 DRXJ_16TO8(90), /* im20 */
12059                 DRXJ_16TO8(73), /* im21 */
12060                 DRXJ_16TO8(55), /* im22 */
12061                 DRXJ_16TO8(148),        /* im23 */
12062                 DRXJ_16TO8(86), /* im24 */
12063                 DRXJ_16TO8(146),        /* im25 */
12064                 DRXJ_16TO8(687),        /* im26 */
12065                 DRXJ_16TO8(877) /* im27 */
12066         };
12067         const u8 dk_i_l_lp_taps_re[] = {
12068                 DRXJ_16TO8(-23),        /* re0  */
12069                 DRXJ_16TO8(9),  /* re1  */
12070                 DRXJ_16TO8(16), /* re2  */
12071                 DRXJ_16TO8(-26),        /* re3  */
12072                 DRXJ_16TO8(-3), /* re4  */
12073                 DRXJ_16TO8(13), /* re5  */
12074                 DRXJ_16TO8(-19),        /* re6  */
12075                 DRXJ_16TO8(-3), /* re7  */
12076                 DRXJ_16TO8(13), /* re8  */
12077                 DRXJ_16TO8(-26),        /* re9  */
12078                 DRXJ_16TO8(-4), /* re10 */
12079                 DRXJ_16TO8(28), /* re11 */
12080                 DRXJ_16TO8(-15),        /* re12 */
12081                 DRXJ_16TO8(-14),        /* re13 */
12082                 DRXJ_16TO8(10), /* re14 */
12083                 DRXJ_16TO8(1),  /* re15 */
12084                 DRXJ_16TO8(39), /* re16 */
12085                 DRXJ_16TO8(-18),        /* re17 */
12086                 DRXJ_16TO8(-90),        /* re18 */
12087                 DRXJ_16TO8(109),        /* re19 */
12088                 DRXJ_16TO8(113),        /* re20 */
12089                 DRXJ_16TO8(-235),       /* re21 */
12090                 DRXJ_16TO8(-49),        /* re22 */
12091                 DRXJ_16TO8(359),        /* re23 */
12092                 DRXJ_16TO8(-79),        /* re24 */
12093                 DRXJ_16TO8(-459),       /* re25 */
12094                 DRXJ_16TO8(206),        /* re26 */
12095                 DRXJ_16TO8(894) /* re27 */
12096         };
12097         const u8 dk_i_l_lp_taps_im[] = {
12098                 DRXJ_16TO8(-8), /* im0  */
12099                 DRXJ_16TO8(-20),        /* im1  */
12100                 DRXJ_16TO8(17), /* im2  */
12101                 DRXJ_16TO8(-14),        /* im3  */
12102                 DRXJ_16TO8(-52),        /* im4  */
12103                 DRXJ_16TO8(4),  /* im5  */
12104                 DRXJ_16TO8(9),  /* im6  */
12105                 DRXJ_16TO8(-62),        /* im7  */
12106                 DRXJ_16TO8(-47),        /* im8  */
12107                 DRXJ_16TO8(0),  /* im9  */
12108                 DRXJ_16TO8(-20),        /* im10 */
12109                 DRXJ_16TO8(-48),        /* im11 */
12110                 DRXJ_16TO8(-65),        /* im12 */
12111                 DRXJ_16TO8(-23),        /* im13 */
12112                 DRXJ_16TO8(44), /* im14 */
12113                 DRXJ_16TO8(-60),        /* im15 */
12114                 DRXJ_16TO8(-113),       /* im16 */
12115                 DRXJ_16TO8(92), /* im17 */
12116                 DRXJ_16TO8(81), /* im18 */
12117                 DRXJ_16TO8(-125),       /* im19 */
12118                 DRXJ_16TO8(28), /* im20 */
12119                 DRXJ_16TO8(182),        /* im21 */
12120                 DRXJ_16TO8(35), /* im22 */
12121                 DRXJ_16TO8(94), /* im23 */
12122                 DRXJ_16TO8(180),        /* im24 */
12123                 DRXJ_16TO8(134),        /* im25 */
12124                 DRXJ_16TO8(657),        /* im26 */
12125                 DRXJ_16TO8(1023)        /* im27 */
12126         };
12127         const u8 fm_taps_re[] = {
12128                 DRXJ_16TO8(0),  /* re0  */
12129                 DRXJ_16TO8(0),  /* re1  */
12130                 DRXJ_16TO8(0),  /* re2  */
12131                 DRXJ_16TO8(0),  /* re3  */
12132                 DRXJ_16TO8(0),  /* re4  */
12133                 DRXJ_16TO8(0),  /* re5  */
12134                 DRXJ_16TO8(0),  /* re6  */
12135                 DRXJ_16TO8(0),  /* re7  */
12136                 DRXJ_16TO8(0),  /* re8  */
12137                 DRXJ_16TO8(0),  /* re9  */
12138                 DRXJ_16TO8(0),  /* re10 */
12139                 DRXJ_16TO8(0),  /* re11 */
12140                 DRXJ_16TO8(0),  /* re12 */
12141                 DRXJ_16TO8(0),  /* re13 */
12142                 DRXJ_16TO8(0),  /* re14 */
12143                 DRXJ_16TO8(0),  /* re15 */
12144                 DRXJ_16TO8(0),  /* re16 */
12145                 DRXJ_16TO8(0),  /* re17 */
12146                 DRXJ_16TO8(0),  /* re18 */
12147                 DRXJ_16TO8(0),  /* re19 */
12148                 DRXJ_16TO8(0),  /* re20 */
12149                 DRXJ_16TO8(0),  /* re21 */
12150                 DRXJ_16TO8(0),  /* re22 */
12151                 DRXJ_16TO8(0),  /* re23 */
12152                 DRXJ_16TO8(0),  /* re24 */
12153                 DRXJ_16TO8(0),  /* re25 */
12154                 DRXJ_16TO8(0),  /* re26 */
12155                 DRXJ_16TO8(0)   /* re27 */
12156         };
12157         const u8 fm_taps_im[] = {
12158                 DRXJ_16TO8(-6), /* im0  */
12159                 DRXJ_16TO8(2),  /* im1  */
12160                 DRXJ_16TO8(14), /* im2  */
12161                 DRXJ_16TO8(-38),        /* im3  */
12162                 DRXJ_16TO8(58), /* im4  */
12163                 DRXJ_16TO8(-62),        /* im5  */
12164                 DRXJ_16TO8(42), /* im6  */
12165                 DRXJ_16TO8(0),  /* im7  */
12166                 DRXJ_16TO8(-45),        /* im8  */
12167                 DRXJ_16TO8(73), /* im9  */
12168                 DRXJ_16TO8(-65),        /* im10 */
12169                 DRXJ_16TO8(23), /* im11 */
12170                 DRXJ_16TO8(34), /* im12 */
12171                 DRXJ_16TO8(-77),        /* im13 */
12172                 DRXJ_16TO8(80), /* im14 */
12173                 DRXJ_16TO8(-39),        /* im15 */
12174                 DRXJ_16TO8(-25),        /* im16 */
12175                 DRXJ_16TO8(78), /* im17 */
12176                 DRXJ_16TO8(-90),        /* im18 */
12177                 DRXJ_16TO8(52), /* im19 */
12178                 DRXJ_16TO8(16), /* im20 */
12179                 DRXJ_16TO8(-77),        /* im21 */
12180                 DRXJ_16TO8(97), /* im22 */
12181                 DRXJ_16TO8(-62),        /* im23 */
12182                 DRXJ_16TO8(-8), /* im24 */
12183                 DRXJ_16TO8(75), /* im25 */
12184                 DRXJ_16TO8(-100),       /* im26 */
12185                 DRXJ_16TO8(70)  /* im27 */
12186         };
12187
12188         struct i2c_device_addr *dev_addr = NULL;
12189         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
12190                 /* parameter_len */ 0,
12191                 /* result_len    */ 0,
12192                 /* *parameter   */ NULL,
12193                 /* *result      */ NULL
12194         };
12195         u16 cmd_result = 0;
12196         u16 cmd_param = 0;
12197 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
12198         struct drxu_code_info ucode_info;
12199         struct drx_common_attr *common_attr = NULL;
12200 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
12201         struct drxj_data *ext_attr = NULL;
12202         int rc;
12203
12204         ext_attr = (struct drxj_data *) demod->my_ext_attr;
12205         dev_addr = demod->my_i2c_dev_addr;
12206
12207 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
12208         common_attr = demod->my_common_attr;
12209
12210         /* Check if audio microcode is already uploaded */
12211         if (!(ext_attr->flag_aud_mc_uploaded)) {
12212                 ucode_info.mc_data = common_attr->microcode;
12213
12214                 /* Upload only audio microcode */
12215                 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_UPLOAD, true);
12216                 if (rc != 0) {
12217                         pr_err("error %d\n", rc);
12218                         goto rw_error;
12219                 }
12220
12221                 if (common_attr->verify_microcode == true) {
12222                         rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_VERIFY, true);
12223                         if (rc != 0) {
12224                                 pr_err("error %d\n", rc);
12225                                 goto rw_error;
12226                         }
12227                 }
12228
12229                 /* Prevent uploading audio microcode again */
12230                 ext_attr->flag_aud_mc_uploaded = true;
12231         }
12232 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
12233
12234         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
12235         if (rc != 0) {
12236                 pr_err("error %d\n", rc);
12237                 goto rw_error;
12238         }
12239         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
12240         if (rc != 0) {
12241                 pr_err("error %d\n", rc);
12242                 goto rw_error;
12243         }
12244         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
12245         if (rc != 0) {
12246                 pr_err("error %d\n", rc);
12247                 goto rw_error;
12248         }
12249         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 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_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
12255         if (rc != 0) {
12256                 pr_err("error %d\n", rc);
12257                 goto rw_error;
12258         }
12259         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
12260         if (rc != 0) {
12261                 pr_err("error %d\n", rc);
12262                 goto rw_error;
12263         }
12264         /* Reset ATV SCU */
12265         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12266             SCU_RAM_COMMAND_CMD_DEMOD_RESET;
12267         cmd_scu.parameter_len = 0;
12268         cmd_scu.result_len = 1;
12269         cmd_scu.parameter = NULL;
12270         cmd_scu.result = &cmd_result;
12271         rc = scu_command(dev_addr, &cmd_scu);
12272         if (rc != 0) {
12273                 pr_err("error %d\n", rc);
12274                 goto rw_error;
12275         }
12276
12277         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_CONTROL__A, ATV_TOP_MOD_CONTROL__PRE, 0);
12278         if (rc != 0) {
12279                 pr_err("error %d\n", rc);
12280                 goto rw_error;
12281         }
12282
12283         /* TODO remove AUTO/OFF patches after ucode fix. */
12284         switch (*standard) {
12285         case DRX_STANDARD_NTSC:
12286                 /* NTSC */
12287                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_MN;
12288
12289                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, IQM_RT_LO_INCR_MN, 0);
12290                 if (rc != 0) {
12291                         pr_err("error %d\n", rc);
12292                         goto rw_error;
12293                 }
12294                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12295                 if (rc != 0) {
12296                         pr_err("error %d\n", rc);
12297                         goto rw_error;
12298                 }
12299                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(ntsc_taps_re), ((u8 *)ntsc_taps_re), 0);
12300                 if (rc != 0) {
12301                         pr_err("error %d\n", rc);
12302                         goto rw_error;
12303                 }
12304                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(ntsc_taps_im), ((u8 *)ntsc_taps_im), 0);
12305                 if (rc != 0) {
12306                         pr_err("error %d\n", rc);
12307                         goto rw_error;
12308                 }
12309
12310                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_MN, 0);
12311                 if (rc != 0) {
12312                         pr_err("error %d\n", rc);
12313                         goto rw_error;
12314                 }
12315                 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);
12316                 if (rc != 0) {
12317                         pr_err("error %d\n", rc);
12318                         goto rw_error;
12319                 }
12320                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_MN, 0);
12321                 if (rc != 0) {
12322                         pr_err("error %d\n", rc);
12323                         goto rw_error;
12324                 }
12325                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_MN | ATV_TOP_STD_VID_POL_MN), 0);
12326                 if (rc != 0) {
12327                         pr_err("error %d\n", rc);
12328                         goto rw_error;
12329                 }
12330                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_MN, 0);
12331                 if (rc != 0) {
12332                         pr_err("error %d\n", rc);
12333                         goto rw_error;
12334                 }
12335
12336                 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);
12337                 if (rc != 0) {
12338                         pr_err("error %d\n", rc);
12339                         goto rw_error;
12340                 }
12341                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12342                 if (rc != 0) {
12343                         pr_err("error %d\n", rc);
12344                         goto rw_error;
12345                 }
12346                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12347                 if (rc != 0) {
12348                         pr_err("error %d\n", rc);
12349                         goto rw_error;
12350                 }
12351                 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);
12352                 if (rc != 0) {
12353                         pr_err("error %d\n", rc);
12354                         goto rw_error;
12355                 }
12356                 ext_attr->phase_correction_bypass = false;
12357                 ext_attr->enable_cvbs_output = true;
12358                 break;
12359         case DRX_STANDARD_FM:
12360                 /* FM */
12361                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_FM;
12362
12363                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2994, 0);
12364                 if (rc != 0) {
12365                         pr_err("error %d\n", rc);
12366                         goto rw_error;
12367                 }
12368                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, 0, 0);
12369                 if (rc != 0) {
12370                         pr_err("error %d\n", rc);
12371                         goto rw_error;
12372                 }
12373                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(fm_taps_re), ((u8 *)fm_taps_re), 0);
12374                 if (rc != 0) {
12375                         pr_err("error %d\n", rc);
12376                         goto rw_error;
12377                 }
12378                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(fm_taps_im), ((u8 *)fm_taps_im), 0);
12379                 if (rc != 0) {
12380                         pr_err("error %d\n", rc);
12381                         goto rw_error;
12382                 }
12383                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_FM | ATV_TOP_STD_VID_POL_FM), 0);
12384                 if (rc != 0) {
12385                         pr_err("error %d\n", rc);
12386                         goto rw_error;
12387                 }
12388                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_CONTROL__A, 0, 0);
12389                 if (rc != 0) {
12390                         pr_err("error %d\n", rc);
12391                         goto rw_error;
12392                 }
12393                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_CONT__A, 0, 0);
12394                 if (rc != 0) {
12395                         pr_err("error %d\n", rc);
12396                         goto rw_error;
12397                 }
12398
12399                 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);
12400                 if (rc != 0) {
12401                         pr_err("error %d\n", rc);
12402                         goto rw_error;
12403                 }
12404                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_ROT_BP__A, IQM_RT_ROT_BP_ROT_OFF_OFF, 0);
12405                 if (rc != 0) {
12406                         pr_err("error %d\n", rc);
12407                         goto rw_error;
12408                 }
12409                 ext_attr->phase_correction_bypass = true;
12410                 ext_attr->enable_cvbs_output = false;
12411                 break;
12412         case DRX_STANDARD_PAL_SECAM_BG:
12413                 /* PAL/SECAM B/G */
12414                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_B;
12415
12416                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 1820, 0);
12417                 if (rc != 0) {
12418                         pr_err("error %d\n", rc);
12419                         goto rw_error;
12420                 }       /* TODO check with IS */
12421                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12422                 if (rc != 0) {
12423                         pr_err("error %d\n", rc);
12424                         goto rw_error;
12425                 }
12426                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_RE0__A, sizeof(bg_taps_re), ((u8 *)bg_taps_re), 0);
12427                 if (rc != 0) {
12428                         pr_err("error %d\n", rc);
12429                         goto rw_error;
12430                 }
12431                 rc = DRXJ_DAP.write_block_func(dev_addr, IQM_CF_TAP_IM0__A, sizeof(bg_taps_im), ((u8 *)bg_taps_im), 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, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_BG, 0);
12437                 if (rc != 0) {
12438                         pr_err("error %d\n", rc);
12439                         goto rw_error;
12440                 }
12441                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_BG, 0);
12442                 if (rc != 0) {
12443                         pr_err("error %d\n", rc);
12444                         goto rw_error;
12445                 }
12446                 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);
12447                 if (rc != 0) {
12448                         pr_err("error %d\n", rc);
12449                         goto rw_error;
12450                 }
12451                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_BG, 0);
12452                 if (rc != 0) {
12453                         pr_err("error %d\n", rc);
12454                         goto rw_error;
12455                 }
12456                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_BG | ATV_TOP_STD_VID_POL_BG), 0);
12457                 if (rc != 0) {
12458                         pr_err("error %d\n", rc);
12459                         goto rw_error;
12460                 }
12461                 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);
12462                 if (rc != 0) {
12463                         pr_err("error %d\n", rc);
12464                         goto rw_error;
12465                 }
12466                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12467                 if (rc != 0) {
12468                         pr_err("error %d\n", rc);
12469                         goto rw_error;
12470                 }
12471                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12472                 if (rc != 0) {
12473                         pr_err("error %d\n", rc);
12474                         goto rw_error;
12475                 }
12476                 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);
12477                 if (rc != 0) {
12478                         pr_err("error %d\n", rc);
12479                         goto rw_error;
12480                 }
12481                 ext_attr->phase_correction_bypass = false;
12482                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12483                 ext_attr->enable_cvbs_output = true;
12484                 break;
12485         case DRX_STANDARD_PAL_SECAM_DK:
12486                 /* PAL/SECAM D/K */
12487                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_DK;
12488
12489                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12490                 if (rc != 0) {
12491                         pr_err("error %d\n", rc);
12492                         goto rw_error;
12493                 }       /* TODO check with IS */
12494                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12495                 if (rc != 0) {
12496                         pr_err("error %d\n", rc);
12497                         goto rw_error;
12498                 }
12499                 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);
12500                 if (rc != 0) {
12501                         pr_err("error %d\n", rc);
12502                         goto rw_error;
12503                 }
12504                 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);
12505                 if (rc != 0) {
12506                         pr_err("error %d\n", rc);
12507                         goto rw_error;
12508                 }
12509                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_DK, 0);
12510                 if (rc != 0) {
12511                         pr_err("error %d\n", rc);
12512                         goto rw_error;
12513                 }
12514                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_DK, 0);
12515                 if (rc != 0) {
12516                         pr_err("error %d\n", rc);
12517                         goto rw_error;
12518                 }
12519                 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);
12520                 if (rc != 0) {
12521                         pr_err("error %d\n", rc);
12522                         goto rw_error;
12523                 }
12524                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_DK, 0);
12525                 if (rc != 0) {
12526                         pr_err("error %d\n", rc);
12527                         goto rw_error;
12528                 }
12529                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_DK | ATV_TOP_STD_VID_POL_DK), 0);
12530                 if (rc != 0) {
12531                         pr_err("error %d\n", rc);
12532                         goto rw_error;
12533                 }
12534                 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);
12535                 if (rc != 0) {
12536                         pr_err("error %d\n", rc);
12537                         goto rw_error;
12538                 }
12539                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12540                 if (rc != 0) {
12541                         pr_err("error %d\n", rc);
12542                         goto rw_error;
12543                 }
12544                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12545                 if (rc != 0) {
12546                         pr_err("error %d\n", rc);
12547                         goto rw_error;
12548                 }
12549                 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);
12550                 if (rc != 0) {
12551                         pr_err("error %d\n", rc);
12552                         goto rw_error;
12553                 }
12554                 ext_attr->phase_correction_bypass = false;
12555                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12556                 ext_attr->enable_cvbs_output = true;
12557                 break;
12558         case DRX_STANDARD_PAL_SECAM_I:
12559                 /* PAL/SECAM I   */
12560                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_I;
12561
12562                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12563                 if (rc != 0) {
12564                         pr_err("error %d\n", rc);
12565                         goto rw_error;
12566                 }       /* TODO check with IS */
12567                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12568                 if (rc != 0) {
12569                         pr_err("error %d\n", rc);
12570                         goto rw_error;
12571                 }
12572                 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);
12573                 if (rc != 0) {
12574                         pr_err("error %d\n", rc);
12575                         goto rw_error;
12576                 }
12577                 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);
12578                 if (rc != 0) {
12579                         pr_err("error %d\n", rc);
12580                         goto rw_error;
12581                 }
12582                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, ATV_TOP_CR_AMP_TH_I, 0);
12583                 if (rc != 0) {
12584                         pr_err("error %d\n", rc);
12585                         goto rw_error;
12586                 }
12587                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_I, 0);
12588                 if (rc != 0) {
12589                         pr_err("error %d\n", rc);
12590                         goto rw_error;
12591                 }
12592                 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);
12593                 if (rc != 0) {
12594                         pr_err("error %d\n", rc);
12595                         goto rw_error;
12596                 }
12597                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_I, 0);
12598                 if (rc != 0) {
12599                         pr_err("error %d\n", rc);
12600                         goto rw_error;
12601                 }
12602                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_I | ATV_TOP_STD_VID_POL_I), 0);
12603                 if (rc != 0) {
12604                         pr_err("error %d\n", rc);
12605                         goto rw_error;
12606                 }
12607                 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);
12608                 if (rc != 0) {
12609                         pr_err("error %d\n", rc);
12610                         goto rw_error;
12611                 }
12612                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12613                 if (rc != 0) {
12614                         pr_err("error %d\n", rc);
12615                         goto rw_error;
12616                 }
12617                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12618                 if (rc != 0) {
12619                         pr_err("error %d\n", rc);
12620                         goto rw_error;
12621                 }
12622                 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);
12623                 if (rc != 0) {
12624                         pr_err("error %d\n", rc);
12625                         goto rw_error;
12626                 }
12627                 ext_attr->phase_correction_bypass = false;
12628                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
12629                 ext_attr->enable_cvbs_output = true;
12630                 break;
12631         case DRX_STANDARD_PAL_SECAM_L:
12632                 /* PAL/SECAM L with negative modulation */
12633                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_L;
12634
12635                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_LO_INCR__A, 2225, 0);
12636                 if (rc != 0) {
12637                         pr_err("error %d\n", rc);
12638                         goto rw_error;
12639                 }       /* TODO check with IS */
12640                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_L, 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, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12646                 if (rc != 0) {
12647                         pr_err("error %d\n", rc);
12648                         goto rw_error;
12649                 }
12650                 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);
12651                 if (rc != 0) {
12652                         pr_err("error %d\n", rc);
12653                         goto rw_error;
12654                 }
12655                 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);
12656                 if (rc != 0) {
12657                         pr_err("error %d\n", rc);
12658                         goto rw_error;
12659                 }
12660                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12661                 if (rc != 0) {
12662                         pr_err("error %d\n", rc);
12663                         goto rw_error;
12664                 }       /* TODO check with IS */
12665                 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);
12666                 if (rc != 0) {
12667                         pr_err("error %d\n", rc);
12668                         goto rw_error;
12669                 }
12670                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_L, 0);
12671                 if (rc != 0) {
12672                         pr_err("error %d\n", rc);
12673                         goto rw_error;
12674                 }
12675                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_L | ATV_TOP_STD_VID_POL_L), 0);
12676                 if (rc != 0) {
12677                         pr_err("error %d\n", rc);
12678                         goto rw_error;
12679                 }
12680                 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);
12681                 if (rc != 0) {
12682                         pr_err("error %d\n", rc);
12683                         goto rw_error;
12684                 }
12685                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12686                 if (rc != 0) {
12687                         pr_err("error %d\n", rc);
12688                         goto rw_error;
12689                 }
12690                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12691                 if (rc != 0) {
12692                         pr_err("error %d\n", rc);
12693                         goto rw_error;
12694                 }
12695                 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);
12696                 if (rc != 0) {
12697                         pr_err("error %d\n", rc);
12698                         goto rw_error;
12699                 }
12700                 ext_attr->phase_correction_bypass = false;
12701                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12702                 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12703                 ext_attr->enable_cvbs_output = true;
12704                 break;
12705         case DRX_STANDARD_PAL_SECAM_LP:
12706                 /* PAL/SECAM L with positive modulation */
12707                 cmd_param = SCU_RAM_ATV_STANDARD_STANDARD_LP;
12708
12709                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_VID_AMP__A, ATV_TOP_VID_AMP_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, IQM_RT_LO_INCR__A, 2225, 0);
12715                 if (rc != 0) {
12716                         pr_err("error %d\n", rc);
12717                         goto rw_error;
12718                 }       /* TODO check with IS */
12719                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_MIDTAP__A, IQM_CF_MIDTAP_RE__M, 0);
12720                 if (rc != 0) {
12721                         pr_err("error %d\n", rc);
12722                         goto rw_error;
12723                 }
12724                 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);
12725                 if (rc != 0) {
12726                         pr_err("error %d\n", rc);
12727                         goto rw_error;
12728                 }
12729                 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);
12730                 if (rc != 0) {
12731                         pr_err("error %d\n", rc);
12732                         goto rw_error;
12733                 }
12734                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_AMP_TH__A, 0x2, 0);
12735                 if (rc != 0) {
12736                         pr_err("error %d\n", rc);
12737                         goto rw_error;
12738                 }       /* TODO check with IS */
12739                 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);
12740                 if (rc != 0) {
12741                         pr_err("error %d\n", rc);
12742                         goto rw_error;
12743                 }
12744                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_OVM_TH__A, ATV_TOP_CR_OVM_TH_LP, 0);
12745                 if (rc != 0) {
12746                         pr_err("error %d\n", rc);
12747                         goto rw_error;
12748                 }
12749                 rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_STD__A, (ATV_TOP_STD_MODE_LP | ATV_TOP_STD_VID_POL_LP), 0);
12750                 if (rc != 0) {
12751                         pr_err("error %d\n", rc);
12752                         goto rw_error;
12753                 }
12754                 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);
12755                 if (rc != 0) {
12756                         pr_err("error %d\n", rc);
12757                         goto rw_error;
12758                 }
12759                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, 0x1000, 0);
12760                 if (rc != 0) {
12761                         pr_err("error %d\n", rc);
12762                         goto rw_error;
12763                 }
12764                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_VID_GAIN_LO__A, 0x0000, 0);
12765                 if (rc != 0) {
12766                         pr_err("error %d\n", rc);
12767                         goto rw_error;
12768                 }
12769                 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);
12770                 if (rc != 0) {
12771                         pr_err("error %d\n", rc);
12772                         goto rw_error;
12773                 }
12774                 ext_attr->phase_correction_bypass = false;
12775                 ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_USER;
12776                 ext_attr->atv_if_agc_cfg.output_level = ext_attr->atv_rf_agc_cfg.top;
12777                 ext_attr->enable_cvbs_output = true;
12778                 break;
12779         default:
12780                 return -EIO;
12781         }
12782
12783         /* Common initializations FM & NTSC & B/G & D/K & I & L & LP */
12784         if (!ext_attr->has_lna) {
12785                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AMUX__A, 0x01, 0);
12786                 if (rc != 0) {
12787                         pr_err("error %d\n", rc);
12788                         goto rw_error;
12789                 }
12790         }
12791
12792         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_STANDARD__A, 0x002, 0);
12793         if (rc != 0) {
12794                 pr_err("error %d\n", rc);
12795                 goto rw_error;
12796         }
12797         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_LEN__A, IQM_AF_CLP_LEN_ATV, 0);
12798         if (rc != 0) {
12799                 pr_err("error %d\n", rc);
12800                 goto rw_error;
12801         }
12802         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_CLP_TH__A, IQM_AF_CLP_TH_ATV, 0);
12803         if (rc != 0) {
12804                 pr_err("error %d\n", rc);
12805                 goto rw_error;
12806         }
12807         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_SNS_LEN__A, IQM_AF_SNS_LEN_ATV, 0);
12808         if (rc != 0) {
12809                 pr_err("error %d\n", rc);
12810                 goto rw_error;
12811         }
12812         rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12813         if (rc != 0) {
12814                 pr_err("error %d\n", rc);
12815                 goto rw_error;
12816         }
12817         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_AGC_IF__A, 10248, 0);
12818         if (rc != 0) {
12819                 pr_err("error %d\n", rc);
12820                 goto rw_error;
12821         }
12822
12823         ext_attr->iqm_rc_rate_ofs = 0x00200000L;
12824         rc = DRXJ_DAP.write_reg32func(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
12825         if (rc != 0) {
12826                 pr_err("error %d\n", rc);
12827                 goto rw_error;
12828         }
12829         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_OFF, 0);
12830         if (rc != 0) {
12831                 pr_err("error %d\n", rc);
12832                 goto rw_error;
12833         }
12834         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RC_STRETCH__A, IQM_RC_STRETCH_ATV, 0);
12835         if (rc != 0) {
12836                 pr_err("error %d\n", rc);
12837                 goto rw_error;
12838         }
12839
12840         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);
12841         if (rc != 0) {
12842                 pr_err("error %d\n", rc);
12843                 goto rw_error;
12844         }
12845
12846         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_ATV__M, 0);
12847         if (rc != 0) {
12848                 pr_err("error %d\n", rc);
12849                 goto rw_error;
12850         }
12851         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_CF_SYMMETRIC__A, IQM_CF_SYMMETRIC_IM__M, 0);
12852         if (rc != 0) {
12853                 pr_err("error %d\n", rc);
12854                 goto rw_error;
12855         }
12856         /* default: SIF in standby */
12857         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_SYNC_SLICE__A, ATV_TOP_SYNC_SLICE_MN, 0);
12858         if (rc != 0) {
12859                 pr_err("error %d\n", rc);
12860                 goto rw_error;
12861         }
12862         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_MOD_ACCU__A, ATV_TOP_MOD_ACCU__PRE, 0);
12863         if (rc != 0) {
12864                 pr_err("error %d\n", rc);
12865                 goto rw_error;
12866         }
12867
12868         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, 0x080, 0);
12869         if (rc != 0) {
12870                 pr_err("error %d\n", rc);
12871                 goto rw_error;
12872         }
12873         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_FAGC_TH_RED__A, 10, 0);
12874         if (rc != 0) {
12875                 pr_err("error %d\n", rc);
12876                 goto rw_error;
12877         }
12878         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AAGC_CNT__A, 7, 0);
12879         if (rc != 0) {
12880                 pr_err("error %d\n", rc);
12881                 goto rw_error;
12882         }
12883         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_NAGC_KI_MIN__A, 0x0225, 0);
12884         if (rc != 0) {
12885                 pr_err("error %d\n", rc);
12886                 goto rw_error;
12887         }
12888         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_NAGC_KI_MAX__A, 0x0547, 0);
12889         if (rc != 0) {
12890                 pr_err("error %d\n", rc);
12891                 goto rw_error;
12892         }
12893         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_KI_CHANGE_TH__A, 20, 0);
12894         if (rc != 0) {
12895                 pr_err("error %d\n", rc);
12896                 goto rw_error;
12897         }
12898         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_LOCK__A, 0, 0);
12899         if (rc != 0) {
12900                 pr_err("error %d\n", rc);
12901                 goto rw_error;
12902         }
12903
12904         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_RT_DELAY__A, IQM_RT_DELAY__PRE, 0);
12905         if (rc != 0) {
12906                 pr_err("error %d\n", rc);
12907                 goto rw_error;
12908         }
12909         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BPC_KI_MIN__A, 531, 0);
12910         if (rc != 0) {
12911                 pr_err("error %d\n", rc);
12912                 goto rw_error;
12913         }
12914         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_PAGC_KI_MIN__A, 1061, 0);
12915         if (rc != 0) {
12916                 pr_err("error %d\n", rc);
12917                 goto rw_error;
12918         }
12919         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_REF_MIN__A, 100, 0);
12920         if (rc != 0) {
12921                 pr_err("error %d\n", rc);
12922                 goto rw_error;
12923         }
12924         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_REF_MAX__A, 260, 0);
12925         if (rc != 0) {
12926                 pr_err("error %d\n", rc);
12927                 goto rw_error;
12928         }
12929         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_BP_LVL__A, 0, 0);
12930         if (rc != 0) {
12931                 pr_err("error %d\n", rc);
12932                 goto rw_error;
12933         }
12934         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MAX__A, 0, 0);
12935         if (rc != 0) {
12936                 pr_err("error %d\n", rc);
12937                 goto rw_error;
12938         }
12939         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_AMS_MIN__A, 2047, 0);
12940         if (rc != 0) {
12941                 pr_err("error %d\n", rc);
12942                 goto rw_error;
12943         }
12944         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_GPIO__A, 0, 0);
12945         if (rc != 0) {
12946                 pr_err("error %d\n", rc);
12947                 goto rw_error;
12948         }
12949
12950         /* Override reset values with current shadow settings */
12951         rc = atv_update_config(demod, true);
12952         if (rc != 0) {
12953                 pr_err("error %d\n", rc);
12954                 goto rw_error;
12955         }
12956
12957         /* Configure/restore AGC settings */
12958         rc = init_agc(demod);
12959         if (rc != 0) {
12960                 pr_err("error %d\n", rc);
12961                 goto rw_error;
12962         }
12963         rc = set_agc_if(demod, &(ext_attr->atv_if_agc_cfg), false);
12964         if (rc != 0) {
12965                 pr_err("error %d\n", rc);
12966                 goto rw_error;
12967         }
12968         rc = set_agc_rf(demod, &(ext_attr->atv_rf_agc_cfg), false);
12969         if (rc != 0) {
12970                 pr_err("error %d\n", rc);
12971                 goto rw_error;
12972         }
12973         rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->atv_pre_saw_cfg));
12974         if (rc != 0) {
12975                 pr_err("error %d\n", rc);
12976                 goto rw_error;
12977         }
12978
12979         /* Set SCU ATV substandard,assuming this doesn't require running ATV block */
12980         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
12981             SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
12982         cmd_scu.parameter_len = 1;
12983         cmd_scu.result_len = 1;
12984         cmd_scu.parameter = &cmd_param;
12985         cmd_scu.result = &cmd_result;
12986         rc = scu_command(dev_addr, &cmd_scu);
12987         if (rc != 0) {
12988                 pr_err("error %d\n", rc);
12989                 goto rw_error;
12990         }
12991
12992         /* turn the analog work around on/off (must after set_env b/c it is set in mc) */
12993         if (ext_attr->mfx == 0x03) {
12994                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 0, 0);
12995                 if (rc != 0) {
12996                         pr_err("error %d\n", rc);
12997                         goto rw_error;
12998                 }
12999         } else {
13000                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_ENABLE_IIR_WA__A, 1, 0);
13001                 if (rc != 0) {
13002                         pr_err("error %d\n", rc);
13003                         goto rw_error;
13004                 }
13005                 rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ATV_IIR_CRIT__A, 225, 0);
13006                 if (rc != 0) {
13007                         pr_err("error %d\n", rc);
13008                         goto rw_error;
13009                 }
13010         }
13011
13012         return 0;
13013 rw_error:
13014         return -EIO;
13015 }
13016 #endif
13017
13018 /* -------------------------------------------------------------------------- */
13019
13020 #ifndef DRXJ_DIGITAL_ONLY
13021 /**
13022 * \fn int set_atv_channel ()
13023 * \brief Set ATV channel.
13024 * \param demod:   instance of demod.
13025 * \return int.
13026 *
13027 * Not much needs to be done here, only start the SCU for NTSC/FM.
13028 * Mirrored channels are not expected in the RF domain, so IQM FS setting
13029 * doesn't need to be remembered.
13030 * The channel->mirror parameter is therefor ignored.
13031 *
13032 */
13033 static int
13034 set_atv_channel(struct drx_demod_instance *demod,
13035                 s32 tuner_freq_offset,
13036               struct drx_channel *channel, enum drx_standard standard)
13037 {
13038         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
13039                 /* parameter_len */ 0,
13040                 /* result_len    */ 0,
13041                 /* parameter    */ NULL,
13042                 /* result       */ NULL
13043         };
13044         u16 cmd_result = 0;
13045         struct drxj_data *ext_attr = NULL;
13046         struct i2c_device_addr *dev_addr = NULL;
13047         int rc;
13048
13049         dev_addr = demod->my_i2c_dev_addr;
13050         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13051
13052         /*
13053            Program frequency shifter
13054            No need to account for mirroring on RF
13055          */
13056         if (channel->mirror == DRX_MIRROR_AUTO)
13057                 ext_attr->mirror = DRX_MIRROR_NO;
13058         else
13059                 ext_attr->mirror = channel->mirror;
13060
13061         rc = set_frequency(demod, channel, tuner_freq_offset);
13062         if (rc != 0) {
13063                 pr_err("error %d\n", rc);
13064                 goto rw_error;
13065         }
13066         rc = DRXJ_DAP.write_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, ATV_TOP_CR_FREQ__PRE, 0);
13067         if (rc != 0) {
13068                 pr_err("error %d\n", rc);
13069                 goto rw_error;
13070         }
13071
13072         /* Start ATV SCU */
13073         cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
13074             SCU_RAM_COMMAND_CMD_DEMOD_START;
13075         cmd_scu.parameter_len = 0;
13076         cmd_scu.result_len = 1;
13077         cmd_scu.parameter = NULL;
13078         cmd_scu.result = &cmd_result;
13079         rc = scu_command(dev_addr, &cmd_scu);
13080         if (rc != 0) {
13081                 pr_err("error %d\n", rc);
13082                 goto rw_error;
13083         }
13084
13085 /*   if ( (ext_attr->standard == DRX_STANDARD_FM) && (ext_attr->flagSetAUDdone == true) )
13086    {
13087       ext_attr->detectedRDS = (bool)false;
13088    }*/
13089
13090         return 0;
13091 rw_error:
13092         return -EIO;
13093 }
13094 #endif
13095
13096 /* -------------------------------------------------------------------------- */
13097
13098 /**
13099 * \fn int get_atv_channel ()
13100 * \brief Set ATV channel.
13101 * \param demod:   instance of demod.
13102 * \param channel: pointer to channel data.
13103 * \param standard: NTSC or FM.
13104 * \return int.
13105 *
13106 * Covers NTSC, PAL/SECAM - B/G, D/K, I, L, LP and FM.
13107 * Computes the frequency offset in te RF domain and adds it to
13108 * channel->frequency. Determines the value for channel->bandwidth.
13109 *
13110 */
13111 #ifndef DRXJ_DIGITAL_ONLY
13112 static int
13113 get_atv_channel(struct drx_demod_instance *demod,
13114                 struct drx_channel *channel, enum drx_standard standard)
13115 {
13116         s32 offset = 0;
13117         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
13118         int rc;
13119
13120         /* Bandwidth */
13121         channel->bandwidth = ((struct drxj_data *) demod->my_ext_attr)->curr_bandwidth;
13122
13123         switch (standard) {
13124         case DRX_STANDARD_NTSC:
13125         case DRX_STANDARD_PAL_SECAM_BG:
13126         case DRX_STANDARD_PAL_SECAM_DK:
13127         case DRX_STANDARD_PAL_SECAM_I:
13128         case DRX_STANDARD_PAL_SECAM_L:
13129                 {
13130                         u16 measured_offset = 0;
13131
13132                         /* get measured frequency offset */
13133                         rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13134                         if (rc != 0) {
13135                                 pr_err("error %d\n", rc);
13136                                 goto rw_error;
13137                         }
13138                         /* Signed 8 bit register => sign extension needed */
13139                         if ((measured_offset & 0x0080) != 0)
13140                                 measured_offset |= 0xFF80;
13141                         offset +=
13142                             (s32) (((s16) measured_offset) * 10);
13143                         break;
13144                 }
13145         case DRX_STANDARD_PAL_SECAM_LP:
13146                 {
13147                         u16 measured_offset = 0;
13148
13149                         /* get measured frequency offset */
13150                         rc = DRXJ_DAP.read_reg16func(dev_addr, ATV_TOP_CR_FREQ__A, &measured_offset, 0);
13151                         if (rc != 0) {
13152                                 pr_err("error %d\n", rc);
13153                                 goto rw_error;
13154                         }
13155                         /* Signed 8 bit register => sign extension needed */
13156                         if ((measured_offset & 0x0080) != 0)
13157                                 measured_offset |= 0xFF80;
13158                         offset -=
13159                             (s32) (((s16) measured_offset) * 10);
13160                 }
13161                 break;
13162         case DRX_STANDARD_FM:
13163                 /* TODO: compute offset using AUD_DSP_RD_FM_DC_LEVEL_A__A and
13164                    AUD_DSP_RD_FM_DC_LEVEL_B__A. For now leave frequency as is.
13165                  */
13166                 /* No bandwidth know for FM */
13167                 channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
13168                 break;
13169         default:
13170                 return -EIO;
13171         }
13172
13173         channel->frequency -= offset;
13174
13175         return 0;
13176 rw_error:
13177         return -EIO;
13178 }
13179
13180 /* -------------------------------------------------------------------------- */
13181 /**
13182 * \fn int get_atv_sig_strength()
13183 * \brief Retrieve signal strength for ATV & FM.
13184 * \param devmod Pointer to demodulator instance.
13185 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
13186 * \return int.
13187 * \retval 0 sig_strength contains valid data.
13188 * \retval -EIO Erroneous data, sig_strength equals 0.
13189 *
13190 * Taking into account:
13191 *  * digital gain
13192 *  * IF gain      (not implemented yet, waiting for IF gain control by ucode)
13193 *  * RF gain
13194 *
13195 * All weights (digital, if, rf) must add up to 100.
13196 *
13197 * TODO: ? dynamically adapt weights in case RF and/or IF agc of drxj
13198 *         is not used ?
13199 */
13200 static int
13201 get_atv_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
13202 {
13203         struct i2c_device_addr *dev_addr = NULL;
13204         struct drxj_data *ext_attr = NULL;
13205         int rc;
13206
13207         /* All weights must add up to 100 (%)
13208            TODO: change weights when IF ctrl is available */
13209         u32 digital_weight = 50;        /* 0 .. 100 */
13210         u32 rf_weight = 50;     /* 0 .. 100 */
13211         u32 if_weight = 0;      /* 0 .. 100 */
13212
13213         u16 digital_curr_gain = 0;
13214         u32 digital_max_gain = 0;
13215         u32 digital_min_gain = 0;
13216         u16 rf_curr_gain = 0;
13217         u32 rf_max_gain = 0x800;        /* taken from ucode */
13218         u32 rf_min_gain = 0x7fff;
13219         u16 if_curr_gain = 0;
13220         u32 if_max_gain = 0x800;        /* taken from ucode */
13221         u32 if_min_gain = 0x7fff;
13222
13223         u32 digital_strength = 0;       /* 0.. 100 */
13224         u32 rf_strength = 0;    /* 0.. 100 */
13225         u32 if_strength = 0;    /* 0.. 100 */
13226
13227         dev_addr = demod->my_i2c_dev_addr;
13228         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13229
13230         *sig_strength = 0;
13231
13232         switch (ext_attr->standard) {
13233         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
13234         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
13235         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
13236         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
13237         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
13238         case DRX_STANDARD_NTSC:
13239                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_VID_GAIN_HI__A, &digital_curr_gain, 0);
13240                 if (rc != 0) {
13241                         pr_err("error %d\n", rc);
13242                         goto rw_error;
13243                 }
13244                 digital_max_gain = 22512;       /* taken from ucode */
13245                 digital_min_gain = 2400;        /* taken from ucode */
13246                 break;
13247         case DRX_STANDARD_FM:
13248                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_SIF_GAIN__A, &digital_curr_gain, 0);
13249                 if (rc != 0) {
13250                         pr_err("error %d\n", rc);
13251                         goto rw_error;
13252                 }
13253                 digital_max_gain = 0x4ff;       /* taken from ucode */
13254                 digital_min_gain = 0;   /* taken from ucode */
13255                 break;
13256         default:
13257                 return -EIO;
13258                 break;
13259         }
13260         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_RF__A, &rf_curr_gain, 0);
13261         if (rc != 0) {
13262                 pr_err("error %d\n", rc);
13263                 goto rw_error;
13264         }
13265         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_AF_AGC_IF__A, &if_curr_gain, 0);
13266         if (rc != 0) {
13267                 pr_err("error %d\n", rc);
13268                 goto rw_error;
13269         }
13270
13271         /* clipping */
13272         if (digital_curr_gain >= digital_max_gain)
13273                 digital_curr_gain = (u16)digital_max_gain;
13274         if (digital_curr_gain <= digital_min_gain)
13275                 digital_curr_gain = (u16)digital_min_gain;
13276         if (if_curr_gain <= if_max_gain)
13277                 if_curr_gain = (u16)if_max_gain;
13278         if (if_curr_gain >= if_min_gain)
13279                 if_curr_gain = (u16)if_min_gain;
13280         if (rf_curr_gain <= rf_max_gain)
13281                 rf_curr_gain = (u16)rf_max_gain;
13282         if (rf_curr_gain >= rf_min_gain)
13283                 rf_curr_gain = (u16)rf_min_gain;
13284
13285         /* TODO: use SCU_RAM_ATV_RAGC_HR__A to shift max and min in case
13286            of clipping at ADC */
13287
13288         /* Compute signal strength (in %) per "gain domain" */
13289
13290         /* Digital gain  */
13291         /* TODO: ADC clipping not handled */
13292         digital_strength = (100 * (digital_max_gain - (u32) digital_curr_gain)) /
13293             (digital_max_gain - digital_min_gain);
13294
13295         /* TODO: IF gain not implemented yet in microcode, check after impl. */
13296         if_strength = (100 * ((u32) if_curr_gain - if_max_gain)) /
13297             (if_min_gain - if_max_gain);
13298
13299         /* Rf gain */
13300         /* TODO: ADC clipping not handled */
13301         rf_strength = (100 * ((u32) rf_curr_gain - rf_max_gain)) /
13302             (rf_min_gain - rf_max_gain);
13303
13304         /* Compute a weighted signal strength (in %) */
13305         *sig_strength = (u16) (digital_weight * digital_strength +
13306                                 rf_weight * rf_strength + if_weight * if_strength);
13307         *sig_strength /= 100;
13308
13309         return 0;
13310 rw_error:
13311         return -EIO;
13312 }
13313
13314 /* -------------------------------------------------------------------------- */
13315 /**
13316 * \fn int atv_sig_quality()
13317 * \brief Retrieve signal quality indication for ATV.
13318 * \param devmod Pointer to demodulator instance.
13319 * \param sig_quality Pointer to signal quality structure.
13320 * \return int.
13321 * \retval 0 sig_quality contains valid data.
13322 * \retval -EIO Erroneous data, sig_quality indicator equals 0.
13323 *
13324 *
13325 */
13326 static int
13327 atv_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
13328 {
13329         struct i2c_device_addr *dev_addr = NULL;
13330         u16 quality_indicator = 0;
13331         int rc;
13332
13333         dev_addr = demod->my_i2c_dev_addr;
13334
13335         /* defined values for fields not used */
13336         sig_quality->MER = 0;
13337         sig_quality->pre_viterbi_ber = 0;
13338         sig_quality->post_viterbi_ber = 0;
13339         sig_quality->scale_factor_ber = 1;
13340         sig_quality->packet_error = 0;
13341         sig_quality->post_reed_solomon_ber = 0;
13342
13343         /*
13344            Mapping:
13345            0x000..0x080: strong signal  => 80% .. 100%
13346            0x080..0x700: weak signal    => 30% .. 80%
13347            0x700..0x7ff: no signal      => 0%  .. 30%
13348          */
13349
13350         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ATV_CR_LOCK__A, &quality_indicator, 0);
13351         if (rc != 0) {
13352                 pr_err("error %d\n", rc);
13353                 goto rw_error;
13354         }
13355         quality_indicator &= SCU_RAM_ATV_CR_LOCK_CR_LOCK__M;
13356         if (quality_indicator <= 0x80) {
13357                 sig_quality->indicator =
13358                     80 + ((20 * (0x80 - quality_indicator)) / 0x80);
13359         } else if (quality_indicator <= 0x700)
13360                 sig_quality->indicator = 30 + ((50 * (0x700 - quality_indicator)) / (0x700 - 0x81));
13361         else
13362                 sig_quality->indicator = (30 * (0x7FF - quality_indicator)) / (0x7FF - 0x701);
13363
13364         return 0;
13365 rw_error:
13366         return -EIO;
13367 }
13368 #endif /* DRXJ_DIGITAL_ONLY */
13369
13370 /*============================================================================*/
13371 /*==                     END ATV DATAPATH FUNCTIONS                         ==*/
13372 /*============================================================================*/
13373
13374 #ifndef DRXJ_EXCLUDE_AUDIO
13375 /*===========================================================================*/
13376 /*===========================================================================*/
13377 /*==                      AUDIO DATAPATH FUNCTIONS                         ==*/
13378 /*===========================================================================*/
13379 /*===========================================================================*/
13380
13381 /*
13382 * \brief Power up AUD.
13383 * \param demod instance of demodulator
13384 * \return int.
13385 *
13386 */
13387 static int power_up_aud(struct drx_demod_instance *demod, bool set_standard)
13388 {
13389         enum drx_aud_standard aud_standard = DRX_AUD_STANDARD_AUTO;
13390         struct i2c_device_addr *dev_addr = NULL;
13391         int rc;
13392
13393         dev_addr = demod->my_i2c_dev_addr;
13394
13395         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_TOP_COMM_EXEC__A, AUD_TOP_COMM_EXEC_ACTIVE, 0);
13396         if (rc != 0) {
13397                 pr_err("error %d\n", rc);
13398                 goto rw_error;
13399         }
13400         /* setup TR interface: R/W mode, fifosize=8 */
13401         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_TOP_TR_MDE__A, 8, 0);
13402         if (rc != 0) {
13403                 pr_err("error %d\n", rc);
13404                 goto rw_error;
13405         }
13406         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_ACTIVE, 0);
13407         if (rc != 0) {
13408                 pr_err("error %d\n", rc);
13409                 goto rw_error;
13410         }
13411
13412         if (set_standard) {
13413                 rc = aud_ctrl_set_standard(demod, &aud_standard);
13414                 if (rc != 0) {
13415                         pr_err("error %d\n", rc);
13416                         goto rw_error;
13417                 }
13418         }
13419
13420         return 0;
13421 rw_error:
13422         return -EIO;
13423 }
13424
13425 /*============================================================================*/
13426
13427 /**
13428 * \brief Power up AUD.
13429 * \param demod instance of demodulator
13430 * \return int.
13431 *
13432 */
13433 static int power_down_aud(struct drx_demod_instance *demod)
13434 {
13435         struct i2c_device_addr *dev_addr = NULL;
13436         struct drxj_data *ext_attr = NULL;
13437         int rc;
13438
13439         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13440         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13441
13442         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
13443         if (rc != 0) {
13444                 pr_err("error %d\n", rc);
13445                 goto rw_error;
13446         }
13447
13448         ext_attr->aud_data.audio_is_active = false;
13449
13450         return 0;
13451 rw_error:
13452         return -EIO;
13453 }
13454
13455 /*============================================================================*/
13456 /**
13457 * \brief Get Modus data from audio RAM
13458 * \param demod instance of demodulator
13459 * \param pointer to modus
13460 * \return int.
13461 *
13462 */
13463 static int aud_get_modus(struct drx_demod_instance *demod, u16 *modus)
13464 {
13465         struct i2c_device_addr *dev_addr = NULL;
13466         struct drxj_data *ext_attr = NULL;
13467         int rc;
13468
13469         u16 r_modus = 0;
13470         u16 r_modus_hi = 0;
13471         u16 r_modus_lo = 0;
13472
13473         if (modus == NULL)
13474                 return -EINVAL;
13475
13476         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13477         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13478
13479         /* power up */
13480         if (ext_attr->aud_data.audio_is_active == false) {
13481                 rc = power_up_aud(demod, true);
13482                 if (rc != 0) {
13483                         pr_err("error %d\n", rc);
13484                         goto rw_error;
13485                 }
13486                 ext_attr->aud_data.audio_is_active = true;
13487         }
13488
13489         /* Modus register is combined in to RAM location */
13490         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_MODUS_HI__A, &r_modus_hi, 0);
13491         if (rc != 0) {
13492                 pr_err("error %d\n", rc);
13493                 goto rw_error;
13494         }
13495         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_MODUS_LO__A, &r_modus_lo, 0);
13496         if (rc != 0) {
13497                 pr_err("error %d\n", rc);
13498                 goto rw_error;
13499         }
13500
13501         r_modus = ((r_modus_hi << 12) & AUD_DEM_RAM_MODUS_HI__M)
13502             | (((r_modus_lo & AUD_DEM_RAM_MODUS_LO__M)));
13503
13504         *modus = r_modus;
13505
13506         return 0;
13507 rw_error:
13508         return -EIO;
13509
13510 }
13511
13512 /*============================================================================*/
13513 /**
13514 * \brief Get audio RDS dat
13515 * \param demod instance of demodulator
13516 * \param pointer to struct drx_cfg_aud_rds * \return int.
13517 *
13518 */
13519 static int
13520 aud_ctrl_get_cfg_rds(struct drx_demod_instance *demod, struct drx_cfg_aud_rds *status)
13521 {
13522         struct i2c_device_addr *addr = NULL;
13523         struct drxj_data *ext_attr = NULL;
13524         int rc;
13525
13526         u16 r_rds_array_cnt_init = 0;
13527         u16 r_rds_array_cnt_check = 0;
13528         u16 r_rds_data = 0;
13529         u16 rds_data_cnt = 0;
13530
13531         addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13532         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13533
13534         if (status == NULL)
13535                 return -EINVAL;
13536
13537         /* power up */
13538         if (ext_attr->aud_data.audio_is_active == false) {
13539                 rc = power_up_aud(demod, true);
13540                 if (rc != 0) {
13541                         pr_err("error %d\n", rc);
13542                         goto rw_error;
13543                 }
13544                 ext_attr->aud_data.audio_is_active = true;
13545         }
13546
13547         status->valid = false;
13548
13549         rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_init, 0);
13550         if (rc != 0) {
13551                 pr_err("error %d\n", rc);
13552                 goto rw_error;
13553         }
13554
13555         if (r_rds_array_cnt_init ==
13556             AUD_DEM_RD_RDS_ARRAY_CNT_RDS_ARRAY_CT_RDS_DATA_NOT_VALID) {
13557                 /* invalid data */
13558                 return 0;
13559         }
13560
13561         if (ext_attr->aud_data.rds_data_counter == r_rds_array_cnt_init) {
13562                 /* no new data */
13563                 return 0;
13564         }
13565
13566         /* RDS is detected, as long as FM radio is selected assume
13567            RDS will be available                                    */
13568         ext_attr->aud_data.rds_data_present = true;
13569
13570         /* new data */
13571         /* read the data */
13572         for (rds_data_cnt = 0; rds_data_cnt < AUD_RDS_ARRAY_SIZE; rds_data_cnt++) {
13573                 rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_DATA__A, &r_rds_data, 0);
13574                 if (rc != 0) {
13575                         pr_err("error %d\n", rc);
13576                         goto rw_error;
13577                 }
13578                 status->data[rds_data_cnt] = r_rds_data;
13579         }
13580
13581         rc = DRXJ_DAP.read_reg16func(addr, AUD_DEM_RD_RDS_ARRAY_CNT__A, &r_rds_array_cnt_check, 0);
13582         if (rc != 0) {
13583                 pr_err("error %d\n", rc);
13584                 goto rw_error;
13585         }
13586
13587         if (r_rds_array_cnt_check == r_rds_array_cnt_init) {
13588                 status->valid = true;
13589                 ext_attr->aud_data.rds_data_counter = r_rds_array_cnt_check;
13590         }
13591
13592         return 0;
13593 rw_error:
13594         return -EIO;
13595 }
13596
13597 /*============================================================================*/
13598 /**
13599 * \brief Get the current audio carrier detection status
13600 * \param demod instance of demodulator
13601 * \param pointer to aud_ctrl_get_status
13602 * \return int.
13603 *
13604 */
13605 static int
13606 aud_ctrl_get_carrier_detect_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13607 {
13608         struct drxj_data *ext_attr = NULL;
13609         struct i2c_device_addr *dev_addr = NULL;
13610         int rc;
13611         u16 r_data = 0;
13612
13613         if (status == NULL)
13614                 return -EINVAL;
13615
13616         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13617         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13618
13619         /* power up */
13620         if (ext_attr->aud_data.audio_is_active == false) {
13621                 rc = power_up_aud(demod, true);
13622                 if (rc != 0) {
13623                         pr_err("error %d\n", rc);
13624                         goto rw_error;
13625                 }
13626                 ext_attr->aud_data.audio_is_active = true;
13627         }
13628
13629         /* initialize the variables */
13630         status->carrier_a = false;
13631         status->carrier_b = false;
13632         status->nicam_status = DRX_AUD_NICAM_NOT_DETECTED;
13633         status->sap = false;
13634         status->stereo = false;
13635
13636         /* read stereo sound mode indication */
13637         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RD_STATUS__A, &r_data, 0);
13638         if (rc != 0) {
13639                 pr_err("error %d\n", rc);
13640                 goto rw_error;
13641         }
13642
13643         /* carrier a detected */
13644         if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_A__M) == AUD_DEM_RD_STATUS_STAT_CARR_A_DETECTED)
13645                 status->carrier_a = true;
13646
13647         /* carrier b detected */
13648         if ((r_data & AUD_DEM_RD_STATUS_STAT_CARR_B__M) == AUD_DEM_RD_STATUS_STAT_CARR_B_DETECTED)
13649                 status->carrier_b = true;
13650         /* nicam detected */
13651         if ((r_data & AUD_DEM_RD_STATUS_STAT_NICAM__M) ==
13652             AUD_DEM_RD_STATUS_STAT_NICAM_NICAM_DETECTED) {
13653                 if ((r_data & AUD_DEM_RD_STATUS_BAD_NICAM__M) == AUD_DEM_RD_STATUS_BAD_NICAM_OK)
13654                         status->nicam_status = DRX_AUD_NICAM_DETECTED;
13655                 else
13656                         status->nicam_status = DRX_AUD_NICAM_BAD;
13657         }
13658
13659         /* audio mode bilingual or SAP detected */
13660         if ((r_data & AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP__M) == AUD_DEM_RD_STATUS_STAT_BIL_OR_SAP_SAP)
13661                 status->sap = true;
13662
13663         /* stereo detected */
13664         if ((r_data & AUD_DEM_RD_STATUS_STAT_STEREO__M) == AUD_DEM_RD_STATUS_STAT_STEREO_STEREO)
13665                 status->stereo = true;
13666
13667         return 0;
13668 rw_error:
13669         return -EIO;
13670 }
13671
13672 /*============================================================================*/
13673 /**
13674 * \brief Get the current audio status parameters
13675 * \param demod instance of demodulator
13676 * \param pointer to aud_ctrl_get_status
13677 * \return int.
13678 *
13679 */
13680 static int
13681 aud_ctrl_get_status(struct drx_demod_instance *demod, struct drx_aud_status *status)
13682 {
13683         struct drxj_data *ext_attr = NULL;
13684         struct i2c_device_addr *dev_addr = NULL;
13685         struct drx_cfg_aud_rds rds = { false, {0} };
13686         int rc;
13687         u16 r_data = 0;
13688
13689         if (status == NULL)
13690                 return -EINVAL;
13691
13692         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13693         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13694
13695         /* carrier detection */
13696         rc = aud_ctrl_get_carrier_detect_status(demod, status);
13697         if (rc != 0) {
13698                 pr_err("error %d\n", rc);
13699                 goto rw_error;
13700         }
13701
13702         /* rds data */
13703         status->rds = false;
13704         rc = aud_ctrl_get_cfg_rds(demod, &rds);
13705         if (rc != 0) {
13706                 pr_err("error %d\n", rc);
13707                 goto rw_error;
13708         }
13709         status->rds = ext_attr->aud_data.rds_data_present;
13710
13711         /* fm_ident */
13712         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_IDENT_VALUE__A, &r_data, 0);
13713         if (rc != 0) {
13714                 pr_err("error %d\n", rc);
13715                 goto rw_error;
13716         }
13717         r_data >>= AUD_DSP_RD_FM_IDENT_VALUE_FM_IDENT__B;
13718         status->fm_ident = (s8) r_data;
13719
13720         return 0;
13721 rw_error:
13722         return -EIO;
13723 }
13724
13725 /*============================================================================*/
13726 /**
13727 * \brief Get the current volume settings
13728 * \param demod instance of demodulator
13729 * \param pointer to struct drx_cfg_aud_volume * \return int.
13730 *
13731 */
13732 static int
13733 aud_ctrl_get_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13734 {
13735         struct i2c_device_addr *dev_addr = NULL;
13736         struct drxj_data *ext_attr = NULL;
13737         int rc;
13738
13739         u16 r_volume = 0;
13740         u16 r_avc = 0;
13741         u16 r_strength_left = 0;
13742         u16 r_strength_right = 0;
13743
13744         if (volume == NULL)
13745                 return -EINVAL;
13746
13747         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13748         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13749
13750         /* power up */
13751         if (ext_attr->aud_data.audio_is_active == false) {
13752                 rc = power_up_aud(demod, true);
13753                 if (rc != 0) {
13754                         pr_err("error %d\n", rc);
13755                         goto rw_error;
13756                 }
13757                 ext_attr->aud_data.audio_is_active = true;
13758         }
13759
13760         /* volume */
13761         volume->mute = ext_attr->aud_data.volume.mute;
13762         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, &r_volume, 0);
13763         if (rc != 0) {
13764                 pr_err("error %d\n", rc);
13765                 goto rw_error;
13766         }
13767         if (r_volume == 0) {
13768                 volume->mute = true;
13769                 volume->volume = ext_attr->aud_data.volume.volume;
13770         } else {
13771                 volume->mute = false;
13772                 volume->volume = ((r_volume & AUD_DSP_WR_VOLUME_VOL_MAIN__M) >>
13773                                   AUD_DSP_WR_VOLUME_VOL_MAIN__B) -
13774                     AUD_VOLUME_ZERO_DB;
13775                 if (volume->volume < AUD_VOLUME_DB_MIN)
13776                         volume->volume = AUD_VOLUME_DB_MIN;
13777                 if (volume->volume > AUD_VOLUME_DB_MAX)
13778                         volume->volume = AUD_VOLUME_DB_MAX;
13779         }
13780
13781         /* automatic volume control */
13782         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AVC__A, &r_avc, 0);
13783         if (rc != 0) {
13784                 pr_err("error %d\n", rc);
13785                 goto rw_error;
13786         }
13787
13788         if ((r_avc & AUD_DSP_WR_AVC_AVC_ON__M) == AUD_DSP_WR_AVC_AVC_ON_OFF) {
13789                 volume->avc_mode = DRX_AUD_AVC_OFF;
13790         } else {
13791                 switch (r_avc & AUD_DSP_WR_AVC_AVC_DECAY__M) {
13792                 case AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC:
13793                         volume->avc_mode = DRX_AUD_AVC_DECAYTIME_20MS;
13794                         break;
13795                 case AUD_DSP_WR_AVC_AVC_DECAY_8_SEC:
13796                         volume->avc_mode = DRX_AUD_AVC_DECAYTIME_8S;
13797                         break;
13798                 case AUD_DSP_WR_AVC_AVC_DECAY_4_SEC:
13799                         volume->avc_mode = DRX_AUD_AVC_DECAYTIME_4S;
13800                         break;
13801                 case AUD_DSP_WR_AVC_AVC_DECAY_2_SEC:
13802                         volume->avc_mode = DRX_AUD_AVC_DECAYTIME_2S;
13803                         break;
13804                 default:
13805                         return -EIO;
13806                         break;
13807                 }
13808         }
13809
13810         /* max attenuation */
13811         switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_ATT__M) {
13812         case AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB:
13813                 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_12DB;
13814                 break;
13815         case AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB:
13816                 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_18DB;
13817                 break;
13818         case AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB:
13819                 volume->avc_max_atten = DRX_AUD_AVC_MAX_ATTEN_24DB;
13820                 break;
13821         default:
13822                 return -EIO;
13823                 break;
13824         }
13825
13826         /* max gain */
13827         switch (r_avc & AUD_DSP_WR_AVC_AVC_MAX_GAIN__M) {
13828         case AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB:
13829                 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_0DB;
13830                 break;
13831         case AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB:
13832                 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_6DB;
13833                 break;
13834         case AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB:
13835                 volume->avc_max_gain = DRX_AUD_AVC_MAX_GAIN_12DB;
13836                 break;
13837         default:
13838                 return -EIO;
13839                 break;
13840         }
13841
13842         /* reference level */
13843         volume->avc_ref_level = (u16) ((r_avc & AUD_DSP_WR_AVC_AVC_REF_LEV__M) >>
13844                                        AUD_DSP_WR_AVC_AVC_REF_LEV__B);
13845
13846         /* read qpeak registers and calculate strength of left and right carrier */
13847         /* quasi peaks formula: QP(dB) = 20 * log( AUD_DSP_RD_QPEAKx / Q(0dB) */
13848         /* Q(0dB) represents QP value of 0dB (hex value 0x4000) */
13849         /* left carrier */
13850
13851         /* QP vaues */
13852         /* left carrier */
13853         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_QPEAK_L__A, &r_strength_left, 0);
13854         if (rc != 0) {
13855                 pr_err("error %d\n", rc);
13856                 goto rw_error;
13857         }
13858         volume->strength_left = (((s16) log1_times100(r_strength_left)) -
13859                                 AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
13860
13861         /* right carrier */
13862         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_QPEAK_R__A, &r_strength_right, 0);
13863         if (rc != 0) {
13864                 pr_err("error %d\n", rc);
13865                 goto rw_error;
13866         }
13867         volume->strength_right = (((s16) log1_times100(r_strength_right)) -
13868                                  AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100) / 5;
13869
13870         return 0;
13871 rw_error:
13872         return -EIO;
13873 }
13874
13875 /*============================================================================*/
13876 /**
13877 * \brief Set the current volume settings
13878 * \param demod instance of demodulator
13879 * \param pointer to struct drx_cfg_aud_volume * \return int.
13880 *
13881 */
13882 static int
13883 aud_ctrl_set_cfg_volume(struct drx_demod_instance *demod, struct drx_cfg_aud_volume *volume)
13884 {
13885         struct i2c_device_addr *dev_addr = NULL;
13886         struct drxj_data *ext_attr = NULL;
13887         int rc;
13888
13889         u16 w_volume = 0;
13890         u16 w_avc = 0;
13891
13892         if (volume == NULL)
13893                 return -EINVAL;
13894
13895         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
13896         ext_attr = (struct drxj_data *) demod->my_ext_attr;
13897
13898         /* power up */
13899         if (ext_attr->aud_data.audio_is_active == false) {
13900                 rc = power_up_aud(demod, true);
13901                 if (rc != 0) {
13902                         pr_err("error %d\n", rc);
13903                         goto rw_error;
13904                 }
13905                 ext_attr->aud_data.audio_is_active = true;
13906         }
13907
13908         /* volume */
13909         /* volume range from -60 to 12 (expressed in dB) */
13910         if ((volume->volume < AUD_VOLUME_DB_MIN) ||
13911             (volume->volume > AUD_VOLUME_DB_MAX))
13912                 return -EINVAL;
13913
13914         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, &w_volume, 0);
13915         if (rc != 0) {
13916                 pr_err("error %d\n", rc);
13917                 goto rw_error;
13918         }
13919
13920         /* clear the volume mask */
13921         w_volume &= (u16) ~AUD_DSP_WR_VOLUME_VOL_MAIN__M;
13922         if (volume->mute == true)
13923                 w_volume |= (u16)(0);
13924         else
13925                 w_volume |= (u16)((volume->volume + AUD_VOLUME_ZERO_DB) << AUD_DSP_WR_VOLUME_VOL_MAIN__B);
13926
13927         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
13928         if (rc != 0) {
13929                 pr_err("error %d\n", rc);
13930                 goto rw_error;
13931         }
13932
13933         /* automatic volume control */
13934         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AVC__A, &w_avc, 0);
13935         if (rc != 0) {
13936                 pr_err("error %d\n", rc);
13937                 goto rw_error;
13938         }
13939
13940         /* clear masks that require writing */
13941         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_ON__M;
13942         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_DECAY__M;
13943
13944         if (volume->avc_mode == DRX_AUD_AVC_OFF) {
13945                 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_OFF);
13946         } else {
13947
13948                 w_avc |= (AUD_DSP_WR_AVC_AVC_ON_ON);
13949
13950                 /* avc decay */
13951                 switch (volume->avc_mode) {
13952                 case DRX_AUD_AVC_DECAYTIME_20MS:
13953                         w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_20_MSEC;
13954                         break;
13955                 case DRX_AUD_AVC_DECAYTIME_8S:
13956                         w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_8_SEC;
13957                         break;
13958                 case DRX_AUD_AVC_DECAYTIME_4S:
13959                         w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_4_SEC;
13960                         break;
13961                 case DRX_AUD_AVC_DECAYTIME_2S:
13962                         w_avc |= AUD_DSP_WR_AVC_AVC_DECAY_2_SEC;
13963                         break;
13964                 default:
13965                         return -EINVAL;
13966                 }
13967         }
13968
13969         /* max attenuation */
13970         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_ATT__M;
13971         switch (volume->avc_max_atten) {
13972         case DRX_AUD_AVC_MAX_ATTEN_12DB:
13973                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_12DB;
13974                 break;
13975         case DRX_AUD_AVC_MAX_ATTEN_18DB:
13976                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_18DB;
13977                 break;
13978         case DRX_AUD_AVC_MAX_ATTEN_24DB:
13979                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_ATT_24DB;
13980                 break;
13981         default:
13982                 return -EINVAL;
13983         }
13984
13985         /* max gain */
13986         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_MAX_GAIN__M;
13987         switch (volume->avc_max_gain) {
13988         case DRX_AUD_AVC_MAX_GAIN_0DB:
13989                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_0DB;
13990                 break;
13991         case DRX_AUD_AVC_MAX_GAIN_6DB:
13992                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_6DB;
13993                 break;
13994         case DRX_AUD_AVC_MAX_GAIN_12DB:
13995                 w_avc |= AUD_DSP_WR_AVC_AVC_MAX_GAIN_12DB;
13996                 break;
13997         default:
13998                 return -EINVAL;
13999         }
14000
14001         /* avc reference level */
14002         if (volume->avc_ref_level > AUD_MAX_AVC_REF_LEVEL)
14003                 return -EINVAL;
14004
14005         w_avc &= (u16) ~AUD_DSP_WR_AVC_AVC_REF_LEV__M;
14006         w_avc |= (u16) (volume->avc_ref_level << AUD_DSP_WR_AVC_AVC_REF_LEV__B);
14007
14008         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_AVC__A, w_avc, 0);
14009         if (rc != 0) {
14010                 pr_err("error %d\n", rc);
14011                 goto rw_error;
14012         }
14013
14014         /* all done, store config in data structure */
14015         ext_attr->aud_data.volume = *volume;
14016
14017         return 0;
14018 rw_error:
14019         return -EIO;
14020 }
14021
14022 /*============================================================================*/
14023 /**
14024 * \brief Get the I2S settings
14025 * \param demod instance of demodulator
14026 * \param pointer to struct drx_cfg_i2s_output * \return int.
14027 *
14028 */
14029 static int
14030 aud_ctrl_get_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
14031 {
14032         struct i2c_device_addr *dev_addr = NULL;
14033         struct drxj_data *ext_attr = NULL;
14034         int rc;
14035         u16 w_i2s_config = 0;
14036         u16 r_i2s_freq = 0;
14037
14038         if (output == NULL)
14039                 return -EINVAL;
14040
14041         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14042         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14043
14044         /* power up */
14045         if (ext_attr->aud_data.audio_is_active == false) {
14046                 rc = power_up_aud(demod, true);
14047                 if (rc != 0) {
14048                         pr_err("error %d\n", rc);
14049                         goto rw_error;
14050                 }
14051                 ext_attr->aud_data.audio_is_active = true;
14052         }
14053
14054         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14055         if (rc != 0) {
14056                 pr_err("error %d\n", rc);
14057                 goto rw_error;
14058         }
14059         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, &r_i2s_freq, 0);
14060         if (rc != 0) {
14061                 pr_err("error %d\n", rc);
14062                 goto rw_error;
14063         }
14064
14065         /* I2S mode */
14066         switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M) {
14067         case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER:
14068                 output->mode = DRX_I2S_MODE_MASTER;
14069                 break;
14070         case AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE:
14071                 output->mode = DRX_I2S_MODE_SLAVE;
14072                 break;
14073         default:
14074                 return -EIO;
14075         }
14076
14077         /* I2S format */
14078         switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M) {
14079         case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY:
14080                 output->format = DRX_I2S_FORMAT_WS_ADVANCED;
14081                 break;
14082         case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY:
14083                 output->format = DRX_I2S_FORMAT_WS_WITH_DATA;
14084                 break;
14085         default:
14086                 return -EIO;
14087         }
14088
14089         /* I2S word length */
14090         switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M) {
14091         case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16:
14092                 output->word_length = DRX_I2S_WORDLENGTH_16;
14093                 break;
14094         case AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32:
14095                 output->word_length = DRX_I2S_WORDLENGTH_32;
14096                 break;
14097         default:
14098                 return -EIO;
14099         }
14100
14101         /* I2S polarity */
14102         switch (w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M) {
14103         case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH:
14104                 output->polarity = DRX_I2S_POLARITY_LEFT;
14105                 break;
14106         case AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW:
14107                 output->polarity = DRX_I2S_POLARITY_RIGHT;
14108                 break;
14109         default:
14110                 return -EIO;
14111         }
14112
14113         /* I2S output enabled */
14114         if ((w_i2s_config & AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M) == AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE)
14115                 output->output_enable = true;
14116         else
14117                 output->output_enable = false;
14118
14119         if (r_i2s_freq > 0) {
14120                 output->frequency = 6144UL * 48000 / r_i2s_freq;
14121                 if (output->word_length == DRX_I2S_WORDLENGTH_16)
14122                         output->frequency *= 2;
14123         } else {
14124                 output->frequency = AUD_I2S_FREQUENCY_MAX;
14125         }
14126
14127         return 0;
14128 rw_error:
14129         return -EIO;
14130 }
14131
14132 /*============================================================================*/
14133 /**
14134 * \brief Set the I2S settings
14135 * \param demod instance of demodulator
14136 * \param pointer to struct drx_cfg_i2s_output * \return int.
14137 *
14138 */
14139 static int
14140 aud_ctrl_set_cfg_output_i2s(struct drx_demod_instance *demod, struct drx_cfg_i2s_output *output)
14141 {
14142         struct i2c_device_addr *dev_addr = NULL;
14143         struct drxj_data *ext_attr = NULL;
14144         int rc;
14145         u16 w_i2s_config = 0;
14146         u16 w_i2s_pads_data_da = 0;
14147         u16 w_i2s_pads_data_cl = 0;
14148         u16 w_i2s_pads_data_ws = 0;
14149         u32 w_i2s_freq = 0;
14150
14151         if (output == NULL)
14152                 return -EINVAL;
14153
14154         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
14155         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14156
14157         /* power up */
14158         if (ext_attr->aud_data.audio_is_active == false) {
14159                 rc = power_up_aud(demod, true);
14160                 if (rc != 0) {
14161                         pr_err("error %d\n", rc);
14162                         goto rw_error;
14163                 }
14164                 ext_attr->aud_data.audio_is_active = true;
14165         }
14166
14167         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_I2S_CONFIG2__A, &w_i2s_config, 0);
14168         if (rc != 0) {
14169                 pr_err("error %d\n", rc);
14170                 goto rw_error;
14171         }
14172
14173         /* I2S mode */
14174         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST__M;
14175
14176         switch (output->mode) {
14177         case DRX_I2S_MODE_MASTER:
14178                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_MASTER;
14179                 break;
14180         case DRX_I2S_MODE_SLAVE:
14181                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_SLV_MST_SLAVE;
14182                 break;
14183         default:
14184                 return -EINVAL;
14185         }
14186
14187         /* I2S format */
14188         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE__M;
14189
14190         switch (output->format) {
14191         case DRX_I2S_FORMAT_WS_ADVANCED:
14192                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_DELAY;
14193                 break;
14194         case DRX_I2S_FORMAT_WS_WITH_DATA:
14195                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_MODE_NO_DELAY;
14196                 break;
14197         default:
14198                 return -EINVAL;
14199         }
14200
14201         /* I2S word length */
14202         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN__M;
14203
14204         switch (output->word_length) {
14205         case DRX_I2S_WORDLENGTH_16:
14206                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_16;
14207                 break;
14208         case DRX_I2S_WORDLENGTH_32:
14209                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WORD_LEN_BIT_32;
14210                 break;
14211         default:
14212                 return -EINVAL;
14213         }
14214
14215         /* I2S polarity */
14216         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL__M;
14217         switch (output->polarity) {
14218         case DRX_I2S_POLARITY_LEFT:
14219                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_HIGH;
14220                 break;
14221         case DRX_I2S_POLARITY_RIGHT:
14222                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_WS_POL_LEFT_LOW;
14223                 break;
14224         default:
14225                 return -EINVAL;
14226         }
14227
14228         /* I2S output enabled */
14229         w_i2s_config &= (u16) ~AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE__M;
14230         if (output->output_enable == true)
14231                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_ENABLE;
14232         else
14233                 w_i2s_config |= AUD_DEM_WR_I2S_CONFIG2_I2S_ENABLE_DISABLE;
14234
14235         /*
14236            I2S frequency
14237
14238            w_i2s_freq = 6144 * 48000 * nrbits / ( 32 * frequency )
14239
14240            16bit: 6144 * 48000 / ( 2 * freq ) = ( 6144 * 48000 / freq ) / 2
14241            32bit: 6144 * 48000 / freq         = ( 6144 * 48000 / freq )
14242          */
14243         if ((output->frequency > AUD_I2S_FREQUENCY_MAX) ||
14244             output->frequency < AUD_I2S_FREQUENCY_MIN) {
14245                 return -EINVAL;
14246         }
14247
14248         w_i2s_freq = (6144UL * 48000UL) + (output->frequency >> 1);
14249         w_i2s_freq /= output->frequency;
14250
14251         if (output->word_length == DRX_I2S_WORDLENGTH_16)
14252                 w_i2s_freq *= 2;
14253
14254         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_I2S_CONFIG2__A, w_i2s_config, 0);
14255         if (rc != 0) {
14256                 pr_err("error %d\n", rc);
14257                 goto rw_error;
14258         }
14259         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_I2S_OUT_FS__A, (u16)w_i2s_freq, 0);
14260         if (rc != 0) {
14261                 pr_err("error %d\n", rc);
14262                 goto rw_error;
14263         }
14264
14265         /* configure I2S output pads for master or slave mode */
14266         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
14267         if (rc != 0) {
14268                 pr_err("error %d\n", rc);
14269                 goto rw_error;
14270         }
14271
14272         if (output->mode == DRX_I2S_MODE_MASTER) {
14273                 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__MASTER |
14274                     SIO_PDR_I2S_DA_CFG_DRIVE__MASTER;
14275                 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__MASTER |
14276                     SIO_PDR_I2S_CL_CFG_DRIVE__MASTER;
14277                 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__MASTER |
14278                     SIO_PDR_I2S_WS_CFG_DRIVE__MASTER;
14279         } else {
14280                 w_i2s_pads_data_da = SIO_PDR_I2S_DA_CFG_MODE__SLAVE |
14281                     SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE;
14282                 w_i2s_pads_data_cl = SIO_PDR_I2S_CL_CFG_MODE__SLAVE |
14283                     SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE;
14284                 w_i2s_pads_data_ws = SIO_PDR_I2S_WS_CFG_MODE__SLAVE |
14285                     SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE;
14286         }
14287
14288         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_DA_CFG__A, w_i2s_pads_data_da, 0);
14289         if (rc != 0) {
14290                 pr_err("error %d\n", rc);
14291                 goto rw_error;
14292         }
14293         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_CL_CFG__A, w_i2s_pads_data_cl, 0);
14294         if (rc != 0) {
14295                 pr_err("error %d\n", rc);
14296                 goto rw_error;
14297         }
14298         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_PDR_I2S_WS_CFG__A, w_i2s_pads_data_ws, 0);
14299         if (rc != 0) {
14300                 pr_err("error %d\n", rc);
14301                 goto rw_error;
14302         }
14303
14304         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
14305         if (rc != 0) {
14306                 pr_err("error %d\n", rc);
14307                 goto rw_error;
14308         }
14309
14310         /* all done, store config in data structure */
14311         ext_attr->aud_data.i2sdata = *output;
14312
14313         return 0;
14314 rw_error:
14315         return -EIO;
14316 }
14317
14318 /*============================================================================*/
14319 /**
14320 * \brief Get the Automatic Standard Select (ASS)
14321 *        and Automatic Sound Change (ASC)
14322 * \param demod instance of demodulator
14323 * \param pointer to pDRXAudAutoSound_t
14324 * \return int.
14325 *
14326 */
14327 static int
14328 aud_ctrl_get_cfg_auto_sound(struct drx_demod_instance *demod,
14329                             enum drx_cfg_aud_auto_sound *auto_sound)
14330 {
14331         struct drxj_data *ext_attr = NULL;
14332         int rc;
14333         u16 r_modus = 0;
14334
14335         if (auto_sound == NULL)
14336                 return -EINVAL;
14337
14338         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14339
14340         /* power up */
14341         if (ext_attr->aud_data.audio_is_active == false) {
14342                 rc = power_up_aud(demod, true);
14343                 if (rc != 0) {
14344                         pr_err("error %d\n", rc);
14345                         goto rw_error;
14346                 }
14347                 ext_attr->aud_data.audio_is_active = true;
14348         }
14349
14350         rc = aud_get_modus(demod, &r_modus);
14351         if (rc != 0) {
14352                 pr_err("error %d\n", rc);
14353                 goto rw_error;
14354         }
14355
14356         switch (r_modus & (AUD_DEM_WR_MODUS_MOD_ASS__M |
14357                           AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M)) {
14358         case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14359         case AUD_DEM_WR_MODUS_MOD_ASS_OFF | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14360                 *auto_sound =
14361                     DRX_AUD_AUTO_SOUND_OFF;
14362                 break;
14363         case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED:
14364                 *auto_sound =
14365                     DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON;
14366                 break;
14367         case AUD_DEM_WR_MODUS_MOD_ASS_ON | AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED:
14368                 *auto_sound =
14369                     DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF;
14370                 break;
14371         default:
14372                 return -EIO;
14373         }
14374
14375         return 0;
14376 rw_error:
14377         return -EIO;
14378 }
14379
14380 /*============================================================================*/
14381 /**
14382 * \brief Set the Automatic Standard Select (ASS)
14383 *        and Automatic Sound Change (ASC)
14384 * \param demod instance of demodulator
14385 * \param pointer to pDRXAudAutoSound_t
14386 * \return int.
14387 *
14388 */
14389 static int
14390 aud_ctr_setl_cfg_auto_sound(struct drx_demod_instance *demod,
14391                             enum drx_cfg_aud_auto_sound *auto_sound)
14392 {
14393         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14394         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14395         int rc;
14396         u16 r_modus = 0;
14397         u16 w_modus = 0;
14398
14399         if (auto_sound == NULL)
14400                 return -EINVAL;
14401
14402         dev_addr = demod->my_i2c_dev_addr;
14403         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14404
14405         /* power up */
14406         if (ext_attr->aud_data.audio_is_active == false) {
14407                 rc = power_up_aud(demod, true);
14408                 if (rc != 0) {
14409                         pr_err("error %d\n", rc);
14410                         goto rw_error;
14411                 }
14412                 ext_attr->aud_data.audio_is_active = true;
14413         }
14414
14415         rc = aud_get_modus(demod, &r_modus);
14416         if (rc != 0) {
14417                 pr_err("error %d\n", rc);
14418                 goto rw_error;
14419         }
14420
14421         w_modus = r_modus;
14422         /* clear ASS & ASC bits */
14423         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_ASS__M;
14424         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG__M;
14425
14426         switch (*auto_sound) {
14427         case DRX_AUD_AUTO_SOUND_OFF:
14428                 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_OFF;
14429                 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14430                 break;
14431         case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON:
14432                 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14433                 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_ENABLED;
14434                 break;
14435         case DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_OFF:
14436                 w_modus |= AUD_DEM_WR_MODUS_MOD_ASS_ON;
14437                 w_modus |= AUD_DEM_WR_MODUS_MOD_DIS_STD_CHG_DISABLED;
14438                 break;
14439         default:
14440                 return -EINVAL;
14441         }
14442
14443         if (w_modus != r_modus) {
14444                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14445                 if (rc != 0) {
14446                         pr_err("error %d\n", rc);
14447                         goto rw_error;
14448                 }
14449         }
14450         /* copy to data structure */
14451         ext_attr->aud_data.auto_sound = *auto_sound;
14452
14453         return 0;
14454 rw_error:
14455         return -EIO;
14456 }
14457
14458 /*============================================================================*/
14459 /**
14460 * \brief Get the Automatic Standard Select thresholds
14461 * \param demod instance of demodulator
14462 * \param pointer to pDRXAudASSThres_t
14463 * \return int.
14464 *
14465 */
14466 static int
14467 aud_ctrl_get_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14468 {
14469         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14470         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14471         int rc;
14472         u16 thres_a2 = 0;
14473         u16 thres_btsc = 0;
14474         u16 thres_nicam = 0;
14475
14476         if (thres == NULL)
14477                 return -EINVAL;
14478
14479         dev_addr = demod->my_i2c_dev_addr;
14480         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14481
14482         /* power up */
14483         if (ext_attr->aud_data.audio_is_active == false) {
14484                 rc = power_up_aud(demod, true);
14485                 if (rc != 0) {
14486                         pr_err("error %d\n", rc);
14487                         goto rw_error;
14488                 }
14489                 ext_attr->aud_data.audio_is_active = true;
14490         }
14491
14492         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_A2_THRSHLD__A, &thres_a2, 0);
14493         if (rc != 0) {
14494                 pr_err("error %d\n", rc);
14495                 goto rw_error;
14496         }
14497         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_BTSC_THRSHLD__A, &thres_btsc, 0);
14498         if (rc != 0) {
14499                 pr_err("error %d\n", rc);
14500                 goto rw_error;
14501         }
14502         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_NICAM_THRSHLD__A, &thres_nicam, 0);
14503         if (rc != 0) {
14504                 pr_err("error %d\n", rc);
14505                 goto rw_error;
14506         }
14507
14508         thres->a2 = thres_a2;
14509         thres->btsc = thres_btsc;
14510         thres->nicam = thres_nicam;
14511
14512         return 0;
14513 rw_error:
14514         return -EIO;
14515 }
14516
14517 /*============================================================================*/
14518 /**
14519 * \brief Get the Automatic Standard Select thresholds
14520 * \param demod instance of demodulator
14521 * \param pointer to pDRXAudASSThres_t
14522 * \return int.
14523 *
14524 */
14525 static int
14526 aud_ctrl_set_cfg_ass_thres(struct drx_demod_instance *demod, struct drx_cfg_aud_ass_thres *thres)
14527 {
14528         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14529         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14530         int rc;
14531         if (thres == NULL)
14532                 return -EINVAL;
14533
14534         dev_addr = demod->my_i2c_dev_addr;
14535         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14536
14537         /* power up */
14538         if (ext_attr->aud_data.audio_is_active == false) {
14539                 rc = power_up_aud(demod, true);
14540                 if (rc != 0) {
14541                         pr_err("error %d\n", rc);
14542                         goto rw_error;
14543                 }
14544                 ext_attr->aud_data.audio_is_active = true;
14545         }
14546
14547         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_A2_THRSHLD__A, thres->a2, 0);
14548         if (rc != 0) {
14549                 pr_err("error %d\n", rc);
14550                 goto rw_error;
14551         }
14552         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_BTSC_THRSHLD__A, thres->btsc, 0);
14553         if (rc != 0) {
14554                 pr_err("error %d\n", rc);
14555                 goto rw_error;
14556         }
14557         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_NICAM_THRSHLD__A, thres->nicam, 0);
14558         if (rc != 0) {
14559                 pr_err("error %d\n", rc);
14560                 goto rw_error;
14561         }
14562
14563         /* update DRXK data structure with hardware values */
14564         ext_attr->aud_data.ass_thresholds = *thres;
14565
14566         return 0;
14567 rw_error:
14568         return -EIO;
14569 }
14570
14571 /*============================================================================*/
14572 /**
14573 * \brief Get Audio Carrier settings
14574 * \param demod instance of demodulator
14575 * \param pointer to struct drx_aud_carrier ** \return int.
14576 *
14577 */
14578 static int
14579 aud_ctrl_get_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14580 {
14581         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14582         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14583         int rc;
14584         u16 w_modus = 0;
14585
14586         u16 dco_a_hi = 0;
14587         u16 dco_a_lo = 0;
14588         u16 dco_b_hi = 0;
14589         u16 dco_b_lo = 0;
14590
14591         u32 valA = 0;
14592         u32 valB = 0;
14593
14594         u16 dc_lvl_a = 0;
14595         u16 dc_lvl_b = 0;
14596
14597         u16 cm_thes_a = 0;
14598         u16 cm_thes_b = 0;
14599
14600         if (carriers == NULL)
14601                 return -EINVAL;
14602
14603         dev_addr = demod->my_i2c_dev_addr;
14604         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14605
14606         /* power up */
14607         if (ext_attr->aud_data.audio_is_active == false) {
14608                 rc = power_up_aud(demod, true);
14609                 if (rc != 0) {
14610                         pr_err("error %d\n", rc);
14611                         goto rw_error;
14612                 }
14613                 ext_attr->aud_data.audio_is_active = true;
14614         }
14615
14616         rc = aud_get_modus(demod, &w_modus);
14617         if (rc != 0) {
14618                 pr_err("error %d\n", rc);
14619                 goto rw_error;
14620         }
14621
14622         /* Behaviour of primary audio channel */
14623         switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_A__M)) {
14624         case AUD_DEM_WR_MODUS_MOD_CM_A_MUTE:
14625                 carriers->a.opt = DRX_NO_CARRIER_MUTE;
14626                 break;
14627         case AUD_DEM_WR_MODUS_MOD_CM_A_NOISE:
14628                 carriers->a.opt = DRX_NO_CARRIER_NOISE;
14629                 break;
14630         default:
14631                 return -EIO;
14632                 break;
14633         }
14634
14635         /* Behaviour of secondary audio channel */
14636         switch (w_modus & (AUD_DEM_WR_MODUS_MOD_CM_B__M)) {
14637         case AUD_DEM_WR_MODUS_MOD_CM_B_MUTE:
14638                 carriers->b.opt = DRX_NO_CARRIER_MUTE;
14639                 break;
14640         case AUD_DEM_WR_MODUS_MOD_CM_B_NOISE:
14641                 carriers->b.opt = DRX_NO_CARRIER_NOISE;
14642                 break;
14643         default:
14644                 return -EIO;
14645                 break;
14646         }
14647
14648         /* frequency adjustment for primary & secondary audio channel */
14649         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_A_HI__A, &dco_a_hi, 0);
14650         if (rc != 0) {
14651                 pr_err("error %d\n", rc);
14652                 goto rw_error;
14653         }
14654         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_A_LO__A, &dco_a_lo, 0);
14655         if (rc != 0) {
14656                 pr_err("error %d\n", rc);
14657                 goto rw_error;
14658         }
14659         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_B_HI__A, &dco_b_hi, 0);
14660         if (rc != 0) {
14661                 pr_err("error %d\n", rc);
14662                 goto rw_error;
14663         }
14664         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_DCO_B_LO__A, &dco_b_lo, 0);
14665         if (rc != 0) {
14666                 pr_err("error %d\n", rc);
14667                 goto rw_error;
14668         }
14669
14670         valA = (((u32) dco_a_hi) << 12) | ((u32) dco_a_lo & 0xFFF);
14671         valB = (((u32) dco_b_hi) << 12) | ((u32) dco_b_lo & 0xFFF);
14672
14673         /* Multiply by 20250 * 1>>24  ~= 2 / 1657 */
14674         carriers->a.dco = DRX_S24TODRXFREQ(valA) * 2L / 1657L;
14675         carriers->b.dco = DRX_S24TODRXFREQ(valB) * 2L / 1657L;
14676
14677         /* DC level of the incoming FM signal on the primary
14678            & seconday sound channel */
14679         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_A__A, &dc_lvl_a, 0);
14680         if (rc != 0) {
14681                 pr_err("error %d\n", rc);
14682                 goto rw_error;
14683         }
14684         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_RD_FM_DC_LEVEL_B__A, &dc_lvl_b, 0);
14685         if (rc != 0) {
14686                 pr_err("error %d\n", rc);
14687                 goto rw_error;
14688         }
14689
14690         /* offset (kHz) = (dcLvl / 322) */
14691         carriers->a.shift = (DRX_U16TODRXFREQ(dc_lvl_a) / 322L);
14692         carriers->b.shift = (DRX_U16TODRXFREQ(dc_lvl_b) / 322L);
14693
14694         /* Carrier detetcion threshold for primary & secondary channel */
14695         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_CM_A_THRSHLD__A, &cm_thes_a, 0);
14696         if (rc != 0) {
14697                 pr_err("error %d\n", rc);
14698                 goto rw_error;
14699         }
14700         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RAM_CM_B_THRSHLD__A, &cm_thes_b, 0);
14701         if (rc != 0) {
14702                 pr_err("error %d\n", rc);
14703                 goto rw_error;
14704         }
14705
14706         carriers->a.thres = cm_thes_a;
14707         carriers->b.thres = cm_thes_b;
14708
14709         return 0;
14710 rw_error:
14711         return -EIO;
14712 }
14713
14714 /*============================================================================*/
14715 /**
14716 * \brief Set Audio Carrier settings
14717 * \param demod instance of demodulator
14718 * \param pointer to struct drx_aud_carrier ** \return int.
14719 *
14720 */
14721 static int
14722 aud_ctrl_set_cfg_carrier(struct drx_demod_instance *demod, struct drx_cfg_aud_carriers *carriers)
14723 {
14724         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14725         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14726         int rc;
14727         u16 w_modus = 0;
14728         u16 r_modus = 0;
14729         u16 dco_a_hi = 0;
14730         u16 dco_a_lo = 0;
14731         u16 dco_b_hi = 0;
14732         u16 dco_b_lo = 0;
14733         s32 valA = 0;
14734         s32 valB = 0;
14735
14736         if (carriers == NULL)
14737                 return -EINVAL;
14738
14739         dev_addr = demod->my_i2c_dev_addr;
14740         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14741
14742         /* power up */
14743         if (ext_attr->aud_data.audio_is_active == false) {
14744                 rc = power_up_aud(demod, true);
14745                 if (rc != 0) {
14746                         pr_err("error %d\n", rc);
14747                         goto rw_error;
14748                 }
14749                 ext_attr->aud_data.audio_is_active = true;
14750         }
14751
14752         rc = aud_get_modus(demod, &r_modus);
14753         if (rc != 0) {
14754                 pr_err("error %d\n", rc);
14755                 goto rw_error;
14756         }
14757
14758         w_modus = r_modus;
14759         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_A__M;
14760         /* Behaviour of primary audio channel */
14761         switch (carriers->a.opt) {
14762         case DRX_NO_CARRIER_MUTE:
14763                 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_MUTE;
14764                 break;
14765         case DRX_NO_CARRIER_NOISE:
14766                 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_A_NOISE;
14767                 break;
14768         default:
14769                 return -EINVAL;
14770                 break;
14771         }
14772
14773         /* Behaviour of secondary audio channel */
14774         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_CM_B__M;
14775         switch (carriers->b.opt) {
14776         case DRX_NO_CARRIER_MUTE:
14777                 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_MUTE;
14778                 break;
14779         case DRX_NO_CARRIER_NOISE:
14780                 w_modus |= AUD_DEM_WR_MODUS_MOD_CM_B_NOISE;
14781                 break;
14782         default:
14783                 return -EINVAL;
14784                 break;
14785         }
14786
14787         /* now update the modus register */
14788         if (w_modus != r_modus) {
14789                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
14790                 if (rc != 0) {
14791                         pr_err("error %d\n", rc);
14792                         goto rw_error;
14793                 }
14794         }
14795
14796         /* frequency adjustment for primary & secondary audio channel */
14797         valA = (s32) ((carriers->a.dco) * 1657L / 2);
14798         valB = (s32) ((carriers->b.dco) * 1657L / 2);
14799
14800         dco_a_hi = (u16) ((valA >> 12) & 0xFFF);
14801         dco_a_lo = (u16) (valA & 0xFFF);
14802         dco_b_hi = (u16) ((valB >> 12) & 0xFFF);
14803         dco_b_lo = (u16) (valB & 0xFFF);
14804
14805         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_A_HI__A, dco_a_hi, 0);
14806         if (rc != 0) {
14807                 pr_err("error %d\n", rc);
14808                 goto rw_error;
14809         }
14810         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_A_LO__A, dco_a_lo, 0);
14811         if (rc != 0) {
14812                 pr_err("error %d\n", rc);
14813                 goto rw_error;
14814         }
14815         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_B_HI__A, dco_b_hi, 0);
14816         if (rc != 0) {
14817                 pr_err("error %d\n", rc);
14818                 goto rw_error;
14819         }
14820         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_DCO_B_LO__A, dco_b_lo, 0);
14821         if (rc != 0) {
14822                 pr_err("error %d\n", rc);
14823                 goto rw_error;
14824         }
14825
14826         /* Carrier detetcion threshold for primary & secondary channel */
14827         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_CM_A_THRSHLD__A, carriers->a.thres, 0);
14828         if (rc != 0) {
14829                 pr_err("error %d\n", rc);
14830                 goto rw_error;
14831         }
14832         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_CM_B_THRSHLD__A, carriers->b.thres, 0);
14833         if (rc != 0) {
14834                 pr_err("error %d\n", rc);
14835                 goto rw_error;
14836         }
14837
14838         /* update DRXK data structure */
14839         ext_attr->aud_data.carriers = *carriers;
14840
14841         return 0;
14842 rw_error:
14843         return -EIO;
14844 }
14845
14846 /*============================================================================*/
14847 /**
14848 * \brief Get I2S Source, I2S matrix and FM matrix
14849 * \param demod instance of demodulator
14850 * \param pointer to pDRXAudmixer_t
14851 * \return int.
14852 *
14853 */
14854 static int
14855 aud_ctrl_get_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
14856 {
14857         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14858         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14859         int rc;
14860         u16 src_i2s_matr = 0;
14861         u16 fm_matr = 0;
14862
14863         if (mixer == NULL)
14864                 return -EINVAL;
14865
14866         dev_addr = demod->my_i2c_dev_addr;
14867         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14868
14869         /* power up */
14870         if (ext_attr->aud_data.audio_is_active == false) {
14871                 rc = power_up_aud(demod, true);
14872                 if (rc != 0) {
14873                         pr_err("error %d\n", rc);
14874                         goto rw_error;
14875                 }
14876                 ext_attr->aud_data.audio_is_active = true;
14877         }
14878
14879         /* Source Selctor */
14880         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
14881         if (rc != 0) {
14882                 pr_err("error %d\n", rc);
14883                 goto rw_error;
14884         }
14885
14886         switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M) {
14887         case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO:
14888                 mixer->source_i2s = DRX_AUD_SRC_MONO;
14889                 break;
14890         case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB:
14891                 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_AB;
14892                 break;
14893         case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A:
14894                 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_A;
14895                 break;
14896         case AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B:
14897                 mixer->source_i2s = DRX_AUD_SRC_STEREO_OR_B;
14898                 break;
14899         default:
14900                 return -EIO;
14901         }
14902
14903         /* Matrix */
14904         switch (src_i2s_matr & AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M) {
14905         case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO:
14906                 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_MONO;
14907                 break;
14908         case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO:
14909                 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_STEREO;
14910                 break;
14911         case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A:
14912                 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_A_MONO;
14913                 break;
14914         case AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B:
14915                 mixer->matrix_i2s = DRX_AUD_I2S_MATRIX_B_MONO;
14916                 break;
14917         default:
14918                 return -EIO;
14919         }
14920
14921         /* FM Matrix */
14922         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
14923         if (rc != 0) {
14924                 pr_err("error %d\n", rc);
14925                 goto rw_error;
14926         }
14927         switch (fm_matr & AUD_DEM_WR_FM_MATRIX__M) {
14928         case AUD_DEM_WR_FM_MATRIX_NO_MATRIX:
14929                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_NO_MATRIX;
14930                 break;
14931         case AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX:
14932                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_GERMAN;
14933                 break;
14934         case AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX:
14935                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_KOREAN;
14936                 break;
14937         case AUD_DEM_WR_FM_MATRIX_SOUND_A:
14938                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_A;
14939                 break;
14940         case AUD_DEM_WR_FM_MATRIX_SOUND_B:
14941                 mixer->matrix_fm = DRX_AUD_FM_MATRIX_SOUND_B;
14942                 break;
14943         default:
14944                 return -EIO;
14945         }
14946
14947         return 0;
14948 rw_error:
14949         return -EIO;
14950 }
14951
14952 /*============================================================================*/
14953 /**
14954 * \brief Set I2S Source, I2S matrix and FM matrix
14955 * \param demod instance of demodulator
14956 * \param pointer to DRXAudmixer_t
14957 * \return int.
14958 *
14959 */
14960 static int
14961 aud_ctrl_set_cfg_mixer(struct drx_demod_instance *demod, struct drx_cfg_aud_mixer *mixer)
14962 {
14963         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
14964         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
14965         int rc;
14966         u16 src_i2s_matr = 0;
14967         u16 fm_matr = 0;
14968
14969         if (mixer == NULL)
14970                 return -EINVAL;
14971
14972         dev_addr = demod->my_i2c_dev_addr;
14973         ext_attr = (struct drxj_data *) demod->my_ext_attr;
14974
14975         /* power up */
14976         if (ext_attr->aud_data.audio_is_active == false) {
14977                 rc = power_up_aud(demod, true);
14978                 if (rc != 0) {
14979                         pr_err("error %d\n", rc);
14980                         goto rw_error;
14981                 }
14982                 ext_attr->aud_data.audio_is_active = true;
14983         }
14984
14985         /* Source Selctor */
14986         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, &src_i2s_matr, 0);
14987         if (rc != 0) {
14988                 pr_err("error %d\n", rc);
14989                 goto rw_error;
14990         }
14991         src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S__M;
14992
14993         switch (mixer->source_i2s) {
14994         case DRX_AUD_SRC_MONO:
14995                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_MONO;
14996                 break;
14997         case DRX_AUD_SRC_STEREO_OR_AB:
14998                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_AB;
14999                 break;
15000         case DRX_AUD_SRC_STEREO_OR_A:
15001                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_A;
15002                 break;
15003         case DRX_AUD_SRC_STEREO_OR_B:
15004                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_SRC_I2S_STEREO_B;
15005                 break;
15006         default:
15007                 return -EINVAL;
15008         }
15009
15010         /* Matrix */
15011         src_i2s_matr &= (u16) ~AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S__M;
15012         switch (mixer->matrix_i2s) {
15013         case DRX_AUD_I2S_MATRIX_MONO:
15014                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_MONO;
15015                 break;
15016         case DRX_AUD_I2S_MATRIX_STEREO:
15017                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_STEREO;
15018                 break;
15019         case DRX_AUD_I2S_MATRIX_A_MONO:
15020                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_A;
15021                 break;
15022         case DRX_AUD_I2S_MATRIX_B_MONO:
15023                 src_i2s_matr |= AUD_DSP_WR_SRC_I2S_MATR_MAT_I2S_SOUND_B;
15024                 break;
15025         default:
15026                 return -EINVAL;
15027         }
15028         /* write the result */
15029         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_SRC_I2S_MATR__A, src_i2s_matr, 0);
15030         if (rc != 0) {
15031                 pr_err("error %d\n", rc);
15032                 goto rw_error;
15033         }
15034
15035         /* FM Matrix */
15036         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, &fm_matr, 0);
15037         if (rc != 0) {
15038                 pr_err("error %d\n", rc);
15039                 goto rw_error;
15040         }
15041         fm_matr &= (u16) ~AUD_DEM_WR_FM_MATRIX__M;
15042         switch (mixer->matrix_fm) {
15043         case DRX_AUD_FM_MATRIX_NO_MATRIX:
15044                 fm_matr |= AUD_DEM_WR_FM_MATRIX_NO_MATRIX;
15045                 break;
15046         case DRX_AUD_FM_MATRIX_GERMAN:
15047                 fm_matr |= AUD_DEM_WR_FM_MATRIX_GERMAN_MATRIX;
15048                 break;
15049         case DRX_AUD_FM_MATRIX_KOREAN:
15050                 fm_matr |= AUD_DEM_WR_FM_MATRIX_KOREAN_MATRIX;
15051                 break;
15052         case DRX_AUD_FM_MATRIX_SOUND_A:
15053                 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_A;
15054                 break;
15055         case DRX_AUD_FM_MATRIX_SOUND_B:
15056                 fm_matr |= AUD_DEM_WR_FM_MATRIX_SOUND_B;
15057                 break;
15058         default:
15059                 return -EINVAL;
15060         }
15061
15062         /* Only write if ASS is off */
15063         if (ext_attr->aud_data.auto_sound == DRX_AUD_AUTO_SOUND_OFF) {
15064                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_FM_MATRIX__A, fm_matr, 0);
15065                 if (rc != 0) {
15066                         pr_err("error %d\n", rc);
15067                         goto rw_error;
15068                 }
15069         }
15070
15071         /* update the data structure with hardware state */
15072         ext_attr->aud_data.mixer = *mixer;
15073
15074         return 0;
15075 rw_error:
15076         return -EIO;
15077 }
15078
15079 /*============================================================================*/
15080 /**
15081 * \brief Set AV Sync settings
15082 * \param demod instance of demodulator
15083 * \param pointer to DRXICfgAVSync_t
15084 * \return int.
15085 *
15086 */
15087 static int
15088 aud_ctrl_set_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15089 {
15090         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15091         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15092         int rc;
15093         u16 w_aud_vid_sync = 0;
15094
15095         if (av_sync == NULL)
15096                 return -EINVAL;
15097
15098         dev_addr = demod->my_i2c_dev_addr;
15099         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15100
15101         /* power up */
15102         if (ext_attr->aud_data.audio_is_active == false) {
15103                 rc = power_up_aud(demod, true);
15104                 if (rc != 0) {
15105                         pr_err("error %d\n", rc);
15106                         goto rw_error;
15107                 }
15108                 ext_attr->aud_data.audio_is_active = true;
15109         }
15110
15111         /* audio/video synchronisation */
15112         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15113         if (rc != 0) {
15114                 pr_err("error %d\n", rc);
15115                 goto rw_error;
15116         }
15117
15118         w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_ON__M;
15119
15120         if (*av_sync == DRX_AUD_AVSYNC_OFF)
15121                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE;
15122         else
15123                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_ON_ENABLE;
15124
15125         w_aud_vid_sync &= (u16) ~AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M;
15126
15127         switch (*av_sync) {
15128         case DRX_AUD_AVSYNC_NTSC:
15129                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC;
15130                 break;
15131         case DRX_AUD_AVSYNC_MONOCHROME:
15132                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME;
15133                 break;
15134         case DRX_AUD_AVSYNC_PAL_SECAM:
15135                 w_aud_vid_sync |= AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM;
15136                 break;
15137         case DRX_AUD_AVSYNC_OFF:
15138                 /* OK */
15139                 break;
15140         default:
15141                 return -EINVAL;
15142         }
15143
15144         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, w_aud_vid_sync, 0);
15145         if (rc != 0) {
15146                 pr_err("error %d\n", rc);
15147                 goto rw_error;
15148         }
15149         return 0;
15150 rw_error:
15151         return -EIO;
15152 }
15153
15154 /*============================================================================*/
15155 /**
15156 * \brief Get AV Sync settings
15157 * \param demod instance of demodulator
15158 * \param pointer to DRXICfgAVSync_t
15159 * \return int.
15160 *
15161 */
15162 static int
15163 aud_ctrl_get_cfg_av_sync(struct drx_demod_instance *demod, enum drx_cfg_aud_av_sync *av_sync)
15164 {
15165         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15166         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15167         int rc;
15168         u16 w_aud_vid_sync = 0;
15169
15170         if (av_sync == NULL)
15171                 return -EINVAL;
15172
15173         dev_addr = demod->my_i2c_dev_addr;
15174         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15175
15176         /* power up */
15177         if (ext_attr->aud_data.audio_is_active == false) {
15178                 rc = power_up_aud(demod, true);
15179                 if (rc != 0) {
15180                         pr_err("error %d\n", rc);
15181                         goto rw_error;
15182                 }
15183                 ext_attr->aud_data.audio_is_active = true;
15184         }
15185
15186         /* audio/video synchronisation */
15187         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_AV_SYNC__A, &w_aud_vid_sync, 0);
15188         if (rc != 0) {
15189                 pr_err("error %d\n", rc);
15190                 goto rw_error;
15191         }
15192
15193         if ((w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_ON__M) ==
15194             AUD_DSP_WR_AV_SYNC_AV_ON_DISABLE) {
15195                 *av_sync = DRX_AUD_AVSYNC_OFF;
15196                 return 0;
15197         }
15198
15199         switch (w_aud_vid_sync & AUD_DSP_WR_AV_SYNC_AV_STD_SEL__M) {
15200         case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_NTSC:
15201                 *av_sync = DRX_AUD_AVSYNC_NTSC;
15202                 break;
15203         case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_MONOCHROME:
15204                 *av_sync = DRX_AUD_AVSYNC_MONOCHROME;
15205                 break;
15206         case AUD_DSP_WR_AV_SYNC_AV_STD_SEL_PAL_SECAM:
15207                 *av_sync = DRX_AUD_AVSYNC_PAL_SECAM;
15208                 break;
15209         default:
15210                 return -EIO;
15211         }
15212
15213         return 0;
15214 rw_error:
15215         return -EIO;
15216 }
15217
15218 /*============================================================================*/
15219 /**
15220 * \brief Get deviation mode
15221 * \param demod instance of demodulator
15222 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15223 *
15224 */
15225 static int
15226 aud_ctrl_get_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15227 {
15228         u16 r_modus = 0;
15229         int rc;
15230
15231         if (dev == NULL)
15232                 return -EINVAL;
15233
15234         rc = aud_get_modus(demod, &r_modus);
15235         if (rc != 0) {
15236                 pr_err("error %d\n", rc);
15237                 goto rw_error;
15238         }
15239
15240         switch (r_modus & AUD_DEM_WR_MODUS_MOD_HDEV_A__M) {
15241         case AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL:
15242                 *dev = DRX_AUD_DEVIATION_NORMAL;
15243                 break;
15244         case AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION:
15245                 *dev = DRX_AUD_DEVIATION_HIGH;
15246                 break;
15247         default:
15248                 return -EIO;
15249         }
15250
15251         return 0;
15252 rw_error:
15253         return -EIO;
15254 }
15255
15256 /*============================================================================*/
15257 /**
15258 * \brief Get deviation mode
15259 * \param demod instance of demodulator
15260 * \param pointer to enum drx_cfg_aud_deviation * \return int.
15261 *
15262 */
15263 static int
15264 aud_ctrl_set_cfg_dev(struct drx_demod_instance *demod, enum drx_cfg_aud_deviation *dev)
15265 {
15266         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15267         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15268         int rc;
15269         u16 w_modus = 0;
15270         u16 r_modus = 0;
15271
15272         if (dev == NULL)
15273                 return -EINVAL;
15274
15275         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15276         dev_addr = demod->my_i2c_dev_addr;
15277
15278         rc = aud_get_modus(demod, &r_modus);
15279         if (rc != 0) {
15280                 pr_err("error %d\n", rc);
15281                 goto rw_error;
15282         }
15283
15284         w_modus = r_modus;
15285
15286         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_HDEV_A__M;
15287
15288         switch (*dev) {
15289         case DRX_AUD_DEVIATION_NORMAL:
15290                 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_NORMAL;
15291                 break;
15292         case DRX_AUD_DEVIATION_HIGH:
15293                 w_modus |= AUD_DEM_WR_MODUS_MOD_HDEV_A_HIGH_DEVIATION;
15294                 break;
15295         default:
15296                 return -EINVAL;
15297         }
15298
15299         /* now update the modus register */
15300         if (w_modus != r_modus) {
15301                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15302                 if (rc != 0) {
15303                         pr_err("error %d\n", rc);
15304                         goto rw_error;
15305                 }
15306         }
15307         /* store in drxk data struct */
15308         ext_attr->aud_data.deviation = *dev;
15309
15310         return 0;
15311 rw_error:
15312         return -EIO;
15313 }
15314
15315 /*============================================================================*/
15316 /**
15317 * \brief Get Prescaler settings
15318 * \param demod instance of demodulator
15319 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15320 *
15321 */
15322 static int
15323 aud_ctrl_get_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15324 {
15325         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15326         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15327         int rc;
15328         u16 r_max_fm_deviation = 0;
15329         u16 r_nicam_prescaler = 0;
15330
15331         if (presc == NULL)
15332                 return -EINVAL;
15333
15334         dev_addr = demod->my_i2c_dev_addr;
15335         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15336
15337         /* power up */
15338         if (ext_attr->aud_data.audio_is_active == false) {
15339                 rc = power_up_aud(demod, true);
15340                 if (rc != 0) {
15341                         pr_err("error %d\n", rc);
15342                         goto rw_error;
15343                 }
15344                 ext_attr->aud_data.audio_is_active = true;
15345         }
15346
15347         /* read register data */
15348         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, &r_nicam_prescaler, 0);
15349         if (rc != 0) {
15350                 pr_err("error %d\n", rc);
15351                 goto rw_error;
15352         }
15353         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DSP_WR_FM_PRESC__A, &r_max_fm_deviation, 0);
15354         if (rc != 0) {
15355                 pr_err("error %d\n", rc);
15356                 goto rw_error;
15357         }
15358
15359         /* calculate max FM deviation */
15360         r_max_fm_deviation >>= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15361         if (r_max_fm_deviation > 0) {
15362                 presc->fm_deviation = 3600UL + (r_max_fm_deviation >> 1);
15363                 presc->fm_deviation /= r_max_fm_deviation;
15364         } else {
15365                 presc->fm_deviation = 380;      /* kHz */
15366         }
15367
15368         /* calculate NICAM gain from pre-scaler */
15369         /*
15370            nicam_gain   = 20 * ( log10( preScaler / 16) )
15371            = ( 100log10( preScaler ) - 100log10( 16 ) ) / 5
15372
15373            because log1_times100() cannot return negative numbers
15374            = ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) ) / 5
15375
15376            for 0.1dB resolution:
15377
15378            nicam_gain   = 200 * ( log10( preScaler / 16) )
15379            = 2 * ( 100log10( 10 * preScaler ) - 100log10( 10 * 16) )
15380            = ( 100log10( 10 * preScaler^2 ) - 100log10( 10 * 16^2 ) )
15381
15382          */
15383         r_nicam_prescaler >>= 8;
15384         if (r_nicam_prescaler <= 1)
15385                 presc->nicam_gain = -241;
15386         else
15387                 presc->nicam_gain = (s16)(((s32)(log1_times100(10 * r_nicam_prescaler * r_nicam_prescaler)) - (s32)(log1_times100(10 * 16 * 16))));
15388
15389         return 0;
15390 rw_error:
15391         return -EIO;
15392 }
15393
15394 /*============================================================================*/
15395 /**
15396 * \brief Set Prescaler settings
15397 * \param demod instance of demodulator
15398 * \param pointer to struct drx_cfg_aud_prescale * \return int.
15399 *
15400 */
15401 static int
15402 aud_ctrl_set_cfg_prescale(struct drx_demod_instance *demod, struct drx_cfg_aud_prescale *presc)
15403 {
15404         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15405         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15406         int rc;
15407         u16 w_max_fm_deviation = 0;
15408         u16 nicam_prescaler;
15409
15410         if (presc == NULL)
15411                 return -EINVAL;
15412
15413         dev_addr = demod->my_i2c_dev_addr;
15414         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15415
15416         /* power up */
15417         if (ext_attr->aud_data.audio_is_active == false) {
15418                 rc = power_up_aud(demod, true);
15419                 if (rc != 0) {
15420                         pr_err("error %d\n", rc);
15421                         goto rw_error;
15422                 }
15423                 ext_attr->aud_data.audio_is_active = true;
15424         }
15425
15426         /* setting of max FM deviation */
15427         w_max_fm_deviation = (u16) (frac(3600UL, presc->fm_deviation, 0));
15428         w_max_fm_deviation <<= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC__B;
15429         if (w_max_fm_deviation >= AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION)
15430                 w_max_fm_deviation = AUD_DSP_WR_FM_PRESC_FM_AM_PRESC_28_KHZ_FM_DEVIATION;
15431
15432         /* NICAM Prescaler */
15433         if ((presc->nicam_gain >= -241) && (presc->nicam_gain <= 180)) {
15434                 /* calculation
15435
15436                    prescaler = 16 * 10^( gd_b / 20 )
15437
15438                    minval of gd_b = -20*log( 16 ) = -24.1dB
15439
15440                    negative numbers not allowed for d_b2lin_times100, so
15441
15442                    prescaler = 16 * 10^( gd_b / 20 )
15443                    = 10^( (gd_b / 20) + log10(16) )
15444                    = 10^( (gd_b + 20log10(16)) / 20 )
15445
15446                    in 0.1dB
15447
15448                    = 10^( G0.1dB + 200log10(16)) / 200 )
15449
15450                  */
15451                 nicam_prescaler = (u16)
15452                     ((d_b2lin_times100(presc->nicam_gain + 241UL) + 50UL) / 100UL);
15453
15454                 /* clip result */
15455                 if (nicam_prescaler > 127)
15456                         nicam_prescaler = 127;
15457
15458                 /* shift before writing to register */
15459                 nicam_prescaler <<= 8;
15460         } else {
15461                 return -EINVAL;
15462         }
15463         /* end of setting NICAM Prescaler */
15464
15465         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_NICAM_PRESC__A, nicam_prescaler, 0);
15466         if (rc != 0) {
15467                 pr_err("error %d\n", rc);
15468                 goto rw_error;
15469         }
15470         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_FM_PRESC__A, w_max_fm_deviation, 0);
15471         if (rc != 0) {
15472                 pr_err("error %d\n", rc);
15473                 goto rw_error;
15474         }
15475
15476         ext_attr->aud_data.prescale = *presc;
15477
15478         return 0;
15479 rw_error:
15480         return -EIO;
15481 }
15482
15483 /*============================================================================*/
15484 /**
15485 * \brief Beep
15486 * \param demod instance of demodulator
15487 * \param pointer to struct drx_aud_beep * \return int.
15488 *
15489 */
15490 static int aud_ctrl_beep(struct drx_demod_instance *demod, struct drx_aud_beep *beep)
15491 {
15492         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
15493         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
15494         int rc;
15495         u16 the_beep = 0;
15496         u16 volume = 0;
15497         u32 frequency = 0;
15498
15499         if (beep == NULL)
15500                 return -EINVAL;
15501
15502         dev_addr = demod->my_i2c_dev_addr;
15503         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15504
15505         /* power up */
15506         if (ext_attr->aud_data.audio_is_active == false) {
15507                 rc = power_up_aud(demod, true);
15508                 if (rc != 0) {
15509                         pr_err("error %d\n", rc);
15510                         goto rw_error;
15511                 }
15512                 ext_attr->aud_data.audio_is_active = true;
15513         }
15514
15515         if ((beep->volume > 0) || (beep->volume < -127))
15516                 return -EINVAL;
15517
15518         if (beep->frequency > 3000)
15519                 return -EINVAL;
15520
15521         volume = (u16) beep->volume + 127;
15522         the_beep |= volume << AUD_DSP_WR_BEEPER_BEEP_VOLUME__B;
15523
15524         frequency = ((u32) beep->frequency) * 23 / 500;
15525         if (frequency > AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M)
15526                 frequency = AUD_DSP_WR_BEEPER_BEEP_FREQUENCY__M;
15527         the_beep |= (u16) frequency;
15528
15529         if (beep->mute == true)
15530                 the_beep = 0;
15531
15532         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_BEEPER__A, the_beep, 0);
15533         if (rc != 0) {
15534                 pr_err("error %d\n", rc);
15535                 goto rw_error;
15536         }
15537
15538         return 0;
15539 rw_error:
15540         return -EIO;
15541 }
15542
15543 /*============================================================================*/
15544 /**
15545 * \brief Set an audio standard
15546 * \param demod instance of demodulator
15547 * \param pointer to enum drx_aud_standard * \return int.
15548 *
15549 */
15550 static int
15551 aud_ctrl_set_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15552 {
15553         struct i2c_device_addr *dev_addr = NULL;
15554         struct drxj_data *ext_attr = NULL;
15555         enum drx_standard current_standard = DRX_STANDARD_UNKNOWN;
15556         int rc;
15557         u16 w_standard = 0;
15558         u16 w_modus = 0;
15559         u16 r_modus = 0;
15560
15561         bool mute_buffer = false;
15562         s16 volume_buffer = 0;
15563         u16 w_volume = 0;
15564
15565         if (standard == NULL)
15566                 return -EINVAL;
15567
15568         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15569         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15570
15571         /* power up */
15572         if (ext_attr->aud_data.audio_is_active == false) {
15573                 rc = power_up_aud(demod, false);
15574                 if (rc != 0) {
15575                         pr_err("error %d\n", rc);
15576                         goto rw_error;
15577                 }
15578                 ext_attr->aud_data.audio_is_active = true;
15579         }
15580
15581         /* reset RDS data availability flag */
15582         ext_attr->aud_data.rds_data_present = false;
15583
15584         /* we need to mute from here to avoid noise during standard switching */
15585         mute_buffer = ext_attr->aud_data.volume.mute;
15586         volume_buffer = ext_attr->aud_data.volume.volume;
15587
15588         ext_attr->aud_data.volume.mute = true;
15589         /* restore data structure from DRX ExtAttr, call volume first to mute */
15590         rc = aud_ctrl_set_cfg_volume(demod, &ext_attr->aud_data.volume);
15591         if (rc != 0) {
15592                 pr_err("error %d\n", rc);
15593                 goto rw_error;
15594         }
15595         rc = aud_ctrl_set_cfg_carrier(demod, &ext_attr->aud_data.carriers);
15596         if (rc != 0) {
15597                 pr_err("error %d\n", rc);
15598                 goto rw_error;
15599         }
15600         rc = aud_ctrl_set_cfg_ass_thres(demod, &ext_attr->aud_data.ass_thresholds);
15601         if (rc != 0) {
15602                 pr_err("error %d\n", rc);
15603                 goto rw_error;
15604         }
15605         rc = aud_ctr_setl_cfg_auto_sound(demod, &ext_attr->aud_data.auto_sound);
15606         if (rc != 0) {
15607                 pr_err("error %d\n", rc);
15608                 goto rw_error;
15609         }
15610         rc = aud_ctrl_set_cfg_mixer(demod, &ext_attr->aud_data.mixer);
15611         if (rc != 0) {
15612                 pr_err("error %d\n", rc);
15613                 goto rw_error;
15614         }
15615         rc = aud_ctrl_set_cfg_av_sync(demod, &ext_attr->aud_data.av_sync);
15616         if (rc != 0) {
15617                 pr_err("error %d\n", rc);
15618                 goto rw_error;
15619         }
15620         rc = aud_ctrl_set_cfg_output_i2s(demod, &ext_attr->aud_data.i2sdata);
15621         if (rc != 0) {
15622                 pr_err("error %d\n", rc);
15623                 goto rw_error;
15624         }
15625
15626         /* get prescaler from presets */
15627         rc = aud_ctrl_set_cfg_prescale(demod, &ext_attr->aud_data.prescale);
15628         if (rc != 0) {
15629                 pr_err("error %d\n", rc);
15630                 goto rw_error;
15631         }
15632
15633         rc = aud_get_modus(demod, &r_modus);
15634         if (rc != 0) {
15635                 pr_err("error %d\n", rc);
15636                 goto rw_error;
15637         }
15638
15639         w_modus = r_modus;
15640
15641         switch (*standard) {
15642         case DRX_AUD_STANDARD_AUTO:
15643                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15644                 break;
15645         case DRX_AUD_STANDARD_BTSC:
15646                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_STEREO;
15647                 if (ext_attr->aud_data.btsc_detect == DRX_BTSC_MONO_AND_SAP)
15648                         w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BTSC_SAP;
15649                 break;
15650         case DRX_AUD_STANDARD_A2:
15651                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_M_KOREA;
15652                 break;
15653         case DRX_AUD_STANDARD_EIAJ:
15654                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_EIA_J;
15655                 break;
15656         case DRX_AUD_STANDARD_FM_STEREO:
15657                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_FM_RADIO;
15658                 break;
15659         case DRX_AUD_STANDARD_BG_FM:
15660                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_FM;
15661                 break;
15662         case DRX_AUD_STANDARD_D_K1:
15663                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K1;
15664                 break;
15665         case DRX_AUD_STANDARD_D_K2:
15666                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K2;
15667                 break;
15668         case DRX_AUD_STANDARD_D_K3:
15669                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K3;
15670                 break;
15671         case DRX_AUD_STANDARD_BG_NICAM_FM:
15672                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_BG_NICAM_FM;
15673                 break;
15674         case DRX_AUD_STANDARD_L_NICAM_AM:
15675                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_L_NICAM_AM;
15676                 break;
15677         case DRX_AUD_STANDARD_I_NICAM_FM:
15678                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_I_NICAM_FM;
15679                 break;
15680         case DRX_AUD_STANDARD_D_K_NICAM_FM:
15681                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_D_K_NICAM_FM;
15682                 break;
15683         case DRX_AUD_STANDARD_UNKNOWN:
15684                 w_standard = AUD_DEM_WR_STANDARD_SEL_STD_SEL_AUTO;
15685                 break;
15686         default:
15687                 return -EIO;
15688         }
15689
15690         if (*standard == DRX_AUD_STANDARD_AUTO) {
15691                 /* we need the current standard here */
15692                 current_standard = ext_attr->standard;
15693
15694                 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_6_5MHZ__M;
15695
15696                 if ((current_standard == DRX_STANDARD_PAL_SECAM_L) || (current_standard == DRX_STANDARD_PAL_SECAM_LP))
15697                         w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_SECAM);
15698                 else
15699                         w_modus |= (AUD_DEM_WR_MODUS_MOD_6_5MHZ_D_K);
15700
15701                 w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_4_5MHZ__M;
15702                 if (current_standard == DRX_STANDARD_NTSC)
15703                         w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_M_BTSC);
15704                 else
15705                         w_modus |= (AUD_DEM_WR_MODUS_MOD_4_5MHZ_CHROMA);
15706
15707         }
15708
15709         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_FMRADIO__M;
15710
15711         /* just get hardcoded deemphasis and activate here */
15712         if (ext_attr->aud_data.deemph == DRX_AUD_FM_DEEMPH_50US)
15713                 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_EU_50U);
15714         else
15715                 w_modus |= (AUD_DEM_WR_MODUS_MOD_FMRADIO_US_75U);
15716
15717         w_modus &= (u16) ~AUD_DEM_WR_MODUS_MOD_BTSC__M;
15718         if (ext_attr->aud_data.btsc_detect == DRX_BTSC_STEREO)
15719                 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_STEREO);
15720         else
15721                 w_modus |= (AUD_DEM_WR_MODUS_MOD_BTSC_BTSC_SAP);
15722
15723         if (w_modus != r_modus) {
15724                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_MODUS__A, w_modus, 0);
15725                 if (rc != 0) {
15726                         pr_err("error %d\n", rc);
15727                         goto rw_error;
15728                 }
15729         }
15730
15731         rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DEM_WR_STANDARD_SEL__A, w_standard, 0);
15732         if (rc != 0) {
15733                 pr_err("error %d\n", rc);
15734                 goto rw_error;
15735         }
15736
15737    /**************************************************************************/
15738         /* NOT calling aud_ctrl_set_cfg_volume to avoid interfering standard          */
15739         /* detection, need to keep things very minimal here, but keep audio       */
15740         /* buffers intact                                                         */
15741    /**************************************************************************/
15742         ext_attr->aud_data.volume.mute = mute_buffer;
15743         if (ext_attr->aud_data.volume.mute == false) {
15744                 w_volume |= (u16) ((volume_buffer + AUD_VOLUME_ZERO_DB) <<
15745                                     AUD_DSP_WR_VOLUME_VOL_MAIN__B);
15746                 rc = DRXJ_DAP.write_reg16func(dev_addr, AUD_DSP_WR_VOLUME__A, w_volume, 0);
15747                 if (rc != 0) {
15748                         pr_err("error %d\n", rc);
15749                         goto rw_error;
15750                 }
15751         }
15752
15753         /* write standard selected */
15754         ext_attr->aud_data.audio_standard = *standard;
15755
15756         return 0;
15757 rw_error:
15758         return -EIO;
15759 }
15760
15761 /*============================================================================*/
15762 /**
15763 * \brief Get the current audio standard
15764 * \param demod instance of demodulator
15765 * \param pointer to enum drx_aud_standard * \return int.
15766 *
15767 */
15768 static int
15769 aud_ctrl_get_standard(struct drx_demod_instance *demod, enum drx_aud_standard *standard)
15770 {
15771         struct i2c_device_addr *dev_addr = NULL;
15772         struct drxj_data *ext_attr = NULL;
15773         int rc;
15774         u16 r_data = 0;
15775
15776         if (standard == NULL)
15777                 return -EINVAL;
15778
15779         ext_attr = (struct drxj_data *) demod->my_ext_attr;
15780         dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
15781
15782         /* power up */
15783         if (ext_attr->aud_data.audio_is_active == false) {
15784                 rc = power_up_aud(demod, true);
15785                 if (rc != 0) {
15786                         pr_err("error %d\n", rc);
15787                         goto rw_error;
15788                 }
15789                 ext_attr->aud_data.audio_is_active = true;
15790         }
15791
15792         *standard = DRX_AUD_STANDARD_UNKNOWN;
15793
15794         rc = DRXJ_DAP.read_reg16func(dev_addr, AUD_DEM_RD_STANDARD_RES__A, &r_data, 0);
15795         if (rc != 0) {
15796                 pr_err("error %d\n", rc);
15797                 goto rw_error;
15798         }
15799
15800         /* return OK if the detection is not ready yet */
15801         if (r_data >= AUD_DEM_RD_STANDARD_RES_STD_RESULT_DETECTION_STILL_ACTIVE) {
15802                 *standard = DRX_AUD_STANDARD_NOT_READY;
15803                 return 0;
15804         }
15805
15806         /* detection done, return correct standard */
15807         switch (r_data) {
15808                 /* no standard detected */
15809         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NO_SOUND_STANDARD:
15810                 *standard = DRX_AUD_STANDARD_UNKNOWN;
15811                 break;
15812                 /* standard is KOREA(A2) */
15813         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_M_DUAL_CARRIER_FM:
15814                 *standard = DRX_AUD_STANDARD_A2;
15815                 break;
15816                 /* standard is EIA-J (Japan) */
15817         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_NTSC_EIA_J:
15818                 *standard = DRX_AUD_STANDARD_EIAJ;
15819                 break;
15820                 /* standard is BTSC-stereo */
15821         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_STEREO:
15822                 *standard = DRX_AUD_STANDARD_BTSC;
15823                 break;
15824                 /* standard is BTSC-mono (SAP) */
15825         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_BTSC_MONO_SAP:
15826                 *standard = DRX_AUD_STANDARD_BTSC;
15827                 break;
15828                 /* standard is FM radio */
15829         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_FM_RADIO:
15830                 *standard = DRX_AUD_STANDARD_FM_STEREO;
15831                 break;
15832                 /* standard is BG FM */
15833         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_DUAL_CARRIER_FM:
15834                 *standard = DRX_AUD_STANDARD_BG_FM;
15835                 break;
15836                 /* standard is DK-1 FM */
15837         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K1_DUAL_CARRIER_FM:
15838                 *standard = DRX_AUD_STANDARD_D_K1;
15839                 break;
15840                 /* standard is DK-2 FM */
15841         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K2_DUAL_CARRIER_FM:
15842                 *standard = DRX_AUD_STANDARD_D_K2;
15843                 break;
15844                 /* standard is DK-3 FM */
15845         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K3_DUAL_CARRIER_FM:
15846                 *standard = DRX_AUD_STANDARD_D_K3;
15847                 break;
15848                 /* standard is BG-NICAM FM */
15849         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_B_G_NICAM_FM:
15850                 *standard = DRX_AUD_STANDARD_BG_NICAM_FM;
15851                 break;
15852                 /* standard is L-NICAM AM */
15853         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_L_NICAM_AM:
15854                 *standard = DRX_AUD_STANDARD_L_NICAM_AM;
15855                 break;
15856                 /* standard is I-NICAM FM */
15857         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_I_NICAM_FM:
15858                 *standard = DRX_AUD_STANDARD_I_NICAM_FM;
15859                 break;
15860                 /* standard is DK-NICAM FM */
15861         case AUD_DEM_RD_STANDARD_RES_STD_RESULT_D_K_NICAM_FM:
15862                 *standard = DRX_AUD_STANDARD_D_K_NICAM_FM;
15863                 break;
15864         default:
15865                 *standard = DRX_AUD_STANDARD_UNKNOWN;
15866         }
15867
15868         return 0;
15869 rw_error:
15870         return -EIO;
15871
15872 }
15873
15874 /*============================================================================*/
15875 /**
15876 * \brief Retreive lock status in case of FM standard
15877 * \param demod instance of demodulator
15878 * \param pointer to lock status
15879 * \return int.
15880 *
15881 */
15882 static int
15883 fm_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
15884 {
15885         struct drx_aud_status status;
15886         int rc;
15887
15888         /* Check detection of audio carriers */
15889         rc = aud_ctrl_get_carrier_detect_status(demod, &status);
15890         if (rc != 0) {
15891                 pr_err("error %d\n", rc);
15892                 goto rw_error;
15893         }
15894
15895         /* locked if either primary or secondary carrier is detected */
15896         if ((status.carrier_a == true) || (status.carrier_b == true))
15897                 *lock_stat = DRX_LOCKED;
15898         else
15899                 *lock_stat = DRX_NOT_LOCKED;
15900
15901         return 0;
15902
15903 rw_error:
15904         return -EIO;
15905 }
15906
15907 /*============================================================================*/
15908 /**
15909 * \brief retreive signal quality in case of FM standard
15910 * \param demod instance of demodulator
15911 * \param pointer to signal quality
15912 * \return int.
15913 *
15914 * Only the quality indicator field is will be supplied.
15915 * This will either be 0% or 100%, nothing in between.
15916 *
15917 */
15918 static int
15919 fm_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
15920 {
15921         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
15922         int rc;
15923
15924         rc = fm_lock_status(demod, &lock_status);
15925         if (rc != 0) {
15926                 pr_err("error %d\n", rc);
15927                 goto rw_error;
15928         }
15929         if (lock_status == DRX_LOCKED)
15930                 sig_quality->indicator = 100;
15931         else
15932                 sig_quality->indicator = 0;
15933
15934         return 0;
15935
15936 rw_error:
15937         return -EIO;
15938 }
15939
15940 #endif
15941
15942 /*===========================================================================*/
15943 /*==                    END AUDIO DATAPATH FUNCTIONS                       ==*/
15944 /*===========================================================================*/
15945
15946 /*============================================================================*/
15947 /*============================================================================*/
15948 /*==                       OOB DATAPATH FUNCTIONS                           ==*/
15949 /*============================================================================*/
15950 /*============================================================================*/
15951 #ifndef DRXJ_DIGITAL_ONLY
15952 /**
15953 * \fn int get_oob_lock_status ()
15954 * \brief Get OOB lock status.
15955 * \param dev_addr I2C address
15956   \      oob_lock OOB lock status.
15957 * \return int.
15958 *
15959 * Gets OOB lock status
15960 *
15961 */
15962 static int
15963 get_oob_lock_status(struct drx_demod_instance *demod,
15964                     struct i2c_device_addr *dev_addr, enum drx_lock_status *oob_lock)
15965 {
15966         struct drxjscu_cmd scu_cmd;
15967         int rc;
15968         u16 cmd_result[2];
15969         u16 oob_lock_state;
15970
15971         *oob_lock = DRX_NOT_LOCKED;
15972
15973         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB |
15974             SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
15975         scu_cmd.result_len = 2;
15976         scu_cmd.result = cmd_result;
15977         scu_cmd.parameter_len = 0;
15978
15979         rc = scu_command(dev_addr, &scu_cmd);
15980         if (rc != 0) {
15981                 pr_err("error %d\n", rc);
15982                 goto rw_error;
15983         }
15984
15985         if (scu_cmd.result[1] < 0x4000) {
15986                 /* 0x00 NOT LOCKED */
15987                 *oob_lock = DRX_NOT_LOCKED;
15988         } else if (scu_cmd.result[1] < 0x8000) {
15989                 /* 0x40 DEMOD LOCKED */
15990                 *oob_lock = DRXJ_OOB_SYNC_LOCK;
15991         } else if (scu_cmd.result[1] < 0xC000) {
15992                 /* 0x80 DEMOD + OOB LOCKED (system lock) */
15993                 oob_lock_state = scu_cmd.result[1] & 0x00FF;
15994
15995                 if (oob_lock_state & 0x0008)
15996                         *oob_lock = DRXJ_OOB_SYNC_LOCK;
15997                 else if ((oob_lock_state & 0x0002) && (oob_lock_state & 0x0001))
15998                         *oob_lock = DRXJ_OOB_AGC_LOCK;
15999         } else {
16000                 /* 0xC0 NEVER LOCKED (system will never be able to lock to the signal) */
16001                 *oob_lock = DRX_NEVER_LOCK;
16002         }
16003
16004         /* *oob_lock = scu_cmd.result[1]; */
16005
16006         return 0;
16007 rw_error:
16008         return -EIO;
16009 }
16010
16011 /**
16012 * \fn int get_oob_symbol_rate_offset ()
16013 * \brief Get OOB Symbol rate offset. Unit is [ppm]
16014 * \param dev_addr I2C address
16015 * \      Symbol Rate Offset OOB parameter.
16016 * \return int.
16017 *
16018 * Gets OOB frequency offset
16019 *
16020 */
16021 static int
16022 get_oob_symbol_rate_offset(struct i2c_device_addr *dev_addr, s32 *symbol_rate_offset)
16023 {
16024 /*  offset = -{(timing_offset/2^19)*(symbol_rate/12,656250MHz)}*10^6 [ppm]  */
16025 /*  offset = -{(timing_offset/2^19)*(symbol_rate/12656250)}*10^6 [ppm]  */
16026 /*  after reconfiguration: */
16027 /*  offset = -{(timing_offset*symbol_rate)/(2^19*12656250)}*10^6 [ppm]  */
16028 /*  shift symbol rate left by 5 without lossing information */
16029 /*  offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^14*12656250)}*10^6 [ppm]*/
16030 /*  shift 10^6 left by 6 without loosing information */
16031 /*  offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*12656250)}*15625 [ppm]*/
16032 /*  trim 12656250/15625 = 810 */
16033 /*  offset = -{(timing_offset*(symbol_rate * 2^-5))/(2^8*810)} [ppm]  */
16034 /*  offset = -[(symbol_rate * 2^-5)*(timing_offset)/(2^8)]/810 [ppm]  */
16035         int rc;
16036         s32 timing_offset = 0;
16037         u32 unsigned_timing_offset = 0;
16038         s32 division_factor = 810;
16039         u16 data = 0;
16040         u32 symbol_rate = 0;
16041         bool negative = false;
16042
16043         *symbol_rate_offset = 0;
16044         /* read data rate */
16045         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &data, 0);
16046         if (rc != 0) {
16047                 pr_err("error %d\n", rc);
16048                 goto rw_error;
16049         }
16050         switch (data & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16051         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16052         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16053         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16054         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16055                 symbol_rate = 1024000;  /* bps */
16056                 break;
16057         case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16058         case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16059                 symbol_rate = 772000;   /* bps */
16060                 break;
16061         case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16062         case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16063                 symbol_rate = 1544000;  /* bps */
16064                 break;
16065         default:
16066                 return -EIO;
16067         }
16068
16069         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_CON_CTI_DTI_R__A, &data, 0);
16070         if (rc != 0) {
16071                 pr_err("error %d\n", rc);
16072                 goto rw_error;
16073         }
16074         /* convert data to positive and keep information about sign */
16075         if ((data & 0x8000) == 0x8000) {
16076                 if (data == 0x8000)
16077                         unsigned_timing_offset = 32768;
16078                 else
16079                         unsigned_timing_offset = 0x00007FFF & (u32) (-data);
16080                 negative = true;
16081         } else
16082                 unsigned_timing_offset = (u32) data;
16083
16084         symbol_rate = symbol_rate >> 5;
16085         unsigned_timing_offset = (unsigned_timing_offset * symbol_rate);
16086         unsigned_timing_offset = frac(unsigned_timing_offset, 256, FRAC_ROUND);
16087         unsigned_timing_offset = frac(unsigned_timing_offset,
16088                                     division_factor, FRAC_ROUND);
16089         if (negative)
16090                 timing_offset = (s32) unsigned_timing_offset;
16091         else
16092                 timing_offset = -(s32) unsigned_timing_offset;
16093
16094         *symbol_rate_offset = timing_offset;
16095
16096         return 0;
16097 rw_error:
16098         return -EIO;
16099 }
16100
16101 /**
16102 * \fn int get_oob_freq_offset ()
16103 * \brief Get OOB lock status.
16104 * \param dev_addr I2C address
16105 * \      freq_offset OOB frequency offset.
16106 * \return int.
16107 *
16108 * Gets OOB frequency offset
16109 *
16110 */
16111 static int
16112 get_oob_freq_offset(struct drx_demod_instance *demod, s32 *freq_offset)
16113 {
16114         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
16115         struct i2c_device_addr *dev_addr = NULL;
16116         int rc;
16117         u16 data = 0;
16118         u16 rot = 0;
16119         u16 symbol_rate_reg = 0;
16120         u32 symbol_rate = 0;
16121         s32 coarse_freq_offset = 0;
16122         s32 fine_freq_offset = 0;
16123         s32 fine_sign = 1;
16124         s32 coarse_sign = 1;
16125         u32 data64hi = 0;
16126         u32 data64lo = 0;
16127         u32 temp_freq_offset = 0;
16128
16129         /* check arguments */
16130         if ((demod == NULL) || (freq_offset == NULL))
16131                 return -EINVAL;
16132
16133         dev_addr = demod->my_i2c_dev_addr;
16134         common_attr = (struct drx_common_attr *) demod->my_common_attr;
16135
16136         *freq_offset = 0;
16137
16138         /* read sign (spectrum inversion) */
16139         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_IQM_FRQ_W__A, &rot, 0);
16140         if (rc != 0) {
16141                 pr_err("error %d\n", rc);
16142                 goto rw_error;
16143         }
16144
16145         /* read frequency offset */
16146         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_FRQ_OFFSET__A, &data, 0);
16147         if (rc != 0) {
16148                 pr_err("error %d\n", rc);
16149                 goto rw_error;
16150         }
16151         /* find COARSE frequency offset */
16152         /* coarse_freq_offset = ( 25312500Hz*FRQ_OFFSET >> 21 ); */
16153         if (data & 0x8000) {
16154                 data = (0xffff - data + 1);
16155                 coarse_sign = -1;
16156         }
16157         mult32(data, (common_attr->sys_clock_freq * 1000) / 6, &data64hi,
16158                &data64lo);
16159         temp_freq_offset = (((data64lo >> 21) & 0x7ff) | (data64hi << 11));
16160
16161         /* get value in KHz */
16162         coarse_freq_offset = coarse_sign * frac(temp_freq_offset, 1000, FRAC_ROUND);    /* KHz */
16163         /* read data rate */
16164         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_DATA_RATE__A, &symbol_rate_reg, 0);
16165         if (rc != 0) {
16166                 pr_err("error %d\n", rc);
16167                 goto rw_error;
16168         }
16169         switch (symbol_rate_reg & SCU_RAM_ORX_RF_RX_DATA_RATE__M) {
16170         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC:
16171         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC:
16172         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC_ALT:
16173         case SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC_ALT:
16174                 symbol_rate = 1024000;
16175                 break;
16176         case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC:
16177         case SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC:
16178                 symbol_rate = 772000;
16179                 break;
16180         case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC:
16181         case SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC:
16182                 symbol_rate = 1544000;
16183                 break;
16184         default:
16185                 return -EIO;
16186         }
16187
16188         /* find FINE frequency offset */
16189         /* fine_freq_offset = ( (CORRECTION_VALUE*symbol_rate) >> 18 ); */
16190         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_CON_CPH_FRQ_R__A, &data, 0);
16191         if (rc != 0) {
16192                 pr_err("error %d\n", rc);
16193                 goto rw_error;
16194         }
16195         /* at least 5 MSB are 0 so first divide with 2^5 without information loss */
16196         fine_freq_offset = (symbol_rate >> 5);
16197         if (data & 0x8000) {
16198                 fine_freq_offset *= 0xffff - data + 1;  /* Hz */
16199                 fine_sign = -1;
16200         } else {
16201                 fine_freq_offset *= data;       /* Hz */
16202         }
16203         /* Left to divide with 8192 (2^13) */
16204         fine_freq_offset = frac(fine_freq_offset, 8192, FRAC_ROUND);
16205         /* and to divide with 1000 to get KHz */
16206         fine_freq_offset = fine_sign * frac(fine_freq_offset, 1000, FRAC_ROUND);        /* KHz */
16207
16208         if ((rot & 0x8000) == 0x8000)
16209                 *freq_offset = -(coarse_freq_offset + fine_freq_offset);
16210         else
16211                 *freq_offset = (coarse_freq_offset + fine_freq_offset);
16212
16213         return 0;
16214 rw_error:
16215         return -EIO;
16216 }
16217
16218 /**
16219 * \fn int get_oob_frequency ()
16220 * \brief Get OOB frequency (Unit:KHz).
16221 * \param dev_addr I2C address
16222 * \      frequency OOB frequency parameters.
16223 * \return int.
16224 *
16225 * Gets OOB frequency
16226 *
16227 */
16228 static int
16229 get_oob_frequency(struct drx_demod_instance *demod, s32 *frequency)
16230 {
16231         struct i2c_device_addr *dev_addr = NULL;
16232         int rc;
16233         u16 data = 0;
16234         s32 freq_offset = 0;
16235         s32 freq = 0;
16236
16237         dev_addr = demod->my_i2c_dev_addr;
16238
16239         *frequency = 0;         /* KHz */
16240
16241         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_RF_RX_FREQUENCY_VALUE__A, &data, 0);
16242         if (rc != 0) {
16243                 pr_err("error %d\n", rc);
16244                 goto rw_error;
16245         }
16246
16247         freq = (s32) ((s32) data * 50 + 50000L);
16248
16249         rc = get_oob_freq_offset(demod, &freq_offset);
16250         if (rc != 0) {
16251                 pr_err("error %d\n", rc);
16252                 goto rw_error;
16253         }
16254
16255         *frequency = freq + freq_offset;
16256
16257         return 0;
16258 rw_error:
16259         return -EIO;
16260 }
16261
16262 /**
16263 * \fn int get_oobmer ()
16264 * \brief Get OOB MER.
16265 * \param dev_addr I2C address
16266   \      MER OOB parameter in dB.
16267 * \return int.
16268 *
16269 * Gets OOB MER. Table for MER is in Programming guide.
16270 *
16271 */
16272 static int get_oobmer(struct i2c_device_addr *dev_addr, u32 *mer)
16273 {
16274         int rc;
16275         u16 data = 0;
16276
16277         *mer = 0;
16278         /* READ MER */
16279         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_EQU_MER_MER_R__A, &data, 0);
16280         if (rc != 0) {
16281                 pr_err("error %d\n", rc);
16282                 goto rw_error;
16283         }
16284         switch (data) {
16285         case 0:         /* fall through */
16286         case 1:
16287                 *mer = 39;
16288                 break;
16289         case 2:
16290                 *mer = 33;
16291                 break;
16292         case 3:
16293                 *mer = 29;
16294                 break;
16295         case 4:
16296                 *mer = 27;
16297                 break;
16298         case 5:
16299                 *mer = 25;
16300                 break;
16301         case 6:
16302                 *mer = 23;
16303                 break;
16304         case 7:
16305                 *mer = 22;
16306                 break;
16307         case 8:
16308                 *mer = 21;
16309                 break;
16310         case 9:
16311                 *mer = 20;
16312                 break;
16313         case 10:
16314                 *mer = 19;
16315                 break;
16316         case 11:
16317                 *mer = 18;
16318                 break;
16319         case 12:
16320                 *mer = 17;
16321                 break;
16322         case 13:                /* fall through */
16323         case 14:
16324                 *mer = 16;
16325                 break;
16326         case 15:                /* fall through */
16327         case 16:
16328                 *mer = 15;
16329                 break;
16330         case 17:                /* fall through */
16331         case 18:
16332                 *mer = 14;
16333                 break;
16334         case 19:                /* fall through */
16335         case 20:
16336                 *mer = 13;
16337                 break;
16338         case 21:                /* fall through */
16339         case 22:
16340                 *mer = 12;
16341                 break;
16342         case 23:                /* fall through */
16343         case 24:                /* fall through */
16344         case 25:
16345                 *mer = 11;
16346                 break;
16347         case 26:                /* fall through */
16348         case 27:                /* fall through */
16349         case 28:
16350                 *mer = 10;
16351                 break;
16352         case 29:                /* fall through */
16353         case 30:                /* fall through */
16354         case 31:                /* fall through */
16355         case 32:
16356                 *mer = 9;
16357                 break;
16358         case 33:                /* fall through */
16359         case 34:                /* fall through */
16360         case 35:                /* fall through */
16361         case 36:
16362                 *mer = 8;
16363                 break;
16364         case 37:                /* fall through */
16365         case 38:                /* fall through */
16366         case 39:                /* fall through */
16367         case 40:
16368                 *mer = 7;
16369                 break;
16370         case 41:                /* fall through */
16371         case 42:                /* fall through */
16372         case 43:                /* fall through */
16373         case 44:                /* fall through */
16374         case 45:
16375                 *mer = 6;
16376                 break;
16377         case 46:                /* fall through */
16378         case 47:                /* fall through */
16379         case 48:                /* fall through */
16380         case 49:                /* fall through */
16381         case 50:                /* fall through */
16382                 *mer = 5;
16383                 break;
16384         case 51:                /* fall through */
16385         case 52:                /* fall through */
16386         case 53:                /* fall through */
16387         case 54:                /* fall through */
16388         case 55:                /* fall through */
16389         case 56:                /* fall through */
16390         case 57:
16391                 *mer = 4;
16392                 break;
16393         case 58:                /* fall through */
16394         case 59:                /* fall through */
16395         case 60:                /* fall through */
16396         case 61:                /* fall through */
16397         case 62:                /* fall through */
16398         case 63:
16399                 *mer = 0;
16400                 break;
16401         default:
16402                 *mer = 0;
16403                 break;
16404         }
16405         return 0;
16406 rw_error:
16407         return -EIO;
16408 }
16409 #endif /*#ifndef DRXJ_DIGITAL_ONLY */
16410
16411 /**
16412 * \fn int set_orx_nsu_aox()
16413 * \brief Configure OrxNsuAox for OOB
16414 * \param demod instance of demodulator.
16415 * \param active
16416 * \return int.
16417 */
16418 static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
16419 {
16420         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
16421         int rc;
16422         u16 data = 0;
16423
16424         /* Configure NSU_AOX */
16425         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
16426         if (rc != 0) {
16427                 pr_err("error %d\n", rc);
16428                 goto rw_error;
16429         }
16430         if (!active)
16431                 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));
16432         else
16433                 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);
16434         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
16435         if (rc != 0) {
16436                 pr_err("error %d\n", rc);
16437                 goto rw_error;
16438         }
16439
16440         return 0;
16441 rw_error:
16442         return -EIO;
16443 }
16444
16445 /**
16446 * \fn int ctrl_set_oob()
16447 * \brief Set OOB channel to be used.
16448 * \param demod instance of demodulator
16449 * \param oob_param OOB parameters for channel setting.
16450 * \frequency should be in KHz
16451 * \return int.
16452 *
16453 * Accepts  only. Returns error otherwise.
16454 * Demapper value is written after scu_command START
16455 * because START command causes COMM_EXEC transition
16456 * from 0 to 1 which causes all registers to be
16457 * overwritten with initial value
16458 *
16459 */
16460
16461 /* Nyquist filter impulse response */
16462 #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 */
16463 #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 */
16464 #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) */
16465
16466 /* Coefficients for the nyquist fitler (total: 27 taps) */
16467 #define NYQFILTERLEN 27
16468
16469 static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
16470 {
16471 #ifndef DRXJ_DIGITAL_ONLY
16472         int rc;
16473         s32 freq = 0;   /* KHz */
16474         struct i2c_device_addr *dev_addr = NULL;
16475         struct drxj_data *ext_attr = NULL;
16476         u16 i = 0;
16477         bool mirror_freq_spect_oob = false;
16478         u16 trk_filter_value = 0;
16479         struct drxjscu_cmd scu_cmd;
16480         u16 set_param_parameters[3];
16481         u16 cmd_result[2] = { 0, 0 };
16482         s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
16483                 IMPULSE_COSINE_ALPHA_0_3,       /* Target Mode 0 */
16484                 IMPULSE_COSINE_ALPHA_0_3,       /* Target Mode 1 */
16485                 IMPULSE_COSINE_ALPHA_0_5,       /* Target Mode 2 */
16486                 IMPULSE_COSINE_ALPHA_RO_0_5     /* Target Mode 3 */
16487         };
16488         u8 mode_val[4] = { 2, 2, 0, 1 };
16489         u8 pfi_coeffs[4][6] = {
16490                 {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) */
16491                 {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) */
16492                 {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) */
16493                 {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) */
16494         };
16495         u16 mode_index;
16496
16497         dev_addr = demod->my_i2c_dev_addr;
16498         ext_attr = (struct drxj_data *) demod->my_ext_attr;
16499         mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
16500
16501         /* Check parameters */
16502         if (oob_param == NULL) {
16503                 /* power off oob module  */
16504                 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16505                     | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
16506                 scu_cmd.parameter_len = 0;
16507                 scu_cmd.result_len = 1;
16508                 scu_cmd.result = cmd_result;
16509                 rc = scu_command(dev_addr, &scu_cmd);
16510                 if (rc != 0) {
16511                         pr_err("error %d\n", rc);
16512                         goto rw_error;
16513                 }
16514                 rc = set_orx_nsu_aox(demod, false);
16515                 if (rc != 0) {
16516                         pr_err("error %d\n", rc);
16517                         goto rw_error;
16518                 }
16519                 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
16520                 if (rc != 0) {
16521                         pr_err("error %d\n", rc);
16522                         goto rw_error;
16523                 }
16524
16525                 ext_attr->oob_power_on = false;
16526                 return 0;
16527         }
16528
16529         freq = oob_param->frequency;
16530         if ((freq < 70000) || (freq > 130000))
16531                 return -EIO;
16532         freq = (freq - 50000) / 50;
16533
16534         {
16535                 u16 index = 0;
16536                 u16 remainder = 0;
16537                 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
16538
16539                 index = (u16) ((freq - 400) / 200);
16540                 remainder = (u16) ((freq - 400) % 200);
16541                 trk_filter_value =
16542                     trk_filtercfg[index] - (trk_filtercfg[index] -
16543                                            trk_filtercfg[index +
16544                                                         1]) / 10 * remainder /
16545                     20;
16546         }
16547
16548    /*********/
16549         /* Stop  */
16550    /*********/
16551         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
16552         if (rc != 0) {
16553                 pr_err("error %d\n", rc);
16554                 goto rw_error;
16555         }
16556         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16557             | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
16558         scu_cmd.parameter_len = 0;
16559         scu_cmd.result_len = 1;
16560         scu_cmd.result = cmd_result;
16561         rc = scu_command(dev_addr, &scu_cmd);
16562         if (rc != 0) {
16563                 pr_err("error %d\n", rc);
16564                 goto rw_error;
16565         }
16566    /*********/
16567         /* Reset */
16568    /*********/
16569         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16570             | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
16571         scu_cmd.parameter_len = 0;
16572         scu_cmd.result_len = 1;
16573         scu_cmd.result = cmd_result;
16574         rc = scu_command(dev_addr, &scu_cmd);
16575         if (rc != 0) {
16576                 pr_err("error %d\n", rc);
16577                 goto rw_error;
16578         }
16579    /***********/
16580         /* SET_ENV */
16581    /***********/
16582         /* set frequency, spectrum inversion and data rate */
16583         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16584             | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
16585         scu_cmd.parameter_len = 3;
16586         /* 1-data rate;2-frequency */
16587         switch (oob_param->standard) {
16588         case DRX_OOB_MODE_A:
16589                 if (
16590                            /* signal is transmitted inverted */
16591                            ((oob_param->spectrum_inverted == true) &
16592                             /* and tuner is not mirroring the signal */
16593                             (!mirror_freq_spect_oob)) |
16594                            /* or */
16595                            /* signal is transmitted noninverted */
16596                            ((oob_param->spectrum_inverted == false) &
16597                             /* and tuner is mirroring the signal */
16598                             (mirror_freq_spect_oob))
16599                     )
16600                         set_param_parameters[0] =
16601                             SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
16602                 else
16603                         set_param_parameters[0] =
16604                             SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
16605                 break;
16606         case DRX_OOB_MODE_B_GRADE_A:
16607                 if (
16608                            /* signal is transmitted inverted */
16609                            ((oob_param->spectrum_inverted == true) &
16610                             /* and tuner is not mirroring the signal */
16611                             (!mirror_freq_spect_oob)) |
16612                            /* or */
16613                            /* signal is transmitted noninverted */
16614                            ((oob_param->spectrum_inverted == false) &
16615                             /* and tuner is mirroring the signal */
16616                             (mirror_freq_spect_oob))
16617                     )
16618                         set_param_parameters[0] =
16619                             SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
16620                 else
16621                         set_param_parameters[0] =
16622                             SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
16623                 break;
16624         case DRX_OOB_MODE_B_GRADE_B:
16625         default:
16626                 if (
16627                            /* signal is transmitted inverted */
16628                            ((oob_param->spectrum_inverted == true) &
16629                             /* and tuner is not mirroring the signal */
16630                             (!mirror_freq_spect_oob)) |
16631                            /* or */
16632                            /* signal is transmitted noninverted */
16633                            ((oob_param->spectrum_inverted == false) &
16634                             /* and tuner is mirroring the signal */
16635                             (mirror_freq_spect_oob))
16636                     )
16637                         set_param_parameters[0] =
16638                             SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
16639                 else
16640                         set_param_parameters[0] =
16641                             SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
16642                 break;
16643         }
16644         set_param_parameters[1] = (u16) (freq & 0xFFFF);
16645         set_param_parameters[2] = trk_filter_value;
16646         scu_cmd.parameter = set_param_parameters;
16647         scu_cmd.result_len = 1;
16648         scu_cmd.result = cmd_result;
16649         mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
16650         rc = scu_command(dev_addr, &scu_cmd);
16651         if (rc != 0) {
16652                 pr_err("error %d\n", rc);
16653                 goto rw_error;
16654         }
16655
16656         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
16657         if (rc != 0) {
16658                 pr_err("error %d\n", rc);
16659                 goto rw_error;
16660         }       /*  Write magic word to enable pdr reg write  */
16661         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);
16662         if (rc != 0) {
16663                 pr_err("error %d\n", rc);
16664                 goto rw_error;
16665         }
16666         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);
16667         if (rc != 0) {
16668                 pr_err("error %d\n", rc);
16669                 goto rw_error;
16670         }
16671         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
16672         if (rc != 0) {
16673                 pr_err("error %d\n", rc);
16674                 goto rw_error;
16675         }       /*  Write magic word to disable pdr reg write */
16676
16677         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
16678         if (rc != 0) {
16679                 pr_err("error %d\n", rc);
16680                 goto rw_error;
16681         }
16682         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
16683         if (rc != 0) {
16684                 pr_err("error %d\n", rc);
16685                 goto rw_error;
16686         }
16687         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
16688         if (rc != 0) {
16689                 pr_err("error %d\n", rc);
16690                 goto rw_error;
16691         }
16692
16693         /* ddc */
16694         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
16695         if (rc != 0) {
16696                 pr_err("error %d\n", rc);
16697                 goto rw_error;
16698         }
16699
16700         /* nsu */
16701         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
16702         if (rc != 0) {
16703                 pr_err("error %d\n", rc);
16704                 goto rw_error;
16705         }
16706
16707         /* initialization for target mode */
16708         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
16709         if (rc != 0) {
16710                 pr_err("error %d\n", rc);
16711                 goto rw_error;
16712         }
16713         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
16714         if (rc != 0) {
16715                 pr_err("error %d\n", rc);
16716                 goto rw_error;
16717         }
16718
16719         /* Reset bits for timing and freq. recovery */
16720         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
16721         if (rc != 0) {
16722                 pr_err("error %d\n", rc);
16723                 goto rw_error;
16724         }
16725         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
16726         if (rc != 0) {
16727                 pr_err("error %d\n", rc);
16728                 goto rw_error;
16729         }
16730         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
16731         if (rc != 0) {
16732                 pr_err("error %d\n", rc);
16733                 goto rw_error;
16734         }
16735         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
16736         if (rc != 0) {
16737                 pr_err("error %d\n", rc);
16738                 goto rw_error;
16739         }
16740
16741         /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
16742         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
16743         if (rc != 0) {
16744                 pr_err("error %d\n", rc);
16745                 goto rw_error;
16746         }
16747         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
16748         if (rc != 0) {
16749                 pr_err("error %d\n", rc);
16750                 goto rw_error;
16751         }
16752         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
16753         if (rc != 0) {
16754                 pr_err("error %d\n", rc);
16755                 goto rw_error;
16756         }
16757         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
16758         if (rc != 0) {
16759                 pr_err("error %d\n", rc);
16760                 goto rw_error;
16761         }
16762         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
16763         if (rc != 0) {
16764                 pr_err("error %d\n", rc);
16765                 goto rw_error;
16766         }
16767
16768         /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
16769         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
16770         if (rc != 0) {
16771                 pr_err("error %d\n", rc);
16772                 goto rw_error;
16773         }
16774         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
16775         if (rc != 0) {
16776                 pr_err("error %d\n", rc);
16777                 goto rw_error;
16778         }
16779         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
16780         if (rc != 0) {
16781                 pr_err("error %d\n", rc);
16782                 goto rw_error;
16783         }
16784         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
16785         if (rc != 0) {
16786                 pr_err("error %d\n", rc);
16787                 goto rw_error;
16788         }
16789         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
16790         if (rc != 0) {
16791                 pr_err("error %d\n", rc);
16792                 goto rw_error;
16793         }
16794
16795         /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
16796         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
16797         if (rc != 0) {
16798                 pr_err("error %d\n", rc);
16799                 goto rw_error;
16800         }
16801         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
16802         if (rc != 0) {
16803                 pr_err("error %d\n", rc);
16804                 goto rw_error;
16805         }
16806         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
16807         if (rc != 0) {
16808                 pr_err("error %d\n", rc);
16809                 goto rw_error;
16810         }
16811         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
16812         if (rc != 0) {
16813                 pr_err("error %d\n", rc);
16814                 goto rw_error;
16815         }
16816         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
16817         if (rc != 0) {
16818                 pr_err("error %d\n", rc);
16819                 goto rw_error;
16820         }
16821
16822         /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
16823         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
16824         if (rc != 0) {
16825                 pr_err("error %d\n", rc);
16826                 goto rw_error;
16827         }
16828         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
16829         if (rc != 0) {
16830                 pr_err("error %d\n", rc);
16831                 goto rw_error;
16832         }
16833         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
16834         if (rc != 0) {
16835                 pr_err("error %d\n", rc);
16836                 goto rw_error;
16837         }
16838         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
16839         if (rc != 0) {
16840                 pr_err("error %d\n", rc);
16841                 goto rw_error;
16842         }
16843         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
16844         if (rc != 0) {
16845                 pr_err("error %d\n", rc);
16846                 goto rw_error;
16847         }
16848
16849         /* TIM_LOCK = {300,      -2048, 8, -8, 0, 1<<4}; */
16850         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
16851         if (rc != 0) {
16852                 pr_err("error %d\n", rc);
16853                 goto rw_error;
16854         }
16855         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
16856         if (rc != 0) {
16857                 pr_err("error %d\n", rc);
16858                 goto rw_error;
16859         }
16860         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
16861         if (rc != 0) {
16862                 pr_err("error %d\n", rc);
16863                 goto rw_error;
16864         }
16865         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
16866         if (rc != 0) {
16867                 pr_err("error %d\n", rc);
16868                 goto rw_error;
16869         }
16870         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
16871         if (rc != 0) {
16872                 pr_err("error %d\n", rc);
16873                 goto rw_error;
16874         }
16875
16876         /* EQU_LOCK = {20,      -2048, 8, -8, 0, 1<<5}; */
16877         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 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, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
16883         if (rc != 0) {
16884                 pr_err("error %d\n", rc);
16885                 goto rw_error;
16886         }
16887         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
16888         if (rc != 0) {
16889                 pr_err("error %d\n", rc);
16890                 goto rw_error;
16891         }
16892         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
16893         if (rc != 0) {
16894                 pr_err("error %d\n", rc);
16895                 goto rw_error;
16896         }
16897         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
16898         if (rc != 0) {
16899                 pr_err("error %d\n", rc);
16900                 goto rw_error;
16901         }
16902
16903         /* PRE-Filter coefficients (PFI) */
16904         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);
16905         if (rc != 0) {
16906                 pr_err("error %d\n", rc);
16907                 goto rw_error;
16908         }
16909         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
16910         if (rc != 0) {
16911                 pr_err("error %d\n", rc);
16912                 goto rw_error;
16913         }
16914
16915         /* NYQUIST-Filter coefficients (NYQ) */
16916         for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
16917                 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
16918                 if (rc != 0) {
16919                         pr_err("error %d\n", rc);
16920                         goto rw_error;
16921                 }
16922                 rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
16923                 if (rc != 0) {
16924                         pr_err("error %d\n", rc);
16925                         goto rw_error;
16926                 }
16927         }
16928         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
16929         if (rc != 0) {
16930                 pr_err("error %d\n", rc);
16931                 goto rw_error;
16932         }
16933         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
16934         if (rc != 0) {
16935                 pr_err("error %d\n", rc);
16936                 goto rw_error;
16937         }
16938         /*********/
16939         /* Start */
16940         /*********/
16941         scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
16942             | SCU_RAM_COMMAND_CMD_DEMOD_START;
16943         scu_cmd.parameter_len = 0;
16944         scu_cmd.result_len = 1;
16945         scu_cmd.result = cmd_result;
16946         rc = scu_command(dev_addr, &scu_cmd);
16947         if (rc != 0) {
16948                 pr_err("error %d\n", rc);
16949                 goto rw_error;
16950         }
16951
16952         rc = set_orx_nsu_aox(demod, true);
16953         if (rc != 0) {
16954                 pr_err("error %d\n", rc);
16955                 goto rw_error;
16956         }
16957         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
16958         if (rc != 0) {
16959                 pr_err("error %d\n", rc);
16960                 goto rw_error;
16961         }
16962
16963         ext_attr->oob_power_on = true;
16964
16965         return 0;
16966 rw_error:
16967 #endif
16968         return -EIO;
16969 }
16970
16971 /**
16972 * \fn int ctrl_get_oob()
16973 * \brief Set modulation standard to be used.
16974 * \param demod instance of demodulator
16975 * \param oob_status OOB status parameters.
16976 * \return int.
16977 */
16978 static int
16979 ctrl_get_oob(struct drx_demod_instance *demod, struct drxoob_status *oob_status)
16980 {
16981 #ifndef DRXJ_DIGITAL_ONLY
16982         int rc;
16983         struct i2c_device_addr *dev_addr = NULL;
16984         struct drxj_data *ext_attr = NULL;
16985         u16 data = 0;
16986
16987         dev_addr = demod->my_i2c_dev_addr;
16988         ext_attr = (struct drxj_data *) demod->my_ext_attr;
16989
16990         /* check arguments */
16991         if (oob_status == NULL)
16992                 return -EINVAL;
16993
16994         if (!ext_attr->oob_power_on)
16995                 return -EIO;
16996
16997         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_DDC_OFO_SET_W__A, &data, 0);
16998         if (rc != 0) {
16999                 pr_err("error %d\n", rc);
17000                 goto rw_error;
17001         }
17002         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &data, 0);
17003         if (rc != 0) {
17004                 pr_err("error %d\n", rc);
17005                 goto rw_error;
17006         }
17007         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_AAG_THR_W__A, &data, 0);
17008         if (rc != 0) {
17009                 pr_err("error %d\n", rc);
17010                 goto rw_error;
17011         }
17012         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_DGN_KI__A, &data, 0);
17013         if (rc != 0) {
17014                 pr_err("error %d\n", rc);
17015                 goto rw_error;
17016         }
17017         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
17018         if (rc != 0) {
17019                 pr_err("error %d\n", rc);
17020                 goto rw_error;
17021         }
17022
17023         rc = get_oob_lock_status(demod, dev_addr, &oob_status->lock);
17024         if (rc != 0) {
17025                 pr_err("error %d\n", rc);
17026                 goto rw_error;
17027         }
17028         rc = get_oob_frequency(demod, &oob_status->frequency);
17029         if (rc != 0) {
17030                 pr_err("error %d\n", rc);
17031                 goto rw_error;
17032         }
17033         rc = get_oobmer(dev_addr, &oob_status->mer);
17034         if (rc != 0) {
17035                 pr_err("error %d\n", rc);
17036                 goto rw_error;
17037         }
17038         rc = get_oob_symbol_rate_offset(dev_addr, &oob_status->symbol_rate_offset);
17039         if (rc != 0) {
17040                 pr_err("error %d\n", rc);
17041                 goto rw_error;
17042         }
17043
17044         return 0;
17045 rw_error:
17046 #endif
17047         return -EIO;
17048 }
17049
17050 /**
17051 * \fn int ctrl_set_cfg_oob_pre_saw()
17052 * \brief Configure PreSAW treshold value
17053 * \param cfg_data Pointer to configuration parameter
17054 * \return Error code
17055 */
17056 #ifndef DRXJ_DIGITAL_ONLY
17057 static int
17058 ctrl_set_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17059 {
17060         struct i2c_device_addr *dev_addr = NULL;
17061         struct drxj_data *ext_attr = NULL;
17062         int rc;
17063
17064         if (cfg_data == NULL)
17065                 return -EINVAL;
17066
17067         dev_addr = demod->my_i2c_dev_addr;
17068         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17069
17070         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_STHR_W__A, *cfg_data, 0);
17071         if (rc != 0) {
17072                 pr_err("error %d\n", rc);
17073                 goto rw_error;
17074         }
17075         ext_attr->oob_pre_saw = *cfg_data;
17076         return 0;
17077 rw_error:
17078         return -EIO;
17079 }
17080 #endif
17081
17082 /**
17083 * \fn int ctrl_get_cfg_oob_pre_saw()
17084 * \brief Configure PreSAW treshold value
17085 * \param cfg_data Pointer to configuration parameter
17086 * \return Error code
17087 */
17088 #ifndef DRXJ_DIGITAL_ONLY
17089 static int
17090 ctrl_get_cfg_oob_pre_saw(struct drx_demod_instance *demod, u16 *cfg_data)
17091 {
17092         struct drxj_data *ext_attr = NULL;
17093
17094         if (cfg_data == NULL)
17095                 return -EINVAL;
17096
17097         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17098
17099         *cfg_data = ext_attr->oob_pre_saw;
17100
17101         return 0;
17102 }
17103 #endif
17104
17105 /**
17106 * \fn int ctrl_set_cfg_oob_lo_power()
17107 * \brief Configure LO Power value
17108 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17109 */
17110 #ifndef DRXJ_DIGITAL_ONLY
17111 static int
17112 ctrl_set_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17113 {
17114         struct i2c_device_addr *dev_addr = NULL;
17115         struct drxj_data *ext_attr = NULL;
17116         int rc;
17117
17118         if (cfg_data == NULL)
17119                 return -EINVAL;
17120
17121         dev_addr = demod->my_i2c_dev_addr;
17122         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17123
17124         rc = DRXJ_DAP.write_reg16func(dev_addr, ORX_NSU_AOX_LOPOW_W__A, *cfg_data, 0);
17125         if (rc != 0) {
17126                 pr_err("error %d\n", rc);
17127                 goto rw_error;
17128         }
17129         ext_attr->oob_lo_pow = *cfg_data;
17130         return 0;
17131 rw_error:
17132         return -EIO;
17133 }
17134 #endif
17135
17136 /**
17137 * \fn int ctrl_get_cfg_oob_lo_power()
17138 * \brief Configure LO Power value
17139 * \param cfg_data Pointer to enum drxj_cfg_oob_lo_power ** \return Error code
17140 */
17141 #ifndef DRXJ_DIGITAL_ONLY
17142 static int
17143 ctrl_get_cfg_oob_lo_power(struct drx_demod_instance *demod, enum drxj_cfg_oob_lo_power *cfg_data)
17144 {
17145         struct drxj_data *ext_attr = NULL;
17146
17147         if (cfg_data == NULL)
17148                 return -EINVAL;
17149
17150         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17151
17152         *cfg_data = ext_attr->oob_lo_pow;
17153
17154         return 0;
17155 }
17156 #endif
17157 /*============================================================================*/
17158 /*==                     END OOB DATAPATH FUNCTIONS                         ==*/
17159 /*============================================================================*/
17160
17161 /*=============================================================================
17162   ===== MC command related functions ==========================================
17163   ===========================================================================*/
17164
17165 /*=============================================================================
17166   ===== ctrl_set_channel() ==========================================================
17167   ===========================================================================*/
17168 /**
17169 * \fn int ctrl_set_channel()
17170 * \brief Select a new transmission channel.
17171 * \param demod instance of demod.
17172 * \param channel Pointer to channel data.
17173 * \return int.
17174 *
17175 * In case the tuner module is not used and in case of NTSC/FM the pogrammer
17176 * must tune the tuner to the centre frequency of the NTSC/FM channel.
17177 *
17178 */
17179 static int
17180 ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17181 {
17182         int rc;
17183         s32 tuner_set_freq = 0;
17184         s32 tuner_get_freq = 0;
17185         s32 tuner_freq_offset = 0;
17186         s32 intermediate_freq = 0;
17187         struct drxj_data *ext_attr = NULL;
17188         struct i2c_device_addr *dev_addr = NULL;
17189         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17190         u32 tuner_mode = 0;
17191         struct drx_common_attr *common_attr = NULL;
17192         bool bridge_closed = false;
17193 #ifndef DRXJ_VSB_ONLY
17194         u32 min_symbol_rate = 0;
17195         u32 max_symbol_rate = 0;
17196         int bandwidth_temp = 0;
17197         int bandwidth = 0;
17198 #endif
17199    /*== check arguments ======================================================*/
17200         if ((demod == NULL) || (channel == NULL))
17201                 return -EINVAL;
17202
17203         common_attr = (struct drx_common_attr *) demod->my_common_attr;
17204         dev_addr = demod->my_i2c_dev_addr;
17205         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17206         standard = ext_attr->standard;
17207
17208         /* check valid standards */
17209         switch (standard) {
17210         case DRX_STANDARD_8VSB:
17211 #ifndef DRXJ_VSB_ONLY
17212         case DRX_STANDARD_ITU_A:
17213         case DRX_STANDARD_ITU_B:
17214         case DRX_STANDARD_ITU_C:
17215 #endif /* DRXJ_VSB_ONLY */
17216 #ifndef DRXJ_DIGITAL_ONLY
17217         case DRX_STANDARD_NTSC:
17218         case DRX_STANDARD_FM:
17219         case DRX_STANDARD_PAL_SECAM_BG:
17220         case DRX_STANDARD_PAL_SECAM_DK:
17221         case DRX_STANDARD_PAL_SECAM_I:
17222         case DRX_STANDARD_PAL_SECAM_L:
17223         case DRX_STANDARD_PAL_SECAM_LP:
17224 #endif /* DRXJ_DIGITAL_ONLY */
17225                 break;
17226         case DRX_STANDARD_UNKNOWN:
17227         default:
17228                 return -EINVAL;
17229         }
17230
17231         /* check bandwidth QAM annex B, NTSC and 8VSB */
17232         if ((standard == DRX_STANDARD_ITU_B) ||
17233             (standard == DRX_STANDARD_8VSB) ||
17234             (standard == DRX_STANDARD_NTSC)) {
17235                 switch (channel->bandwidth) {
17236                 case DRX_BANDWIDTH_6MHZ:
17237                 case DRX_BANDWIDTH_UNKNOWN:     /* fall through */
17238                         channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17239                         break;
17240                 case DRX_BANDWIDTH_8MHZ:        /* fall through */
17241                 case DRX_BANDWIDTH_7MHZ:        /* fall through */
17242                 default:
17243                         return -EINVAL;
17244                 }
17245         }
17246 #ifndef DRXJ_DIGITAL_ONLY
17247         if (standard == DRX_STANDARD_PAL_SECAM_BG) {
17248                 switch (channel->bandwidth) {
17249                 case DRX_BANDWIDTH_7MHZ:        /* fall through */
17250                 case DRX_BANDWIDTH_8MHZ:
17251                         /* ok */
17252                         break;
17253                 case DRX_BANDWIDTH_6MHZ:        /* fall through */
17254                 case DRX_BANDWIDTH_UNKNOWN:     /* fall through */
17255                 default:
17256                         return -EINVAL;
17257                 }
17258         }
17259         /* check bandwidth PAL/SECAM  */
17260         if ((standard == DRX_STANDARD_PAL_SECAM_BG) ||
17261             (standard == DRX_STANDARD_PAL_SECAM_DK) ||
17262             (standard == DRX_STANDARD_PAL_SECAM_I) ||
17263             (standard == DRX_STANDARD_PAL_SECAM_L) ||
17264             (standard == DRX_STANDARD_PAL_SECAM_LP)) {
17265                 switch (channel->bandwidth) {
17266                 case DRX_BANDWIDTH_8MHZ:
17267                 case DRX_BANDWIDTH_UNKNOWN:     /* fall through */
17268                         channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17269                         break;
17270                 case DRX_BANDWIDTH_6MHZ:        /* fall through */
17271                 case DRX_BANDWIDTH_7MHZ:        /* fall through */
17272                 default:
17273                         return -EINVAL;
17274                 }
17275         }
17276 #endif
17277
17278         /* For QAM annex A and annex C:
17279            -check symbolrate and constellation
17280            -derive bandwidth from symbolrate (input bandwidth is ignored)
17281          */
17282 #ifndef DRXJ_VSB_ONLY
17283         if ((standard == DRX_STANDARD_ITU_A) ||
17284             (standard == DRX_STANDARD_ITU_C)) {
17285                 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
17286                 int bw_rolloff_factor = 0;
17287
17288                 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
17289                 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
17290                 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
17291                 /* config SMA_TX pin to SAW switch mode */
17292                 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
17293                 if (rc != 0) {
17294                         pr_err("error %d\n", rc);
17295                         goto rw_error;
17296                 }
17297
17298                 if (channel->symbolrate < min_symbol_rate ||
17299                     channel->symbolrate > max_symbol_rate) {
17300                         return -EINVAL;
17301                 }
17302
17303                 switch (channel->constellation) {
17304                 case DRX_CONSTELLATION_QAM16:   /* fall through */
17305                 case DRX_CONSTELLATION_QAM32:   /* fall through */
17306                 case DRX_CONSTELLATION_QAM64:   /* fall through */
17307                 case DRX_CONSTELLATION_QAM128:  /* fall through */
17308                 case DRX_CONSTELLATION_QAM256:
17309                         bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
17310                         bandwidth = bandwidth_temp / 100;
17311
17312                         if ((bandwidth_temp % 100) >= 50)
17313                                 bandwidth++;
17314
17315                         if (bandwidth <= 6100000) {
17316                                 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17317                         } else if ((bandwidth > 6100000)
17318                                    && (bandwidth <= 7100000)) {
17319                                 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
17320                         } else if (bandwidth > 7100000) {
17321                                 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
17322                         }
17323                         break;
17324                 default:
17325                         return -EINVAL;
17326                 }
17327         }
17328
17329         /* For QAM annex B:
17330            -check constellation
17331          */
17332         if (standard == DRX_STANDARD_ITU_B) {
17333                 switch (channel->constellation) {
17334                 case DRX_CONSTELLATION_AUTO:
17335                 case DRX_CONSTELLATION_QAM256:
17336                 case DRX_CONSTELLATION_QAM64:
17337                         break;
17338                 default:
17339                         return -EINVAL;
17340                 }
17341
17342                 switch (channel->interleavemode) {
17343                 case DRX_INTERLEAVEMODE_I128_J1:
17344                 case DRX_INTERLEAVEMODE_I128_J1_V2:
17345                 case DRX_INTERLEAVEMODE_I128_J2:
17346                 case DRX_INTERLEAVEMODE_I64_J2:
17347                 case DRX_INTERLEAVEMODE_I128_J3:
17348                 case DRX_INTERLEAVEMODE_I32_J4:
17349                 case DRX_INTERLEAVEMODE_I128_J4:
17350                 case DRX_INTERLEAVEMODE_I16_J8:
17351                 case DRX_INTERLEAVEMODE_I128_J5:
17352                 case DRX_INTERLEAVEMODE_I8_J16:
17353                 case DRX_INTERLEAVEMODE_I128_J6:
17354                 case DRX_INTERLEAVEMODE_I128_J7:
17355                 case DRX_INTERLEAVEMODE_I128_J8:
17356                 case DRX_INTERLEAVEMODE_I12_J17:
17357                 case DRX_INTERLEAVEMODE_I5_J4:
17358                 case DRX_INTERLEAVEMODE_B52_M240:
17359                 case DRX_INTERLEAVEMODE_B52_M720:
17360                 case DRX_INTERLEAVEMODE_UNKNOWN:
17361                 case DRX_INTERLEAVEMODE_AUTO:
17362                         break;
17363                 default:
17364                         return -EINVAL;
17365                 }
17366         }
17367
17368         if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
17369                 /* SAW SW, user UIO is used for switchable SAW */
17370                 struct drxuio_data uio1 = { DRX_UIO1, false };
17371
17372                 switch (channel->bandwidth) {
17373                 case DRX_BANDWIDTH_8MHZ:
17374                         uio1.value = true;
17375                         break;
17376                 case DRX_BANDWIDTH_7MHZ:
17377                         uio1.value = false;
17378                         break;
17379                 case DRX_BANDWIDTH_6MHZ:
17380                         uio1.value = false;
17381                         break;
17382                 case DRX_BANDWIDTH_UNKNOWN:
17383                 default:
17384                         return -EINVAL;
17385                 }
17386
17387                 rc = ctrl_uio_write(demod, &uio1);
17388                 if (rc != 0) {
17389                         pr_err("error %d\n", rc);
17390                         goto rw_error;
17391                 }
17392         }
17393 #endif /* DRXJ_VSB_ONLY */
17394         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
17395         if (rc != 0) {
17396                 pr_err("error %d\n", rc);
17397                 goto rw_error;
17398         }
17399    /*== Tune, fast mode ======================================================*/
17400         if (demod->my_tuner != NULL) {
17401                 /* Determine tuner mode and freq to tune to ... */
17402                 switch (standard) {
17403 #ifndef DRXJ_DIGITAL_ONLY
17404                 case DRX_STANDARD_NTSC: /* fallthrough */
17405                 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17406                 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17407                 case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
17408                 case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
17409                 case DRX_STANDARD_PAL_SECAM_LP:
17410                         /* expecting center frequency, not picture carrier so no
17411                            conversion .... */
17412                         tuner_mode |= TUNER_MODE_ANALOG;
17413                         tuner_set_freq = channel->frequency;
17414                         break;
17415                 case DRX_STANDARD_FM:
17416                         /* center frequency (equals sound carrier) as input,
17417                            tune to edge of SAW */
17418                         tuner_mode |= TUNER_MODE_ANALOG;
17419                         tuner_set_freq =
17420                             channel->frequency + DRXJ_FM_CARRIER_FREQ_OFFSET;
17421                         break;
17422 #endif
17423                 case DRX_STANDARD_8VSB: /* fallthrough */
17424 #ifndef DRXJ_VSB_ONLY
17425                 case DRX_STANDARD_ITU_A:        /* fallthrough */
17426                 case DRX_STANDARD_ITU_B:        /* fallthrough */
17427                 case DRX_STANDARD_ITU_C:
17428 #endif
17429                         tuner_mode |= TUNER_MODE_DIGITAL;
17430                         tuner_set_freq = channel->frequency;
17431                         break;
17432                 case DRX_STANDARD_UNKNOWN:
17433                 default:
17434                         return -EIO;
17435                 }               /* switch(standard) */
17436
17437                 tuner_mode |= TUNER_MODE_SWITCH;
17438                 switch (channel->bandwidth) {
17439                 case DRX_BANDWIDTH_8MHZ:
17440                         tuner_mode |= TUNER_MODE_8MHZ;
17441                         break;
17442                 case DRX_BANDWIDTH_7MHZ:
17443                         tuner_mode |= TUNER_MODE_7MHZ;
17444                         break;
17445                 case DRX_BANDWIDTH_6MHZ:
17446                         tuner_mode |= TUNER_MODE_6MHZ;
17447                         break;
17448                 default:
17449                         /* TODO: for FM which bandwidth to use ?
17450                            also check offset from centre frequency ?
17451                            For now using 6MHz.
17452                          */
17453                         tuner_mode |= TUNER_MODE_6MHZ;
17454                         break;
17455                         /* return (-EINVAL); */
17456                 }
17457
17458                 /* store bandwidth for GetChannel() */
17459                 ext_attr->curr_bandwidth = channel->bandwidth;
17460                 ext_attr->curr_symbol_rate = channel->symbolrate;
17461                 ext_attr->frequency = tuner_set_freq;
17462                 if (common_attr->tuner_port_nr == 1) {
17463                         /* close tuner bridge */
17464                         bridge_closed = true;
17465                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
17466                         if (rc != 0) {
17467                                 pr_err("error %d\n", rc);
17468                                 goto rw_error;
17469                         }
17470                         /* set tuner frequency */
17471                 }
17472
17473                 rc = drxbsp_tuner_set_frequency(demod->my_tuner, tuner_mode, tuner_set_freq);
17474                 if (rc != 0) {
17475                         pr_err("error %d\n", rc);
17476                         goto rw_error;
17477                 }
17478                 if (common_attr->tuner_port_nr == 1) {
17479                         /* open tuner bridge */
17480                         bridge_closed = false;
17481                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
17482                         if (rc != 0) {
17483                                 pr_err("error %d\n", rc);
17484                                 goto rw_error;
17485                         }
17486                 }
17487
17488                 /* Get actual frequency set by tuner and compute offset */
17489                 rc = drxbsp_tuner_get_frequency(demod->my_tuner, 0, &tuner_get_freq, &intermediate_freq);
17490                 if (rc != 0) {
17491                         pr_err("error %d\n", rc);
17492                         goto rw_error;
17493                 }
17494                 tuner_freq_offset = tuner_get_freq - tuner_set_freq;
17495                 common_attr->intermediate_freq = intermediate_freq;
17496         } else {
17497                 /* no tuner instance defined, use fixed intermediate frequency */
17498                 tuner_freq_offset = 0;
17499                 intermediate_freq = demod->my_common_attr->intermediate_freq;
17500         }                       /* if ( demod->my_tuner != NULL ) */
17501
17502    /*== Setup demod for specific standard ====================================*/
17503         switch (standard) {
17504         case DRX_STANDARD_8VSB:
17505                 if (channel->mirror == DRX_MIRROR_AUTO)
17506                         ext_attr->mirror = DRX_MIRROR_NO;
17507                 else
17508                         ext_attr->mirror = channel->mirror;
17509                 rc = set_vsb(demod);
17510                 if (rc != 0) {
17511                         pr_err("error %d\n", rc);
17512                         goto rw_error;
17513                 }
17514                 rc = set_frequency(demod, channel, tuner_freq_offset);
17515                 if (rc != 0) {
17516                         pr_err("error %d\n", rc);
17517                         goto rw_error;
17518                 }
17519                 break;
17520 #ifndef DRXJ_DIGITAL_ONLY
17521         case DRX_STANDARD_NTSC: /* fallthrough */
17522         case DRX_STANDARD_FM:   /* fallthrough */
17523         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
17524         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
17525         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
17526         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
17527         case DRX_STANDARD_PAL_SECAM_LP:
17528                 if (channel->mirror == DRX_MIRROR_AUTO)
17529                         ext_attr->mirror = DRX_MIRROR_NO;
17530                 else
17531                         ext_attr->mirror = channel->mirror;
17532                 rc = set_atv_channel(demod, tuner_freq_offset, channel, standard);
17533                 if (rc != 0) {
17534                         pr_err("error %d\n", rc);
17535                         goto rw_error;
17536                 }
17537                 break;
17538 #endif
17539 #ifndef DRXJ_VSB_ONLY
17540         case DRX_STANDARD_ITU_A:        /* fallthrough */
17541         case DRX_STANDARD_ITU_B:        /* fallthrough */
17542         case DRX_STANDARD_ITU_C:
17543                 rc = set_qam_channel(demod, channel, tuner_freq_offset);
17544                 if (rc != 0) {
17545                         pr_err("error %d\n", rc);
17546                         goto rw_error;
17547                 }
17548                 break;
17549 #endif
17550         case DRX_STANDARD_UNKNOWN:
17551         default:
17552                 return -EIO;
17553         }
17554
17555    /*== Re-tune, slow mode ===================================================*/
17556         if (demod->my_tuner != NULL) {
17557                 /* tune to slow mode */
17558                 tuner_mode &= ~TUNER_MODE_SWITCH;
17559                 tuner_mode |= TUNER_MODE_LOCK;
17560
17561                 if (common_attr->tuner_port_nr == 1) {
17562                         /* close tuner bridge */
17563                         bridge_closed = true;
17564                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
17565                         if (rc != 0) {
17566                                 pr_err("error %d\n", rc);
17567                                 goto rw_error;
17568                         }
17569                 }
17570
17571                 /* set tuner frequency */
17572                 rc = drxbsp_tuner_set_frequency(demod->my_tuner, tuner_mode, tuner_set_freq);
17573                 if (rc != 0) {
17574                         pr_err("error %d\n", rc);
17575                         goto rw_error;
17576                 }
17577                 if (common_attr->tuner_port_nr == 1) {
17578                         /* open tuner bridge */
17579                         bridge_closed = false;
17580                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
17581                         if (rc != 0) {
17582                                 pr_err("error %d\n", rc);
17583                                 goto rw_error;
17584                         }
17585                 }
17586         }
17587
17588         /* if ( demod->my_tuner !=NULL ) */
17589         /* flag the packet error counter reset */
17590         ext_attr->reset_pkt_err_acc = true;
17591
17592         return 0;
17593 rw_error:
17594         return -EIO;
17595 }
17596
17597 /*=============================================================================
17598   ===== ctrl_get_channel() ==========================================================
17599   ===========================================================================*/
17600 /**
17601 * \fn int ctrl_get_channel()
17602 * \brief Retreive parameters of current transmission channel.
17603 * \param demod   Pointer to demod instance.
17604 * \param channel Pointer to channel data.
17605 * \return int.
17606 */
17607 static int
17608 ctrl_get_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
17609 {
17610         struct i2c_device_addr *dev_addr = NULL;
17611         struct drxj_data *ext_attr = NULL;
17612         int rc;
17613         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17614         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17615         struct drx_common_attr *common_attr = NULL;
17616         s32 intermediate_freq = 0;
17617         s32 ctl_freq_offset = 0;
17618         u32 iqm_rc_rate_lo = 0;
17619         u32 adc_frequency = 0;
17620 #ifndef DRXJ_VSB_ONLY
17621         int bandwidth_temp = 0;
17622         int bandwidth = 0;
17623 #endif
17624
17625         /* check arguments */
17626         if ((demod == NULL) || (channel == NULL))
17627                 return -EINVAL;
17628
17629         dev_addr = demod->my_i2c_dev_addr;
17630         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17631         standard = ext_attr->standard;
17632         common_attr = (struct drx_common_attr *) demod->my_common_attr;
17633
17634         /* initialize channel fields */
17635         channel->mirror = DRX_MIRROR_UNKNOWN;
17636         channel->hierarchy = DRX_HIERARCHY_UNKNOWN;
17637         channel->priority = DRX_PRIORITY_UNKNOWN;
17638         channel->coderate = DRX_CODERATE_UNKNOWN;
17639         channel->guard = DRX_GUARD_UNKNOWN;
17640         channel->fftmode = DRX_FFTMODE_UNKNOWN;
17641         channel->classification = DRX_CLASSIFICATION_UNKNOWN;
17642         channel->bandwidth = DRX_BANDWIDTH_UNKNOWN;
17643         channel->constellation = DRX_CONSTELLATION_UNKNOWN;
17644         channel->symbolrate = 0;
17645         channel->interleavemode = DRX_INTERLEAVEMODE_UNKNOWN;
17646         channel->carrier = DRX_CARRIER_UNKNOWN;
17647         channel->framemode = DRX_FRAMEMODE_UNKNOWN;
17648 /*   channel->interleaver       = DRX_INTERLEAVER_UNKNOWN;*/
17649         channel->ldpc = DRX_LDPC_UNKNOWN;
17650
17651         if (demod->my_tuner != NULL) {
17652                 s32 tuner_freq_offset = 0;
17653                 bool tuner_mirror = common_attr->mirror_freq_spect ? false : true;
17654
17655                 /* Get frequency from tuner */
17656                 rc = drxbsp_tuner_get_frequency(demod->my_tuner, 0, &(channel->frequency), &intermediate_freq);
17657                 if (rc != 0) {
17658                         pr_err("error %d\n", rc);
17659                         goto rw_error;
17660                 }
17661                 tuner_freq_offset = channel->frequency - ext_attr->frequency;
17662                 if (tuner_mirror) {
17663                         /* positive image */
17664                         channel->frequency += tuner_freq_offset;
17665                 } else {
17666                         /* negative image */
17667                         channel->frequency -= tuner_freq_offset;
17668                 }
17669
17670                 /* Handle sound carrier offset in RF domain */
17671                 if (standard == DRX_STANDARD_FM)
17672                         channel->frequency -= DRXJ_FM_CARRIER_FREQ_OFFSET;
17673         } else {
17674                 intermediate_freq = common_attr->intermediate_freq;
17675         }
17676
17677         /* check lock status */
17678         rc = ctrl_lock_status(demod, &lock_status);
17679         if (rc != 0) {
17680                 pr_err("error %d\n", rc);
17681                 goto rw_error;
17682         }
17683         if ((lock_status == DRX_LOCKED) || (lock_status == DRXJ_DEMOD_LOCK)) {
17684                 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_RC_RATE_LO__A, &iqm_rc_rate_lo, 0);
17685                 if (rc != 0) {
17686                         pr_err("error %d\n", rc);
17687                         goto rw_error;
17688                 }
17689                 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
17690
17691                 channel->symbolrate =
17692                     frac28(adc_frequency, (iqm_rc_rate_lo + (1 << 23))) >> 7;
17693
17694                 switch (standard) {
17695                 case DRX_STANDARD_8VSB:
17696                         channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17697                         /* get the channel frequency */
17698                         rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17699                         if (rc != 0) {
17700                                 pr_err("error %d\n", rc);
17701                                 goto rw_error;
17702                         }
17703                         channel->frequency -= ctl_freq_offset;
17704                         /* get the channel constellation */
17705                         channel->constellation = DRX_CONSTELLATION_AUTO;
17706                         break;
17707 #ifndef DRXJ_VSB_ONLY
17708                 case DRX_STANDARD_ITU_A:
17709                 case DRX_STANDARD_ITU_B:
17710                 case DRX_STANDARD_ITU_C:
17711                         {
17712                                 /* get the channel frequency */
17713                                 rc = get_ctl_freq_offset(demod, &ctl_freq_offset);
17714                                 if (rc != 0) {
17715                                         pr_err("error %d\n", rc);
17716                                         goto rw_error;
17717                                 }
17718                                 channel->frequency -= ctl_freq_offset;
17719
17720                                 if (standard == DRX_STANDARD_ITU_B) {
17721                                         channel->bandwidth = DRX_BANDWIDTH_6MHZ;
17722                                 } else {
17723                                         /* annex A & C */
17724
17725                                         u32 roll_off = 113;     /* default annex C */
17726
17727                                         if (standard == DRX_STANDARD_ITU_A)
17728                                                 roll_off = 115;
17729
17730                                         bandwidth_temp =
17731                                             channel->symbolrate * roll_off;
17732                                         bandwidth = bandwidth_temp / 100;
17733
17734                                         if ((bandwidth_temp % 100) >= 50)
17735                                                 bandwidth++;
17736
17737                                         if (bandwidth <= 6000000) {
17738                                                 channel->bandwidth =
17739                                                     DRX_BANDWIDTH_6MHZ;
17740                                         } else if ((bandwidth > 6000000)
17741                                                    && (bandwidth <= 7000000)) {
17742                                                 channel->bandwidth =
17743                                                     DRX_BANDWIDTH_7MHZ;
17744                                         } else if (bandwidth > 7000000) {
17745                                                 channel->bandwidth =
17746                                                     DRX_BANDWIDTH_8MHZ;
17747                                         }
17748                                 }       /* if (standard == DRX_STANDARD_ITU_B) */
17749
17750                                 {
17751                                         struct drxjscu_cmd cmd_scu = { 0, 0, 0, NULL, NULL };
17752                                         u16 cmd_result[3] = { 0, 0, 0 };
17753
17754                                         cmd_scu.command =
17755                                             SCU_RAM_COMMAND_STANDARD_QAM |
17756                                             SCU_RAM_COMMAND_CMD_DEMOD_GET_PARAM;
17757                                         cmd_scu.parameter_len = 0;
17758                                         cmd_scu.result_len = 3;
17759                                         cmd_scu.parameter = NULL;
17760                                         cmd_scu.result = cmd_result;
17761                                         rc = scu_command(dev_addr, &cmd_scu);
17762                                         if (rc != 0) {
17763                                                 pr_err("error %d\n", rc);
17764                                                 goto rw_error;
17765                                         }
17766
17767                                         channel->interleavemode =
17768                                             (enum drx_interleave_mode) (cmd_scu.
17769                                                                     result[2]);
17770                                 }
17771
17772                                 switch (ext_attr->constellation) {
17773                                 case DRX_CONSTELLATION_QAM256:
17774                                         channel->constellation =
17775                                             DRX_CONSTELLATION_QAM256;
17776                                         break;
17777                                 case DRX_CONSTELLATION_QAM128:
17778                                         channel->constellation =
17779                                             DRX_CONSTELLATION_QAM128;
17780                                         break;
17781                                 case DRX_CONSTELLATION_QAM64:
17782                                         channel->constellation =
17783                                             DRX_CONSTELLATION_QAM64;
17784                                         break;
17785                                 case DRX_CONSTELLATION_QAM32:
17786                                         channel->constellation =
17787                                             DRX_CONSTELLATION_QAM32;
17788                                         break;
17789                                 case DRX_CONSTELLATION_QAM16:
17790                                         channel->constellation =
17791                                             DRX_CONSTELLATION_QAM16;
17792                                         break;
17793                                 default:
17794                                         channel->constellation =
17795                                             DRX_CONSTELLATION_UNKNOWN;
17796                                         return -EIO;
17797                                 }
17798                         }
17799                         break;
17800 #endif
17801 #ifndef DRXJ_DIGITAL_ONLY
17802                 case DRX_STANDARD_NTSC: /* fall trough */
17803                 case DRX_STANDARD_PAL_SECAM_BG:
17804                 case DRX_STANDARD_PAL_SECAM_DK:
17805                 case DRX_STANDARD_PAL_SECAM_I:
17806                 case DRX_STANDARD_PAL_SECAM_L:
17807                 case DRX_STANDARD_PAL_SECAM_LP:
17808                 case DRX_STANDARD_FM:
17809                         rc = get_atv_channel(demod, channel, standard);
17810                         if (rc != 0) {
17811                                 pr_err("error %d\n", rc);
17812                                 goto rw_error;
17813                         }
17814                         break;
17815 #endif
17816                 case DRX_STANDARD_UNKNOWN:      /* fall trough */
17817                 default:
17818                         return -EIO;
17819                 }               /* switch ( standard ) */
17820
17821                 if (lock_status == DRX_LOCKED)
17822                         channel->mirror = ext_attr->mirror;
17823         }
17824         /* if ( lock_status == DRX_LOCKED ) */
17825         return 0;
17826 rw_error:
17827         return -EIO;
17828 }
17829
17830 /*=============================================================================
17831   ===== SigQuality() ==========================================================
17832   ===========================================================================*/
17833
17834 static u16
17835 mer2indicator(u16 mer, u16 min_mer, u16 threshold_mer, u16 max_mer)
17836 {
17837         u16 indicator = 0;
17838
17839         if (mer < min_mer) {
17840                 indicator = 0;
17841         } else if (mer < threshold_mer) {
17842                 if ((threshold_mer - min_mer) != 0)
17843                         indicator = 25 * (mer - min_mer) / (threshold_mer - min_mer);
17844         } else if (mer < max_mer) {
17845                 if ((max_mer - threshold_mer) != 0)
17846                         indicator = 25 + 75 * (mer - threshold_mer) / (max_mer - threshold_mer);
17847                 else
17848                         indicator = 25;
17849         } else {
17850                 indicator = 100;
17851         }
17852
17853         return indicator;
17854 }
17855
17856 /**
17857 * \fn int ctrl_sig_quality()
17858 * \brief Retreive signal quality form device.
17859 * \param devmod Pointer to demodulator instance.
17860 * \param sig_quality Pointer to signal quality data.
17861 * \return int.
17862 * \retval 0 sig_quality contains valid data.
17863 * \retval -EINVAL sig_quality is NULL.
17864 * \retval -EIO Erroneous data, sig_quality contains invalid data.
17865
17866 */
17867 static int
17868 ctrl_sig_quality(struct drx_demod_instance *demod, struct drx_sig_quality *sig_quality)
17869 {
17870         struct i2c_device_addr *dev_addr = NULL;
17871         struct drxj_data *ext_attr = NULL;
17872         int rc;
17873         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
17874         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
17875         u16 min_mer = 0;
17876         u16 max_mer = 0;
17877         u16 threshold_mer = 0;
17878
17879         /* Check arguments */
17880         if ((sig_quality == NULL) || (demod == NULL))
17881                 return -EINVAL;
17882
17883         ext_attr = (struct drxj_data *) demod->my_ext_attr;
17884         standard = ext_attr->standard;
17885
17886         /* get basic information */
17887         dev_addr = demod->my_i2c_dev_addr;
17888         rc = ctrl_lock_status(demod, &lock_status);
17889         if (rc != 0) {
17890                 pr_err("error %d\n", rc);
17891                 goto rw_error;
17892         }
17893         switch (standard) {
17894         case DRX_STANDARD_8VSB:
17895 #ifdef DRXJ_SIGNAL_ACCUM_ERR
17896                 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
17897                 if (rc != 0) {
17898                         pr_err("error %d\n", rc);
17899                         goto rw_error;
17900                 }
17901 #else
17902                 rc = get_vsb_post_rs_pck_err(dev_addr, &sig_quality->packet_error);
17903                 if (rc != 0) {
17904                         pr_err("error %d\n", rc);
17905                         goto rw_error;
17906                 }
17907 #endif
17908                 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
17909                         sig_quality->post_viterbi_ber = 500000;
17910                         sig_quality->MER = 20;
17911                         sig_quality->pre_viterbi_ber = 0;
17912                 } else {
17913                         /* PostViterbi is compute in steps of 10^(-6) */
17914                         rc = get_vs_bpre_viterbi_ber(dev_addr, &sig_quality->pre_viterbi_ber);
17915                         if (rc != 0) {
17916                                 pr_err("error %d\n", rc);
17917                                 goto rw_error;
17918                         }
17919                         rc = get_vs_bpost_viterbi_ber(dev_addr, &sig_quality->post_viterbi_ber);
17920                         if (rc != 0) {
17921                                 pr_err("error %d\n", rc);
17922                                 goto rw_error;
17923                         }
17924                         rc = get_vsbmer(dev_addr, &sig_quality->MER);
17925                         if (rc != 0) {
17926                                 pr_err("error %d\n", rc);
17927                                 goto rw_error;
17928                         }
17929                 }
17930                 min_mer = 20;
17931                 max_mer = 360;
17932                 threshold_mer = 145;
17933                 sig_quality->post_reed_solomon_ber = 0;
17934                 sig_quality->scale_factor_ber = 1000000;
17935                 sig_quality->indicator =
17936                     mer2indicator(sig_quality->MER, min_mer, threshold_mer,
17937                                   max_mer);
17938                 break;
17939 #ifndef DRXJ_VSB_ONLY
17940         case DRX_STANDARD_ITU_A:
17941         case DRX_STANDARD_ITU_B:
17942         case DRX_STANDARD_ITU_C:
17943                 rc = ctrl_get_qam_sig_quality(demod, sig_quality);
17944                 if (rc != 0) {
17945                         pr_err("error %d\n", rc);
17946                         goto rw_error;
17947                 }
17948                 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
17949                         switch (ext_attr->constellation) {
17950                         case DRX_CONSTELLATION_QAM256:
17951                                 sig_quality->MER = 210;
17952                                 break;
17953                         case DRX_CONSTELLATION_QAM128:
17954                                 sig_quality->MER = 180;
17955                                 break;
17956                         case DRX_CONSTELLATION_QAM64:
17957                                 sig_quality->MER = 150;
17958                                 break;
17959                         case DRX_CONSTELLATION_QAM32:
17960                                 sig_quality->MER = 120;
17961                                 break;
17962                         case DRX_CONSTELLATION_QAM16:
17963                                 sig_quality->MER = 90;
17964                                 break;
17965                         default:
17966                                 sig_quality->MER = 0;
17967                                 return -EIO;
17968                         }
17969                 }
17970
17971                 switch (ext_attr->constellation) {
17972                 case DRX_CONSTELLATION_QAM256:
17973                         min_mer = 210;
17974                         threshold_mer = 270;
17975                         max_mer = 380;
17976                         break;
17977                 case DRX_CONSTELLATION_QAM64:
17978                         min_mer = 150;
17979                         threshold_mer = 210;
17980                         max_mer = 380;
17981                         break;
17982                 case DRX_CONSTELLATION_QAM128:
17983                 case DRX_CONSTELLATION_QAM32:
17984                 case DRX_CONSTELLATION_QAM16:
17985                         break;
17986                 default:
17987                         return -EIO;
17988                 }
17989                 sig_quality->indicator =
17990                     mer2indicator(sig_quality->MER, min_mer, threshold_mer,
17991                                   max_mer);
17992                 break;
17993 #endif
17994 #ifndef DRXJ_DIGITAL_ONLY
17995         case DRX_STANDARD_PAL_SECAM_BG:
17996         case DRX_STANDARD_PAL_SECAM_DK:
17997         case DRX_STANDARD_PAL_SECAM_I:
17998         case DRX_STANDARD_PAL_SECAM_L:
17999         case DRX_STANDARD_PAL_SECAM_LP:
18000         case DRX_STANDARD_NTSC:
18001                 rc = atv_sig_quality(demod, sig_quality);
18002                 if (rc != 0) {
18003                         pr_err("error %d\n", rc);
18004                         goto rw_error;
18005                 }
18006                 break;
18007         case DRX_STANDARD_FM:
18008                 rc = fm_sig_quality(demod, sig_quality);
18009                 if (rc != 0) {
18010                         pr_err("error %d\n", rc);
18011                         goto rw_error;
18012                 }
18013                 break;
18014 #endif
18015         default:
18016                 return -EIO;
18017         }
18018
18019         return 0;
18020 rw_error:
18021         return -EIO;
18022 }
18023
18024 /*============================================================================*/
18025
18026 /**
18027 * \fn int ctrl_lock_status()
18028 * \brief Retreive lock status .
18029 * \param dev_addr Pointer to demodulator device address.
18030 * \param lock_stat Pointer to lock status structure.
18031 * \return int.
18032 *
18033 */
18034 static int
18035 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
18036 {
18037         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18038         struct drxj_data *ext_attr = NULL;
18039         struct i2c_device_addr *dev_addr = NULL;
18040         struct drxjscu_cmd cmd_scu = { /* command      */ 0,
18041                 /* parameter_len */ 0,
18042                 /* result_len    */ 0,
18043                 /* *parameter   */ NULL,
18044                 /* *result      */ NULL
18045         };
18046         int rc;
18047         u16 cmd_result[2] = { 0, 0 };
18048         u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
18049
18050         /* check arguments */
18051         if ((demod == NULL) || (lock_stat == NULL))
18052                 return -EINVAL;
18053
18054         dev_addr = demod->my_i2c_dev_addr;
18055         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18056         standard = ext_attr->standard;
18057
18058         *lock_stat = DRX_NOT_LOCKED;
18059
18060         /* define the SCU command code */
18061         switch (standard) {
18062         case DRX_STANDARD_8VSB:
18063                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
18064                     SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18065                 demod_lock |= 0x6;
18066                 break;
18067 #ifndef DRXJ_VSB_ONLY
18068         case DRX_STANDARD_ITU_A:
18069         case DRX_STANDARD_ITU_B:
18070         case DRX_STANDARD_ITU_C:
18071                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
18072                     SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18073                 break;
18074 #endif
18075 #ifndef DRXJ_DIGITAL_ONLY
18076         case DRX_STANDARD_NTSC:
18077         case DRX_STANDARD_PAL_SECAM_BG:
18078         case DRX_STANDARD_PAL_SECAM_DK:
18079         case DRX_STANDARD_PAL_SECAM_I:
18080         case DRX_STANDARD_PAL_SECAM_L:
18081         case DRX_STANDARD_PAL_SECAM_LP:
18082                 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
18083                     SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
18084                 break;
18085         case DRX_STANDARD_FM:
18086                 return fm_lock_status(demod, lock_stat);
18087 #endif
18088         case DRX_STANDARD_UNKNOWN:      /* fallthrough */
18089         default:
18090                 return -EIO;
18091         }
18092
18093         /* define the SCU command paramters and execute the command */
18094         cmd_scu.parameter_len = 0;
18095         cmd_scu.result_len = 2;
18096         cmd_scu.parameter = NULL;
18097         cmd_scu.result = cmd_result;
18098         rc = scu_command(dev_addr, &cmd_scu);
18099         if (rc != 0) {
18100                 pr_err("error %d\n", rc);
18101                 goto rw_error;
18102         }
18103
18104         /* set the lock status */
18105         if (cmd_scu.result[1] < demod_lock) {
18106                 /* 0x0000 NOT LOCKED */
18107                 *lock_stat = DRX_NOT_LOCKED;
18108         } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
18109                 *lock_stat = DRXJ_DEMOD_LOCK;
18110         } else if (cmd_scu.result[1] <
18111                    SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
18112                 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
18113                 *lock_stat = DRX_LOCKED;
18114         } else {
18115                 /* 0xC000 NEVER LOCKED */
18116                 /* (system will never be able to lock to the signal) */
18117                 *lock_stat = DRX_NEVER_LOCK;
18118         }
18119
18120         return 0;
18121 rw_error:
18122         return -EIO;
18123 }
18124
18125 /*============================================================================*/
18126
18127 /**
18128 * \fn int ctrl_constel()
18129 * \brief Retreive a constellation point via I2C.
18130 * \param demod Pointer to demodulator instance.
18131 * \param complex_nr Pointer to the structure in which to store the
18132                    constellation point.
18133 * \return int.
18134 */
18135 static int
18136 ctrl_constel(struct drx_demod_instance *demod, struct drx_complex *complex_nr)
18137 {
18138         int rc;
18139         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18140                                                      /**< active standard */
18141
18142         /* check arguments */
18143         if ((demod == NULL) || (complex_nr == NULL))
18144                 return -EINVAL;
18145
18146         /* read device info */
18147         standard = ((struct drxj_data *) demod->my_ext_attr)->standard;
18148
18149         /* Read constellation point  */
18150         switch (standard) {
18151         case DRX_STANDARD_8VSB:
18152                 rc = ctrl_get_vsb_constel(demod, complex_nr);
18153                 if (rc != 0) {
18154                         pr_err("error %d\n", rc);
18155                         goto rw_error;
18156                 }
18157                 break;
18158 #ifndef DRXJ_VSB_ONLY
18159         case DRX_STANDARD_ITU_A:        /* fallthrough */
18160         case DRX_STANDARD_ITU_B:        /* fallthrough */
18161         case DRX_STANDARD_ITU_C:
18162                 rc = ctrl_get_qam_constel(demod, complex_nr);
18163                 if (rc != 0) {
18164                         pr_err("error %d\n", rc);
18165                         goto rw_error;
18166                 }
18167                 break;
18168 #endif
18169         case DRX_STANDARD_UNKNOWN:
18170         default:
18171                 return -EIO;
18172         }
18173
18174         return 0;
18175 rw_error:
18176         return -EIO;
18177 }
18178
18179 /*============================================================================*/
18180
18181 /**
18182 * \fn int ctrl_set_standard()
18183 * \brief Set modulation standard to be used.
18184 * \param standard Modulation standard.
18185 * \return int.
18186 *
18187 * Setup stuff for the desired demodulation standard.
18188 * Disable and power down the previous selected demodulation standard
18189 *
18190 */
18191 static int
18192 ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18193 {
18194         struct drxj_data *ext_attr = NULL;
18195         int rc;
18196         enum drx_standard prev_standard;
18197
18198         /* check arguments */
18199         if ((standard == NULL) || (demod == NULL))
18200                 return -EINVAL;
18201
18202         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18203         prev_standard = ext_attr->standard;
18204
18205         /*
18206            Stop and power down previous standard
18207          */
18208         switch (prev_standard) {
18209 #ifndef DRXJ_VSB_ONLY
18210         case DRX_STANDARD_ITU_A:        /* fallthrough */
18211         case DRX_STANDARD_ITU_B:        /* fallthrough */
18212         case DRX_STANDARD_ITU_C:
18213                 rc = power_down_qam(demod, false);
18214                 if (rc != 0) {
18215                         pr_err("error %d\n", rc);
18216                         goto rw_error;
18217                 }
18218                 break;
18219 #endif
18220         case DRX_STANDARD_8VSB:
18221                 rc = power_down_vsb(demod, false);
18222                 if (rc != 0) {
18223                         pr_err("error %d\n", rc);
18224                         goto rw_error;
18225                 }
18226                 break;
18227 #ifndef DRXJ_DIGITAL_ONLY
18228         case DRX_STANDARD_NTSC: /* fallthrough */
18229         case DRX_STANDARD_FM:   /* fallthrough */
18230         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18231         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18232         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
18233         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
18234         case DRX_STANDARD_PAL_SECAM_LP:
18235                 rc = power_down_atv(demod, prev_standard, false);
18236                 if (rc != 0) {
18237                         pr_err("error %d\n", rc);
18238                         goto rw_error;
18239                 }
18240                 break;
18241 #endif
18242         case DRX_STANDARD_UNKNOWN:
18243                 /* Do nothing */
18244                 break;
18245         case DRX_STANDARD_AUTO: /* fallthrough */
18246         default:
18247                 return -EINVAL;
18248         }
18249
18250         /*
18251            Initialize channel independent registers
18252            Power up new standard
18253          */
18254         ext_attr->standard = *standard;
18255
18256         switch (*standard) {
18257 #ifndef DRXJ_VSB_ONLY
18258         case DRX_STANDARD_ITU_A:        /* fallthrough */
18259         case DRX_STANDARD_ITU_B:        /* fallthrough */
18260         case DRX_STANDARD_ITU_C:
18261                 do {
18262                         u16 dummy;
18263                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18264                         if (rc != 0) {
18265                                 pr_err("error %d\n", rc);
18266                                 goto rw_error;
18267                         }
18268                 } while (0);
18269                 break;
18270 #endif
18271         case DRX_STANDARD_8VSB:
18272                 rc = set_vsb_leak_n_gain(demod);
18273                 if (rc != 0) {
18274                         pr_err("error %d\n", rc);
18275                         goto rw_error;
18276                 }
18277                 break;
18278 #ifndef DRXJ_DIGITAL_ONLY
18279         case DRX_STANDARD_NTSC: /* fallthrough */
18280         case DRX_STANDARD_FM:   /* fallthrough */
18281         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18282         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18283         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
18284         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
18285         case DRX_STANDARD_PAL_SECAM_LP:
18286                 rc = set_atv_standard(demod, standard);
18287                 if (rc != 0) {
18288                         pr_err("error %d\n", rc);
18289                         goto rw_error;
18290                 }
18291                 rc = power_up_atv(demod, *standard);
18292                 if (rc != 0) {
18293                         pr_err("error %d\n", rc);
18294                         goto rw_error;
18295                 }
18296                 break;
18297 #endif
18298         default:
18299                 ext_attr->standard = DRX_STANDARD_UNKNOWN;
18300                 return -EINVAL;
18301                 break;
18302         }
18303
18304         return 0;
18305 rw_error:
18306         /* Don't know what the standard is now ... try again */
18307         ext_attr->standard = DRX_STANDARD_UNKNOWN;
18308         return -EIO;
18309 }
18310
18311 /*============================================================================*/
18312
18313 /**
18314 * \fn int ctrl_get_standard()
18315 * \brief Get modulation standard currently used to demodulate.
18316 * \param standard Modulation standard.
18317 * \return int.
18318 *
18319 * Returns 8VSB, NTSC, QAM only.
18320 *
18321 */
18322 static int
18323 ctrl_get_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
18324 {
18325         struct drxj_data *ext_attr = NULL;
18326         int rc;
18327         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18328
18329         /* check arguments */
18330         if (standard == NULL)
18331                 return -EINVAL;
18332
18333         *standard = ext_attr->standard;
18334         do {
18335                 u16 dummy;
18336                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18337                 if (rc != 0) {
18338                         pr_err("error %d\n", rc);
18339                         goto rw_error;
18340                 }
18341         } while (0);
18342
18343         return 0;
18344 rw_error:
18345         return -EIO;
18346 }
18347
18348 /*============================================================================*/
18349
18350 /**
18351 * \fn int ctrl_get_cfg_symbol_clock_offset()
18352 * \brief Get frequency offsets of STR.
18353 * \param pointer to s32.
18354 * \return int.
18355 *
18356 */
18357 static int
18358 ctrl_get_cfg_symbol_clock_offset(struct drx_demod_instance *demod, s32 *rate_offset)
18359 {
18360         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
18361         int rc;
18362         struct drxj_data *ext_attr = NULL;
18363
18364         /* check arguments */
18365         if (rate_offset == NULL)
18366                 return -EINVAL;
18367
18368         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18369         standard = ext_attr->standard;
18370
18371         switch (standard) {
18372         case DRX_STANDARD_8VSB: /* fallthrough */
18373 #ifndef DRXJ_VSB_ONLY
18374         case DRX_STANDARD_ITU_A:        /* fallthrough */
18375         case DRX_STANDARD_ITU_B:        /* fallthrough */
18376         case DRX_STANDARD_ITU_C:
18377 #endif
18378                 rc = get_str_freq_offset(demod, rate_offset);
18379                 if (rc != 0) {
18380                         pr_err("error %d\n", rc);
18381                         goto rw_error;
18382                 }
18383                 break;
18384         case DRX_STANDARD_NTSC:
18385         case DRX_STANDARD_UNKNOWN:
18386         default:
18387                 return -EINVAL;
18388         }
18389
18390         return 0;
18391 rw_error:
18392         return -EIO;
18393 }
18394
18395 /*============================================================================*/
18396
18397 static void drxj_reset_mode(struct drxj_data *ext_attr)
18398 {
18399         /* Initialize default AFE configuartion for QAM */
18400         if (ext_attr->has_lna) {
18401                 /* IF AGC off, PGA active */
18402 #ifndef DRXJ_VSB_ONLY
18403                 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
18404                 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
18405                 ext_attr->qam_pga_cfg = 140 + (11 * 13);
18406 #endif
18407                 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
18408                 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
18409                 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
18410         } else {
18411                 /* IF AGC on, PGA not active */
18412 #ifndef DRXJ_VSB_ONLY
18413                 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
18414                 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18415                 ext_attr->qam_if_agc_cfg.min_output_level = 0;
18416                 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
18417                 ext_attr->qam_if_agc_cfg.speed = 3;
18418                 ext_attr->qam_if_agc_cfg.top = 1297;
18419                 ext_attr->qam_pga_cfg = 140;
18420 #endif
18421                 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
18422                 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18423                 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
18424                 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
18425                 ext_attr->vsb_if_agc_cfg.speed = 3;
18426                 ext_attr->vsb_if_agc_cfg.top = 1024;
18427                 ext_attr->vsb_pga_cfg = 140;
18428         }
18429         /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
18430         /* mc has not used them */
18431 #ifndef DRXJ_VSB_ONLY
18432         ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
18433         ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18434         ext_attr->qam_rf_agc_cfg.min_output_level = 0;
18435         ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
18436         ext_attr->qam_rf_agc_cfg.speed = 3;
18437         ext_attr->qam_rf_agc_cfg.top = 9500;
18438         ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
18439         ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
18440         ext_attr->qam_pre_saw_cfg.reference = 0x07;
18441         ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
18442 #endif
18443         /* Initialize default AFE configuartion for VSB */
18444         ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
18445         ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18446         ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
18447         ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
18448         ext_attr->vsb_rf_agc_cfg.speed = 3;
18449         ext_attr->vsb_rf_agc_cfg.top = 9500;
18450         ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
18451         ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
18452         ext_attr->vsb_pre_saw_cfg.reference = 0x07;
18453         ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
18454
18455 #ifndef DRXJ_DIGITAL_ONLY
18456         /* Initialize default AFE configuartion for ATV */
18457         ext_attr->atv_rf_agc_cfg.standard = DRX_STANDARD_NTSC;
18458         ext_attr->atv_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18459         ext_attr->atv_rf_agc_cfg.top = 9500;
18460         ext_attr->atv_rf_agc_cfg.cut_off_current = 4000;
18461         ext_attr->atv_rf_agc_cfg.speed = 3;
18462         ext_attr->atv_if_agc_cfg.standard = DRX_STANDARD_NTSC;
18463         ext_attr->atv_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
18464         ext_attr->atv_if_agc_cfg.speed = 3;
18465         ext_attr->atv_if_agc_cfg.top = 2400;
18466         ext_attr->atv_pre_saw_cfg.reference = 0x0007;
18467         ext_attr->atv_pre_saw_cfg.use_pre_saw = true;
18468         ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
18469 #endif
18470 }
18471
18472 /**
18473 * \fn int ctrl_power_mode()
18474 * \brief Set the power mode of the device to the specified power mode
18475 * \param demod Pointer to demodulator instance.
18476 * \param mode  Pointer to new power mode.
18477 * \return int.
18478 * \retval 0          Success
18479 * \retval -EIO       I2C error or other failure
18480 * \retval -EINVAL Invalid mode argument.
18481 *
18482 *
18483 */
18484 static int
18485 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
18486 {
18487         struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
18488         struct drxj_data *ext_attr = (struct drxj_data *) NULL;
18489         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
18490         int rc;
18491         u16 sio_cc_pwd_mode = 0;
18492
18493         common_attr = (struct drx_common_attr *) demod->my_common_attr;
18494         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18495         dev_addr = demod->my_i2c_dev_addr;
18496
18497         /* Check arguments */
18498         if (mode == NULL)
18499                 return -EINVAL;
18500
18501         /* If already in requested power mode, do nothing */
18502         if (common_attr->current_power_mode == *mode)
18503                 return 0;
18504
18505         switch (*mode) {
18506         case DRX_POWER_UP:
18507         case DRXJ_POWER_DOWN_MAIN_PATH:
18508                 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
18509                 break;
18510         case DRXJ_POWER_DOWN_CORE:
18511                 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
18512                 break;
18513         case DRXJ_POWER_DOWN_PLL:
18514                 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
18515                 break;
18516         case DRX_POWER_DOWN:
18517                 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
18518                 break;
18519         default:
18520                 /* Unknow sleep mode */
18521                 return -EINVAL;
18522                 break;
18523         }
18524
18525         /* Check if device needs to be powered up */
18526         if ((common_attr->current_power_mode != DRX_POWER_UP)) {
18527                 rc = power_up_device(demod);
18528                 if (rc != 0) {
18529                         pr_err("error %d\n", rc);
18530                         goto rw_error;
18531                 }
18532         }
18533
18534         if ((*mode == DRX_POWER_UP)) {
18535                 /* Restore analog & pin configuartion */
18536
18537                 /* Initialize default AFE configuartion for VSB */
18538                 drxj_reset_mode(ext_attr);
18539         } else {
18540                 /* Power down to requested mode */
18541                 /* Backup some register settings */
18542                 /* Set pins with possible pull-ups connected to them in input mode */
18543                 /* Analog power down */
18544                 /* ADC power down */
18545                 /* Power down device */
18546                 /* stop all comm_exec */
18547                 /*
18548                    Stop and power down previous standard
18549                  */
18550
18551                 switch (ext_attr->standard) {
18552                 case DRX_STANDARD_ITU_A:
18553                 case DRX_STANDARD_ITU_B:
18554                 case DRX_STANDARD_ITU_C:
18555                         rc = power_down_qam(demod, true);
18556                         if (rc != 0) {
18557                                 pr_err("error %d\n", rc);
18558                                 goto rw_error;
18559                         }
18560                         break;
18561                 case DRX_STANDARD_8VSB:
18562                         rc = power_down_vsb(demod, true);
18563                         if (rc != 0) {
18564                                 pr_err("error %d\n", rc);
18565                                 goto rw_error;
18566                         }
18567                         break;
18568                 case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
18569                 case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
18570                 case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
18571                 case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
18572                 case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
18573                 case DRX_STANDARD_NTSC: /* fallthrough */
18574                 case DRX_STANDARD_FM:
18575                         rc = power_down_atv(demod, ext_attr->standard, true);
18576                         if (rc != 0) {
18577                                 pr_err("error %d\n", rc);
18578                                 goto rw_error;
18579                         }
18580                         break;
18581                 case DRX_STANDARD_UNKNOWN:
18582                         /* Do nothing */
18583                         break;
18584                 case DRX_STANDARD_AUTO: /* fallthrough */
18585                 default:
18586                         return -EIO;
18587                 }
18588
18589                 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
18590                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
18591                         if (rc != 0) {
18592                                 pr_err("error %d\n", rc);
18593                                 goto rw_error;
18594                         }
18595                         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
18596                         if (rc != 0) {
18597                                 pr_err("error %d\n", rc);
18598                                 goto rw_error;
18599                         }
18600
18601                         /* Initialize HI, wakeup key especially before put IC to sleep */
18602                         rc = init_hi(demod);
18603                         if (rc != 0) {
18604                                 pr_err("error %d\n", rc);
18605                                 goto rw_error;
18606                         }
18607
18608                         ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
18609                         rc = hi_cfg_command(demod);
18610                         if (rc != 0) {
18611                                 pr_err("error %d\n", rc);
18612                                 goto rw_error;
18613                         }
18614                 }
18615         }
18616
18617         common_attr->current_power_mode = *mode;
18618
18619         return 0;
18620 rw_error:
18621         return -EIO;
18622 }
18623
18624 /*============================================================================*/
18625
18626 /**
18627 * \fn int ctrl_version()
18628 * \brief Report version of microcode and if possible version of device
18629 * \param demod Pointer to demodulator instance.
18630 * \param version_list Pointer to pointer of linked list of versions.
18631 * \return int.
18632 *
18633 * Using static structures so no allocation of memory is needed.
18634 * Filling in all the fields each time, cause you don't know if they are
18635 * changed by the application.
18636 *
18637 * For device:
18638 * Major version number will be last two digits of family number.
18639 * Minor number will be full respin number
18640 * Patch will be metal fix number+1
18641 * Examples:
18642 * DRX3942J A2 => number: 42.1.2 text: "DRX3942J:A2"
18643 * DRX3933J B1 => number: 33.2.1 text: "DRX3933J:B1"
18644 *
18645 */
18646 static int
18647 ctrl_version(struct drx_demod_instance *demod, struct drx_version_list **version_list)
18648 {
18649         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
18650         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
18651         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18652         int rc;
18653         u16 ucode_major_minor = 0;      /* BCD Ma:Ma:Ma:Mi */
18654         u16 ucode_patch = 0;    /* BCD Pa:Pa:Pa:Pa */
18655         u16 major = 0;
18656         u16 minor = 0;
18657         u16 patch = 0;
18658         u16 idx = 0;
18659         u32 jtag = 0;
18660         u16 subtype = 0;
18661         u16 mfx = 0;
18662         u16 bid = 0;
18663         u16 key = 0;
18664         static char ucode_name[] = "Microcode";
18665         static char device_name[] = "Device";
18666
18667         dev_addr = demod->my_i2c_dev_addr;
18668         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18669         common_attr = (struct drx_common_attr *) demod->my_common_attr;
18670
18671         /* Microcode version *************************************** */
18672
18673         ext_attr->v_version[0].module_type = DRX_MODULE_MICROCODE;
18674         ext_attr->v_version[0].module_name = ucode_name;
18675         ext_attr->v_version[0].v_string = ext_attr->v_text[0];
18676
18677         if (common_attr->is_opened == true) {
18678                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_VERSION_HI__A, &ucode_major_minor, 0);
18679                 if (rc != 0) {
18680                         pr_err("error %d\n", rc);
18681                         goto rw_error;
18682                 }
18683                 rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_VERSION_LO__A, &ucode_patch, 0);
18684                 if (rc != 0) {
18685                         pr_err("error %d\n", rc);
18686                         goto rw_error;
18687                 }
18688
18689                 /* Translate BCD to numbers and string */
18690                 /* TODO: The most significant Ma and Pa will be ignored, check with spec */
18691                 minor = (ucode_major_minor & 0xF);
18692                 ucode_major_minor >>= 4;
18693                 major = (ucode_major_minor & 0xF);
18694                 ucode_major_minor >>= 4;
18695                 major += (10 * (ucode_major_minor & 0xF));
18696                 patch = (ucode_patch & 0xF);
18697                 ucode_patch >>= 4;
18698                 patch += (10 * (ucode_patch & 0xF));
18699                 ucode_patch >>= 4;
18700                 patch += (100 * (ucode_patch & 0xF));
18701         } else {
18702                 /* No microcode uploaded, No Rom existed, set version to 0.0.0 */
18703                 patch = 0;
18704                 minor = 0;
18705                 major = 0;
18706         }
18707         ext_attr->v_version[0].v_major = major;
18708         ext_attr->v_version[0].v_minor = minor;
18709         ext_attr->v_version[0].v_patch = patch;
18710
18711         if (major / 10 != 0) {
18712                 ext_attr->v_version[0].v_string[idx++] =
18713                     ((char)(major / 10)) + '0';
18714                 major %= 10;
18715         }
18716         ext_attr->v_version[0].v_string[idx++] = ((char)major) + '0';
18717         ext_attr->v_version[0].v_string[idx++] = '.';
18718         ext_attr->v_version[0].v_string[idx++] = ((char)minor) + '0';
18719         ext_attr->v_version[0].v_string[idx++] = '.';
18720         if (patch / 100 != 0) {
18721                 ext_attr->v_version[0].v_string[idx++] =
18722                     ((char)(patch / 100)) + '0';
18723                 patch %= 100;
18724         }
18725         if (patch / 10 != 0) {
18726                 ext_attr->v_version[0].v_string[idx++] =
18727                     ((char)(patch / 10)) + '0';
18728                 patch %= 10;
18729         }
18730         ext_attr->v_version[0].v_string[idx++] = ((char)patch) + '0';
18731         ext_attr->v_version[0].v_string[idx] = '\0';
18732
18733         ext_attr->v_list_elements[0].version = &(ext_attr->v_version[0]);
18734         ext_attr->v_list_elements[0].next = &(ext_attr->v_list_elements[1]);
18735
18736         /* Device version *************************************** */
18737         /* Check device id */
18738         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, &key, 0);
18739         if (rc != 0) {
18740                 pr_err("error %d\n", rc);
18741                 goto rw_error;
18742         }
18743         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
18744         if (rc != 0) {
18745                 pr_err("error %d\n", rc);
18746                 goto rw_error;
18747         }
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         rc = DRXJ_DAP.read_reg16func(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
18754         if (rc != 0) {
18755                 pr_err("error %d\n", rc);
18756                 goto rw_error;
18757         }
18758         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_TOP_COMM_KEY__A, key, 0);
18759         if (rc != 0) {
18760                 pr_err("error %d\n", rc);
18761                 goto rw_error;
18762         }
18763
18764         ext_attr->v_version[1].module_type = DRX_MODULE_DEVICE;
18765         ext_attr->v_version[1].module_name = device_name;
18766         ext_attr->v_version[1].v_string = ext_attr->v_text[1];
18767         ext_attr->v_version[1].v_string[0] = 'D';
18768         ext_attr->v_version[1].v_string[1] = 'R';
18769         ext_attr->v_version[1].v_string[2] = 'X';
18770         ext_attr->v_version[1].v_string[3] = '3';
18771         ext_attr->v_version[1].v_string[4] = '9';
18772         ext_attr->v_version[1].v_string[7] = 'J';
18773         ext_attr->v_version[1].v_string[8] = ':';
18774         ext_attr->v_version[1].v_string[11] = '\0';
18775
18776         /* DRX39xxJ type Ax */
18777         /* TODO semantics of mfx and spin are unclear */
18778         subtype = (u16) ((jtag >> 12) & 0xFF);
18779         mfx = (u16) (jtag >> 29);
18780         ext_attr->v_version[1].v_minor = 1;
18781         if (mfx == 0x03)
18782                 ext_attr->v_version[1].v_patch = mfx + 2;
18783         else
18784                 ext_attr->v_version[1].v_patch = mfx + 1;
18785         ext_attr->v_version[1].v_string[6] = ((char)(subtype & 0xF)) + '0';
18786         ext_attr->v_version[1].v_major = (subtype & 0x0F);
18787         subtype >>= 4;
18788         ext_attr->v_version[1].v_string[5] = ((char)(subtype & 0xF)) + '0';
18789         ext_attr->v_version[1].v_major += 10 * subtype;
18790         ext_attr->v_version[1].v_string[9] = 'A';
18791         if (mfx == 0x03)
18792                 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '2';
18793         else
18794                 ext_attr->v_version[1].v_string[10] = ((char)(mfx & 0xF)) + '1';
18795
18796         ext_attr->v_list_elements[1].version = &(ext_attr->v_version[1]);
18797         ext_attr->v_list_elements[1].next = (struct drx_version_list *) (NULL);
18798
18799         *version_list = &(ext_attr->v_list_elements[0]);
18800
18801         return 0;
18802
18803 rw_error:
18804         *version_list = (struct drx_version_list *) (NULL);
18805         return -EIO;
18806
18807 }
18808
18809 /*============================================================================*/
18810
18811 /**
18812 * \fn int ctrl_probe_device()
18813 * \brief Probe device, check if it is present
18814 * \param demod Pointer to demodulator instance.
18815 * \return int.
18816 * \retval 0    a drx39xxj device has been detected.
18817 * \retval -EIO no drx39xxj device detected.
18818 *
18819 * This funtion can be caled before open() and after close().
18820 *
18821 */
18822
18823 static int ctrl_probe_device(struct drx_demod_instance *demod)
18824 {
18825         enum drx_power_mode org_power_mode = DRX_POWER_UP;
18826         int ret_status = 0;
18827         struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
18828         int rc;
18829
18830         common_attr = (struct drx_common_attr *) demod->my_common_attr;
18831
18832         if (common_attr->is_opened == false
18833             || common_attr->current_power_mode != DRX_POWER_UP) {
18834                 struct i2c_device_addr *dev_addr = NULL;
18835                 enum drx_power_mode power_mode = DRX_POWER_UP;
18836                 u32 jtag = 0;
18837
18838                 dev_addr = demod->my_i2c_dev_addr;
18839
18840                 /* Remeber original power mode */
18841                 org_power_mode = common_attr->current_power_mode;
18842
18843                 if (demod->my_common_attr->is_opened == false) {
18844                         rc = power_up_device(demod);
18845                         if (rc != 0) {
18846                                 pr_err("error %d\n", rc);
18847                                 goto rw_error;
18848                         }
18849                         common_attr->current_power_mode = DRX_POWER_UP;
18850                 } else {
18851                         /* Wake-up device, feedback from device */
18852                         rc = ctrl_power_mode(demod, &power_mode);
18853                         if (rc != 0) {
18854                                 pr_err("error %d\n", rc);
18855                                 goto rw_error;
18856                         }
18857                 }
18858                 /* Initialize HI, wakeup key especially */
18859                 rc = init_hi(demod);
18860                 if (rc != 0) {
18861                         pr_err("error %d\n", rc);
18862                         goto rw_error;
18863                 }
18864
18865                 /* Check device id */
18866                 rc = DRXJ_DAP.read_reg32func(dev_addr, SIO_TOP_JTAGID_LO__A, &jtag, 0);
18867                 if (rc != 0) {
18868                         pr_err("error %d\n", rc);
18869                         goto rw_error;
18870                 }
18871                 jtag = (jtag >> 12) & 0xFFFF;
18872                 switch (jtag) {
18873                 case 0x3931:    /* fallthrough */
18874                 case 0x3932:    /* fallthrough */
18875                 case 0x3933:    /* fallthrough */
18876                 case 0x3934:    /* fallthrough */
18877                 case 0x3941:    /* fallthrough */
18878                 case 0x3942:    /* fallthrough */
18879                 case 0x3943:    /* fallthrough */
18880                 case 0x3944:    /* fallthrough */
18881                 case 0x3945:    /* fallthrough */
18882                 case 0x3946:
18883                         /* ok , do nothing */
18884                         break;
18885                 default:
18886                         ret_status = -EIO;
18887                         break;
18888                 }
18889
18890                 /* Device was not opened, return to orginal powermode,
18891                    feedback from device */
18892                 rc = ctrl_power_mode(demod, &org_power_mode);
18893                 if (rc != 0) {
18894                         pr_err("error %d\n", rc);
18895                         goto rw_error;
18896                 }
18897         } else {
18898                 /* dummy read to make this function fail in case device
18899                    suddenly disappears after a succesful drx_open */
18900                 do {
18901                         u16 dummy;
18902                         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
18903                         if (rc != 0) {
18904                                 pr_err("error %d\n", rc);
18905                                 goto rw_error;
18906                         }
18907                 } while (0);
18908         }
18909
18910         return ret_status;
18911
18912 rw_error:
18913         common_attr->current_power_mode = org_power_mode;
18914         return -EIO;
18915 }
18916
18917 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
18918 /*============================================================================*/
18919
18920 /**
18921 * \fn int is_mc_block_audio()
18922 * \brief Check if MC block is Audio or not Audio.
18923 * \param addr        Pointer to demodulator instance.
18924 * \param audioUpload true  if MC block is Audio
18925                      false if MC block not Audio
18926 * \return bool.
18927 */
18928 bool is_mc_block_audio(u32 addr)
18929 {
18930         if ((addr == AUD_XFP_PRAM_4K__A) || (addr == AUD_XDFP_PRAM_4K__A))
18931                 return true;
18932
18933         return false;
18934 }
18935
18936 /*============================================================================*/
18937
18938 /**
18939 * \fn int ctrl_u_code_upload()
18940 * \brief Handle Audio or !Audio part of microcode upload.
18941 * \param demod          Pointer to demodulator instance.
18942 * \param mc_info         Pointer to information about microcode data.
18943 * \param action         Either UCODE_UPLOAD or UCODE_VERIFY.
18944 * \param upload_audio_mc  true  if Audio MC need to be uploaded.
18945                         false if !Audio MC need to be uploaded.
18946 * \return int.
18947 */
18948 static int
18949 ctrl_u_code_upload(struct drx_demod_instance *demod,
18950                    struct drxu_code_info *mc_info,
18951                    enum drxu_code_actionaction, bool upload_audio_mc)
18952 {
18953         u16 i = 0;
18954         u16 mc_nr_of_blks = 0;
18955         u16 mc_magic_word = 0;
18956         u8 *mc_data = (u8 *)(NULL);
18957         struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
18958         struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
18959         int rc;
18960
18961         dev_addr = demod->my_i2c_dev_addr;
18962         ext_attr = (struct drxj_data *) demod->my_ext_attr;
18963
18964         /* Check arguments */
18965         if (!mc_info || !mc_info->mc_data) {
18966                 return -EINVAL;
18967         }
18968
18969         mc_data = mc_info->mc_data;
18970
18971         /* Check data */
18972         mc_magic_word = u_code_read16(mc_data);
18973         mc_data += sizeof(u16);
18974         mc_nr_of_blks = u_code_read16(mc_data);
18975         mc_data += sizeof(u16);
18976
18977         if ((mc_magic_word != DRXJ_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
18978                 /* wrong endianess or wrong data ? */
18979                 return -EINVAL;
18980         }
18981
18982         /* Process microcode blocks */
18983         for (i = 0; i < mc_nr_of_blks; i++) {
18984                 struct drxu_code_block_hdr block_hdr;
18985                 u16 mc_block_nr_bytes = 0;
18986
18987                 /* Process block header */
18988                 block_hdr.addr = u_code_read32(mc_data);
18989                 mc_data += sizeof(u32);
18990                 block_hdr.size = u_code_read16(mc_data);
18991                 mc_data += sizeof(u16);
18992                 block_hdr.flags = u_code_read16(mc_data);
18993                 mc_data += sizeof(u16);
18994                 block_hdr.CRC = u_code_read16(mc_data);
18995                 mc_data += sizeof(u16);
18996
18997                 /* Check block header on:
18998                    - no data
18999                    - data larger then 64Kb
19000                    - if CRC enabled check CRC
19001                  */
19002                 if ((block_hdr.size == 0) ||
19003                     (block_hdr.size > 0x7FFF) ||
19004                     (((block_hdr.flags & DRXJ_UCODE_CRC_FLAG) != 0) &&
19005                      (block_hdr.CRC != u_code_compute_crc(mc_data, block_hdr.size)))
19006                     ) {
19007                         /* Wrong data ! */
19008                         return -EINVAL;
19009                 }
19010
19011                 mc_block_nr_bytes = block_hdr.size * sizeof(u16);
19012
19013                 /* Perform the desired action */
19014                 /* Check which part of MC need to be uploaded - Audio or not Audio */
19015                 if (is_mc_block_audio(block_hdr.addr) == upload_audio_mc) {
19016                         switch (action) {
19017             /*===================================================================*/
19018                         case UCODE_UPLOAD:
19019                                 {
19020                                         /* Upload microcode */
19021                                         if (demod->my_access_funct->
19022                                             write_block_func(dev_addr,
19023                                                            (dr_xaddr_t) block_hdr.
19024                                                            addr, mc_block_nr_bytes,
19025                                                            mc_data,
19026                                                            0x0000) !=
19027                                             0) {
19028                                                 return -EIO;
19029                                         }
19030                                 }
19031                                 break;
19032
19033             /*===================================================================*/
19034                         case UCODE_VERIFY:
19035                                 {
19036                                         int result = 0;
19037                                         u8 mc_data_buffer
19038                                             [DRXJ_UCODE_MAX_BUF_SIZE];
19039                                         u32 bytes_to_compare = 0;
19040                                         u32 bytes_left_to_compare = 0;
19041                                         u32 curr_addr = (dr_xaddr_t) 0;
19042                                         u8 *curr_ptr = NULL;
19043
19044                                         bytes_left_to_compare = mc_block_nr_bytes;
19045                                         curr_addr = block_hdr.addr;
19046                                         curr_ptr = mc_data;
19047
19048                                         while (bytes_left_to_compare != 0) {
19049                                                 if (bytes_left_to_compare > ((u32)DRXJ_UCODE_MAX_BUF_SIZE))
19050                                                         bytes_to_compare = ((u32)DRXJ_UCODE_MAX_BUF_SIZE);
19051                                                 else
19052                                                         bytes_to_compare = bytes_left_to_compare;
19053
19054                                                 if (demod->my_access_funct->
19055                                                     read_block_func(dev_addr,
19056                                                                   curr_addr,
19057                                                                   (u16)
19058                                                                   bytes_to_compare,
19059                                                                   (u8 *)
19060                                                                   mc_data_buffer,
19061                                                                   0x0000) !=
19062                                                     0) {
19063                                                         return -EIO;
19064                                                 }
19065
19066                                                 result =
19067                                                     drxbsp_hst_memcmp(curr_ptr,
19068                                                                       mc_data_buffer,
19069                                                                       bytes_to_compare);
19070
19071                                                 if (result != 0)
19072                                                         return -EIO;
19073
19074                                                 curr_addr +=
19075                                                     ((dr_xaddr_t)
19076                                                      (bytes_to_compare / 2));
19077                                                 curr_ptr =
19078                                                     &(curr_ptr[bytes_to_compare]);
19079                                                 bytes_left_to_compare -=
19080                                                     ((u32) bytes_to_compare);
19081                                         }       /* while( bytes_to_compare > DRXJ_UCODE_MAX_BUF_SIZE ) */
19082                                 }
19083                                 break;
19084
19085             /*===================================================================*/
19086                         default:
19087                                 return -EINVAL;
19088                                 break;
19089
19090                         }       /* switch ( action ) */
19091                 }
19092
19093                 /* if( is_mc_block_audio( block_hdr.addr ) == upload_audio_mc ) */
19094                 /* Next block */
19095                 mc_data += mc_block_nr_bytes;
19096         }                       /* for( i = 0 ; i<mc_nr_of_blks ; i++ ) */
19097
19098         if (!upload_audio_mc)
19099                 ext_attr->flag_aud_mc_uploaded = false;
19100
19101         return 0;
19102 }
19103 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
19104
19105 /*============================================================================*/
19106 /*== CTRL Set/Get Config related functions ===================================*/
19107 /*============================================================================*/
19108
19109 /*===== SigStrength() =========================================================*/
19110 /**
19111 * \fn int ctrl_sig_strength()
19112 * \brief Retrieve signal strength.
19113 * \param devmod Pointer to demodulator instance.
19114 * \param sig_quality Pointer to signal strength data; range 0, .. , 100.
19115 * \return int.
19116 * \retval 0 sig_strength contains valid data.
19117 * \retval -EINVAL sig_strength is NULL.
19118 * \retval -EIO Erroneous data, sig_strength contains invalid data.
19119
19120 */
19121 static int
19122 ctrl_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
19123 {
19124         struct drxj_data *ext_attr = NULL;
19125         enum drx_standard standard = DRX_STANDARD_UNKNOWN;
19126         int rc;
19127
19128         /* Check arguments */
19129         if ((sig_strength == NULL) || (demod == NULL))
19130                 return -EINVAL;
19131
19132         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19133         standard = ext_attr->standard;
19134         *sig_strength = 0;
19135
19136         /* Signal strength indication for each standard */
19137         switch (standard) {
19138         case DRX_STANDARD_8VSB: /* fallthrough */
19139 #ifndef DRXJ_VSB_ONLY
19140         case DRX_STANDARD_ITU_A:        /* fallthrough */
19141         case DRX_STANDARD_ITU_B:        /* fallthrough */
19142         case DRX_STANDARD_ITU_C:
19143 #endif
19144                 rc = get_sig_strength(demod, sig_strength);
19145                 if (rc != 0) {
19146                         pr_err("error %d\n", rc);
19147                         goto rw_error;
19148                 }
19149                 break;
19150 #ifndef DRXJ_DIGITAL_ONLY
19151         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19152         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19153         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19154         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19155         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19156         case DRX_STANDARD_NTSC: /* fallthrough */
19157         case DRX_STANDARD_FM:
19158                 rc = get_atv_sig_strength(demod, sig_strength);
19159                 if (rc != 0) {
19160                         pr_err("error %d\n", rc);
19161                         goto rw_error;
19162                 }
19163                 break;
19164 #endif
19165         case DRX_STANDARD_UNKNOWN:      /* fallthrough */
19166         default:
19167                 return -EINVAL;
19168         }
19169
19170         /* TODO */
19171         /* find out if signal strength is calculated in the same way for all standards */
19172         return 0;
19173 rw_error:
19174         return -EIO;
19175 }
19176
19177 /*============================================================================*/
19178 /**
19179 * \fn int ctrl_get_cfg_oob_misc()
19180 * \brief Get current state information of OOB.
19181 * \param pointer to struct drxj_cfg_oob_misc.
19182 * \return int.
19183 *
19184 */
19185 #ifndef DRXJ_DIGITAL_ONLY
19186 static int
19187 ctrl_get_cfg_oob_misc(struct drx_demod_instance *demod, struct drxj_cfg_oob_misc *misc)
19188 {
19189         struct i2c_device_addr *dev_addr = NULL;
19190         int rc;
19191         u16 lock = 0U;
19192         u16 state = 0U;
19193         u16 data = 0U;
19194         u16 digital_agc_mant = 0U;
19195         u16 digital_agc_exp = 0U;
19196
19197         /* check arguments */
19198         if (misc == NULL)
19199                 return -EINVAL;
19200
19201         dev_addr = demod->my_i2c_dev_addr;
19202
19203         /* TODO */
19204         /* check if the same registers are used for all standards (QAM/VSB/ATV) */
19205         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_IFGAIN_W__A, &misc->agc.IFAGC, 0);
19206         if (rc != 0) {
19207                 pr_err("error %d\n", rc);
19208                 goto rw_error;
19209         }
19210         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_NSU_TUN_RFGAIN_W__A, &misc->agc.RFAGC, 0);
19211         if (rc != 0) {
19212                 pr_err("error %d\n", rc);
19213                 goto rw_error;
19214         }
19215         rc = DRXJ_DAP.read_reg16func(dev_addr, ORX_FWP_SRC_DGN_W__A, &data, 0);
19216         if (rc != 0) {
19217                 pr_err("error %d\n", rc);
19218                 goto rw_error;
19219         }
19220
19221         digital_agc_mant = data & ORX_FWP_SRC_DGN_W_MANT__M;
19222         digital_agc_exp = (data & ORX_FWP_SRC_DGN_W_EXP__M)
19223             >> ORX_FWP_SRC_DGN_W_EXP__B;
19224         misc->agc.digital_agc = digital_agc_mant << digital_agc_exp;
19225
19226         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_LOCK__A, &lock, 0);
19227         if (rc != 0) {
19228                 pr_err("error %d\n", rc);
19229                 goto rw_error;
19230         }
19231
19232         misc->ana_gain_lock = ((lock & 0x0001) ? true : false);
19233         misc->dig_gain_lock = ((lock & 0x0002) ? true : false);
19234         misc->freq_lock = ((lock & 0x0004) ? true : false);
19235         misc->phase_lock = ((lock & 0x0008) ? true : false);
19236         misc->sym_timing_lock = ((lock & 0x0010) ? true : false);
19237         misc->eq_lock = ((lock & 0x0020) ? true : false);
19238
19239         rc = drxj_dap_scu_atomic_read_reg16(dev_addr, SCU_RAM_ORX_SCU_STATE__A, &state, 0);
19240         if (rc != 0) {
19241                 pr_err("error %d\n", rc);
19242                 goto rw_error;
19243         }
19244         misc->state = (state >> 8) & 0xff;
19245
19246         return 0;
19247 rw_error:
19248         return -EIO;
19249 }
19250 #endif
19251
19252 /**
19253 * \fn int ctrl_get_cfg_vsb_misc()
19254 * \brief Get current state information of OOB.
19255 * \param pointer to struct drxj_cfg_oob_misc.
19256 * \return int.
19257 *
19258 */
19259 static int
19260 ctrl_get_cfg_vsb_misc(struct drx_demod_instance *demod, struct drxj_cfg_vsb_misc *misc)
19261 {
19262         struct i2c_device_addr *dev_addr = NULL;
19263         int rc;
19264
19265         /* check arguments */
19266         if (misc == NULL)
19267                 return -EINVAL;
19268
19269         dev_addr = demod->my_i2c_dev_addr;
19270
19271         rc = get_vsb_symb_err(dev_addr, &misc->symb_error);
19272         if (rc != 0) {
19273                 pr_err("error %d\n", rc);
19274                 goto rw_error;
19275         }
19276
19277         return 0;
19278 rw_error:
19279         return -EIO;
19280 }
19281
19282 /*============================================================================*/
19283
19284 /**
19285 * \fn int ctrl_set_cfg_agc_if()
19286 * \brief Set IF AGC.
19287 * \param demod demod instance
19288 * \param agc_settings If agc configuration
19289 * \return int.
19290 *
19291 * Check arguments
19292 * Dispatch handling to standard specific function.
19293 *
19294 */
19295 static int
19296 ctrl_set_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19297 {
19298         /* check arguments */
19299         if (agc_settings == NULL)
19300                 return -EINVAL;
19301
19302         switch (agc_settings->ctrl_mode) {
19303         case DRX_AGC_CTRL_AUTO: /* fallthrough */
19304         case DRX_AGC_CTRL_USER: /* fallthrough */
19305         case DRX_AGC_CTRL_OFF:  /* fallthrough */
19306                 break;
19307         default:
19308                 return -EINVAL;
19309         }
19310
19311         /* Distpatch */
19312         switch (agc_settings->standard) {
19313         case DRX_STANDARD_8VSB: /* fallthrough */
19314 #ifndef DRXJ_VSB_ONLY
19315         case DRX_STANDARD_ITU_A:        /* fallthrough */
19316         case DRX_STANDARD_ITU_B:        /* fallthrough */
19317         case DRX_STANDARD_ITU_C:
19318 #endif
19319 #ifndef DRXJ_DIGITAL_ONLY
19320         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19321         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19322         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19323         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19324         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19325         case DRX_STANDARD_NTSC: /* fallthrough */
19326         case DRX_STANDARD_FM:
19327 #endif
19328                 return set_agc_if(demod, agc_settings, true);
19329         case DRX_STANDARD_UNKNOWN:
19330         default:
19331                 return -EINVAL;
19332         }
19333
19334         return 0;
19335 }
19336
19337 /*============================================================================*/
19338
19339 /**
19340 * \fn int ctrl_get_cfg_agc_if()
19341 * \brief Retrieve IF AGC settings.
19342 * \param demod demod instance
19343 * \param agc_settings If agc configuration
19344 * \return int.
19345 *
19346 * Check arguments
19347 * Dispatch handling to standard specific function.
19348 *
19349 */
19350 static int
19351 ctrl_get_cfg_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19352 {
19353         /* check arguments */
19354         if (agc_settings == NULL)
19355                 return -EINVAL;
19356
19357         /* Distpatch */
19358         switch (agc_settings->standard) {
19359         case DRX_STANDARD_8VSB: /* fallthrough */
19360 #ifndef DRXJ_VSB_ONLY
19361         case DRX_STANDARD_ITU_A:        /* fallthrough */
19362         case DRX_STANDARD_ITU_B:        /* fallthrough */
19363         case DRX_STANDARD_ITU_C:
19364 #endif
19365 #ifndef DRXJ_DIGITAL_ONLY
19366         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19367         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19368         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19369         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19370         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19371         case DRX_STANDARD_NTSC: /* fallthrough */
19372         case DRX_STANDARD_FM:
19373 #endif
19374                 return get_agc_if(demod, agc_settings);
19375         case DRX_STANDARD_UNKNOWN:
19376         default:
19377                 return -EINVAL;
19378         }
19379
19380         return 0;
19381 }
19382
19383 /*============================================================================*/
19384
19385 /**
19386 * \fn int ctrl_set_cfg_agc_rf()
19387 * \brief Set RF AGC.
19388 * \param demod demod instance
19389 * \param agc_settings rf agc configuration
19390 * \return int.
19391 *
19392 * Check arguments
19393 * Dispatch handling to standard specific function.
19394 *
19395 */
19396 static int
19397 ctrl_set_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19398 {
19399         /* check arguments */
19400         if (agc_settings == NULL)
19401                 return -EINVAL;
19402
19403         switch (agc_settings->ctrl_mode) {
19404         case DRX_AGC_CTRL_AUTO: /* fallthrough */
19405         case DRX_AGC_CTRL_USER: /* fallthrough */
19406         case DRX_AGC_CTRL_OFF:
19407                 break;
19408         default:
19409                 return -EINVAL;
19410         }
19411
19412         /* Distpatch */
19413         switch (agc_settings->standard) {
19414         case DRX_STANDARD_8VSB: /* fallthrough */
19415 #ifndef DRXJ_VSB_ONLY
19416         case DRX_STANDARD_ITU_A:        /* fallthrough */
19417         case DRX_STANDARD_ITU_B:        /* fallthrough */
19418         case DRX_STANDARD_ITU_C:
19419 #endif
19420 #ifndef DRXJ_DIGITAL_ONLY
19421         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19422         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19423         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19424         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19425         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19426         case DRX_STANDARD_NTSC: /* fallthrough */
19427         case DRX_STANDARD_FM:
19428 #endif
19429                 return set_agc_rf(demod, agc_settings, true);
19430         case DRX_STANDARD_UNKNOWN:
19431         default:
19432                 return -EINVAL;
19433         }
19434
19435         return 0;
19436 }
19437
19438 /*============================================================================*/
19439
19440 /**
19441 * \fn int ctrl_get_cfg_agc_rf()
19442 * \brief Retrieve RF AGC settings.
19443 * \param demod demod instance
19444 * \param agc_settings Rf agc configuration
19445 * \return int.
19446 *
19447 * Check arguments
19448 * Dispatch handling to standard specific function.
19449 *
19450 */
19451 static int
19452 ctrl_get_cfg_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings)
19453 {
19454         /* check arguments */
19455         if (agc_settings == NULL)
19456                 return -EINVAL;
19457
19458         /* Distpatch */
19459         switch (agc_settings->standard) {
19460         case DRX_STANDARD_8VSB: /* fallthrough */
19461 #ifndef DRXJ_VSB_ONLY
19462         case DRX_STANDARD_ITU_A:        /* fallthrough */
19463         case DRX_STANDARD_ITU_B:        /* fallthrough */
19464         case DRX_STANDARD_ITU_C:
19465 #endif
19466 #ifndef DRXJ_DIGITAL_ONLY
19467         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19468         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19469         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19470         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19471         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19472         case DRX_STANDARD_NTSC: /* fallthrough */
19473         case DRX_STANDARD_FM:
19474 #endif
19475                 return get_agc_rf(demod, agc_settings);
19476         case DRX_STANDARD_UNKNOWN:
19477         default:
19478                 return -EINVAL;
19479         }
19480
19481         return 0;
19482 }
19483
19484 /*============================================================================*/
19485
19486 /**
19487 * \fn int ctrl_get_cfg_agc_internal()
19488 * \brief Retrieve internal AGC value.
19489 * \param demod demod instance
19490 * \param u16
19491 * \return int.
19492 *
19493 * Check arguments
19494 * Dispatch handling to standard specific function.
19495 *
19496 */
19497 static int
19498 ctrl_get_cfg_agc_internal(struct drx_demod_instance *demod, u16 *agc_internal)
19499 {
19500         struct i2c_device_addr *dev_addr = NULL;
19501         int rc;
19502         enum drx_lock_status lock_status = DRX_NOT_LOCKED;
19503         struct drxj_data *ext_attr = NULL;
19504         u16 iqm_cf_scale_sh = 0;
19505         u16 iqm_cf_power = 0;
19506         u16 iqm_cf_amp = 0;
19507         u16 iqm_cf_gain = 0;
19508
19509         /* check arguments */
19510         if (agc_internal == NULL)
19511                 return -EINVAL;
19512         dev_addr = demod->my_i2c_dev_addr;
19513         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19514
19515         rc = ctrl_lock_status(demod, &lock_status);
19516         if (rc != 0) {
19517                 pr_err("error %d\n", rc);
19518                 goto rw_error;
19519         }
19520         if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
19521                 *agc_internal = 0;
19522                 return 0;
19523         }
19524
19525         /* Distpatch */
19526         switch (ext_attr->standard) {
19527         case DRX_STANDARD_8VSB:
19528                 iqm_cf_gain = 57;
19529                 break;
19530 #ifndef DRXJ_VSB_ONLY
19531         case DRX_STANDARD_ITU_A:
19532         case DRX_STANDARD_ITU_B:
19533         case DRX_STANDARD_ITU_C:
19534                 switch (ext_attr->constellation) {
19535                 case DRX_CONSTELLATION_QAM256:
19536                 case DRX_CONSTELLATION_QAM128:
19537                 case DRX_CONSTELLATION_QAM32:
19538                 case DRX_CONSTELLATION_QAM16:
19539                         iqm_cf_gain = 57;
19540                         break;
19541                 case DRX_CONSTELLATION_QAM64:
19542                         iqm_cf_gain = 56;
19543                         break;
19544                 default:
19545                         return -EIO;
19546                 }
19547                 break;
19548 #endif
19549         default:
19550                 return -EINVAL;
19551         }
19552
19553         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_POW__A, &iqm_cf_power, 0);
19554         if (rc != 0) {
19555                 pr_err("error %d\n", rc);
19556                 goto rw_error;
19557         }
19558         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_SCALE_SH__A, &iqm_cf_scale_sh, 0);
19559         if (rc != 0) {
19560                 pr_err("error %d\n", rc);
19561                 goto rw_error;
19562         }
19563         rc = DRXJ_DAP.read_reg16func(dev_addr, IQM_CF_AMP__A, &iqm_cf_amp, 0);
19564         if (rc != 0) {
19565                 pr_err("error %d\n", rc);
19566                 goto rw_error;
19567         }
19568         /* IQM_CF_PWR_CORRECTION_dB = 3;
19569            P5dB =10*log10(IQM_CF_POW)+12-6*9-IQM_CF_PWR_CORRECTION_dB; */
19570         /* P4dB = P5dB -20*log10(IQM_CF_AMP)-6*10
19571            -IQM_CF_Gain_dB-18+6*(27-IQM_CF_SCALE_SH*2-10)
19572            +6*7+10*log10(1+0.115/4); */
19573         /* PadcdB = P4dB +3 -6 +60; dBmV */
19574         *agc_internal = (u16) (log1_times100(iqm_cf_power)
19575                                 - 2 * log1_times100(iqm_cf_amp)
19576                                 - iqm_cf_gain - 120 * iqm_cf_scale_sh + 781);
19577
19578         return 0;
19579 rw_error:
19580         return -EIO;
19581 }
19582
19583 /*============================================================================*/
19584
19585 /**
19586 * \fn int ctrl_set_cfg_pre_saw()
19587 * \brief Set Pre-saw reference.
19588 * \param demod demod instance
19589 * \param u16 *
19590 * \return int.
19591 *
19592 * Check arguments
19593 * Dispatch handling to standard specific function.
19594 *
19595 */
19596 static int
19597 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19598 {
19599         struct i2c_device_addr *dev_addr = NULL;
19600         struct drxj_data *ext_attr = NULL;
19601         int rc;
19602
19603         dev_addr = demod->my_i2c_dev_addr;
19604         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19605
19606         /* check arguments */
19607         if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
19608             ) {
19609                 return -EINVAL;
19610         }
19611
19612         /* Only if standard is currently active */
19613         if ((ext_attr->standard == pre_saw->standard) ||
19614             (DRXJ_ISQAMSTD(ext_attr->standard) &&
19615              DRXJ_ISQAMSTD(pre_saw->standard)) ||
19616             (DRXJ_ISATVSTD(ext_attr->standard) &&
19617              DRXJ_ISATVSTD(pre_saw->standard))) {
19618                 rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
19619                 if (rc != 0) {
19620                         pr_err("error %d\n", rc);
19621                         goto rw_error;
19622                 }
19623         }
19624
19625         /* Store pre-saw settings */
19626         switch (pre_saw->standard) {
19627         case DRX_STANDARD_8VSB:
19628                 ext_attr->vsb_pre_saw_cfg = *pre_saw;
19629                 break;
19630 #ifndef DRXJ_VSB_ONLY
19631         case DRX_STANDARD_ITU_A:        /* fallthrough */
19632         case DRX_STANDARD_ITU_B:        /* fallthrough */
19633         case DRX_STANDARD_ITU_C:
19634                 ext_attr->qam_pre_saw_cfg = *pre_saw;
19635                 break;
19636 #endif
19637 #ifndef DRXJ_DIGITAL_ONLY
19638         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19639         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19640         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19641         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19642         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19643         case DRX_STANDARD_NTSC: /* fallthrough */
19644         case DRX_STANDARD_FM:
19645                 ext_attr->atv_pre_saw_cfg = *pre_saw;
19646                 break;
19647 #endif
19648         default:
19649                 return -EINVAL;
19650         }
19651
19652         return 0;
19653 rw_error:
19654         return -EIO;
19655 }
19656
19657 /*============================================================================*/
19658
19659 /**
19660 * \fn int ctrl_set_cfg_afe_gain()
19661 * \brief Set AFE Gain.
19662 * \param demod demod instance
19663 * \param u16 *
19664 * \return int.
19665 *
19666 * Check arguments
19667 * Dispatch handling to standard specific function.
19668 *
19669 */
19670 static int
19671 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19672 {
19673         struct i2c_device_addr *dev_addr = NULL;
19674         struct drxj_data *ext_attr = NULL;
19675         int rc;
19676         u8 gain = 0;
19677
19678         /* check arguments */
19679         if (afe_gain == NULL)
19680                 return -EINVAL;
19681
19682         dev_addr = demod->my_i2c_dev_addr;
19683         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19684
19685         switch (afe_gain->standard) {
19686         case DRX_STANDARD_8VSB: /* fallthrough */
19687 #ifndef DRXJ_VSB_ONLY
19688         case DRX_STANDARD_ITU_A:        /* fallthrough */
19689         case DRX_STANDARD_ITU_B:        /* fallthrough */
19690         case DRX_STANDARD_ITU_C:
19691 #endif
19692                 /* Do nothing */
19693                 break;
19694         default:
19695                 return -EINVAL;
19696         }
19697
19698         /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
19699            So I (PJ) think interface requires choice between auto, user mode */
19700
19701         if (afe_gain->gain >= 329)
19702                 gain = 15;
19703         else if (afe_gain->gain <= 147)
19704                 gain = 0;
19705         else
19706                 gain = (afe_gain->gain - 140 + 6) / 13;
19707
19708         /* Only if standard is currently active */
19709         if (ext_attr->standard == afe_gain->standard) {
19710                         rc = DRXJ_DAP.write_reg16func(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
19711                         if (rc != 0) {
19712                                 pr_err("error %d\n", rc);
19713                                 goto rw_error;
19714                         }
19715                 }
19716
19717         /* Store AFE Gain settings */
19718         switch (afe_gain->standard) {
19719         case DRX_STANDARD_8VSB:
19720                 ext_attr->vsb_pga_cfg = gain * 13 + 140;
19721                 break;
19722 #ifndef DRXJ_VSB_ONLY
19723         case DRX_STANDARD_ITU_A:        /* fallthrough */
19724         case DRX_STANDARD_ITU_B:        /* fallthrough */
19725         case DRX_STANDARD_ITU_C:
19726                 ext_attr->qam_pga_cfg = gain * 13 + 140;
19727                 break;
19728 #endif
19729         default:
19730                 return -EIO;
19731         }
19732
19733         return 0;
19734 rw_error:
19735         return -EIO;
19736 }
19737
19738 /*============================================================================*/
19739
19740 /**
19741 * \fn int ctrl_get_cfg_pre_saw()
19742 * \brief Get Pre-saw reference setting.
19743 * \param demod demod instance
19744 * \param u16 *
19745 * \return int.
19746 *
19747 * Check arguments
19748 * Dispatch handling to standard specific function.
19749 *
19750 */
19751 static int
19752 ctrl_get_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
19753 {
19754         struct drxj_data *ext_attr = NULL;
19755
19756         /* check arguments */
19757         if (pre_saw == NULL)
19758                 return -EINVAL;
19759
19760         ext_attr = (struct drxj_data *) demod->my_ext_attr;
19761
19762         switch (pre_saw->standard) {
19763         case DRX_STANDARD_8VSB:
19764                 *pre_saw = ext_attr->vsb_pre_saw_cfg;
19765                 break;
19766 #ifndef DRXJ_VSB_ONLY
19767         case DRX_STANDARD_ITU_A:        /* fallthrough */
19768         case DRX_STANDARD_ITU_B:        /* fallthrough */
19769         case DRX_STANDARD_ITU_C:
19770                 *pre_saw = ext_attr->qam_pre_saw_cfg;
19771                 break;
19772 #endif
19773 #ifndef DRXJ_DIGITAL_ONLY
19774         case DRX_STANDARD_PAL_SECAM_BG: /* fallthrough */
19775         case DRX_STANDARD_PAL_SECAM_DK: /* fallthrough */
19776         case DRX_STANDARD_PAL_SECAM_I:  /* fallthrough */
19777         case DRX_STANDARD_PAL_SECAM_L:  /* fallthrough */
19778         case DRX_STANDARD_PAL_SECAM_LP: /* fallthrough */
19779         case DRX_STANDARD_NTSC:
19780                 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_NTSC;
19781                 *pre_saw = ext_attr->atv_pre_saw_cfg;
19782                 break;
19783         case DRX_STANDARD_FM:
19784                 ext_attr->atv_pre_saw_cfg.standard = DRX_STANDARD_FM;
19785                 *pre_saw = ext_attr->atv_pre_saw_cfg;
19786                 break;
19787 #endif
19788         default:
19789                 return -EINVAL;
19790         }
19791
19792         return 0;
19793 }
19794
19795 /*============================================================================*/
19796
19797 /**
19798 * \fn int ctrl_get_cfg_afe_gain()
19799 * \brief Get AFE Gain.
19800 * \param demod demod instance
19801 * \param u16 *
19802 * \return int.
19803 *
19804 * Check arguments
19805 * Dispatch handling to standard specific function.
19806 *
19807 */
19808 static int
19809 ctrl_get_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
19810 {
19811         struct drxj_data *ext_attr = NULL;
19812
19813         /* check arguments */
19814         if (afe_gain == NULL)
19815                 return -EINVAL;
19816
19817         ext_attr = demod->my_ext_attr;
19818
19819         switch (afe_gain->standard) {
19820         case DRX_STANDARD_8VSB:
19821                 afe_gain->gain = ext_attr->vsb_pga_cfg;
19822                 break;
19823 #ifndef DRXJ_VSB_ONLY
19824         case DRX_STANDARD_ITU_A:        /* fallthrough */
19825         case DRX_STANDARD_ITU_B:        /* fallthrough */
19826         case DRX_STANDARD_ITU_C:
19827                 afe_gain->gain = ext_attr->qam_pga_cfg;
19828                 break;
19829 #endif
19830         default:
19831                 return -EINVAL;
19832         }
19833
19834         return 0;
19835 }
19836
19837 /*============================================================================*/
19838
19839 /**
19840 * \fn int ctrl_get_fec_meas_seq_count()
19841 * \brief Get FEC measurement sequnce number.
19842 * \param demod demod instance
19843 * \param u16 *
19844 * \return int.
19845 *
19846 * Check arguments
19847 * Dispatch handling to standard specific function.
19848 *
19849 */
19850 static int
19851 ctrl_get_fec_meas_seq_count(struct drx_demod_instance *demod, u16 *fec_meas_seq_count)
19852 {
19853         int rc;
19854         /* check arguments */
19855         if (fec_meas_seq_count == NULL)
19856                 return -EINVAL;
19857
19858         rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, fec_meas_seq_count, 0);
19859         if (rc != 0) {
19860                 pr_err("error %d\n", rc);
19861                 goto rw_error;
19862         }
19863
19864         return 0;
19865 rw_error:
19866         return -EIO;
19867 }
19868
19869 /*============================================================================*/
19870
19871 /**
19872 * \fn int ctrl_get_accum_cr_rs_cw_err()
19873 * \brief Get accumulative corrected RS codeword number.
19874 * \param demod demod instance
19875 * \param u32 *
19876 * \return int.
19877 *
19878 * Check arguments
19879 * Dispatch handling to standard specific function.
19880 *
19881 */
19882 static int
19883 ctrl_get_accum_cr_rs_cw_err(struct drx_demod_instance *demod, u32 *accum_cr_rs_cw_err)
19884 {
19885         int rc;
19886         if (accum_cr_rs_cw_err == NULL)
19887                 return -EINVAL;
19888
19889         rc = DRXJ_DAP.read_reg32func(demod->my_i2c_dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, accum_cr_rs_cw_err, 0);
19890         if (rc != 0) {
19891                 pr_err("error %d\n", rc);
19892                 goto rw_error;
19893         }
19894
19895         return 0;
19896 rw_error:
19897         return -EIO;
19898 }
19899
19900 /**
19901 * \fn int ctrl_set_cfg()
19902 * \brief Set 'some' configuration of the device.
19903 * \param devmod Pointer to demodulator instance.
19904 * \param config Pointer to configuration parameters (type and data).
19905 * \return int.
19906
19907 */
19908 static int ctrl_set_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
19909 {
19910         int rc;
19911
19912         if (config == NULL)
19913                 return -EINVAL;
19914
19915         do {
19916                 u16 dummy;
19917                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
19918                 if (rc != 0) {
19919                         pr_err("error %d\n", rc);
19920                         goto rw_error;
19921                 }
19922         } while (0);
19923         switch (config->cfg_type) {
19924         case DRX_CFG_MPEG_OUTPUT:
19925                 return ctrl_set_cfg_mpeg_output(demod,
19926                                             (struct drx_cfg_mpeg_output *) config->
19927                                             cfg_data);
19928         case DRX_CFG_PINS_SAFE_MODE:
19929                 return ctrl_set_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
19930         case DRXJ_CFG_AGC_RF:
19931                 return ctrl_set_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
19932         case DRXJ_CFG_AGC_IF:
19933                 return ctrl_set_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
19934         case DRXJ_CFG_PRE_SAW:
19935                 return ctrl_set_cfg_pre_saw(demod,
19936                                         (struct drxj_cfg_pre_saw *) config->cfg_data);
19937         case DRXJ_CFG_AFE_GAIN:
19938                 return ctrl_set_cfg_afe_gain(demod,
19939                                          (struct drxj_cfg_afe_gain *) config->cfg_data);
19940         case DRXJ_CFG_SMART_ANT:
19941                 return ctrl_set_cfg_smart_ant(demod,
19942                                           (struct drxj_cfg_smart_ant *) (config->
19943                                                                 cfg_data));
19944         case DRXJ_CFG_RESET_PACKET_ERR:
19945                 return ctrl_set_cfg_reset_pkt_err(demod);
19946 #ifndef DRXJ_DIGITAL_ONLY
19947         case DRXJ_CFG_OOB_PRE_SAW:
19948                 return ctrl_set_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
19949         case DRXJ_CFG_OOB_LO_POW:
19950                 return ctrl_set_cfg_oob_lo_power(demod,
19951                                             (enum drxj_cfg_oob_lo_power *) (config->
19952                                                                     cfg_data));
19953         case DRXJ_CFG_ATV_MISC:
19954                 return ctrl_set_cfg_atv_misc(demod,
19955                                          (struct drxj_cfg_atv_misc *) config->cfg_data);
19956         case DRXJ_CFG_ATV_EQU_COEF:
19957                 return ctrl_set_cfg_atv_equ_coef(demod,
19958                                             (struct drxj_cfg_atv_equ_coef *) config->
19959                                             cfg_data);
19960         case DRXJ_CFG_ATV_OUTPUT:
19961                 return ctrl_set_cfg_atv_output(demod,
19962                                            (struct drxj_cfg_atv_output *) config->
19963                                            cfg_data);
19964 #endif
19965         case DRXJ_CFG_MPEG_OUTPUT_MISC:
19966                 return ctrl_set_cfg_mpeg_output_misc(demod,
19967                                                 (struct drxj_cfg_mpeg_output_misc *)
19968                                                 config->cfg_data);
19969 #ifndef DRXJ_EXCLUDE_AUDIO
19970         case DRX_CFG_AUD_VOLUME:
19971                 return aud_ctrl_set_cfg_volume(demod,
19972                                            (struct drx_cfg_aud_volume *) config->
19973                                            cfg_data);
19974         case DRX_CFG_I2S_OUTPUT:
19975                 return aud_ctrl_set_cfg_output_i2s(demod,
19976                                               (struct drx_cfg_i2s_output *) config->
19977                                               cfg_data);
19978         case DRX_CFG_AUD_AUTOSOUND:
19979                 return aud_ctr_setl_cfg_auto_sound(demod, (enum drx_cfg_aud_auto_sound *)
19980                                               config->cfg_data);
19981         case DRX_CFG_AUD_ASS_THRES:
19982                 return aud_ctrl_set_cfg_ass_thres(demod, (struct drx_cfg_aud_ass_thres *)
19983                                              config->cfg_data);
19984         case DRX_CFG_AUD_CARRIER:
19985                 return aud_ctrl_set_cfg_carrier(demod,
19986                                             (struct drx_cfg_aud_carriers *) config->
19987                                             cfg_data);
19988         case DRX_CFG_AUD_DEVIATION:
19989                 return aud_ctrl_set_cfg_dev(demod,
19990                                         (enum drx_cfg_aud_deviation *) config->
19991                                         cfg_data);
19992         case DRX_CFG_AUD_PRESCALE:
19993                 return aud_ctrl_set_cfg_prescale(demod,
19994                                              (struct drx_cfg_aud_prescale *) config->
19995                                              cfg_data);
19996         case DRX_CFG_AUD_MIXER:
19997                 return aud_ctrl_set_cfg_mixer(demod,
19998                                           (struct drx_cfg_aud_mixer *) config->cfg_data);
19999         case DRX_CFG_AUD_AVSYNC:
20000                 return aud_ctrl_set_cfg_av_sync(demod,
20001                                            (enum drx_cfg_aud_av_sync *) config->
20002                                            cfg_data);
20003
20004 #endif
20005         default:
20006                 return -EINVAL;
20007         }
20008
20009         return 0;
20010 rw_error:
20011         return -EIO;
20012 }
20013
20014 /*============================================================================*/
20015
20016 /**
20017 * \fn int ctrl_get_cfg()
20018 * \brief Get 'some' configuration of the device.
20019 * \param devmod Pointer to demodulator instance.
20020 * \param config Pointer to configuration parameters (type and data).
20021 * \return int.
20022 */
20023
20024 static int ctrl_get_cfg(struct drx_demod_instance *demod, struct drx_cfg *config)
20025 {
20026         int rc;
20027
20028         if (config == NULL)
20029                 return -EINVAL;
20030
20031         do {
20032                 u16 dummy;
20033                 rc = DRXJ_DAP.read_reg16func(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
20034                 if (rc != 0) {
20035                         pr_err("error %d\n", rc);
20036                         goto rw_error;
20037                 }
20038         } while (0);
20039
20040         switch (config->cfg_type) {
20041         case DRX_CFG_MPEG_OUTPUT:
20042                 return ctrl_get_cfg_mpeg_output(demod,
20043                                             (struct drx_cfg_mpeg_output *) config->
20044                                             cfg_data);
20045         case DRX_CFG_PINS_SAFE_MODE:
20046                 return ctrl_get_cfg_pdr_safe_mode(demod, (bool *)config->cfg_data);
20047         case DRXJ_CFG_AGC_RF:
20048                 return ctrl_get_cfg_agc_rf(demod, (struct drxj_cfg_agc *) config->cfg_data);
20049         case DRXJ_CFG_AGC_IF:
20050                 return ctrl_get_cfg_agc_if(demod, (struct drxj_cfg_agc *) config->cfg_data);
20051         case DRXJ_CFG_AGC_INTERNAL:
20052                 return ctrl_get_cfg_agc_internal(demod, (u16 *)config->cfg_data);
20053         case DRXJ_CFG_PRE_SAW:
20054                 return ctrl_get_cfg_pre_saw(demod,
20055                                         (struct drxj_cfg_pre_saw *) config->cfg_data);
20056         case DRXJ_CFG_AFE_GAIN:
20057                 return ctrl_get_cfg_afe_gain(demod,
20058                                          (struct drxj_cfg_afe_gain *) config->cfg_data);
20059         case DRXJ_CFG_ACCUM_CR_RS_CW_ERR:
20060                 return ctrl_get_accum_cr_rs_cw_err(demod, (u32 *)config->cfg_data);
20061         case DRXJ_CFG_FEC_MERS_SEQ_COUNT:
20062                 return ctrl_get_fec_meas_seq_count(demod, (u16 *)config->cfg_data);
20063         case DRXJ_CFG_VSB_MISC:
20064                 return ctrl_get_cfg_vsb_misc(demod,
20065                                          (struct drxj_cfg_vsb_misc *) config->cfg_data);
20066         case DRXJ_CFG_SYMBOL_CLK_OFFSET:
20067                 return ctrl_get_cfg_symbol_clock_offset(demod,
20068                                                    (s32 *)config->cfg_data);
20069 #ifndef DRXJ_DIGITAL_ONLY
20070         case DRXJ_CFG_OOB_MISC:
20071                 return ctrl_get_cfg_oob_misc(demod,
20072                                          (struct drxj_cfg_oob_misc *) config->cfg_data);
20073         case DRXJ_CFG_OOB_PRE_SAW:
20074                 return ctrl_get_cfg_oob_pre_saw(demod, (u16 *)(config->cfg_data));
20075         case DRXJ_CFG_OOB_LO_POW:
20076                 return ctrl_get_cfg_oob_lo_power(demod,
20077                                             (enum drxj_cfg_oob_lo_power *) (config->
20078                                                                     cfg_data));
20079         case DRXJ_CFG_ATV_EQU_COEF:
20080                 return ctrl_get_cfg_atv_equ_coef(demod,
20081                                             (struct drxj_cfg_atv_equ_coef *) config->
20082                                             cfg_data);
20083         case DRXJ_CFG_ATV_MISC:
20084                 return ctrl_get_cfg_atv_misc(demod,
20085                                          (struct drxj_cfg_atv_misc *) config->cfg_data);
20086         case DRXJ_CFG_ATV_OUTPUT:
20087                 return ctrl_get_cfg_atv_output(demod,
20088                                            (struct drxj_cfg_atv_output *) config->
20089                                            cfg_data);
20090         case DRXJ_CFG_ATV_AGC_STATUS:
20091                 return ctrl_get_cfg_atv_agc_status(demod,
20092                                               (struct drxj_cfg_atv_agc_status *) config->
20093                                               cfg_data);
20094 #endif
20095         case DRXJ_CFG_MPEG_OUTPUT_MISC:
20096                 return ctrl_get_cfg_mpeg_output_misc(demod,
20097                                                 (struct drxj_cfg_mpeg_output_misc *)
20098                                                 config->cfg_data);
20099         case DRXJ_CFG_HW_CFG:
20100                 return ctrl_get_cfg_hw_cfg(demod,
20101                                        (struct drxj_cfg_hw_cfg *) config->cfg_data);
20102 #ifndef DRXJ_EXCLUDE_AUDIO
20103         case DRX_CFG_AUD_VOLUME:
20104                 return aud_ctrl_get_cfg_volume(demod,
20105                                            (struct drx_cfg_aud_volume *) config->
20106                                            cfg_data);
20107         case DRX_CFG_I2S_OUTPUT:
20108                 return aud_ctrl_get_cfg_output_i2s(demod,
20109                                               (struct drx_cfg_i2s_output *) config->
20110                                               cfg_data);
20111
20112         case DRX_CFG_AUD_RDS:
20113                 return aud_ctrl_get_cfg_rds(demod,
20114                                         (struct drx_cfg_aud_rds *) config->cfg_data);
20115         case DRX_CFG_AUD_AUTOSOUND:
20116                 return aud_ctrl_get_cfg_auto_sound(demod,
20117                                               (enum drx_cfg_aud_auto_sound *) config->
20118                                               cfg_data);
20119         case DRX_CFG_AUD_ASS_THRES:
20120                 return aud_ctrl_get_cfg_ass_thres(demod,
20121                                              (struct drx_cfg_aud_ass_thres *) config->
20122                                              cfg_data);
20123         case DRX_CFG_AUD_CARRIER:
20124                 return aud_ctrl_get_cfg_carrier(demod,
20125                                             (struct drx_cfg_aud_carriers *) config->
20126                                             cfg_data);
20127         case DRX_CFG_AUD_DEVIATION:
20128                 return aud_ctrl_get_cfg_dev(demod,
20129                                         (enum drx_cfg_aud_deviation *) config->
20130                                         cfg_data);
20131         case DRX_CFG_AUD_PRESCALE:
20132                 return aud_ctrl_get_cfg_prescale(demod,
20133                                              (struct drx_cfg_aud_prescale *) config->
20134                                              cfg_data);
20135         case DRX_CFG_AUD_MIXER:
20136                 return aud_ctrl_get_cfg_mixer(demod,
20137                                           (struct drx_cfg_aud_mixer *) config->cfg_data);
20138         case DRX_CFG_AUD_AVSYNC:
20139                 return aud_ctrl_get_cfg_av_sync(demod,
20140                                            (enum drx_cfg_aud_av_sync *) config->
20141                                            cfg_data);
20142 #endif
20143
20144         default:
20145                 return -EINVAL;
20146         }
20147
20148         return 0;
20149 rw_error:
20150         return -EIO;
20151 }
20152
20153 /*=============================================================================
20154 ===== EXPORTED FUNCTIONS ====================================================*/
20155
20156 /**
20157 * \fn drxj_open()
20158 * \brief Open the demod instance, configure device, configure drxdriver
20159 * \return Status_t Return status.
20160 *
20161 * drxj_open() can be called with a NULL ucode image => no ucode upload.
20162 * This means that drxj_open() must NOT contain SCU commands or, in general,
20163 * rely on SCU or AUD ucode to be present.
20164 *
20165 */
20166 int drxj_open(struct drx_demod_instance *demod)
20167 {
20168         struct i2c_device_addr *dev_addr = NULL;
20169         struct drxj_data *ext_attr = NULL;
20170         struct drx_common_attr *common_attr = NULL;
20171         u32 driver_version = 0;
20172         struct drxu_code_info ucode_info;
20173         struct drx_cfg_mpeg_output cfg_mpeg_output;
20174         int rc;
20175
20176         /* Check arguments */
20177         if (demod->my_ext_attr == NULL)
20178                 return -EINVAL;
20179
20180         dev_addr = demod->my_i2c_dev_addr;
20181         ext_attr = (struct drxj_data *) demod->my_ext_attr;
20182         common_attr = (struct drx_common_attr *) demod->my_common_attr;
20183
20184         rc = power_up_device(demod);
20185         if (rc != 0) {
20186                 pr_err("error %d\n", rc);
20187                 goto rw_error;
20188         }
20189         common_attr->current_power_mode = DRX_POWER_UP;
20190
20191         /* has to be in front of setIqmAf and setOrxNsuAox */
20192         rc = get_device_capabilities(demod);
20193         if (rc != 0) {
20194                 pr_err("error %d\n", rc);
20195                 goto rw_error;
20196         }
20197
20198         /* Soft reset of sys- and osc-clockdomain */
20199         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);
20200         if (rc != 0) {
20201                 pr_err("error %d\n", rc);
20202                 goto rw_error;
20203         }
20204         rc = DRXJ_DAP.write_reg16func(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
20205         if (rc != 0) {
20206                 pr_err("error %d\n", rc);
20207                 goto rw_error;
20208         }
20209         rc = drxbsp_hst_sleep(1);
20210         if (rc != 0) {
20211                 pr_err("error %d\n", rc);
20212                 goto rw_error;
20213         }
20214
20215         /* TODO first make sure that everything keeps working before enabling this */
20216         /* PowerDownAnalogBlocks() */
20217         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);
20218         if (rc != 0) {
20219                 pr_err("error %d\n", rc);
20220                 goto rw_error;
20221         }
20222
20223         rc = set_iqm_af(demod, false);
20224         if (rc != 0) {
20225                 pr_err("error %d\n", rc);
20226                 goto rw_error;
20227         }
20228         rc = set_orx_nsu_aox(demod, false);
20229         if (rc != 0) {
20230                 pr_err("error %d\n", rc);
20231                 goto rw_error;
20232         }
20233
20234         rc = init_hi(demod);
20235         if (rc != 0) {
20236                 pr_err("error %d\n", rc);
20237                 goto rw_error;
20238         }
20239
20240         /* disable mpegoutput pins */
20241         cfg_mpeg_output.enable_mpeg_output = false;
20242         rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
20243         if (rc != 0) {
20244                 pr_err("error %d\n", rc);
20245                 goto rw_error;
20246         }
20247         /* Stop AUD Inform SetAudio it will need to do all setting */
20248         rc = power_down_aud(demod);
20249         if (rc != 0) {
20250                 pr_err("error %d\n", rc);
20251                 goto rw_error;
20252         }
20253         /* Stop SCU */
20254         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
20255         if (rc != 0) {
20256                 pr_err("error %d\n", rc);
20257                 goto rw_error;
20258         }
20259
20260         /* Upload microcode */
20261         if (common_attr->microcode_file != NULL) {
20262                 /* Dirty trick to use common ucode upload & verify,
20263                    pretend device is already open */
20264                 common_attr->is_opened = true;
20265                 ucode_info.mc_file = common_attr->microcode_file;
20266
20267 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20268                 /* Upload microcode without audio part */
20269                 rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_UPLOAD, false);
20270                 if (rc != 0) {
20271                         pr_err("error %d\n", rc);
20272                         goto rw_error;
20273                 }
20274 #else
20275                 rc = drx_ctrl(demod, DRX_CTRL_LOAD_UCODE, &ucode_info);
20276                 if (rc != 0) {
20277                         pr_err("error %d\n", rc);
20278                         goto rw_error;
20279                 }
20280 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20281                 if (common_attr->verify_microcode == true) {
20282 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20283                         rc = ctrl_u_code_upload(demod, &ucode_info, UCODE_VERIFY, false);
20284                         if (rc != 0) {
20285                                 pr_err("error %d\n", rc);
20286                                 goto rw_error;
20287                         }
20288 #else
20289                         rc = drx_ctrl(demod, DRX_CTRL_VERIFY_UCODE, &ucode_info);
20290                         if (rc != 0) {
20291                                 pr_err("error %d\n", rc);
20292                                 goto rw_error;
20293                         }
20294 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20295                 }
20296                 common_attr->is_opened = false;
20297         }
20298
20299         /* Run SCU for a little while to initialize microcode version numbers */
20300         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
20301         if (rc != 0) {
20302                 pr_err("error %d\n", rc);
20303                 goto rw_error;
20304         }
20305
20306         /* Open tuner instance */
20307         if (demod->my_tuner != NULL) {
20308                 demod->my_tuner->my_common_attr->my_user_data = (void *)demod;
20309
20310                 if (common_attr->tuner_port_nr == 1) {
20311                         bool bridge_closed = true;
20312                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
20313                         if (rc != 0) {
20314                                 pr_err("error %d\n", rc);
20315                                 goto rw_error;
20316                         }
20317                 }
20318
20319                 rc = drxbsp_tuner_open(demod->my_tuner);
20320                 if (rc != 0) {
20321                         pr_err("error %d\n", rc);
20322                         goto rw_error;
20323                 }
20324
20325                 if (common_attr->tuner_port_nr == 1) {
20326                         bool bridge_closed = false;
20327                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
20328                         if (rc != 0) {
20329                                 pr_err("error %d\n", rc);
20330                                 goto rw_error;
20331                         }
20332                 }
20333                 common_attr->tuner_min_freq_rf =
20334                     ((demod->my_tuner)->my_common_attr->min_freq_rf);
20335                 common_attr->tuner_max_freq_rf =
20336                     ((demod->my_tuner)->my_common_attr->max_freq_rf);
20337         }
20338
20339         /* Initialize scan timeout */
20340         common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
20341         common_attr->scan_desired_lock = DRX_LOCKED;
20342
20343         drxj_reset_mode(ext_attr);
20344         ext_attr->standard = DRX_STANDARD_UNKNOWN;
20345
20346         rc = smart_ant_init(demod);
20347         if (rc != 0) {
20348                 pr_err("error %d\n", rc);
20349                 goto rw_error;
20350         }
20351
20352         /* Stamp driver version number in SCU data RAM in BCD code
20353            Done to enable field application engineers to retreive drxdriver version
20354            via I2C from SCU RAM
20355          */
20356         driver_version = (VERSION_MAJOR / 100) % 10;
20357         driver_version <<= 4;
20358         driver_version += (VERSION_MAJOR / 10) % 10;
20359         driver_version <<= 4;
20360         driver_version += (VERSION_MAJOR % 10);
20361         driver_version <<= 4;
20362         driver_version += (VERSION_MINOR % 10);
20363         driver_version <<= 4;
20364         driver_version += (VERSION_PATCH / 1000) % 10;
20365         driver_version <<= 4;
20366         driver_version += (VERSION_PATCH / 100) % 10;
20367         driver_version <<= 4;
20368         driver_version += (VERSION_PATCH / 10) % 10;
20369         driver_version <<= 4;
20370         driver_version += (VERSION_PATCH % 10);
20371         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
20372         if (rc != 0) {
20373                 pr_err("error %d\n", rc);
20374                 goto rw_error;
20375         }
20376         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
20377         if (rc != 0) {
20378                 pr_err("error %d\n", rc);
20379                 goto rw_error;
20380         }
20381
20382         /* refresh the audio data structure with default */
20383         ext_attr->aud_data = drxj_default_aud_data_g;
20384
20385         return 0;
20386 rw_error:
20387         common_attr->is_opened = false;
20388         return -EIO;
20389 }
20390
20391 /*============================================================================*/
20392 /**
20393 * \fn drxj_close()
20394 * \brief Close the demod instance, power down the device
20395 * \return Status_t Return status.
20396 *
20397 */
20398 int drxj_close(struct drx_demod_instance *demod)
20399 {
20400         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
20401         struct drx_common_attr *common_attr = demod->my_common_attr;
20402         int rc;
20403         enum drx_power_mode power_mode = DRX_POWER_UP;
20404
20405         /* power up */
20406         rc = ctrl_power_mode(demod, &power_mode);
20407         if (rc != 0) {
20408                 pr_err("error %d\n", rc);
20409                 goto rw_error;
20410         }
20411
20412         if (demod->my_tuner != NULL) {
20413                 /* Check if bridge is used */
20414                 if (common_attr->tuner_port_nr == 1) {
20415                         bool bridge_closed = true;
20416                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
20417                         if (rc != 0) {
20418                                 pr_err("error %d\n", rc);
20419                                 goto rw_error;
20420                         }
20421                 }
20422                 rc = drxbsp_tuner_close(demod->my_tuner);
20423                 if (rc != 0) {
20424                         pr_err("error %d\n", rc);
20425                         goto rw_error;
20426                 }
20427                 if (common_attr->tuner_port_nr == 1) {
20428                         bool bridge_closed = false;
20429                         rc = ctrl_i2c_bridge(demod, &bridge_closed);
20430                         if (rc != 0) {
20431                                 pr_err("error %d\n", rc);
20432                                 goto rw_error;
20433                         }
20434                 }
20435         }
20436
20437         rc = DRXJ_DAP.write_reg16func(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
20438         if (rc != 0) {
20439                 pr_err("error %d\n", rc);
20440                 goto rw_error;
20441         }
20442         power_mode = DRX_POWER_DOWN;
20443         rc = ctrl_power_mode(demod, &power_mode);
20444         if (rc != 0) {
20445                 pr_err("error %d\n", rc);
20446                 goto rw_error;
20447         }
20448
20449         return 0;
20450 rw_error:
20451         return -EIO;
20452 }
20453
20454 /*============================================================================*/
20455 /**
20456 * \fn drxj_ctrl()
20457 * \brief DRXJ specific control function
20458 * \return Status_t Return status.
20459 */
20460 int
20461 drxj_ctrl(struct drx_demod_instance *demod, u32 ctrl, void *ctrl_data)
20462 {
20463         switch (ctrl) {
20464       /*======================================================================*/
20465         case DRX_CTRL_SET_CHANNEL:
20466                 {
20467                         return ctrl_set_channel(demod, (struct drx_channel *)ctrl_data);
20468                 }
20469                 break;
20470       /*======================================================================*/
20471         case DRX_CTRL_GET_CHANNEL:
20472                 {
20473                         return ctrl_get_channel(demod, (struct drx_channel *)ctrl_data);
20474                 }
20475                 break;
20476       /*======================================================================*/
20477         case DRX_CTRL_SIG_QUALITY:
20478                 {
20479                         return ctrl_sig_quality(demod,
20480                                               (struct drx_sig_quality *) ctrl_data);
20481                 }
20482                 break;
20483       /*======================================================================*/
20484         case DRX_CTRL_SIG_STRENGTH:
20485                 {
20486                         return ctrl_sig_strength(demod, (u16 *)ctrl_data);
20487                 }
20488                 break;
20489       /*======================================================================*/
20490         case DRX_CTRL_CONSTEL:
20491                 {
20492                         return ctrl_constel(demod, (struct drx_complex *)ctrl_data);
20493                 }
20494                 break;
20495       /*======================================================================*/
20496         case DRX_CTRL_SET_CFG:
20497                 {
20498                         return ctrl_set_cfg(demod, (struct drx_cfg *)ctrl_data);
20499                 }
20500                 break;
20501       /*======================================================================*/
20502         case DRX_CTRL_GET_CFG:
20503                 {
20504                         return ctrl_get_cfg(demod, (struct drx_cfg *)ctrl_data);
20505                 }
20506                 break;
20507       /*======================================================================*/
20508         case DRX_CTRL_I2C_BRIDGE:
20509                 {
20510                         return ctrl_i2c_bridge(demod, (bool *)ctrl_data);
20511                 }
20512                 break;
20513       /*======================================================================*/
20514         case DRX_CTRL_LOCK_STATUS:
20515                 {
20516                         return ctrl_lock_status(demod,
20517                                               (enum drx_lock_status *)ctrl_data);
20518                 }
20519                 break;
20520       /*======================================================================*/
20521         case DRX_CTRL_SET_STANDARD:
20522                 {
20523                         return ctrl_set_standard(demod,
20524                                                (enum drx_standard *)ctrl_data);
20525                 }
20526                 break;
20527       /*======================================================================*/
20528         case DRX_CTRL_GET_STANDARD:
20529                 {
20530                         return ctrl_get_standard(demod,
20531                                                (enum drx_standard *)ctrl_data);
20532                 }
20533                 break;
20534       /*======================================================================*/
20535         case DRX_CTRL_POWER_MODE:
20536                 {
20537                         return ctrl_power_mode(demod, (enum drx_power_mode *)ctrl_data);
20538                 }
20539                 break;
20540       /*======================================================================*/
20541         case DRX_CTRL_VERSION:
20542                 {
20543                         return ctrl_version(demod,
20544                                            (struct drx_version_list **)ctrl_data);
20545                 }
20546                 break;
20547       /*======================================================================*/
20548         case DRX_CTRL_PROBE_DEVICE:
20549                 {
20550                         return ctrl_probe_device(demod);
20551                 }
20552                 break;
20553       /*======================================================================*/
20554         case DRX_CTRL_SET_OOB:
20555                 {
20556                         return ctrl_set_oob(demod, (struct drxoob *)ctrl_data);
20557                 }
20558                 break;
20559       /*======================================================================*/
20560         case DRX_CTRL_GET_OOB:
20561                 {
20562                         return ctrl_get_oob(demod, (struct drxoob_status *)ctrl_data);
20563                 }
20564                 break;
20565       /*======================================================================*/
20566         case DRX_CTRL_SET_UIO_CFG:
20567                 {
20568                         return ctrl_set_uio_cfg(demod, (struct drxuio_cfg *)ctrl_data);
20569                 }
20570                 break;
20571       /*======================================================================*/
20572         case DRX_CTRL_GET_UIO_CFG:
20573                 {
20574                         return ctrl_getuio_cfg(demod, (struct drxuio_cfg *)ctrl_data);
20575                 }
20576                 break;
20577       /*======================================================================*/
20578         case DRX_CTRL_UIO_READ:
20579                 {
20580                         return ctrl_uio_read(demod, (struct drxuio_data *)ctrl_data);
20581                 }
20582                 break;
20583       /*======================================================================*/
20584         case DRX_CTRL_UIO_WRITE:
20585                 {
20586                         return ctrl_uio_write(demod, (struct drxuio_data *)ctrl_data);
20587                 }
20588                 break;
20589       /*======================================================================*/
20590         case DRX_CTRL_AUD_SET_STANDARD:
20591                 {
20592                         return aud_ctrl_set_standard(demod,
20593                                                   (enum drx_aud_standard *) ctrl_data);
20594                 }
20595                 break;
20596       /*======================================================================*/
20597         case DRX_CTRL_AUD_GET_STANDARD:
20598                 {
20599                         return aud_ctrl_get_standard(demod,
20600                                                   (enum drx_aud_standard *) ctrl_data);
20601                 }
20602                 break;
20603       /*======================================================================*/
20604         case DRX_CTRL_AUD_GET_STATUS:
20605                 {
20606                         return aud_ctrl_get_status(demod,
20607                                                 (struct drx_aud_status *) ctrl_data);
20608                 }
20609                 break;
20610       /*======================================================================*/
20611         case DRX_CTRL_AUD_BEEP:
20612                 {
20613                         return aud_ctrl_beep(demod, (struct drx_aud_beep *)ctrl_data);
20614                 }
20615                 break;
20616
20617       /*======================================================================*/
20618         case DRX_CTRL_I2C_READWRITE:
20619                 {
20620                         return ctrl_i2c_write_read(demod,
20621                                                 (struct drxi2c_data *) ctrl_data);
20622                 }
20623                 break;
20624 #ifdef DRXJ_SPLIT_UCODE_UPLOAD
20625         case DRX_CTRL_LOAD_UCODE:
20626                 {
20627                         return ctrl_u_code_upload(demod,
20628                                                (p_drxu_code_info_t) ctrl_data,
20629                                                UCODE_UPLOAD, false);
20630                 }
20631                 break;
20632         case DRX_CTRL_VERIFY_UCODE:
20633                 {
20634                         return ctrl_u_code_upload(demod,
20635                                                (p_drxu_code_info_t) ctrl_data,
20636                                                UCODE_VERIFY, false);
20637                 }
20638                 break;
20639 #endif /* DRXJ_SPLIT_UCODE_UPLOAD */
20640         case DRX_CTRL_VALIDATE_UCODE:
20641                 {
20642                         return ctrl_validate_u_code(demod);
20643                 }
20644                 break;
20645         default:
20646                 return -ENOTSUPP;
20647         }
20648         return 0;
20649 }
20650
20651 /*
20652  * Microcode related functions
20653  */
20654
20655 /**
20656  * drx_u_code_compute_crc       - Compute CRC of block of microcode data.
20657  * @block_data: Pointer to microcode data.
20658  * @nr_words:   Size of microcode block (number of 16 bits words).
20659  *
20660  * returns The computed CRC residue.
20661  */
20662 static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
20663 {
20664         u16 i = 0;
20665         u16 j = 0;
20666         u32 crc_word = 0;
20667         u32 carry = 0;
20668
20669         while (i < nr_words) {
20670                 crc_word |= (u32)be16_to_cpu(*(u32 *)(block_data));
20671                 for (j = 0; j < 16; j++) {
20672                         crc_word <<= 1;
20673                         if (carry != 0)
20674                                 crc_word ^= 0x80050000UL;
20675                         carry = crc_word & 0x80000000UL;
20676                 }
20677                 i++;
20678                 block_data += (sizeof(u16));
20679         }
20680         return (u16)(crc_word >> 16);
20681 }
20682
20683 /**
20684  * drx_check_firmware - checks if the loaded firmware is valid
20685  *
20686  * @demod:      demod structure
20687  * @mc_data:    pointer to the start of the firmware
20688  * @size:       firmware size
20689  */
20690 static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
20691                           unsigned size)
20692 {
20693         struct drxu_code_block_hdr block_hdr;
20694         int i;
20695         unsigned count = 2 * sizeof(u16);
20696         u32 mc_dev_type, mc_version, mc_base_version;
20697         u16 mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data + sizeof(u16)));
20698
20699         /*
20700          * Scan microcode blocks first for version info
20701          * and firmware check
20702          */
20703
20704         /* Clear version block */
20705         DRX_ATTR_MCRECORD(demod).aux_type = 0;
20706         DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
20707         DRX_ATTR_MCRECORD(demod).mc_version = 0;
20708         DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
20709
20710         for (i = 0; i < mc_nr_of_blks; i++) {
20711                 if (count + 3 * sizeof(u16) + sizeof(u32) > size)
20712                         goto eof;
20713
20714                 /* Process block header */
20715                 block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data + count));
20716                 count += sizeof(u32);
20717                 block_hdr.size = be16_to_cpu(*(u32 *)(mc_data + count));
20718                 count += sizeof(u16);
20719                 block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data + count));
20720                 count += sizeof(u16);
20721                 block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data + count));
20722                 count += sizeof(u16);
20723
20724                 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
20725                         count, block_hdr.addr, block_hdr.size, block_hdr.flags,
20726                         block_hdr.CRC);
20727
20728                 if (block_hdr.flags & 0x8) {
20729                         u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
20730                         u16 auxtype;
20731
20732                         if (block_hdr.addr + sizeof(u16) > size)
20733                                 goto eof;
20734
20735                         auxtype = be16_to_cpu(*(u32 *)(auxblk));
20736
20737                         /* Aux block. Check type */
20738                         if (DRX_ISMCVERTYPE(auxtype)) {
20739                                 if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
20740                                         goto eof;
20741
20742                                 auxblk += sizeof(u16);
20743                                 mc_dev_type = be32_to_cpu(*(u32 *)(auxblk));
20744                                 auxblk += sizeof(u32);
20745                                 mc_version = be32_to_cpu(*(u32 *)(auxblk));
20746                                 auxblk += sizeof(u32);
20747                                 mc_base_version = be32_to_cpu(*(u32 *)(auxblk));
20748
20749                                 DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
20750                                 DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
20751                                 DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
20752                                 DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
20753
20754                                 pr_info("Firmware dev %x, ver %x, base ver %x\n",
20755                                         mc_dev_type, mc_version, mc_base_version);
20756
20757                         }
20758                 } else if (count + block_hdr.size * sizeof(u16) > size)
20759                         goto eof;
20760
20761                 count += block_hdr.size * sizeof(u16);
20762         }
20763         return 0;
20764 eof:
20765         pr_err("Firmware is truncated at pos %u/%u\n", count, size);
20766         return -EINVAL;
20767 }
20768
20769 /**
20770  * drx_ctrl_u_code - Handle microcode upload or verify.
20771  * @dev_addr: Address of device.
20772  * @mc_info:  Pointer to information about microcode data.
20773  * @action:  Either UCODE_UPLOAD or UCODE_VERIFY
20774  *
20775  * This function returns:
20776  *      0:
20777  *              - In case of UCODE_UPLOAD: code is successfully uploaded.
20778  *               - In case of UCODE_VERIFY: image on device is equal to
20779  *                image provided to this control function.
20780  *      -EIO:
20781  *              - In case of UCODE_UPLOAD: I2C error.
20782  *              - In case of UCODE_VERIFY: I2C error or image on device
20783  *                is not equal to image provided to this control function.
20784  *      -EINVAL:
20785  *              - Invalid arguments.
20786  *              - Provided image is corrupt
20787  */
20788 static int drx_ctrl_u_code(struct drx_demod_instance *demod,
20789                        struct drxu_code_info *mc_info,
20790                        enum drxu_code_action action)
20791 {
20792         struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
20793         int rc;
20794         u16 i = 0;
20795         u16 mc_nr_of_blks = 0;
20796         u16 mc_magic_word = 0;
20797         const u8 *mc_data_init = NULL;
20798         u8 *mc_data = NULL;
20799         unsigned size;
20800         char *mc_file = mc_info->mc_file;
20801
20802         /* Check arguments */
20803         if (!mc_info || !mc_file)
20804                 return -EINVAL;
20805
20806         if (!demod->firmware) {
20807                 const struct firmware *fw = NULL;
20808
20809                 rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
20810                 if (rc < 0) {
20811                         pr_err("Couldn't read firmware %s\n", mc_file);
20812                         return -ENOENT;
20813                 }
20814                 demod->firmware = fw;
20815
20816                 if (demod->firmware->size < 2 * sizeof(u16)) {
20817                         rc = -EINVAL;
20818                         pr_err("Firmware is too short!\n");
20819                         goto release;
20820                 }
20821
20822                 pr_info("Firmware %s, size %zu\n",
20823                         mc_file, demod->firmware->size);
20824         }
20825
20826         mc_data_init = demod->firmware->data;
20827         size = demod->firmware->size;
20828
20829         mc_data = (void *)mc_data_init;
20830         /* Check data */
20831         mc_magic_word = be16_to_cpu(*(u32 *)(mc_data));
20832         mc_data += sizeof(u16);
20833         mc_nr_of_blks = be16_to_cpu(*(u32 *)(mc_data));
20834         mc_data += sizeof(u16);
20835
20836         if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
20837                 rc = -EINVAL;
20838                 pr_err("Firmware magic word doesn't match\n");
20839                 goto release;
20840         }
20841
20842         if (action == UCODE_UPLOAD) {
20843                 rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
20844                 if (rc)
20845                         goto release;
20846
20847                 /* After scanning, validate the microcode.
20848                    It is also valid if no validation control exists.
20849                  */
20850                 rc = drx_ctrl(demod, DRX_CTRL_VALIDATE_UCODE, NULL);
20851                 if (rc != 0 && rc != -ENOTSUPP) {
20852                         pr_err("Validate ucode not supported\n");
20853                         return rc;
20854                 }
20855                 pr_info("Uploading firmware %s\n", mc_file);
20856         } else if (action == UCODE_VERIFY) {
20857                 pr_info("Verifying if firmware upload was ok.\n");
20858         }
20859
20860         /* Process microcode blocks */
20861         for (i = 0; i < mc_nr_of_blks; i++) {
20862                 struct drxu_code_block_hdr block_hdr;
20863                 u16 mc_block_nr_bytes = 0;
20864
20865                 /* Process block header */
20866                 block_hdr.addr = be32_to_cpu(*(u32 *)(mc_data));
20867                 mc_data += sizeof(u32);
20868                 block_hdr.size = be16_to_cpu(*(u32 *)(mc_data));
20869                 mc_data += sizeof(u16);
20870                 block_hdr.flags = be16_to_cpu(*(u32 *)(mc_data));
20871                 mc_data += sizeof(u16);
20872                 block_hdr.CRC = be16_to_cpu(*(u32 *)(mc_data));
20873                 mc_data += sizeof(u16);
20874
20875                 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
20876                         (unsigned)(mc_data - mc_data_init), block_hdr.addr,
20877                          block_hdr.size, block_hdr.flags, block_hdr.CRC);
20878
20879                 /* Check block header on:
20880                    - data larger than 64Kb
20881                    - if CRC enabled check CRC
20882                  */
20883                 if ((block_hdr.size > 0x7FFF) ||
20884                     (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
20885                      (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
20886                     ) {
20887                         /* Wrong data ! */
20888                         rc = -EINVAL;
20889                         pr_err("firmware CRC is wrong\n");
20890                         goto release;
20891                 }
20892
20893                 if (!block_hdr.size)
20894                         continue;
20895
20896                 mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
20897
20898                 /* Perform the desired action */
20899                 switch (action) {
20900                 case UCODE_UPLOAD:      /* Upload microcode */
20901                         if (demod->my_access_funct->write_block_func(dev_addr,
20902                                                         block_hdr.addr,
20903                                                         mc_block_nr_bytes,
20904                                                         mc_data, 0x0000)) {
20905                                 rc = -EIO;
20906                                 pr_err("error writing firmware at pos %u\n",
20907                                        (unsigned)(mc_data - mc_data_init));
20908                                 goto release;
20909                         }
20910                         break;
20911                 case UCODE_VERIFY: {    /* Verify uploaded microcode */
20912                         int result = 0;
20913                         u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
20914                         u32 bytes_to_comp = 0;
20915                         u32 bytes_left = mc_block_nr_bytes;
20916                         u32 curr_addr = block_hdr.addr;
20917                         u8 *curr_ptr = mc_data;
20918
20919                         while (bytes_left != 0) {
20920                                 if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
20921                                         bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
20922                                 else
20923                                         bytes_to_comp = bytes_left;
20924
20925                                 if (demod->my_access_funct->
20926                                     read_block_func(dev_addr,
20927                                                     curr_addr,
20928                                                     (u16)bytes_to_comp,
20929                                                     (u8 *)mc_data_buffer,
20930                                                     0x0000)) {
20931                                         pr_err("error reading firmware at pos %u\n",
20932                                                (unsigned)(mc_data - mc_data_init));
20933                                         return -EIO;
20934                                 }
20935
20936                                 result =drxbsp_hst_memcmp(curr_ptr,
20937                                                           mc_data_buffer,
20938                                                           bytes_to_comp);
20939
20940                                 if (result) {
20941                                         pr_err("error verifying firmware at pos %u\n",
20942                                                (unsigned)(mc_data - mc_data_init));
20943                                         return -EIO;
20944                                 }
20945
20946                                 curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
20947                                 curr_ptr =&(curr_ptr[bytes_to_comp]);
20948                                 bytes_left -=((u32) bytes_to_comp);
20949                         }
20950                         break;
20951                 }
20952                 default:
20953                         return -EINVAL;
20954                         break;
20955
20956                 }
20957                 mc_data += mc_block_nr_bytes;
20958         }
20959
20960         return 0;
20961
20962 release:
20963         release_firmware(demod->firmware);
20964         demod->firmware = NULL;
20965
20966         return rc;
20967 }
20968
20969 /*============================================================================*/
20970
20971 /**
20972  * drx_ctrl_version - Build list of version information.
20973  * @demod: A pointer to a demodulator instance.
20974  * @version_list: Pointer to linked list of versions.
20975  *
20976  * This function returns:
20977  *      0:              Version information stored in version_list
20978  *      -EINVAL:        Invalid arguments.
20979  */
20980 static int drx_ctrl_version(struct drx_demod_instance *demod,
20981                         struct drx_version_list **version_list)
20982 {
20983         static char drx_driver_core_module_name[] = "Core driver";
20984         static char drx_driver_core_version_text[] =
20985             DRX_VERSIONSTRING(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
20986
20987         static struct drx_version drx_driver_core_version;
20988         static struct drx_version_list drx_driver_core_version_list;
20989
20990         struct drx_version_list *demod_version_list = NULL;
20991         int return_status = -EIO;
20992
20993         /* Check arguments */
20994         if (version_list == NULL)
20995                 return -EINVAL;
20996
20997         /* Get version info list from demod */
20998         return_status = (*(demod->my_demod_funct->ctrl_func)) (demod,
20999                                                            DRX_CTRL_VERSION,
21000                                                            (void *)
21001                                                            &demod_version_list);
21002
21003         /* Always fill in the information of the driver SW . */
21004         drx_driver_core_version.module_type = DRX_MODULE_DRIVERCORE;
21005         drx_driver_core_version.module_name = drx_driver_core_module_name;
21006         drx_driver_core_version.v_major = VERSION_MAJOR;
21007         drx_driver_core_version.v_minor = VERSION_MINOR;
21008         drx_driver_core_version.v_patch = VERSION_PATCH;
21009         drx_driver_core_version.v_string = drx_driver_core_version_text;
21010
21011         drx_driver_core_version_list.version = &drx_driver_core_version;
21012         drx_driver_core_version_list.next = (struct drx_version_list *) (NULL);
21013
21014         if ((return_status == 0) && (demod_version_list != NULL)) {
21015                 /* Append versioninfo from driver to versioninfo from demod  */
21016                 /* Return version info in "bottom-up" order. This way, multiple
21017                    devices can be handled without using malloc. */
21018                 struct drx_version_list *current_list_element = demod_version_list;
21019                 while (current_list_element->next != NULL)
21020                         current_list_element = current_list_element->next;
21021                 current_list_element->next = &drx_driver_core_version_list;
21022
21023                 *version_list = demod_version_list;
21024         } else {
21025                 /* Just return versioninfo from driver */
21026                 *version_list = &drx_driver_core_version_list;
21027         }
21028
21029         return 0;
21030 }
21031
21032 /*
21033  * Exported functions
21034  */
21035
21036 /**
21037  * drx_open - Open a demodulator instance.
21038  * @demod: A pointer to a demodulator instance.
21039  *
21040  * This function returns:
21041  *      0:              Opened demod instance with succes.
21042  *      -EIO:           Driver not initialized or unable to initialize
21043  *                      demod.
21044  *      -EINVAL:        Demod instance has invalid content.
21045  *
21046  */
21047
21048 int drx_open(struct drx_demod_instance *demod)
21049 {
21050         int status = 0;
21051
21052         if ((demod == NULL) ||
21053             (demod->my_demod_funct == NULL) ||
21054             (demod->my_common_attr == NULL) ||
21055             (demod->my_ext_attr == NULL) ||
21056             (demod->my_i2c_dev_addr == NULL) ||
21057             (demod->my_common_attr->is_opened)) {
21058                 return -EINVAL;
21059         }
21060
21061         status = (*(demod->my_demod_funct->open_func)) (demod);
21062
21063         if (status == 0)
21064                 demod->my_common_attr->is_opened = true;
21065
21066         return status;
21067 }
21068
21069 /*============================================================================*/
21070
21071 /**
21072  * drx_close - Close device
21073  * @demod: A pointer to a demodulator instance.
21074  *
21075  * Free resources occupied by device instance.
21076  * Put device into sleep mode.
21077  *
21078  * This function returns:
21079  *      0:              Closed demod instance with succes.
21080  *      -EIO:           Driver not initialized or error during close
21081  *                      demod.
21082  *      -EINVAL:        Demod instance has invalid content.
21083  */
21084 int drx_close(struct drx_demod_instance *demod)
21085 {
21086         int status = 0;
21087
21088         if ((demod == NULL) ||
21089             (demod->my_demod_funct == NULL) ||
21090             (demod->my_common_attr == NULL) ||
21091             (demod->my_ext_attr == NULL) ||
21092             (demod->my_i2c_dev_addr == NULL) ||
21093             (!demod->my_common_attr->is_opened)) {
21094                 return -EINVAL;
21095         }
21096
21097         status = (*(demod->my_demod_funct->close_func)) (demod);
21098
21099         DRX_ATTR_ISOPENED(demod) = false;
21100
21101         return status;
21102 }
21103 /**
21104  * drx_ctrl - Control the device.
21105  * @demod:    A pointer to a demodulator instance.
21106  * @ctrl:     Reference to desired control function.
21107  * @ctrl_data: Pointer to data structure for control function.
21108  *
21109  * Data needed or returned by the control function is stored in ctrl_data.
21110  *
21111  * This function returns:
21112  *      0:              Control function completed successfully.
21113  *      -EIO:           Driver not initialized or error during control demod.
21114  *      -EINVAL:        Demod instance or ctrl_data has invalid content.
21115  *      -ENOTSUPP:      Specified control function is not available.
21116  */
21117
21118 int drx_ctrl(struct drx_demod_instance *demod, u32 ctrl, void *ctrl_data)
21119 {
21120         int status = -EIO;
21121
21122         if ((demod == NULL) ||
21123             (demod->my_demod_funct == NULL) ||
21124             (demod->my_common_attr == NULL) ||
21125             (demod->my_ext_attr == NULL) || (demod->my_i2c_dev_addr == NULL)
21126             ) {
21127                 return -EINVAL;
21128         }
21129
21130         if (((!demod->my_common_attr->is_opened) &&
21131              (ctrl != DRX_CTRL_PROBE_DEVICE) && (ctrl != DRX_CTRL_VERSION))
21132             ) {
21133                 return -EINVAL;
21134         }
21135
21136         if ((DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode) &&
21137              (ctrl != DRX_CTRL_POWER_MODE) &&
21138              (ctrl != DRX_CTRL_PROBE_DEVICE) &&
21139              (ctrl != DRX_CTRL_NOP) && (ctrl != DRX_CTRL_VERSION)
21140             )
21141             ) {
21142                 return -ENOTSUPP;
21143         }
21144
21145         /* Fixed control functions */
21146         switch (ctrl) {
21147       /*======================================================================*/
21148         case DRX_CTRL_NOP:
21149                 /* No operation */
21150                 return 0;
21151                 break;
21152
21153       /*======================================================================*/
21154         case DRX_CTRL_VERSION:
21155                 return drx_ctrl_version(demod, (struct drx_version_list **)ctrl_data);
21156                 break;
21157
21158       /*======================================================================*/
21159         default:
21160                 /* Do nothing */
21161                 break;
21162         }
21163
21164         /* Virtual functions */
21165         /* First try calling function from derived class */
21166         status = (*(demod->my_demod_funct->ctrl_func)) (demod, ctrl, ctrl_data);
21167         if (status == -ENOTSUPP) {
21168                 /* Now try calling a the base class function */
21169                 switch (ctrl) {
21170          /*===================================================================*/
21171                 case DRX_CTRL_LOAD_UCODE:
21172                         return drx_ctrl_u_code(demod,
21173                                          (struct drxu_code_info *)ctrl_data,
21174                                          UCODE_UPLOAD);
21175                         break;
21176
21177          /*===================================================================*/
21178                 case DRX_CTRL_VERIFY_UCODE:
21179                         {
21180                                 return drx_ctrl_u_code(demod,
21181                                                  (struct drxu_code_info *)ctrl_data,
21182                                                  UCODE_VERIFY);
21183                         }
21184                         break;
21185
21186          /*===================================================================*/
21187                 default:
21188                         pr_err("control %d not supported\n", ctrl);
21189                         return -ENOTSUPP;
21190                 }
21191         } else {
21192                 return status;
21193         }
21194
21195         return 0;
21196 }