1 /*
2 Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of Trident Microsystems nor Hauppauge Computer Works
14 nor the names of its contributors may be used to endorse or promote
15 products derived from this software without specific prior written
16 permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 POSSIBILITY OF SUCH DAMAGE.
29
30 DRXJ specific implementation of DRX driver
31 authors: Dragan Savic, Milos Nikolic, Mihajlo Katona, Tao Ding, Paul Janssen
32
33 The Linux DVB Driver for Micronas DRX39xx family (drx3933j) was
34 written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
35
36 This program is free software; you can redistribute it and/or modify
37 it under the terms of the GNU General Public License as published by
38 the Free Software Foundation; either version 2 of the License, or
39 (at your option) any later version.
40
41 This program is distributed in the hope that it will be useful,
42 but WITHOUT ANY WARRANTY; without even the implied warranty of
43 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44
45 GNU General Public License for more details.
46
47 You should have received a copy of the GNU General Public License
48 along with this program; if not, write to the Free Software
49 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
50 */
51
52 /*-----------------------------------------------------------------------------
53 INCLUDE FILES
54 ----------------------------------------------------------------------------*/
55
56 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
57
58 #include <linux/module.h>
59 #include <linux/init.h>
60 #include <linux/string.h>
61 #include <linux/slab.h>
62 #include <asm/div64.h>
63
64 #include <media/dvb_frontend.h>
65 #include "drx39xxj.h"
66
67 #include "drxj.h"
68 #include "drxj_map.h"
69
70 /*============================================================================*/
71 /*=== DEFINES ================================================================*/
72 /*============================================================================*/
73
74 #define DRX39XX_MAIN_FIRMWARE "dvb-fe-drxj-mc-1.0.8.fw"
75
76 /*
77 * \brief Maximum u32 value.
78 */
79 #ifndef MAX_U32
80 #define MAX_U32 ((u32) (0xFFFFFFFFL))
81 #endif
82
83 /* Customer configurable hardware settings, etc */
84 #ifndef MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
85 #define MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
86 #endif
87
88 #ifndef MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
89 #define MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH 0x02
90 #endif
91
92 #ifndef MPEG_OUTPUT_CLK_DRIVE_STRENGTH
93 #define MPEG_OUTPUT_CLK_DRIVE_STRENGTH 0x06
94 #endif
95
96 #ifndef OOB_CRX_DRIVE_STRENGTH
97 #define OOB_CRX_DRIVE_STRENGTH 0x02
98 #endif
99
100 #ifndef OOB_DRX_DRIVE_STRENGTH
101 #define OOB_DRX_DRIVE_STRENGTH 0x02
102 #endif
103 /*** START DJCOMBO patches to DRXJ registermap constants *********************/
104 /*** registermap 200706071303 from drxj **************************************/
105 #define ATV_TOP_CR_AMP_TH_FM 0x0
106 #define ATV_TOP_CR_AMP_TH_L 0xA
107 #define ATV_TOP_CR_AMP_TH_LP 0xA
108 #define ATV_TOP_CR_AMP_TH_BG 0x8
109 #define ATV_TOP_CR_AMP_TH_DK 0x8
110 #define ATV_TOP_CR_AMP_TH_I 0x8
111 #define ATV_TOP_CR_CONT_CR_D_MN 0x18
112 #define ATV_TOP_CR_CONT_CR_D_FM 0x0
113 #define ATV_TOP_CR_CONT_CR_D_L 0x20
114 #define ATV_TOP_CR_CONT_CR_D_LP 0x20
115 #define ATV_TOP_CR_CONT_CR_D_BG 0x18
116 #define ATV_TOP_CR_CONT_CR_D_DK 0x18
117 #define ATV_TOP_CR_CONT_CR_D_I 0x18
118 #define ATV_TOP_CR_CONT_CR_I_MN 0x80
119 #define ATV_TOP_CR_CONT_CR_I_FM 0x0
120 #define ATV_TOP_CR_CONT_CR_I_L 0x80
121 #define ATV_TOP_CR_CONT_CR_I_LP 0x80
122 #define ATV_TOP_CR_CONT_CR_I_BG 0x80
123 #define ATV_TOP_CR_CONT_CR_I_DK 0x80
124 #define ATV_TOP_CR_CONT_CR_I_I 0x80
125 #define ATV_TOP_CR_CONT_CR_P_MN 0x4
126 #define ATV_TOP_CR_CONT_CR_P_FM 0x0
127 #define ATV_TOP_CR_CONT_CR_P_L 0x4
128 #define ATV_TOP_CR_CONT_CR_P_LP 0x4
129 #define ATV_TOP_CR_CONT_CR_P_BG 0x4
130 #define ATV_TOP_CR_CONT_CR_P_DK 0x4
131 #define ATV_TOP_CR_CONT_CR_P_I 0x4
132 #define ATV_TOP_CR_OVM_TH_MN 0xA0
133 #define ATV_TOP_CR_OVM_TH_FM 0x0
134 #define ATV_TOP_CR_OVM_TH_L 0xA0
135 #define ATV_TOP_CR_OVM_TH_LP 0xA0
136 #define ATV_TOP_CR_OVM_TH_BG 0xA0
137 #define ATV_TOP_CR_OVM_TH_DK 0xA0
138 #define ATV_TOP_CR_OVM_TH_I 0xA0
139 #define ATV_TOP_EQU0_EQU_C0_FM 0x0
140 #define ATV_TOP_EQU0_EQU_C0_L 0x3
141 #define ATV_TOP_EQU0_EQU_C0_LP 0x3
142 #define ATV_TOP_EQU0_EQU_C0_BG 0x7
143 #define ATV_TOP_EQU0_EQU_C0_DK 0x0
144 #define ATV_TOP_EQU0_EQU_C0_I 0x3
145 #define ATV_TOP_EQU1_EQU_C1_FM 0x0
146 #define ATV_TOP_EQU1_EQU_C1_L 0x1F6
147 #define ATV_TOP_EQU1_EQU_C1_LP 0x1F6
148 #define ATV_TOP_EQU1_EQU_C1_BG 0x197
149 #define ATV_TOP_EQU1_EQU_C1_DK 0x198
150 #define ATV_TOP_EQU1_EQU_C1_I 0x1F6
151 #define ATV_TOP_EQU2_EQU_C2_FM 0x0
152 #define ATV_TOP_EQU2_EQU_C2_L 0x28
153 #define ATV_TOP_EQU2_EQU_C2_LP 0x28
154 #define ATV_TOP_EQU2_EQU_C2_BG 0xC5
155 #define ATV_TOP_EQU2_EQU_C2_DK 0xB0
156 #define ATV_TOP_EQU2_EQU_C2_I 0x28
157 #define ATV_TOP_EQU3_EQU_C3_FM 0x0
158 #define ATV_TOP_EQU3_EQU_C3_L 0x192
159 #define ATV_TOP_EQU3_EQU_C3_LP 0x192
160 #define ATV_TOP_EQU3_EQU_C3_BG 0x12E
161 #define ATV_TOP_EQU3_EQU_C3_DK 0x18E
162 #define ATV_TOP_EQU3_EQU_C3_I 0x192
163 #define ATV_TOP_STD_MODE_MN 0x0
164 #define ATV_TOP_STD_MODE_FM 0x1
165 #define ATV_TOP_STD_MODE_L 0x0
166 #define ATV_TOP_STD_MODE_LP 0x0
167 #define ATV_TOP_STD_MODE_BG 0x0
168 #define ATV_TOP_STD_MODE_DK 0x0
169 #define ATV_TOP_STD_MODE_I 0x0
170 #define ATV_TOP_STD_VID_POL_MN 0x0
171 #define ATV_TOP_STD_VID_POL_FM 0x0
172 #define ATV_TOP_STD_VID_POL_L 0x2
173 #define ATV_TOP_STD_VID_POL_LP 0x2
174 #define ATV_TOP_STD_VID_POL_BG 0x0
175 #define ATV_TOP_STD_VID_POL_DK 0x0
176 #define ATV_TOP_STD_VID_POL_I 0x0
177 #define ATV_TOP_VID_AMP_MN 0x380
178 #define ATV_TOP_VID_AMP_FM 0x0
179 #define ATV_TOP_VID_AMP_L 0xF50
180 #define ATV_TOP_VID_AMP_LP 0xF50
181 #define ATV_TOP_VID_AMP_BG 0x380
182 #define ATV_TOP_VID_AMP_DK 0x394
183 #define ATV_TOP_VID_AMP_I 0x3D8
184 #define IQM_CF_OUT_ENA_OFDM__M 0x4
185 #define IQM_FS_ADJ_SEL_B_QAM 0x1
186 #define IQM_FS_ADJ_SEL_B_OFF 0x0
187 #define IQM_FS_ADJ_SEL_B_VSB 0x2
188 #define IQM_RC_ADJ_SEL_B_OFF 0x0
189 #define IQM_RC_ADJ_SEL_B_QAM 0x1
190 #define IQM_RC_ADJ_SEL_B_VSB 0x2
191 /*** END DJCOMBO patches to DRXJ registermap *********************************/
192
193 #include "drx_driver_version.h"
194
195 /* #define DRX_DEBUG */
196 #ifdef DRX_DEBUG
197 #include <stdio.h>
198 #endif
199
200 /*-----------------------------------------------------------------------------
201 ENUMS
202 ----------------------------------------------------------------------------*/
203
204 /*-----------------------------------------------------------------------------
205 DEFINES
206 ----------------------------------------------------------------------------*/
207 #ifndef DRXJ_WAKE_UP_KEY
208 #define DRXJ_WAKE_UP_KEY (demod->my_i2c_dev_addr->i2c_addr)
209 #endif
210
211 /*
212 * \def DRXJ_DEF_I2C_ADDR
213 * \brief Default I2C address of a demodulator instance.
214 */
215 #define DRXJ_DEF_I2C_ADDR (0x52)
216
217 /*
218 * \def DRXJ_DEF_DEMOD_DEV_ID
219 * \brief Default device identifier of a demodultor instance.
220 */
221 #define DRXJ_DEF_DEMOD_DEV_ID (1)
222
223 /*
224 * \def DRXJ_SCAN_TIMEOUT
225 * \brief Timeout value for waiting on demod lock during channel scan (millisec).
226 */
227 #define DRXJ_SCAN_TIMEOUT 1000
228
229 /*
230 * \def HI_I2C_DELAY
231 * \brief HI timing delay for I2C timing (in nano seconds)
232 *
233 * Used to compute HI_CFG_DIV
234 */
235 #define HI_I2C_DELAY 42
236
237 /*
238 * \def HI_I2C_BRIDGE_DELAY
239 * \brief HI timing delay for I2C timing (in nano seconds)
240 *
241 * Used to compute HI_CFG_BDL
242 */
243 #define HI_I2C_BRIDGE_DELAY 750
244
245 /*
246 * \brief Time Window for MER and SER Measurement in Units of Segment duration.
247 */
248 #define VSB_TOP_MEASUREMENT_PERIOD 64
249 #define SYMBOLS_PER_SEGMENT 832
250
251 /*
252 * \brief bit rate and segment rate constants used for SER and BER.
253 */
254 /* values taken from the QAM microcode */
255 #define DRXJ_QAM_SL_SIG_POWER_QAM_UNKNOWN 0
256 #define DRXJ_QAM_SL_SIG_POWER_QPSK 32768
257 #define DRXJ_QAM_SL_SIG_POWER_QAM8 24576
258 #define DRXJ_QAM_SL_SIG_POWER_QAM16 40960
259 #define DRXJ_QAM_SL_SIG_POWER_QAM32 20480
260 #define DRXJ_QAM_SL_SIG_POWER_QAM64 43008
261 #define DRXJ_QAM_SL_SIG_POWER_QAM128 20992
262 #define DRXJ_QAM_SL_SIG_POWER_QAM256 43520
263 /*
264 * \brief Min supported symbolrates.
265 */
266 #ifndef DRXJ_QAM_SYMBOLRATE_MIN
267 #define DRXJ_QAM_SYMBOLRATE_MIN (520000)
268 #endif
269
270 /*
271 * \brief Max supported symbolrates.
272 */
273 #ifndef DRXJ_QAM_SYMBOLRATE_MAX
274 #define DRXJ_QAM_SYMBOLRATE_MAX (7233000)
275 #endif
276
277 /*
278 * \def DRXJ_QAM_MAX_WAITTIME
279 * \brief Maximal wait time for QAM auto constellation in ms
280 */
281 #ifndef DRXJ_QAM_MAX_WAITTIME
282 #define DRXJ_QAM_MAX_WAITTIME 900
283 #endif
284
285 #ifndef DRXJ_QAM_FEC_LOCK_WAITTIME
286 #define DRXJ_QAM_FEC_LOCK_WAITTIME 150
287 #endif
288
289 #ifndef DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME
290 #define DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME 200
291 #endif
292
293 /*
294 * \def SCU status and results
295 * \brief SCU
296 */
297 #define DRX_SCU_READY 0
298 #define DRXJ_MAX_WAITTIME 100 /* ms */
299 #define FEC_RS_MEASUREMENT_PERIOD 12894 /* 1 sec */
300 #define FEC_RS_MEASUREMENT_PRESCALE 1 /* n sec */
301
302 /*
303 * \def DRX_AUD_MAX_DEVIATION
304 * \brief Needed for calculation of prescale feature in AUD
305 */
306 #ifndef DRXJ_AUD_MAX_FM_DEVIATION
307 #define DRXJ_AUD_MAX_FM_DEVIATION 100 /* kHz */
308 #endif
309
310 /*
311 * \brief Needed for calculation of NICAM prescale feature in AUD
312 */
313 #ifndef DRXJ_AUD_MAX_NICAM_PRESCALE
314 #define DRXJ_AUD_MAX_NICAM_PRESCALE (9) /* dB */
315 #endif
316
317 /*
318 * \brief Needed for calculation of NICAM prescale feature in AUD
319 */
320 #ifndef DRXJ_AUD_MAX_WAITTIME
321 #define DRXJ_AUD_MAX_WAITTIME 250 /* ms */
322 #endif
323
324 /* ATV config changed flags */
325 #define DRXJ_ATV_CHANGED_COEF (0x00000001UL)
326 #define DRXJ_ATV_CHANGED_PEAK_FLT (0x00000008UL)
327 #define DRXJ_ATV_CHANGED_NOISE_FLT (0x00000010UL)
328 #define DRXJ_ATV_CHANGED_OUTPUT (0x00000020UL)
329 #define DRXJ_ATV_CHANGED_SIF_ATT (0x00000040UL)
330
331 /* UIO define */
332 #define DRX_UIO_MODE_FIRMWARE_SMA DRX_UIO_MODE_FIRMWARE0
333 #define DRX_UIO_MODE_FIRMWARE_SAW DRX_UIO_MODE_FIRMWARE1
334
335 /*
336 * MICROCODE RELATED DEFINES
337 */
338
339 /* Magic word for checking correct Endianness of microcode data */
340 #define DRX_UCODE_MAGIC_WORD ((((u16)'H')<<8)+((u16)'L'))
341
342 /* CRC flag in ucode header, flags field. */
343 #define DRX_UCODE_CRC_FLAG (0x0001)
344
345 /*
346 * Maximum size of buffer used to verify the microcode.
347 * Must be an even number
348 */
349 #define DRX_UCODE_MAX_BUF_SIZE (DRXDAP_MAX_RCHUNKSIZE)
350
351 #if DRX_UCODE_MAX_BUF_SIZE & 1
352 #error DRX_UCODE_MAX_BUF_SIZE must be an even number
353 #endif
354
355 /*
356 * Power mode macros
357 */
358
359 #define DRX_ISPOWERDOWNMODE(mode) ((mode == DRX_POWER_MODE_9) || \
360 (mode == DRX_POWER_MODE_10) || \
361 (mode == DRX_POWER_MODE_11) || \
362 (mode == DRX_POWER_MODE_12) || \
363 (mode == DRX_POWER_MODE_13) || \
364 (mode == DRX_POWER_MODE_14) || \
365 (mode == DRX_POWER_MODE_15) || \
366 (mode == DRX_POWER_MODE_16) || \
367 (mode == DRX_POWER_DOWN))
368
369 /* Pin safe mode macro */
370 #define DRXJ_PIN_SAFE_MODE 0x0000
371 /*============================================================================*/
372 /*=== GLOBAL VARIABLEs =======================================================*/
373 /*============================================================================*/
374 /*
375 */
376
377 /*
378 * \brief Temporary register definitions.
379 * (register definitions that are not yet available in register master)
380 */
381
382 /*****************************************************************************/
383 /* Audio block 0x103 is write only. To avoid shadowing in driver accessing */
384 /* RAM addresses directly. This must be READ ONLY to avoid problems. */
385 /* Writing to the interface addresses are more than only writing the RAM */
386 /* locations */
387 /*****************************************************************************/
388 /*
389 * \brief RAM location of MODUS registers
390 */
391 #define AUD_DEM_RAM_MODUS_HI__A 0x10204A3
392 #define AUD_DEM_RAM_MODUS_HI__M 0xF000
393
394 #define AUD_DEM_RAM_MODUS_LO__A 0x10204A4
395 #define AUD_DEM_RAM_MODUS_LO__M 0x0FFF
396
397 /*
398 * \brief RAM location of I2S config registers
399 */
400 #define AUD_DEM_RAM_I2S_CONFIG1__A 0x10204B1
401 #define AUD_DEM_RAM_I2S_CONFIG2__A 0x10204B2
402
403 /*
404 * \brief RAM location of DCO config registers
405 */
406 #define AUD_DEM_RAM_DCO_B_HI__A 0x1020461
407 #define AUD_DEM_RAM_DCO_B_LO__A 0x1020462
408 #define AUD_DEM_RAM_DCO_A_HI__A 0x1020463
409 #define AUD_DEM_RAM_DCO_A_LO__A 0x1020464
410
411 /*
412 * \brief RAM location of Threshold registers
413 */
414 #define AUD_DEM_RAM_NICAM_THRSHLD__A 0x102045A
415 #define AUD_DEM_RAM_A2_THRSHLD__A 0x10204BB
416 #define AUD_DEM_RAM_BTSC_THRSHLD__A 0x10204A6
417
418 /*
419 * \brief RAM location of Carrier Threshold registers
420 */
421 #define AUD_DEM_RAM_CM_A_THRSHLD__A 0x10204AF
422 #define AUD_DEM_RAM_CM_B_THRSHLD__A 0x10204B0
423
424 /*
425 * \brief FM Matrix register fix
426 */
427 #ifdef AUD_DEM_WR_FM_MATRIX__A
428 #undef AUD_DEM_WR_FM_MATRIX__A
429 #endif
430 #define AUD_DEM_WR_FM_MATRIX__A 0x105006F
431
432 /*============================================================================*/
433 /*
434 * \brief Defines required for audio
435 */
436 #define AUD_VOLUME_ZERO_DB 115
437 #define AUD_VOLUME_DB_MIN -60
438 #define AUD_VOLUME_DB_MAX 12
439 #define AUD_CARRIER_STRENGTH_QP_0DB 0x4000
440 #define AUD_CARRIER_STRENGTH_QP_0DB_LOG10T100 421
441 #define AUD_MAX_AVC_REF_LEVEL 15
442 #define AUD_I2S_FREQUENCY_MAX 48000UL
443 #define AUD_I2S_FREQUENCY_MIN 12000UL
444 #define AUD_RDS_ARRAY_SIZE 18
445
446 /*
447 * \brief Needed for calculation of prescale feature in AUD
448 */
449 #ifndef DRX_AUD_MAX_FM_DEVIATION
450 #define DRX_AUD_MAX_FM_DEVIATION (100) /* kHz */
451 #endif
452
453 /*
454 * \brief Needed for calculation of NICAM prescale feature in AUD
455 */
456 #ifndef DRX_AUD_MAX_NICAM_PRESCALE
457 #define DRX_AUD_MAX_NICAM_PRESCALE (9) /* dB */
458 #endif
459
460 /*============================================================================*/
461 /* Values for I2S Master/Slave pin configurations */
462 #define SIO_PDR_I2S_CL_CFG_MODE__MASTER 0x0004
463 #define SIO_PDR_I2S_CL_CFG_DRIVE__MASTER 0x0008
464 #define SIO_PDR_I2S_CL_CFG_MODE__SLAVE 0x0004
465 #define SIO_PDR_I2S_CL_CFG_DRIVE__SLAVE 0x0000
466
467 #define SIO_PDR_I2S_DA_CFG_MODE__MASTER 0x0003
468 #define SIO_PDR_I2S_DA_CFG_DRIVE__MASTER 0x0008
469 #define SIO_PDR_I2S_DA_CFG_MODE__SLAVE 0x0003
470 #define SIO_PDR_I2S_DA_CFG_DRIVE__SLAVE 0x0008
471
472 #define SIO_PDR_I2S_WS_CFG_MODE__MASTER 0x0004
473 #define SIO_PDR_I2S_WS_CFG_DRIVE__MASTER 0x0008
474 #define SIO_PDR_I2S_WS_CFG_MODE__SLAVE 0x0004
475 #define SIO_PDR_I2S_WS_CFG_DRIVE__SLAVE 0x0000
476
477 /*============================================================================*/
478 /*=== REGISTER ACCESS MACROS =================================================*/
479 /*============================================================================*/
480
481 /*
482 * This macro is used to create byte arrays for block writes.
483 * Block writes speed up I2C traffic between host and demod.
484 * The macro takes care of the required byte order in a 16 bits word.
485 * x -> lowbyte(x), highbyte(x)
486 */
487 #define DRXJ_16TO8(x) ((u8) (((u16)x) & 0xFF)), \
488 ((u8)((((u16)x)>>8)&0xFF))
489 /*
490 * This macro is used to convert byte array to 16 bit register value for block read.
491 * Block read speed up I2C traffic between host and demod.
492 * The macro takes care of the required byte order in a 16 bits word.
493 */
494 #define DRXJ_8TO16(x) ((u16) (x[0] | (x[1] << 8)))
495
496 /*============================================================================*/
497 /*=== MISC DEFINES ===========================================================*/
498 /*============================================================================*/
499
500 /*============================================================================*/
501 /*=== HI COMMAND RELATED DEFINES =============================================*/
502 /*============================================================================*/
503
504 /*
505 * \brief General maximum number of retries for ucode command interfaces
506 */
507 #define DRXJ_MAX_RETRIES (100)
508
509 /*============================================================================*/
510 /*=== STANDARD RELATED MACROS ================================================*/
511 /*============================================================================*/
512
513 #define DRXJ_ISATVSTD(std) ((std == DRX_STANDARD_PAL_SECAM_BG) || \
514 (std == DRX_STANDARD_PAL_SECAM_DK) || \
515 (std == DRX_STANDARD_PAL_SECAM_I) || \
516 (std == DRX_STANDARD_PAL_SECAM_L) || \
517 (std == DRX_STANDARD_PAL_SECAM_LP) || \
518 (std == DRX_STANDARD_NTSC) || \
519 (std == DRX_STANDARD_FM))
520
521 #define DRXJ_ISQAMSTD(std) ((std == DRX_STANDARD_ITU_A) || \
522 (std == DRX_STANDARD_ITU_B) || \
523 (std == DRX_STANDARD_ITU_C) || \
524 (std == DRX_STANDARD_ITU_D))
525
526 /*-----------------------------------------------------------------------------
527 GLOBAL VARIABLES
528 ----------------------------------------------------------------------------*/
529 /*
530 * DRXJ DAP structures
531 */
532
533 static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
534 u32 addr,
535 u16 datasize,
536 u8 *data, u32 flags);
537
538
539 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
540 u32 waddr,
541 u32 raddr,
542 u16 wdata, u16 *rdata);
543
544 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
545 u32 addr,
546 u16 *data, u32 flags);
547
548 static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
549 u32 addr,
550 u32 *data, u32 flags);
551
552 static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
553 u32 addr,
554 u16 datasize,
555 u8 *data, u32 flags);
556
557 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
558 u32 addr,
559 u16 data, u32 flags);
560
561 static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
562 u32 addr,
563 u32 data, u32 flags);
564
565 static struct drxj_data drxj_data_g = {
566 false, /* has_lna : true if LNA (aka PGA) present */
567 false, /* has_oob : true if OOB supported */
568 false, /* has_ntsc: true if NTSC supported */
569 false, /* has_btsc: true if BTSC supported */
570 false, /* has_smatx: true if SMA_TX pin is available */
571 false, /* has_smarx: true if SMA_RX pin is available */
572 false, /* has_gpio : true if GPIO pin is available */
573 false, /* has_irqn : true if IRQN pin is available */
574 0, /* mfx A1/A2/A... */
575
576 /* tuner settings */
577 false, /* tuner mirrors RF signal */
578 /* standard/channel settings */
579 DRX_STANDARD_UNKNOWN, /* current standard */
580 DRX_CONSTELLATION_AUTO, /* constellation */
581 0, /* frequency in KHz */
582 DRX_BANDWIDTH_UNKNOWN, /* curr_bandwidth */
583 DRX_MIRROR_NO, /* mirror */
584
585 /* signal quality information: */
586 /* default values taken from the QAM Programming guide */
587 /* fec_bits_desired should not be less than 4000000 */
588 4000000, /* fec_bits_desired */
589 5, /* fec_vd_plen */
590 4, /* qam_vd_prescale */
591 0xFFFF, /* qamVDPeriod */
592 204 * 8, /* fec_rs_plen annex A */
593 1, /* fec_rs_prescale */
594 FEC_RS_MEASUREMENT_PERIOD, /* fec_rs_period */
595 true, /* reset_pkt_err_acc */
596 0, /* pkt_err_acc_start */
597
598 /* HI configuration */
599 0, /* hi_cfg_timing_div */
600 0, /* hi_cfg_bridge_delay */
601 0, /* hi_cfg_wake_up_key */
602 0, /* hi_cfg_ctrl */
603 0, /* HICfgTimeout */
604 /* UIO configuration */
605 DRX_UIO_MODE_DISABLE, /* uio_sma_rx_mode */
606 DRX_UIO_MODE_DISABLE, /* uio_sma_tx_mode */
607 DRX_UIO_MODE_DISABLE, /* uioASELMode */
608 DRX_UIO_MODE_DISABLE, /* uio_irqn_mode */
609 /* FS setting */
610 0UL, /* iqm_fs_rate_ofs */
611 false, /* pos_image */
612 /* RC setting */
613 0UL, /* iqm_rc_rate_ofs */
614 /* AUD information */
615 /* false, * flagSetAUDdone */
616 /* false, * detectedRDS */
617 /* true, * flagASDRequest */
618 /* false, * flagHDevClear */
619 /* false, * flagHDevSet */
620 /* (u16) 0xFFF, * rdsLastCount */
621
622 /* ATV configuration */
623 0UL, /* flags cfg changes */
624 /* shadow of ATV_TOP_EQU0__A */
625 {-5,
626 ATV_TOP_EQU0_EQU_C0_FM,
627 ATV_TOP_EQU0_EQU_C0_L,
628 ATV_TOP_EQU0_EQU_C0_LP,
629 ATV_TOP_EQU0_EQU_C0_BG,
630 ATV_TOP_EQU0_EQU_C0_DK,
631 ATV_TOP_EQU0_EQU_C0_I},
632 /* shadow of ATV_TOP_EQU1__A */
633 {-50,
634 ATV_TOP_EQU1_EQU_C1_FM,
635 ATV_TOP_EQU1_EQU_C1_L,
636 ATV_TOP_EQU1_EQU_C1_LP,
637 ATV_TOP_EQU1_EQU_C1_BG,
638 ATV_TOP_EQU1_EQU_C1_DK,
639 ATV_TOP_EQU1_EQU_C1_I},
640 /* shadow of ATV_TOP_EQU2__A */
641 {210,
642 ATV_TOP_EQU2_EQU_C2_FM,
643 ATV_TOP_EQU2_EQU_C2_L,
644 ATV_TOP_EQU2_EQU_C2_LP,
645 ATV_TOP_EQU2_EQU_C2_BG,
646 ATV_TOP_EQU2_EQU_C2_DK,
647 ATV_TOP_EQU2_EQU_C2_I},
648 /* shadow of ATV_TOP_EQU3__A */
649 {-160,
650 ATV_TOP_EQU3_EQU_C3_FM,
651 ATV_TOP_EQU3_EQU_C3_L,
652 ATV_TOP_EQU3_EQU_C3_LP,
653 ATV_TOP_EQU3_EQU_C3_BG,
654 ATV_TOP_EQU3_EQU_C3_DK,
655 ATV_TOP_EQU3_EQU_C3_I},
656 false, /* flag: true=bypass */
657 ATV_TOP_VID_PEAK__PRE, /* shadow of ATV_TOP_VID_PEAK__A */
658 ATV_TOP_NOISE_TH__PRE, /* shadow of ATV_TOP_NOISE_TH__A */
659 true, /* flag CVBS output enable */
660 false, /* flag SIF output enable */
661 DRXJ_SIF_ATTENUATION_0DB, /* current SIF att setting */
662 { /* qam_rf_agc_cfg */
663 DRX_STANDARD_ITU_B, /* standard */
664 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
665 0, /* output_level */
666 0, /* min_output_level */
667 0xFFFF, /* max_output_level */
668 0x0000, /* speed */
669 0x0000, /* top */
670 0x0000 /* c.o.c. */
671 },
672 { /* qam_if_agc_cfg */
673 DRX_STANDARD_ITU_B, /* standard */
674 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
675 0, /* output_level */
676 0, /* min_output_level */
677 0xFFFF, /* max_output_level */
678 0x0000, /* speed */
679 0x0000, /* top (don't care) */
680 0x0000 /* c.o.c. (don't care) */
681 },
682 { /* vsb_rf_agc_cfg */
683 DRX_STANDARD_8VSB, /* standard */
684 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
685 0, /* output_level */
686 0, /* min_output_level */
687 0xFFFF, /* max_output_level */
688 0x0000, /* speed */
689 0x0000, /* top (don't care) */
690 0x0000 /* c.o.c. (don't care) */
691 },
692 { /* vsb_if_agc_cfg */
693 DRX_STANDARD_8VSB, /* standard */
694 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
695 0, /* output_level */
696 0, /* min_output_level */
697 0xFFFF, /* max_output_level */
698 0x0000, /* speed */
699 0x0000, /* top (don't care) */
700 0x0000 /* c.o.c. (don't care) */
701 },
702 0, /* qam_pga_cfg */
703 0, /* vsb_pga_cfg */
704 { /* qam_pre_saw_cfg */
705 DRX_STANDARD_ITU_B, /* standard */
706 0, /* reference */
707 false /* use_pre_saw */
708 },
709 { /* vsb_pre_saw_cfg */
710 DRX_STANDARD_8VSB, /* standard */
711 0, /* reference */
712 false /* use_pre_saw */
713 },
714
715 /* Version information */
716 #ifndef _CH_
717 {
718 "01234567890", /* human readable version microcode */
719 "01234567890" /* human readable version device specific code */
720 },
721 {
722 { /* struct drx_version for microcode */
723 DRX_MODULE_UNKNOWN,
724 (char *)(NULL),
725 0,
726 0,
727 0,
728 (char *)(NULL)
729 },
730 { /* struct drx_version for device specific code */
731 DRX_MODULE_UNKNOWN,
732 (char *)(NULL),
733 0,
734 0,
735 0,
736 (char *)(NULL)
737 }
738 },
739 {
740 { /* struct drx_version_list for microcode */
741 (struct drx_version *) (NULL),
742 (struct drx_version_list *) (NULL)
743 },
744 { /* struct drx_version_list for device specific code */
745 (struct drx_version *) (NULL),
746 (struct drx_version_list *) (NULL)
747 }
748 },
749 #endif
750 false, /* smart_ant_inverted */
751 /* Tracking filter setting for OOB */
752 {
753 12000,
754 9300,
755 6600,
756 5280,
757 3700,
758 3000,
759 2000,
760 0},
761 false, /* oob_power_on */
762 0, /* mpeg_ts_static_bitrate */
763 false, /* disable_te_ihandling */
764 false, /* bit_reverse_mpeg_outout */
765 DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO, /* mpeg_output_clock_rate */
766 DRXJ_MPEG_START_WIDTH_1CLKCYC, /* mpeg_start_width */
767
768 /* Pre SAW & Agc configuration for ATV */
769 {
770 DRX_STANDARD_NTSC, /* standard */
771 7, /* reference */
772 true /* use_pre_saw */
773 },
774 { /* ATV RF-AGC */
775 DRX_STANDARD_NTSC, /* standard */
776 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
777 0, /* output_level */
778 0, /* min_output_level (d.c.) */
779 0, /* max_output_level (d.c.) */
780 3, /* speed */
781 9500, /* top */
782 4000 /* cut-off current */
783 },
784 { /* ATV IF-AGC */
785 DRX_STANDARD_NTSC, /* standard */
786 DRX_AGC_CTRL_AUTO, /* ctrl_mode */
787 0, /* output_level */
788 0, /* min_output_level (d.c.) */
789 0, /* max_output_level (d.c.) */
790 3, /* speed */
791 2400, /* top */
792 0 /* c.o.c. (d.c.) */
793 },
794 140, /* ATV PGA config */
795 0, /* curr_symbol_rate */
796
797 false, /* pdr_safe_mode */
798 SIO_PDR_GPIO_CFG__PRE, /* pdr_safe_restore_val_gpio */
799 SIO_PDR_VSYNC_CFG__PRE, /* pdr_safe_restore_val_v_sync */
800 SIO_PDR_SMA_RX_CFG__PRE, /* pdr_safe_restore_val_sma_rx */
801 SIO_PDR_SMA_TX_CFG__PRE, /* pdr_safe_restore_val_sma_tx */
802
803 4, /* oob_pre_saw */
804 DRXJ_OOB_LO_POW_MINUS10DB, /* oob_lo_pow */
805 {
806 false /* aud_data, only first member */
807 },
808 };
809
810 /*
811 * \var drxj_default_addr_g
812 * \brief Default I2C address and device identifier.
813 */
814 static struct i2c_device_addr drxj_default_addr_g = {
815 DRXJ_DEF_I2C_ADDR, /* i2c address */
816 DRXJ_DEF_DEMOD_DEV_ID /* device id */
817 };
818
819 /*
820 * \var drxj_default_comm_attr_g
821 * \brief Default common attributes of a drxj demodulator instance.
822 */
823 static struct drx_common_attr drxj_default_comm_attr_g = {
824 NULL, /* ucode file */
825 true, /* ucode verify switch */
826 {0}, /* version record */
827
828 44000, /* IF in kHz in case no tuner instance is used */
829 (151875 - 0), /* system clock frequency in kHz */
830 0, /* oscillator frequency kHz */
831 0, /* oscillator deviation in ppm, signed */
832 false, /* If true mirror frequency spectrum */
833 {
834 /* MPEG output configuration */
835 true, /* If true, enable MPEG output */
836 false, /* If true, insert RS byte */
837 false, /* If true, parallel out otherwise serial */
838 false, /* If true, invert DATA signals */
839 false, /* If true, invert ERR signal */
840 false, /* If true, invert STR signals */
841 false, /* If true, invert VAL signals */
842 false, /* If true, invert CLK signals */
843 true, /* If true, static MPEG clockrate will
844 be used, otherwise clockrate will
845 adapt to the bitrate of the TS */
846 19392658UL, /* Maximum bitrate in b/s in case
847 static clockrate is selected */
848 DRX_MPEG_STR_WIDTH_1 /* MPEG Start width in clock cycles */
849 },
850 /* Initilisations below can be omitted, they require no user input and
851 are initially 0, NULL or false. The compiler will initialize them to these
852 values when omitted. */
853 false, /* is_opened */
854
855 /* SCAN */
856 NULL, /* no scan params yet */
857 0, /* current scan index */
858 0, /* next scan frequency */
859 false, /* scan ready flag */
860 0, /* max channels to scan */
861 0, /* nr of channels scanned */
862 NULL, /* default scan function */
863 NULL, /* default context pointer */
864 0, /* millisec to wait for demod lock */
865 DRXJ_DEMOD_LOCK, /* desired lock */
866 false,
867
868 /* Power management */
869 DRX_POWER_UP,
870
871 /* Tuner */
872 1, /* nr of I2C port to which tuner is */
873 0L, /* minimum RF input frequency, in kHz */
874 0L, /* maximum RF input frequency, in kHz */
875 false, /* Rf Agc Polarity */
876 false, /* If Agc Polarity */
877 false, /* tuner slow mode */
878
879 { /* current channel (all 0) */
880 0UL /* channel.frequency */
881 },
882 DRX_STANDARD_UNKNOWN, /* current standard */
883 DRX_STANDARD_UNKNOWN, /* previous standard */
884 DRX_STANDARD_UNKNOWN, /* di_cache_standard */
885 false, /* use_bootloader */
886 0UL, /* capabilities */
887 0 /* mfx */
888 };
889
890 /*
891 * \var drxj_default_demod_g
892 * \brief Default drxj demodulator instance.
893 */
894 static struct drx_demod_instance drxj_default_demod_g = {
895 &drxj_default_addr_g, /* i2c address & device id */
896 &drxj_default_comm_attr_g, /* demod common attributes */
897 &drxj_data_g /* demod device specific attributes */
898 };
899
900 /*
901 * \brief Default audio data structure for DRK demodulator instance.
902 *
903 * This structure is DRXK specific.
904 *
905 */
906 static struct drx_aud_data drxj_default_aud_data_g = {
907 false, /* audio_is_active */
908 DRX_AUD_STANDARD_AUTO, /* audio_standard */
909
910 /* i2sdata */
911 {
912 false, /* output_enable */
913 48000, /* frequency */
914 DRX_I2S_MODE_MASTER, /* mode */
915 DRX_I2S_WORDLENGTH_32, /* word_length */
916 DRX_I2S_POLARITY_RIGHT, /* polarity */
917 DRX_I2S_FORMAT_WS_WITH_DATA /* format */
918 },
919 /* volume */
920 {
921 true, /* mute; */
922 0, /* volume */
923 DRX_AUD_AVC_OFF, /* avc_mode */
924 0, /* avc_ref_level */
925 DRX_AUD_AVC_MAX_GAIN_12DB, /* avc_max_gain */
926 DRX_AUD_AVC_MAX_ATTEN_24DB, /* avc_max_atten */
927 0, /* strength_left */
928 0 /* strength_right */
929 },
930 DRX_AUD_AUTO_SOUND_SELECT_ON_CHANGE_ON, /* auto_sound */
931 /* ass_thresholds */
932 {
933 440, /* A2 */
934 12, /* BTSC */
935 700, /* NICAM */
936 },
937 /* carrier */
938 {
939 /* a */
940 {
941 42, /* thres */
942 DRX_NO_CARRIER_NOISE, /* opt */
943 0, /* shift */
944 0 /* dco */
945 },
946 /* b */
947 {
948 42, /* thres */
949 DRX_NO_CARRIER_MUTE, /* opt */
950 0, /* shift */
951 0 /* dco */
952 },
953
954 },
955 /* mixer */
956 {
957 DRX_AUD_SRC_STEREO_OR_A, /* source_i2s */
958 DRX_AUD_I2S_MATRIX_STEREO, /* matrix_i2s */
959 DRX_AUD_FM_MATRIX_SOUND_A /* matrix_fm */
960 },
961 DRX_AUD_DEVIATION_NORMAL, /* deviation */
962 DRX_AUD_AVSYNC_OFF, /* av_sync */
963
964 /* prescale */
965 {
966 DRX_AUD_MAX_FM_DEVIATION, /* fm_deviation */
967 DRX_AUD_MAX_NICAM_PRESCALE /* nicam_gain */
968 },
969 DRX_AUD_FM_DEEMPH_75US, /* deemph */
970 DRX_BTSC_STEREO, /* btsc_detect */
971 0, /* rds_data_counter */
972 false /* rds_data_present */
973 };
974
975 /*-----------------------------------------------------------------------------
976 STRUCTURES
977 ----------------------------------------------------------------------------*/
978 struct drxjeq_stat {
979 u16 eq_mse;
980 u8 eq_mode;
981 u8 eq_ctrl;
982 u8 eq_stat;
983 };
984
985 /* HI command */
986 struct drxj_hi_cmd {
987 u16 cmd;
988 u16 param1;
989 u16 param2;
990 u16 param3;
991 u16 param4;
992 u16 param5;
993 u16 param6;
994 };
995
996 /*============================================================================*/
997 /*=== MICROCODE RELATED STRUCTURES ===========================================*/
998 /*============================================================================*/
999
1000 /*
1001 * struct drxu_code_block_hdr - Structure of the microcode block headers
1002 *
1003 * @addr: Destination address of the data in this block
1004 * @size: Size of the block data following this header counted in
1005 * 16 bits words
1006 * @CRC: CRC value of the data block, only valid if CRC flag is
1007 * set.
1008 */
1009 struct drxu_code_block_hdr {
1010 u32 addr;
1011 u16 size;
1012 u16 flags;
1013 u16 CRC;
1014 };
1015
1016 /*-----------------------------------------------------------------------------
1017 FUNCTIONS
1018 ----------------------------------------------------------------------------*/
1019 /* Some prototypes */
1020 static int
1021 hi_command(struct i2c_device_addr *dev_addr,
1022 const struct drxj_hi_cmd *cmd, u16 *result);
1023
1024 static int
1025 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat);
1026
1027 static int
1028 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode);
1029
1030 static int power_down_aud(struct drx_demod_instance *demod);
1031
1032 static int
1033 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw);
1034
1035 static int
1036 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain);
1037
1038 /*============================================================================*/
1039 /*============================================================================*/
1040 /*== HELPER FUNCTIONS ==*/
1041 /*============================================================================*/
1042 /*============================================================================*/
1043
1044
1045 /*============================================================================*/
1046
1047 /*
1048 * \fn u32 frac28(u32 N, u32 D)
1049 * \brief Compute: (1<<28)*N/D
1050 * \param N 32 bits
1051 * \param D 32 bits
1052 * \return (1<<28)*N/D
1053 * This function is used to avoid floating-point calculations as they may
1054 * not be present on the target platform.
1055
1056 * frac28 performs an unsigned 28/28 bits division to 32-bit fixed point
1057 * fraction used for setting the Frequency Shifter registers.
1058 * N and D can hold numbers up to width: 28-bits.
1059 * The 4 bits integer part and the 28 bits fractional part are calculated.
1060
1061 * Usage condition: ((1<<28)*n)/d < ((1<<32)-1) => (n/d) < 15.999
1062
1063 * N: 0...(1<<28)-1 = 268435454
1064 * D: 0...(1<<28)-1
1065 * Q: 0...(1<<32)-1
1066 */
frac28(u32 N,u32 D)1067 static u32 frac28(u32 N, u32 D)
1068 {
1069 int i = 0;
1070 u32 Q1 = 0;
1071 u32 R0 = 0;
1072
1073 R0 = (N % D) << 4; /* 32-28 == 4 shifts possible at max */
1074 Q1 = N / D; /* integer part, only the 4 least significant bits
1075 will be visible in the result */
1076
1077 /* division using radix 16, 7 nibbles in the result */
1078 for (i = 0; i < 7; i++) {
1079 Q1 = (Q1 << 4) | R0 / D;
1080 R0 = (R0 % D) << 4;
1081 }
1082 /* rounding */
1083 if ((R0 >> 3) >= D)
1084 Q1++;
1085
1086 return Q1;
1087 }
1088
1089 /*
1090 * \fn u32 log1_times100( u32 x)
1091 * \brief Compute: 100*log10(x)
1092 * \param x 32 bits
1093 * \return 100*log10(x)
1094 *
1095 * 100*log10(x)
1096 * = 100*(log2(x)/log2(10)))
1097 * = (100*(2^15)*log2(x))/((2^15)*log2(10))
1098 * = ((200*(2^15)*log2(x))/((2^15)*log2(10)))/2
1099 * = ((200*(2^15)*(log2(x/y)+log2(y)))/((2^15)*log2(10)))/2
1100 * = ((200*(2^15)*log2(x/y))+(200*(2^15)*log2(y)))/((2^15)*log2(10)))/2
1101 *
1102 * where y = 2^k and 1<= (x/y) < 2
1103 */
1104
log1_times100(u32 x)1105 static u32 log1_times100(u32 x)
1106 {
1107 static const u8 scale = 15;
1108 static const u8 index_width = 5;
1109 /*
1110 log2lut[n] = (1<<scale) * 200 * log2( 1.0 + ( (1.0/(1<<INDEXWIDTH)) * n ))
1111 0 <= n < ((1<<INDEXWIDTH)+1)
1112 */
1113
1114 static const u32 log2lut[] = {
1115 0, /* 0.000000 */
1116 290941, /* 290941.300628 */
1117 573196, /* 573196.476418 */
1118 847269, /* 847269.179851 */
1119 1113620, /* 1113620.489452 */
1120 1372674, /* 1372673.576986 */
1121 1624818, /* 1624817.752104 */
1122 1870412, /* 1870411.981536 */
1123 2109788, /* 2109787.962654 */
1124 2343253, /* 2343252.817465 */
1125 2571091, /* 2571091.461923 */
1126 2793569, /* 2793568.696416 */
1127 3010931, /* 3010931.055901 */
1128 3223408, /* 3223408.452106 */
1129 3431216, /* 3431215.635215 */
1130 3634553, /* 3634553.498355 */
1131 3833610, /* 3833610.244726 */
1132 4028562, /* 4028562.434393 */
1133 4219576, /* 4219575.925308 */
1134 4406807, /* 4406806.721144 */
1135 4590402, /* 4590401.736809 */
1136 4770499, /* 4770499.491025 */
1137 4947231, /* 4947230.734179 */
1138 5120719, /* 5120719.018555 */
1139 5291081, /* 5291081.217197 */
1140 5458428, /* 5458427.996830 */
1141 5622864, /* 5622864.249668 */
1142 5784489, /* 5784489.488298 */
1143 5943398, /* 5943398.207380 */
1144 6099680, /* 6099680.215452 */
1145 6253421, /* 6253420.939751 */
1146 6404702, /* 6404701.706649 */
1147 6553600, /* 6553600.000000 */
1148 };
1149
1150 u8 i = 0;
1151 u32 y = 0;
1152 u32 d = 0;
1153 u32 k = 0;
1154 u32 r = 0;
1155
1156 if (x == 0)
1157 return 0;
1158
1159 /* Scale x (normalize) */
1160 /* computing y in log(x/y) = log(x) - log(y) */
1161 if ((x & (((u32) (-1)) << (scale + 1))) == 0) {
1162 for (k = scale; k > 0; k--) {
1163 if (x & (((u32) 1) << scale))
1164 break;
1165 x <<= 1;
1166 }
1167 } else {
1168 for (k = scale; k < 31; k++) {
1169 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
1170 break;
1171 x >>= 1;
1172 }
1173 }
1174 /*
1175 Now x has binary point between bit[scale] and bit[scale-1]
1176 and 1.0 <= x < 2.0 */
1177
1178 /* correction for division: log(x) = log(x/y)+log(y) */
1179 y = k * ((((u32) 1) << scale) * 200);
1180
1181 /* remove integer part */
1182 x &= ((((u32) 1) << scale) - 1);
1183 /* get index */
1184 i = (u8) (x >> (scale - index_width));
1185 /* compute delta (x-a) */
1186 d = x & ((((u32) 1) << (scale - index_width)) - 1);
1187 /* compute log, multiplication ( d* (.. )) must be within range ! */
1188 y += log2lut[i] +
1189 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - index_width));
1190 /* Conver to log10() */
1191 y /= 108853; /* (log2(10) << scale) */
1192 r = (y >> 1);
1193 /* rounding */
1194 if (y & ((u32)1))
1195 r++;
1196
1197 return r;
1198
1199 }
1200
1201 /*
1202 * \fn u32 frac_times1e6( u16 N, u32 D)
1203 * \brief Compute: (N/D) * 1000000.
1204 * \param N nominator 16-bits.
1205 * \param D denominator 32-bits.
1206 * \return u32
1207 * \retval ((N/D) * 1000000), 32 bits
1208 *
1209 * No check on D=0!
1210 */
frac_times1e6(u32 N,u32 D)1211 static u32 frac_times1e6(u32 N, u32 D)
1212 {
1213 u32 remainder = 0;
1214 u32 frac = 0;
1215
1216 /*
1217 frac = (N * 1000000) / D
1218 To let it fit in a 32 bits computation:
1219 frac = (N * (1000000 >> 4)) / (D >> 4)
1220 This would result in a problem in case D < 16 (div by 0).
1221 So we do it more elaborate as shown below.
1222 */
1223 frac = (((u32) N) * (1000000 >> 4)) / D;
1224 frac <<= 4;
1225 remainder = (((u32) N) * (1000000 >> 4)) % D;
1226 remainder <<= 4;
1227 frac += remainder / D;
1228 remainder = remainder % D;
1229 if ((remainder * 2) > D)
1230 frac++;
1231
1232 return frac;
1233 }
1234
1235 /*============================================================================*/
1236
1237
1238 /*
1239 * \brief Values for NICAM prescaler gain. Computed from dB to integer
1240 * and rounded. For calc used formula: 16*10^(prescaleGain[dB]/20).
1241 *
1242 */
1243 #if 0
1244 /* Currently, unused as we lack support for analog TV */
1245 static const u16 nicam_presc_table_val[43] = {
1246 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4,
1247 5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16,
1248 18, 20, 23, 25, 28, 32, 36, 40, 45,
1249 51, 57, 64, 71, 80, 90, 101, 113, 127
1250 };
1251 #endif
1252
1253 /*============================================================================*/
1254 /*== END HELPER FUNCTIONS ==*/
1255 /*============================================================================*/
1256
1257 /*============================================================================*/
1258 /*============================================================================*/
1259 /*== DRXJ DAP FUNCTIONS ==*/
1260 /*============================================================================*/
1261 /*============================================================================*/
1262
1263 /*
1264 This layer takes care of some device specific register access protocols:
1265 -conversion to short address format
1266 -access to audio block
1267 This layer is placed between the drx_dap_fasi and the rest of the drxj
1268 specific implementation. This layer can use address map knowledge whereas
1269 dap_fasi may not use memory map knowledge.
1270
1271 * For audio currently only 16 bits read and write register access is
1272 supported. More is not needed. RMW and 32 or 8 bit access on audio
1273 registers will have undefined behaviour. Flags (RMW, CRC reset, broadcast
1274 single/multi master) will be ignored.
1275
1276 TODO: check ignoring single/multimaster is ok for AUD access ?
1277 */
1278
1279 #define DRXJ_ISAUDWRITE(addr) (((((addr)>>16)&1) == 1) ? true : false)
1280 #define DRXJ_DAP_AUDTRIF_TIMEOUT 80 /* millisec */
1281 /*============================================================================*/
1282
1283 /*
1284 * \fn bool is_handled_by_aud_tr_if( u32 addr )
1285 * \brief Check if this address is handled by the audio token ring interface.
1286 * \param addr
1287 * \return bool
1288 * \retval true Yes, handled by audio token ring interface
1289 * \retval false No, not handled by audio token ring interface
1290 *
1291 */
1292 static
is_handled_by_aud_tr_if(u32 addr)1293 bool is_handled_by_aud_tr_if(u32 addr)
1294 {
1295 bool retval = false;
1296
1297 if ((DRXDAP_FASI_ADDR2BLOCK(addr) == 4) &&
1298 (DRXDAP_FASI_ADDR2BANK(addr) > 1) &&
1299 (DRXDAP_FASI_ADDR2BANK(addr) < 6)) {
1300 retval = true;
1301 }
1302
1303 return retval;
1304 }
1305
1306 /*============================================================================*/
1307
drxbsp_i2c_write_read(struct i2c_device_addr * w_dev_addr,u16 w_count,u8 * wData,struct i2c_device_addr * r_dev_addr,u16 r_count,u8 * r_data)1308 int drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr,
1309 u16 w_count,
1310 u8 *wData,
1311 struct i2c_device_addr *r_dev_addr,
1312 u16 r_count, u8 *r_data)
1313 {
1314 struct drx39xxj_state *state;
1315 struct i2c_msg msg[2];
1316 unsigned int num_msgs;
1317
1318 if (w_dev_addr == NULL) {
1319 /* Read only */
1320 state = r_dev_addr->user_data;
1321 msg[0].addr = r_dev_addr->i2c_addr >> 1;
1322 msg[0].flags = I2C_M_RD;
1323 msg[0].buf = r_data;
1324 msg[0].len = r_count;
1325 num_msgs = 1;
1326 } else if (r_dev_addr == NULL) {
1327 /* Write only */
1328 state = w_dev_addr->user_data;
1329 msg[0].addr = w_dev_addr->i2c_addr >> 1;
1330 msg[0].flags = 0;
1331 msg[0].buf = wData;
1332 msg[0].len = w_count;
1333 num_msgs = 1;
1334 } else {
1335 /* Both write and read */
1336 state = w_dev_addr->user_data;
1337 msg[0].addr = w_dev_addr->i2c_addr >> 1;
1338 msg[0].flags = 0;
1339 msg[0].buf = wData;
1340 msg[0].len = w_count;
1341 msg[1].addr = r_dev_addr->i2c_addr >> 1;
1342 msg[1].flags = I2C_M_RD;
1343 msg[1].buf = r_data;
1344 msg[1].len = r_count;
1345 num_msgs = 2;
1346 }
1347
1348 if (state->i2c == NULL) {
1349 pr_err("i2c was zero, aborting\n");
1350 return 0;
1351 }
1352 if (i2c_transfer(state->i2c, msg, num_msgs) != num_msgs) {
1353 pr_warn("drx3933: I2C write/read failed\n");
1354 return -EREMOTEIO;
1355 }
1356
1357 #ifdef DJH_DEBUG
1358 if (w_dev_addr == NULL || r_dev_addr == NULL)
1359 return 0;
1360
1361 state = w_dev_addr->user_data;
1362
1363 if (state->i2c == NULL)
1364 return 0;
1365
1366 msg[0].addr = w_dev_addr->i2c_addr;
1367 msg[0].flags = 0;
1368 msg[0].buf = wData;
1369 msg[0].len = w_count;
1370 msg[1].addr = r_dev_addr->i2c_addr;
1371 msg[1].flags = I2C_M_RD;
1372 msg[1].buf = r_data;
1373 msg[1].len = r_count;
1374 num_msgs = 2;
1375
1376 pr_debug("drx3933 i2c operation addr=%x i2c=%p, wc=%x rc=%x\n",
1377 w_dev_addr->i2c_addr, state->i2c, w_count, r_count);
1378
1379 if (i2c_transfer(state->i2c, msg, 2) != 2) {
1380 pr_warn("drx3933: I2C write/read failed\n");
1381 return -EREMOTEIO;
1382 }
1383 #endif
1384 return 0;
1385 }
1386
1387 /*============================================================================*/
1388
1389 /*****************************
1390 *
1391 * int drxdap_fasi_read_block (
1392 * struct i2c_device_addr *dev_addr, -- address of I2C device
1393 * u32 addr, -- address of chip register/memory
1394 * u16 datasize, -- number of bytes to read
1395 * u8 *data, -- data to receive
1396 * u32 flags) -- special device flags
1397 *
1398 * Read block data from chip address. Because the chip is word oriented,
1399 * the number of bytes to read must be even.
1400 *
1401 * Make sure that the buffer to receive the data is large enough.
1402 *
1403 * Although this function expects an even number of bytes, it is still byte
1404 * oriented, and the data read back is NOT translated to the endianness of
1405 * the target platform.
1406 *
1407 * Output:
1408 * - 0 if reading was successful
1409 * in that case: data read is in *data.
1410 * - -EIO if anything went wrong
1411 *
1412 ******************************/
1413
drxdap_fasi_read_block(struct i2c_device_addr * dev_addr,u32 addr,u16 datasize,u8 * data,u32 flags)1414 static int drxdap_fasi_read_block(struct i2c_device_addr *dev_addr,
1415 u32 addr,
1416 u16 datasize,
1417 u8 *data, u32 flags)
1418 {
1419 u8 buf[4];
1420 u16 bufx;
1421 int rc;
1422 u16 overhead_size = 0;
1423
1424 /* Check parameters ******************************************************* */
1425 if (dev_addr == NULL)
1426 return -EINVAL;
1427
1428 overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
1429 (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
1430
1431 if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
1432 ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
1433 DRXDAP_FASI_LONG_FORMAT(addr)) ||
1434 (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
1435 ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1)) {
1436 return -EINVAL;
1437 }
1438
1439 /* ReadModifyWrite & mode flag bits are not allowed */
1440 flags &= (~DRXDAP_FASI_RMW & ~DRXDAP_FASI_MODEFLAGS);
1441 #if DRXDAP_SINGLE_MASTER
1442 flags |= DRXDAP_FASI_SINGLE_MASTER;
1443 #endif
1444
1445 /* Read block from I2C **************************************************** */
1446 do {
1447 u16 todo = (datasize < DRXDAP_MAX_RCHUNKSIZE ?
1448 datasize : DRXDAP_MAX_RCHUNKSIZE);
1449
1450 bufx = 0;
1451
1452 addr &= ~DRXDAP_FASI_FLAGS;
1453 addr |= flags;
1454
1455 #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1456 /* short format address preferred but long format otherwise */
1457 if (DRXDAP_FASI_LONG_FORMAT(addr)) {
1458 #endif
1459 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1460 buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
1461 buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
1462 buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
1463 buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
1464 #endif
1465 #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1466 } else {
1467 #endif
1468 #if (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1)
1469 buf[bufx++] = (u8) ((addr << 1) & 0xFF);
1470 buf[bufx++] =
1471 (u8) (((addr >> 16) & 0x0F) |
1472 ((addr >> 18) & 0xF0));
1473 #endif
1474 #if ((DRXDAPFASI_LONG_ADDR_ALLOWED == 1) && (DRXDAPFASI_SHORT_ADDR_ALLOWED == 1))
1475 }
1476 #endif
1477
1478 #if DRXDAP_SINGLE_MASTER
1479 /*
1480 * In single master mode, split the read and write actions.
1481 * No special action is needed for write chunks here.
1482 */
1483 rc = drxbsp_i2c_write_read(dev_addr, bufx, buf,
1484 NULL, 0, NULL);
1485 if (rc == 0)
1486 rc = drxbsp_i2c_write_read(NULL, 0, NULL, dev_addr, todo, data);
1487 #else
1488 /* In multi master mode, do everything in one RW action */
1489 rc = drxbsp_i2c_write_read(dev_addr, bufx, buf, dev_addr, todo,
1490 data);
1491 #endif
1492 data += todo;
1493 addr += (todo >> 1);
1494 datasize -= todo;
1495 } while (datasize && rc == 0);
1496
1497 return rc;
1498 }
1499
1500
1501 /*****************************
1502 *
1503 * int drxdap_fasi_read_reg16 (
1504 * struct i2c_device_addr *dev_addr, -- address of I2C device
1505 * u32 addr, -- address of chip register/memory
1506 * u16 *data, -- data to receive
1507 * u32 flags) -- special device flags
1508 *
1509 * Read one 16-bit register or memory location. The data received back is
1510 * converted back to the target platform's endianness.
1511 *
1512 * Output:
1513 * - 0 if reading was successful
1514 * in that case: read data is at *data
1515 * - -EIO if anything went wrong
1516 *
1517 ******************************/
1518
drxdap_fasi_read_reg16(struct i2c_device_addr * dev_addr,u32 addr,u16 * data,u32 flags)1519 static int drxdap_fasi_read_reg16(struct i2c_device_addr *dev_addr,
1520 u32 addr,
1521 u16 *data, u32 flags)
1522 {
1523 u8 buf[sizeof(*data)];
1524 int rc;
1525
1526 if (!data)
1527 return -EINVAL;
1528
1529 rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
1530 *data = buf[0] + (((u16) buf[1]) << 8);
1531 return rc;
1532 }
1533
1534 /*****************************
1535 *
1536 * int drxdap_fasi_read_reg32 (
1537 * struct i2c_device_addr *dev_addr, -- address of I2C device
1538 * u32 addr, -- address of chip register/memory
1539 * u32 *data, -- data to receive
1540 * u32 flags) -- special device flags
1541 *
1542 * Read one 32-bit register or memory location. The data received back is
1543 * converted back to the target platform's endianness.
1544 *
1545 * Output:
1546 * - 0 if reading was successful
1547 * in that case: read data is at *data
1548 * - -EIO if anything went wrong
1549 *
1550 ******************************/
1551
drxdap_fasi_read_reg32(struct i2c_device_addr * dev_addr,u32 addr,u32 * data,u32 flags)1552 static int drxdap_fasi_read_reg32(struct i2c_device_addr *dev_addr,
1553 u32 addr,
1554 u32 *data, u32 flags)
1555 {
1556 u8 buf[sizeof(*data)];
1557 int rc;
1558
1559 if (!data)
1560 return -EINVAL;
1561
1562 rc = drxdap_fasi_read_block(dev_addr, addr, sizeof(*data), buf, flags);
1563 *data = (((u32) buf[0]) << 0) +
1564 (((u32) buf[1]) << 8) +
1565 (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
1566 return rc;
1567 }
1568
1569 /*****************************
1570 *
1571 * int drxdap_fasi_write_block (
1572 * struct i2c_device_addr *dev_addr, -- address of I2C device
1573 * u32 addr, -- address of chip register/memory
1574 * u16 datasize, -- number of bytes to read
1575 * u8 *data, -- data to receive
1576 * u32 flags) -- special device flags
1577 *
1578 * Write block data to chip address. Because the chip is word oriented,
1579 * the number of bytes to write must be even.
1580 *
1581 * Although this function expects an even number of bytes, it is still byte
1582 * oriented, and the data being written is NOT translated from the endianness of
1583 * the target platform.
1584 *
1585 * Output:
1586 * - 0 if writing was successful
1587 * - -EIO if anything went wrong
1588 *
1589 ******************************/
1590
drxdap_fasi_write_block(struct i2c_device_addr * dev_addr,u32 addr,u16 datasize,u8 * data,u32 flags)1591 static int drxdap_fasi_write_block(struct i2c_device_addr *dev_addr,
1592 u32 addr,
1593 u16 datasize,
1594 u8 *data, u32 flags)
1595 {
1596 u8 buf[DRXDAP_MAX_WCHUNKSIZE];
1597 int st = -EIO;
1598 int first_err = 0;
1599 u16 overhead_size = 0;
1600 u16 block_size = 0;
1601
1602 /* Check parameters ******************************************************* */
1603 if (dev_addr == NULL)
1604 return -EINVAL;
1605
1606 overhead_size = (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1) +
1607 (DRXDAP_FASI_LONG_FORMAT(addr) ? 4 : 2);
1608
1609 if ((DRXDAP_FASI_OFFSET_TOO_LARGE(addr)) ||
1610 ((!(DRXDAPFASI_LONG_ADDR_ALLOWED)) &&
1611 DRXDAP_FASI_LONG_FORMAT(addr)) ||
1612 (overhead_size > (DRXDAP_MAX_WCHUNKSIZE)) ||
1613 ((datasize != 0) && (data == NULL)) || ((datasize & 1) == 1))
1614 return -EINVAL;
1615
1616 flags &= DRXDAP_FASI_FLAGS;
1617 flags &= ~DRXDAP_FASI_MODEFLAGS;
1618 #if DRXDAP_SINGLE_MASTER
1619 flags |= DRXDAP_FASI_SINGLE_MASTER;
1620 #endif
1621
1622 /* Write block to I2C ***************************************************** */
1623 block_size = ((DRXDAP_MAX_WCHUNKSIZE) - overhead_size) & ~1;
1624 do {
1625 u16 todo = 0;
1626 u16 bufx = 0;
1627
1628 /* Buffer device address */
1629 addr &= ~DRXDAP_FASI_FLAGS;
1630 addr |= flags;
1631 #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1632 /* short format address preferred but long format otherwise */
1633 if (DRXDAP_FASI_LONG_FORMAT(addr)) {
1634 #endif
1635 #if ((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1)
1636 buf[bufx++] = (u8) (((addr << 1) & 0xFF) | 0x01);
1637 buf[bufx++] = (u8) ((addr >> 16) & 0xFF);
1638 buf[bufx++] = (u8) ((addr >> 24) & 0xFF);
1639 buf[bufx++] = (u8) ((addr >> 7) & 0xFF);
1640 #endif
1641 #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1642 } else {
1643 #endif
1644 #if ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1)
1645 buf[bufx++] = (u8) ((addr << 1) & 0xFF);
1646 buf[bufx++] =
1647 (u8) (((addr >> 16) & 0x0F) |
1648 ((addr >> 18) & 0xF0));
1649 #endif
1650 #if (((DRXDAPFASI_LONG_ADDR_ALLOWED) == 1) && ((DRXDAPFASI_SHORT_ADDR_ALLOWED) == 1))
1651 }
1652 #endif
1653
1654 /*
1655 In single master mode block_size can be 0. In such a case this I2C
1656 sequense will be visible: (1) write address {i2c addr,
1657 4 bytes chip address} (2) write data {i2c addr, 4 bytes data }
1658 (3) write address (4) write data etc...
1659 Address must be rewritten because HI is reset after data transport and
1660 expects an address.
1661 */
1662 todo = (block_size < datasize ? block_size : datasize);
1663 if (todo == 0) {
1664 u16 overhead_size_i2c_addr = 0;
1665 u16 data_block_size = 0;
1666
1667 overhead_size_i2c_addr =
1668 (IS_I2C_10BIT(dev_addr->i2c_addr) ? 2 : 1);
1669 data_block_size =
1670 (DRXDAP_MAX_WCHUNKSIZE - overhead_size_i2c_addr) & ~1;
1671
1672 /* write device address */
1673 st = drxbsp_i2c_write_read(dev_addr,
1674 (u16) (bufx),
1675 buf,
1676 (struct i2c_device_addr *)(NULL),
1677 0, (u8 *)(NULL));
1678
1679 if ((st != 0) && (first_err == 0)) {
1680 /* at the end, return the first error encountered */
1681 first_err = st;
1682 }
1683 bufx = 0;
1684 todo =
1685 (data_block_size <
1686 datasize ? data_block_size : datasize);
1687 }
1688 memcpy(&buf[bufx], data, todo);
1689 /* write (address if can do and) data */
1690 st = drxbsp_i2c_write_read(dev_addr,
1691 (u16) (bufx + todo),
1692 buf,
1693 (struct i2c_device_addr *)(NULL),
1694 0, (u8 *)(NULL));
1695
1696 if ((st != 0) && (first_err == 0)) {
1697 /* at the end, return the first error encountered */
1698 first_err = st;
1699 }
1700 datasize -= todo;
1701 data += todo;
1702 addr += (todo >> 1);
1703 } while (datasize);
1704
1705 return first_err;
1706 }
1707
1708 /*****************************
1709 *
1710 * int drxdap_fasi_write_reg16 (
1711 * struct i2c_device_addr *dev_addr, -- address of I2C device
1712 * u32 addr, -- address of chip register/memory
1713 * u16 data, -- data to send
1714 * u32 flags) -- special device flags
1715 *
1716 * Write one 16-bit register or memory location. The data being written is
1717 * converted from the target platform's endianness to little endian.
1718 *
1719 * Output:
1720 * - 0 if writing was successful
1721 * - -EIO if anything went wrong
1722 *
1723 ******************************/
1724
drxdap_fasi_write_reg16(struct i2c_device_addr * dev_addr,u32 addr,u16 data,u32 flags)1725 static int drxdap_fasi_write_reg16(struct i2c_device_addr *dev_addr,
1726 u32 addr,
1727 u16 data, u32 flags)
1728 {
1729 u8 buf[sizeof(data)];
1730
1731 buf[0] = (u8) ((data >> 0) & 0xFF);
1732 buf[1] = (u8) ((data >> 8) & 0xFF);
1733
1734 return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
1735 }
1736
1737 /*****************************
1738 *
1739 * int drxdap_fasi_read_modify_write_reg16 (
1740 * struct i2c_device_addr *dev_addr, -- address of I2C device
1741 * u32 waddr, -- address of chip register/memory
1742 * u32 raddr, -- chip address to read back from
1743 * u16 wdata, -- data to send
1744 * u16 *rdata) -- data to receive back
1745 *
1746 * Write 16-bit data, then read back the original contents of that location.
1747 * Requires long addressing format to be allowed.
1748 *
1749 * Before sending data, the data is converted to little endian. The
1750 * data received back is converted back to the target platform's endianness.
1751 *
1752 * WARNING: This function is only guaranteed to work if there is one
1753 * master on the I2C bus.
1754 *
1755 * Output:
1756 * - 0 if reading was successful
1757 * in that case: read back data is at *rdata
1758 * - -EIO if anything went wrong
1759 *
1760 ******************************/
1761
drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr * dev_addr,u32 waddr,u32 raddr,u16 wdata,u16 * rdata)1762 static int drxdap_fasi_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1763 u32 waddr,
1764 u32 raddr,
1765 u16 wdata, u16 *rdata)
1766 {
1767 int rc = -EIO;
1768
1769 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1770 if (rdata == NULL)
1771 return -EINVAL;
1772
1773 rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata, DRXDAP_FASI_RMW);
1774 if (rc == 0)
1775 rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata, 0);
1776 #endif
1777
1778 return rc;
1779 }
1780
1781 /*****************************
1782 *
1783 * int drxdap_fasi_write_reg32 (
1784 * struct i2c_device_addr *dev_addr, -- address of I2C device
1785 * u32 addr, -- address of chip register/memory
1786 * u32 data, -- data to send
1787 * u32 flags) -- special device flags
1788 *
1789 * Write one 32-bit register or memory location. The data being written is
1790 * converted from the target platform's endianness to little endian.
1791 *
1792 * Output:
1793 * - 0 if writing was successful
1794 * - -EIO if anything went wrong
1795 *
1796 ******************************/
1797
drxdap_fasi_write_reg32(struct i2c_device_addr * dev_addr,u32 addr,u32 data,u32 flags)1798 static int drxdap_fasi_write_reg32(struct i2c_device_addr *dev_addr,
1799 u32 addr,
1800 u32 data, u32 flags)
1801 {
1802 u8 buf[sizeof(data)];
1803
1804 buf[0] = (u8) ((data >> 0) & 0xFF);
1805 buf[1] = (u8) ((data >> 8) & 0xFF);
1806 buf[2] = (u8) ((data >> 16) & 0xFF);
1807 buf[3] = (u8) ((data >> 24) & 0xFF);
1808
1809 return drxdap_fasi_write_block(dev_addr, addr, sizeof(data), buf, flags);
1810 }
1811
1812 /*============================================================================*/
1813
1814 /*
1815 * \fn int drxj_dap_rm_write_reg16short
1816 * \brief Read modify write 16 bits audio register using short format only.
1817 * \param dev_addr
1818 * \param waddr Address to write to
1819 * \param raddr Address to read from (usually SIO_HI_RA_RAM_S0_RMWBUF__A)
1820 * \param wdata Data to write
1821 * \param rdata Buffer for data to read
1822 * \return int
1823 * \retval 0 Success
1824 * \retval -EIO Timeout, I2C error, illegal bank
1825 *
1826 * 16 bits register read modify write access using short addressing format only.
1827 * Requires knowledge of the registermap, thus device dependent.
1828 * Using DAP FASI directly to avoid endless recursion of RMWs to audio registers.
1829 *
1830 */
1831
1832 /* TODO correct define should be #if ( DRXDAPFASI_SHORT_ADDR_ALLOWED==1 )
1833 See comments drxj_dap_read_modify_write_reg16 */
1834 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 0)
drxj_dap_rm_write_reg16short(struct i2c_device_addr * dev_addr,u32 waddr,u32 raddr,u16 wdata,u16 * rdata)1835 static int drxj_dap_rm_write_reg16short(struct i2c_device_addr *dev_addr,
1836 u32 waddr,
1837 u32 raddr,
1838 u16 wdata, u16 *rdata)
1839 {
1840 int rc;
1841
1842 if (rdata == NULL)
1843 return -EINVAL;
1844
1845 /* Set RMW flag */
1846 rc = drxdap_fasi_write_reg16(dev_addr,
1847 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1848 SIO_HI_RA_RAM_S0_FLG_ACC_S0_RWM__M,
1849 0x0000);
1850 if (rc == 0) {
1851 /* Write new data: triggers RMW */
1852 rc = drxdap_fasi_write_reg16(dev_addr, waddr, wdata,
1853 0x0000);
1854 }
1855 if (rc == 0) {
1856 /* Read old data */
1857 rc = drxdap_fasi_read_reg16(dev_addr, raddr, rdata,
1858 0x0000);
1859 }
1860 if (rc == 0) {
1861 /* Reset RMW flag */
1862 rc = drxdap_fasi_write_reg16(dev_addr,
1863 SIO_HI_RA_RAM_S0_FLG_ACC__A,
1864 0, 0x0000);
1865 }
1866
1867 return rc;
1868 }
1869 #endif
1870
1871 /*============================================================================*/
1872
drxj_dap_read_modify_write_reg16(struct i2c_device_addr * dev_addr,u32 waddr,u32 raddr,u16 wdata,u16 * rdata)1873 static int drxj_dap_read_modify_write_reg16(struct i2c_device_addr *dev_addr,
1874 u32 waddr,
1875 u32 raddr,
1876 u16 wdata, u16 *rdata)
1877 {
1878 /* TODO: correct short/long addressing format decision,
1879 now long format has higher prio then short because short also
1880 needs virt bnks (not impl yet) for certain audio registers */
1881 #if (DRXDAPFASI_LONG_ADDR_ALLOWED == 1)
1882 return drxdap_fasi_read_modify_write_reg16(dev_addr,
1883 waddr,
1884 raddr, wdata, rdata);
1885 #else
1886 return drxj_dap_rm_write_reg16short(dev_addr, waddr, raddr, wdata, rdata);
1887 #endif
1888 }
1889
1890
1891 /*============================================================================*/
1892
1893 /*
1894 * \fn int drxj_dap_read_aud_reg16
1895 * \brief Read 16 bits audio register
1896 * \param dev_addr
1897 * \param addr
1898 * \param data
1899 * \return int
1900 * \retval 0 Success
1901 * \retval -EIO Timeout, I2C error, illegal bank
1902 *
1903 * 16 bits register read access via audio token ring interface.
1904 *
1905 */
drxj_dap_read_aud_reg16(struct i2c_device_addr * dev_addr,u32 addr,u16 * data)1906 static int drxj_dap_read_aud_reg16(struct i2c_device_addr *dev_addr,
1907 u32 addr, u16 *data)
1908 {
1909 u32 start_timer = 0;
1910 u32 current_timer = 0;
1911 u32 delta_timer = 0;
1912 u16 tr_status = 0;
1913 int stat = -EIO;
1914
1915 /* No read possible for bank 3, return with error */
1916 if (DRXDAP_FASI_ADDR2BANK(addr) == 3) {
1917 stat = -EINVAL;
1918 } else {
1919 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
1920
1921 /* Force reset write bit */
1922 addr &= (~write_bit);
1923
1924 /* Set up read */
1925 start_timer = jiffies_to_msecs(jiffies);
1926 do {
1927 /* RMW to aud TR IF until request is granted or timeout */
1928 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1929 addr,
1930 SIO_HI_RA_RAM_S0_RMWBUF__A,
1931 0x0000, &tr_status);
1932
1933 if (stat != 0)
1934 break;
1935
1936 current_timer = jiffies_to_msecs(jiffies);
1937 delta_timer = current_timer - start_timer;
1938 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1939 stat = -EIO;
1940 break;
1941 }
1942
1943 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
1944 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
1945 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
1946 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
1947 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=3 ) */
1948
1949 /* Wait for read ready status or timeout */
1950 if (stat == 0) {
1951 start_timer = jiffies_to_msecs(jiffies);
1952
1953 while ((tr_status & AUD_TOP_TR_CTR_FIFO_RD_RDY__M) !=
1954 AUD_TOP_TR_CTR_FIFO_RD_RDY_READY) {
1955 stat = drxj_dap_read_reg16(dev_addr,
1956 AUD_TOP_TR_CTR__A,
1957 &tr_status, 0x0000);
1958 if (stat != 0)
1959 break;
1960
1961 current_timer = jiffies_to_msecs(jiffies);
1962 delta_timer = current_timer - start_timer;
1963 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
1964 stat = -EIO;
1965 break;
1966 }
1967 } /* while ( ... ) */
1968 }
1969
1970 /* Read value */
1971 if (stat == 0)
1972 stat = drxj_dap_read_modify_write_reg16(dev_addr,
1973 AUD_TOP_TR_RD_REG__A,
1974 SIO_HI_RA_RAM_S0_RMWBUF__A,
1975 0x0000, data);
1976 return stat;
1977 }
1978
1979 /*============================================================================*/
1980
drxj_dap_read_reg16(struct i2c_device_addr * dev_addr,u32 addr,u16 * data,u32 flags)1981 static int drxj_dap_read_reg16(struct i2c_device_addr *dev_addr,
1982 u32 addr,
1983 u16 *data, u32 flags)
1984 {
1985 int stat = -EIO;
1986
1987 /* Check param */
1988 if ((dev_addr == NULL) || (data == NULL))
1989 return -EINVAL;
1990
1991 if (is_handled_by_aud_tr_if(addr))
1992 stat = drxj_dap_read_aud_reg16(dev_addr, addr, data);
1993 else
1994 stat = drxdap_fasi_read_reg16(dev_addr, addr, data, flags);
1995
1996 return stat;
1997 }
1998 /*============================================================================*/
1999
2000 /*
2001 * \fn int drxj_dap_write_aud_reg16
2002 * \brief Write 16 bits audio register
2003 * \param dev_addr
2004 * \param addr
2005 * \param data
2006 * \return int
2007 * \retval 0 Success
2008 * \retval -EIO Timeout, I2C error, illegal bank
2009 *
2010 * 16 bits register write access via audio token ring interface.
2011 *
2012 */
drxj_dap_write_aud_reg16(struct i2c_device_addr * dev_addr,u32 addr,u16 data)2013 static int drxj_dap_write_aud_reg16(struct i2c_device_addr *dev_addr,
2014 u32 addr, u16 data)
2015 {
2016 int stat = -EIO;
2017
2018 /* No write possible for bank 2, return with error */
2019 if (DRXDAP_FASI_ADDR2BANK(addr) == 2) {
2020 stat = -EINVAL;
2021 } else {
2022 u32 start_timer = 0;
2023 u32 current_timer = 0;
2024 u32 delta_timer = 0;
2025 u16 tr_status = 0;
2026 const u32 write_bit = ((dr_xaddr_t) 1) << 16;
2027
2028 /* Force write bit */
2029 addr |= write_bit;
2030 start_timer = jiffies_to_msecs(jiffies);
2031 do {
2032 /* RMW to aud TR IF until request is granted or timeout */
2033 stat = drxj_dap_read_modify_write_reg16(dev_addr,
2034 addr,
2035 SIO_HI_RA_RAM_S0_RMWBUF__A,
2036 data, &tr_status);
2037 if (stat != 0)
2038 break;
2039
2040 current_timer = jiffies_to_msecs(jiffies);
2041 delta_timer = current_timer - start_timer;
2042 if (delta_timer > DRXJ_DAP_AUDTRIF_TIMEOUT) {
2043 stat = -EIO;
2044 break;
2045 }
2046
2047 } while (((tr_status & AUD_TOP_TR_CTR_FIFO_LOCK__M) ==
2048 AUD_TOP_TR_CTR_FIFO_LOCK_LOCKED) ||
2049 ((tr_status & AUD_TOP_TR_CTR_FIFO_FULL__M) ==
2050 AUD_TOP_TR_CTR_FIFO_FULL_FULL));
2051
2052 } /* if ( DRXDAP_FASI_ADDR2BANK(addr)!=2 ) */
2053
2054 return stat;
2055 }
2056
2057 /*============================================================================*/
2058
drxj_dap_write_reg16(struct i2c_device_addr * dev_addr,u32 addr,u16 data,u32 flags)2059 static int drxj_dap_write_reg16(struct i2c_device_addr *dev_addr,
2060 u32 addr,
2061 u16 data, u32 flags)
2062 {
2063 int stat = -EIO;
2064
2065 /* Check param */
2066 if (dev_addr == NULL)
2067 return -EINVAL;
2068
2069 if (is_handled_by_aud_tr_if(addr))
2070 stat = drxj_dap_write_aud_reg16(dev_addr, addr, data);
2071 else
2072 stat = drxdap_fasi_write_reg16(dev_addr,
2073 addr, data, flags);
2074
2075 return stat;
2076 }
2077
2078 /*============================================================================*/
2079
2080 /* Free data ram in SIO HI */
2081 #define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2082 #define SIO_HI_RA_RAM_USR_END__A 0x420060
2083
2084 #define DRXJ_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2085 #define DRXJ_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2086 #define DRXJ_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2087 #define DRXJ_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2088
2089 /*
2090 * \fn int drxj_dap_atomic_read_write_block()
2091 * \brief Basic access routine for atomic read or write access
2092 * \param dev_addr pointer to i2c dev address
2093 * \param addr destination/source address
2094 * \param datasize size of data buffer in bytes
2095 * \param data pointer to data buffer
2096 * \return int
2097 * \retval 0 Success
2098 * \retval -EIO Timeout, I2C error, illegal bank
2099 *
2100 */
2101 static
drxj_dap_atomic_read_write_block(struct i2c_device_addr * dev_addr,u32 addr,u16 datasize,u8 * data,bool read_flag)2102 int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
2103 u32 addr,
2104 u16 datasize,
2105 u8 *data, bool read_flag)
2106 {
2107 struct drxj_hi_cmd hi_cmd;
2108 int rc;
2109 u16 word;
2110 u16 dummy = 0;
2111 u16 i = 0;
2112
2113 /* Parameter check */
2114 if (!data || !dev_addr || ((datasize % 2)) || ((datasize / 2) > 8))
2115 return -EINVAL;
2116
2117 /* Set up HI parameters to read or write n bytes */
2118 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_ATOMIC_COPY;
2119 hi_cmd.param1 =
2120 (u16) ((DRXDAP_FASI_ADDR2BLOCK(DRXJ_HI_ATOMIC_BUF_START) << 6) +
2121 DRXDAP_FASI_ADDR2BANK(DRXJ_HI_ATOMIC_BUF_START));
2122 hi_cmd.param2 =
2123 (u16) DRXDAP_FASI_ADDR2OFFSET(DRXJ_HI_ATOMIC_BUF_START);
2124 hi_cmd.param3 = (u16) ((datasize / 2) - 1);
2125 if (!read_flag)
2126 hi_cmd.param3 |= DRXJ_HI_ATOMIC_WRITE;
2127 else
2128 hi_cmd.param3 |= DRXJ_HI_ATOMIC_READ;
2129 hi_cmd.param4 = (u16) ((DRXDAP_FASI_ADDR2BLOCK(addr) << 6) +
2130 DRXDAP_FASI_ADDR2BANK(addr));
2131 hi_cmd.param5 = (u16) DRXDAP_FASI_ADDR2OFFSET(addr);
2132
2133 if (!read_flag) {
2134 /* write data to buffer */
2135 for (i = 0; i < (datasize / 2); i++) {
2136
2137 word = ((u16) data[2 * i]);
2138 word += (((u16) data[(2 * i) + 1]) << 8);
2139 drxj_dap_write_reg16(dev_addr,
2140 (DRXJ_HI_ATOMIC_BUF_START + i),
2141 word, 0);
2142 }
2143 }
2144
2145 rc = hi_command(dev_addr, &hi_cmd, &dummy);
2146 if (rc != 0) {
2147 pr_err("error %d\n", rc);
2148 goto rw_error;
2149 }
2150
2151 if (read_flag) {
2152 /* read data from buffer */
2153 for (i = 0; i < (datasize / 2); i++) {
2154 rc = drxj_dap_read_reg16(dev_addr,
2155 (DRXJ_HI_ATOMIC_BUF_START + i),
2156 &word, 0);
2157 if (rc) {
2158 pr_err("error %d\n", rc);
2159 goto rw_error;
2160 }
2161 data[2 * i] = (u8) (word & 0xFF);
2162 data[(2 * i) + 1] = (u8) (word >> 8);
2163 }
2164 }
2165
2166 return 0;
2167
2168 rw_error:
2169 return rc;
2170
2171 }
2172
2173 /*============================================================================*/
2174
2175 /*
2176 * \fn int drxj_dap_atomic_read_reg32()
2177 * \brief Atomic read of 32 bits words
2178 */
2179 static
drxj_dap_atomic_read_reg32(struct i2c_device_addr * dev_addr,u32 addr,u32 * data,u32 flags)2180 int drxj_dap_atomic_read_reg32(struct i2c_device_addr *dev_addr,
2181 u32 addr,
2182 u32 *data, u32 flags)
2183 {
2184 u8 buf[sizeof(*data)] = { 0 };
2185 int rc;
2186 u32 word = 0;
2187
2188 if (!data)
2189 return -EINVAL;
2190
2191 rc = drxj_dap_atomic_read_write_block(dev_addr, addr,
2192 sizeof(*data), buf, true);
2193
2194 if (rc < 0)
2195 return 0;
2196
2197 word = (u32) buf[3];
2198 word <<= 8;
2199 word |= (u32) buf[2];
2200 word <<= 8;
2201 word |= (u32) buf[1];
2202 word <<= 8;
2203 word |= (u32) buf[0];
2204
2205 *data = word;
2206
2207 return rc;
2208 }
2209
2210 /*============================================================================*/
2211
2212 /*============================================================================*/
2213 /*== END DRXJ DAP FUNCTIONS ==*/
2214 /*============================================================================*/
2215
2216 /*============================================================================*/
2217 /*============================================================================*/
2218 /*== HOST INTERFACE FUNCTIONS ==*/
2219 /*============================================================================*/
2220 /*============================================================================*/
2221
2222 /*
2223 * \fn int hi_cfg_command()
2224 * \brief Configure HI with settings stored in the demod structure.
2225 * \param demod Demodulator.
2226 * \return int.
2227 *
2228 * This routine was created because to much orthogonal settings have
2229 * been put into one HI API function (configure). Especially the I2C bridge
2230 * enable/disable should not need re-configuration of the HI.
2231 *
2232 */
hi_cfg_command(const struct drx_demod_instance * demod)2233 static int hi_cfg_command(const struct drx_demod_instance *demod)
2234 {
2235 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2236 struct drxj_hi_cmd hi_cmd;
2237 u16 result = 0;
2238 int rc;
2239
2240 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2241
2242 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_CONFIG;
2243 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
2244 hi_cmd.param2 = ext_attr->hi_cfg_timing_div;
2245 hi_cmd.param3 = ext_attr->hi_cfg_bridge_delay;
2246 hi_cmd.param4 = ext_attr->hi_cfg_wake_up_key;
2247 hi_cmd.param5 = ext_attr->hi_cfg_ctrl;
2248 hi_cmd.param6 = ext_attr->hi_cfg_transmit;
2249
2250 rc = hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
2251 if (rc != 0) {
2252 pr_err("error %d\n", rc);
2253 goto rw_error;
2254 }
2255
2256 /* Reset power down flag (set one call only) */
2257 ext_attr->hi_cfg_ctrl &= (~(SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2258
2259 return 0;
2260
2261 rw_error:
2262 return rc;
2263 }
2264
2265 /*
2266 * \fn int hi_command()
2267 * \brief Configure HI with settings stored in the demod structure.
2268 * \param dev_addr I2C address.
2269 * \param cmd HI command.
2270 * \param result HI command result.
2271 * \return int.
2272 *
2273 * Sends command to HI
2274 *
2275 */
2276 static int
hi_command(struct i2c_device_addr * dev_addr,const struct drxj_hi_cmd * cmd,u16 * result)2277 hi_command(struct i2c_device_addr *dev_addr, const struct drxj_hi_cmd *cmd, u16 *result)
2278 {
2279 u16 wait_cmd = 0;
2280 u16 nr_retries = 0;
2281 bool powerdown_cmd = false;
2282 int rc;
2283
2284 /* Write parameters */
2285 switch (cmd->cmd) {
2286
2287 case SIO_HI_RA_RAM_CMD_CONFIG:
2288 case SIO_HI_RA_RAM_CMD_ATOMIC_COPY:
2289 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_6__A, cmd->param6, 0);
2290 if (rc != 0) {
2291 pr_err("error %d\n", rc);
2292 goto rw_error;
2293 }
2294 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_5__A, cmd->param5, 0);
2295 if (rc != 0) {
2296 pr_err("error %d\n", rc);
2297 goto rw_error;
2298 }
2299 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_4__A, cmd->param4, 0);
2300 if (rc != 0) {
2301 pr_err("error %d\n", rc);
2302 goto rw_error;
2303 }
2304 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_3__A, cmd->param3, 0);
2305 if (rc != 0) {
2306 pr_err("error %d\n", rc);
2307 goto rw_error;
2308 }
2309 fallthrough;
2310 case SIO_HI_RA_RAM_CMD_BRDCTRL:
2311 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_2__A, cmd->param2, 0);
2312 if (rc != 0) {
2313 pr_err("error %d\n", rc);
2314 goto rw_error;
2315 }
2316 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_PAR_1__A, cmd->param1, 0);
2317 if (rc != 0) {
2318 pr_err("error %d\n", rc);
2319 goto rw_error;
2320 }
2321 fallthrough;
2322 case SIO_HI_RA_RAM_CMD_NULL:
2323 /* No parameters */
2324 break;
2325
2326 default:
2327 return -EINVAL;
2328 break;
2329 }
2330
2331 /* Write command */
2332 rc = drxj_dap_write_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, cmd->cmd, 0);
2333 if (rc != 0) {
2334 pr_err("error %d\n", rc);
2335 goto rw_error;
2336 }
2337
2338 if ((cmd->cmd) == SIO_HI_RA_RAM_CMD_RESET)
2339 msleep(1);
2340
2341 /* Detect power down to omit reading result */
2342 powerdown_cmd = (bool) ((cmd->cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
2343 (((cmd->
2344 param5) & SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M)
2345 == SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ));
2346 if (!powerdown_cmd) {
2347 /* Wait until command rdy */
2348 do {
2349 nr_retries++;
2350 if (nr_retries > DRXJ_MAX_RETRIES) {
2351 pr_err("timeout\n");
2352 goto rw_error;
2353 }
2354
2355 rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_CMD__A, &wait_cmd, 0);
2356 if (rc != 0) {
2357 pr_err("error %d\n", rc);
2358 goto rw_error;
2359 }
2360 } while (wait_cmd != 0);
2361
2362 /* Read result */
2363 rc = drxj_dap_read_reg16(dev_addr, SIO_HI_RA_RAM_RES__A, result, 0);
2364 if (rc != 0) {
2365 pr_err("error %d\n", rc);
2366 goto rw_error;
2367 }
2368
2369 }
2370 /* if ( powerdown_cmd == true ) */
2371 return 0;
2372 rw_error:
2373 return rc;
2374 }
2375
2376 /*
2377 * \fn int init_hi( const struct drx_demod_instance *demod )
2378 * \brief Initialise and configurate HI.
2379 * \param demod pointer to demod data.
2380 * \return int Return status.
2381 * \retval 0 Success.
2382 * \retval -EIO Failure.
2383 *
2384 * Needs to know Psys (System Clock period) and Posc (Osc Clock period)
2385 * Need to store configuration in driver because of the way I2C
2386 * bridging is controlled.
2387 *
2388 */
init_hi(const struct drx_demod_instance * demod)2389 static int init_hi(const struct drx_demod_instance *demod)
2390 {
2391 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2392 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2393 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2394 int rc;
2395
2396 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2397 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2398 dev_addr = demod->my_i2c_dev_addr;
2399
2400 /* PATCH for bug 5003, HI ucode v3.1.0 */
2401 rc = drxj_dap_write_reg16(dev_addr, 0x4301D7, 0x801, 0);
2402 if (rc != 0) {
2403 pr_err("error %d\n", rc);
2404 goto rw_error;
2405 }
2406
2407 /* Timing div, 250ns/Psys */
2408 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2409 ext_attr->hi_cfg_timing_div =
2410 (u16) ((common_attr->sys_clock_freq / 1000) * HI_I2C_DELAY) / 1000;
2411 /* Clipping */
2412 if ((ext_attr->hi_cfg_timing_div) > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
2413 ext_attr->hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
2414 /* Bridge delay, uses oscilator clock */
2415 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2416 /* SDA brdige delay */
2417 ext_attr->hi_cfg_bridge_delay =
2418 (u16) ((common_attr->osc_clock_freq / 1000) * HI_I2C_BRIDGE_DELAY) /
2419 1000;
2420 /* Clipping */
2421 if ((ext_attr->hi_cfg_bridge_delay) > SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M)
2422 ext_attr->hi_cfg_bridge_delay = SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
2423 /* SCL bridge delay, same as SDA for now */
2424 ext_attr->hi_cfg_bridge_delay += ((ext_attr->hi_cfg_bridge_delay) <<
2425 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B);
2426 /* Wakeup key, setting the read flag (as suggest in the documentation) does
2427 not always result into a working solution (barebones worked VI2C failed).
2428 Not setting the bit works in all cases . */
2429 ext_attr->hi_cfg_wake_up_key = DRXJ_WAKE_UP_KEY;
2430 /* port/bridge/power down ctrl */
2431 ext_attr->hi_cfg_ctrl = (SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE);
2432 /* transit mode time out delay and watch dog divider */
2433 ext_attr->hi_cfg_transmit = SIO_HI_RA_RAM_PAR_6__PRE;
2434
2435 rc = hi_cfg_command(demod);
2436 if (rc != 0) {
2437 pr_err("error %d\n", rc);
2438 goto rw_error;
2439 }
2440
2441 return 0;
2442
2443 rw_error:
2444 return rc;
2445 }
2446
2447 /*============================================================================*/
2448 /*== END HOST INTERFACE FUNCTIONS ==*/
2449 /*============================================================================*/
2450
2451 /*============================================================================*/
2452 /*============================================================================*/
2453 /*== AUXILIARY FUNCTIONS ==*/
2454 /*============================================================================*/
2455 /*============================================================================*/
2456
2457 /*
2458 * \fn int get_device_capabilities()
2459 * \brief Get and store device capabilities.
2460 * \param demod Pointer to demodulator instance.
2461 * \return int.
2462 * \return 0 Success
2463 * \retval -EIO Failure
2464 *
2465 * Depending on pulldowns on MDx pins the following internals are set:
2466 * * common_attr->osc_clock_freq
2467 * * ext_attr->has_lna
2468 * * ext_attr->has_ntsc
2469 * * ext_attr->has_btsc
2470 * * ext_attr->has_oob
2471 *
2472 */
get_device_capabilities(struct drx_demod_instance * demod)2473 static int get_device_capabilities(struct drx_demod_instance *demod)
2474 {
2475 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2476 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
2477 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2478 u16 sio_pdr_ohw_cfg = 0;
2479 u32 sio_top_jtagid_lo = 0;
2480 u16 bid = 0;
2481 int rc;
2482
2483 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2484 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2485 dev_addr = demod->my_i2c_dev_addr;
2486
2487 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2488 if (rc != 0) {
2489 pr_err("error %d\n", rc);
2490 goto rw_error;
2491 }
2492 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg, 0);
2493 if (rc != 0) {
2494 pr_err("error %d\n", rc);
2495 goto rw_error;
2496 }
2497 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2498 if (rc != 0) {
2499 pr_err("error %d\n", rc);
2500 goto rw_error;
2501 }
2502
2503 switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
2504 case 0:
2505 /* ignore (bypass ?) */
2506 break;
2507 case 1:
2508 /* 27 MHz */
2509 common_attr->osc_clock_freq = 27000;
2510 break;
2511 case 2:
2512 /* 20.25 MHz */
2513 common_attr->osc_clock_freq = 20250;
2514 break;
2515 case 3:
2516 /* 4 MHz */
2517 common_attr->osc_clock_freq = 4000;
2518 break;
2519 default:
2520 return -EIO;
2521 }
2522
2523 /*
2524 Determine device capabilities
2525 Based on pinning v47
2526 */
2527 rc = drxdap_fasi_read_reg32(dev_addr, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo, 0);
2528 if (rc != 0) {
2529 pr_err("error %d\n", rc);
2530 goto rw_error;
2531 }
2532 ext_attr->mfx = (u8) ((sio_top_jtagid_lo >> 29) & 0xF);
2533
2534 switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
2535 case 0x31:
2536 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
2537 if (rc != 0) {
2538 pr_err("error %d\n", rc);
2539 goto rw_error;
2540 }
2541 rc = drxj_dap_read_reg16(dev_addr, SIO_PDR_UIO_IN_HI__A, &bid, 0);
2542 if (rc != 0) {
2543 pr_err("error %d\n", rc);
2544 goto rw_error;
2545 }
2546 bid = (bid >> 10) & 0xf;
2547 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY__PRE, 0);
2548 if (rc != 0) {
2549 pr_err("error %d\n", rc);
2550 goto rw_error;
2551 }
2552
2553 ext_attr->has_lna = true;
2554 ext_attr->has_ntsc = false;
2555 ext_attr->has_btsc = false;
2556 ext_attr->has_oob = false;
2557 ext_attr->has_smatx = true;
2558 ext_attr->has_smarx = false;
2559 ext_attr->has_gpio = false;
2560 ext_attr->has_irqn = false;
2561 break;
2562 case 0x33:
2563 ext_attr->has_lna = false;
2564 ext_attr->has_ntsc = false;
2565 ext_attr->has_btsc = false;
2566 ext_attr->has_oob = false;
2567 ext_attr->has_smatx = true;
2568 ext_attr->has_smarx = false;
2569 ext_attr->has_gpio = false;
2570 ext_attr->has_irqn = false;
2571 break;
2572 case 0x45:
2573 ext_attr->has_lna = true;
2574 ext_attr->has_ntsc = true;
2575 ext_attr->has_btsc = false;
2576 ext_attr->has_oob = false;
2577 ext_attr->has_smatx = true;
2578 ext_attr->has_smarx = true;
2579 ext_attr->has_gpio = true;
2580 ext_attr->has_irqn = false;
2581 break;
2582 case 0x46:
2583 ext_attr->has_lna = false;
2584 ext_attr->has_ntsc = true;
2585 ext_attr->has_btsc = false;
2586 ext_attr->has_oob = false;
2587 ext_attr->has_smatx = true;
2588 ext_attr->has_smarx = true;
2589 ext_attr->has_gpio = true;
2590 ext_attr->has_irqn = false;
2591 break;
2592 case 0x41:
2593 ext_attr->has_lna = true;
2594 ext_attr->has_ntsc = true;
2595 ext_attr->has_btsc = true;
2596 ext_attr->has_oob = false;
2597 ext_attr->has_smatx = true;
2598 ext_attr->has_smarx = true;
2599 ext_attr->has_gpio = true;
2600 ext_attr->has_irqn = false;
2601 break;
2602 case 0x43:
2603 ext_attr->has_lna = false;
2604 ext_attr->has_ntsc = true;
2605 ext_attr->has_btsc = true;
2606 ext_attr->has_oob = false;
2607 ext_attr->has_smatx = true;
2608 ext_attr->has_smarx = true;
2609 ext_attr->has_gpio = true;
2610 ext_attr->has_irqn = false;
2611 break;
2612 case 0x32:
2613 ext_attr->has_lna = true;
2614 ext_attr->has_ntsc = false;
2615 ext_attr->has_btsc = false;
2616 ext_attr->has_oob = true;
2617 ext_attr->has_smatx = true;
2618 ext_attr->has_smarx = true;
2619 ext_attr->has_gpio = true;
2620 ext_attr->has_irqn = true;
2621 break;
2622 case 0x34:
2623 ext_attr->has_lna = false;
2624 ext_attr->has_ntsc = true;
2625 ext_attr->has_btsc = true;
2626 ext_attr->has_oob = true;
2627 ext_attr->has_smatx = true;
2628 ext_attr->has_smarx = true;
2629 ext_attr->has_gpio = true;
2630 ext_attr->has_irqn = true;
2631 break;
2632 case 0x42:
2633 ext_attr->has_lna = true;
2634 ext_attr->has_ntsc = true;
2635 ext_attr->has_btsc = true;
2636 ext_attr->has_oob = true;
2637 ext_attr->has_smatx = true;
2638 ext_attr->has_smarx = true;
2639 ext_attr->has_gpio = true;
2640 ext_attr->has_irqn = true;
2641 break;
2642 case 0x44:
2643 ext_attr->has_lna = false;
2644 ext_attr->has_ntsc = true;
2645 ext_attr->has_btsc = true;
2646 ext_attr->has_oob = true;
2647 ext_attr->has_smatx = true;
2648 ext_attr->has_smarx = true;
2649 ext_attr->has_gpio = true;
2650 ext_attr->has_irqn = true;
2651 break;
2652 default:
2653 /* Unknown device variant */
2654 return -EIO;
2655 break;
2656 }
2657
2658 return 0;
2659 rw_error:
2660 return rc;
2661 }
2662
2663 /*
2664 * \fn int power_up_device()
2665 * \brief Power up device.
2666 * \param demod Pointer to demodulator instance.
2667 * \return int.
2668 * \return 0 Success
2669 * \retval -EIO Failure, I2C or max retries reached
2670 *
2671 */
2672
2673 #ifndef DRXJ_MAX_RETRIES_POWERUP
2674 #define DRXJ_MAX_RETRIES_POWERUP 10
2675 #endif
2676
power_up_device(struct drx_demod_instance * demod)2677 static int power_up_device(struct drx_demod_instance *demod)
2678 {
2679 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2680 u8 data = 0;
2681 u16 retry_count = 0;
2682 struct i2c_device_addr wake_up_addr;
2683
2684 dev_addr = demod->my_i2c_dev_addr;
2685 wake_up_addr.i2c_addr = DRXJ_WAKE_UP_KEY;
2686 wake_up_addr.i2c_dev_id = dev_addr->i2c_dev_id;
2687 wake_up_addr.user_data = dev_addr->user_data;
2688 /*
2689 * I2C access may fail in this case: no ack
2690 * dummy write must be used to wake uop device, dummy read must be used to
2691 * reset HI state machine (avoiding actual writes)
2692 */
2693 do {
2694 data = 0;
2695 drxbsp_i2c_write_read(&wake_up_addr, 1, &data,
2696 (struct i2c_device_addr *)(NULL), 0,
2697 (u8 *)(NULL));
2698 msleep(10);
2699 retry_count++;
2700 } while ((drxbsp_i2c_write_read
2701 ((struct i2c_device_addr *) (NULL), 0, (u8 *)(NULL), dev_addr, 1,
2702 &data)
2703 != 0) && (retry_count < DRXJ_MAX_RETRIES_POWERUP));
2704
2705 /* Need some recovery time .... */
2706 msleep(10);
2707
2708 if (retry_count == DRXJ_MAX_RETRIES_POWERUP)
2709 return -EIO;
2710
2711 return 0;
2712 }
2713
2714 /*----------------------------------------------------------------------------*/
2715 /* MPEG Output Configuration Functions - begin */
2716 /*----------------------------------------------------------------------------*/
2717 /*
2718 * \fn int ctrl_set_cfg_mpeg_output()
2719 * \brief Set MPEG output configuration of the device.
2720 * \param devmod Pointer to demodulator instance.
2721 * \param cfg_data Pointer to mpeg output configuaration.
2722 * \return int.
2723 *
2724 * Configure MPEG output parameters.
2725 *
2726 */
2727 static int
ctrl_set_cfg_mpeg_output(struct drx_demod_instance * demod,struct drx_cfg_mpeg_output * cfg_data)2728 ctrl_set_cfg_mpeg_output(struct drx_demod_instance *demod, struct drx_cfg_mpeg_output *cfg_data)
2729 {
2730 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
2731 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
2732 struct drx_common_attr *common_attr = (struct drx_common_attr *) (NULL);
2733 int rc;
2734 u16 fec_oc_reg_mode = 0;
2735 u16 fec_oc_reg_ipr_mode = 0;
2736 u16 fec_oc_reg_ipr_invert = 0;
2737 u32 max_bit_rate = 0;
2738 u32 rcn_rate = 0;
2739 u32 nr_bits = 0;
2740 u16 sio_pdr_md_cfg = 0;
2741 /* data mask for the output data byte */
2742 u16 invert_data_mask =
2743 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2744 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2745 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2746 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2747
2748 /* check arguments */
2749 if ((demod == NULL) || (cfg_data == NULL))
2750 return -EINVAL;
2751
2752 dev_addr = demod->my_i2c_dev_addr;
2753 ext_attr = (struct drxj_data *) demod->my_ext_attr;
2754 common_attr = (struct drx_common_attr *) demod->my_common_attr;
2755
2756 if (cfg_data->enable_mpeg_output == true) {
2757 /* quick and dirty patch to set MPEG in case current std is not
2758 producing MPEG */
2759 switch (ext_attr->standard) {
2760 case DRX_STANDARD_8VSB:
2761 case DRX_STANDARD_ITU_A:
2762 case DRX_STANDARD_ITU_B:
2763 case DRX_STANDARD_ITU_C:
2764 break;
2765 default:
2766 return 0;
2767 }
2768
2769 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_OCR_INVERT__A, 0, 0);
2770 if (rc != 0) {
2771 pr_err("error %d\n", rc);
2772 goto rw_error;
2773 }
2774 switch (ext_attr->standard) {
2775 case DRX_STANDARD_8VSB:
2776 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, 7, 0);
2777 if (rc != 0) {
2778 pr_err("error %d\n", rc);
2779 goto rw_error;
2780 } /* 2048 bytes fifo ram */
2781 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, 10, 0);
2782 if (rc != 0) {
2783 pr_err("error %d\n", rc);
2784 goto rw_error;
2785 }
2786 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 10, 0);
2787 if (rc != 0) {
2788 pr_err("error %d\n", rc);
2789 goto rw_error;
2790 }
2791 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, 5, 0);
2792 if (rc != 0) {
2793 pr_err("error %d\n", rc);
2794 goto rw_error;
2795 }
2796 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, 7, 0);
2797 if (rc != 0) {
2798 pr_err("error %d\n", rc);
2799 goto rw_error;
2800 }
2801 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 10, 0);
2802 if (rc != 0) {
2803 pr_err("error %d\n", rc);
2804 goto rw_error;
2805 }
2806 /* Low Water Mark for synchronization */
2807 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 3, 0);
2808 if (rc != 0) {
2809 pr_err("error %d\n", rc);
2810 goto rw_error;
2811 }
2812 /* High Water Mark for synchronization */
2813 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 5, 0);
2814 if (rc != 0) {
2815 pr_err("error %d\n", rc);
2816 goto rw_error;
2817 }
2818 break;
2819 case DRX_STANDARD_ITU_A:
2820 case DRX_STANDARD_ITU_C:
2821 switch (ext_attr->constellation) {
2822 case DRX_CONSTELLATION_QAM256:
2823 nr_bits = 8;
2824 break;
2825 case DRX_CONSTELLATION_QAM128:
2826 nr_bits = 7;
2827 break;
2828 case DRX_CONSTELLATION_QAM64:
2829 nr_bits = 6;
2830 break;
2831 case DRX_CONSTELLATION_QAM32:
2832 nr_bits = 5;
2833 break;
2834 case DRX_CONSTELLATION_QAM16:
2835 nr_bits = 4;
2836 break;
2837 default:
2838 return -EIO;
2839 } /* ext_attr->constellation */
2840 /* max_bit_rate = symbol_rate * nr_bits * coef */
2841 /* coef = 188/204 */
2842 max_bit_rate =
2843 (ext_attr->curr_symbol_rate / 8) * nr_bits * 188;
2844 fallthrough; /* as b/c Annex A/C need following settings */
2845 case DRX_STANDARD_ITU_B:
2846 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_USAGE__A, FEC_OC_FCT_USAGE__PRE, 0);
2847 if (rc != 0) {
2848 pr_err("error %d\n", rc);
2849 goto rw_error;
2850 }
2851 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_CTL_UPD_RATE__A, FEC_OC_TMD_CTL_UPD_RATE__PRE, 0);
2852 if (rc != 0) {
2853 pr_err("error %d\n", rc);
2854 goto rw_error;
2855 }
2856 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_TMD_INT_UPD_RATE__A, 5, 0);
2857 if (rc != 0) {
2858 pr_err("error %d\n", rc);
2859 goto rw_error;
2860 }
2861 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_A__A, FEC_OC_AVR_PARM_A__PRE, 0);
2862 if (rc != 0) {
2863 pr_err("error %d\n", rc);
2864 goto rw_error;
2865 }
2866 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_AVR_PARM_B__A, FEC_OC_AVR_PARM_B__PRE, 0);
2867 if (rc != 0) {
2868 pr_err("error %d\n", rc);
2869 goto rw_error;
2870 }
2871 if (cfg_data->static_clk == true) {
2872 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, 0xD, 0);
2873 if (rc != 0) {
2874 pr_err("error %d\n", rc);
2875 goto rw_error;
2876 }
2877 } else {
2878 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_RCN_GAIN__A, FEC_OC_RCN_GAIN__PRE, 0);
2879 if (rc != 0) {
2880 pr_err("error %d\n", rc);
2881 goto rw_error;
2882 }
2883 }
2884 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_LWM__A, 2, 0);
2885 if (rc != 0) {
2886 pr_err("error %d\n", rc);
2887 goto rw_error;
2888 }
2889 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_HWM__A, 12, 0);
2890 if (rc != 0) {
2891 pr_err("error %d\n", rc);
2892 goto rw_error;
2893 }
2894 break;
2895 default:
2896 break;
2897 } /* switch (standard) */
2898
2899 /* Check insertion of the Reed-Solomon parity bytes */
2900 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
2901 if (rc != 0) {
2902 pr_err("error %d\n", rc);
2903 goto rw_error;
2904 }
2905 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode, 0);
2906 if (rc != 0) {
2907 pr_err("error %d\n", rc);
2908 goto rw_error;
2909 }
2910 if (cfg_data->insert_rs_byte == true) {
2911 /* enable parity symbol forward */
2912 fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
2913 /* MVAL disable during parity bytes */
2914 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2915 switch (ext_attr->standard) {
2916 case DRX_STANDARD_8VSB:
2917 rcn_rate = 0x004854D3;
2918 break;
2919 case DRX_STANDARD_ITU_B:
2920 fec_oc_reg_mode |= FEC_OC_MODE_TRANSPARENT__M;
2921 switch (ext_attr->constellation) {
2922 case DRX_CONSTELLATION_QAM256:
2923 rcn_rate = 0x008945E7;
2924 break;
2925 case DRX_CONSTELLATION_QAM64:
2926 rcn_rate = 0x005F64D4;
2927 break;
2928 default:
2929 return -EIO;
2930 }
2931 break;
2932 case DRX_STANDARD_ITU_A:
2933 case DRX_STANDARD_ITU_C:
2934 /* insert_rs_byte = true -> coef = 188/188 -> 1, RS bits are in MPEG output */
2935 rcn_rate =
2936 (frac28
2937 (max_bit_rate,
2938 (u32) (common_attr->sys_clock_freq / 8))) /
2939 188;
2940 break;
2941 default:
2942 return -EIO;
2943 } /* ext_attr->standard */
2944 } else { /* insert_rs_byte == false */
2945
2946 /* disable parity symbol forward */
2947 fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
2948 /* MVAL enable during parity bytes */
2949 fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2950 switch (ext_attr->standard) {
2951 case DRX_STANDARD_8VSB:
2952 rcn_rate = 0x0041605C;
2953 break;
2954 case DRX_STANDARD_ITU_B:
2955 fec_oc_reg_mode &= (~FEC_OC_MODE_TRANSPARENT__M);
2956 switch (ext_attr->constellation) {
2957 case DRX_CONSTELLATION_QAM256:
2958 rcn_rate = 0x0082D6A0;
2959 break;
2960 case DRX_CONSTELLATION_QAM64:
2961 rcn_rate = 0x005AEC1A;
2962 break;
2963 default:
2964 return -EIO;
2965 }
2966 break;
2967 case DRX_STANDARD_ITU_A:
2968 case DRX_STANDARD_ITU_C:
2969 /* insert_rs_byte = false -> coef = 188/204, RS bits not in MPEG output */
2970 rcn_rate =
2971 (frac28
2972 (max_bit_rate,
2973 (u32) (common_attr->sys_clock_freq / 8))) /
2974 204;
2975 break;
2976 default:
2977 return -EIO;
2978 } /* ext_attr->standard */
2979 }
2980
2981 if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> clear ipr_mode[0] */
2982 fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2983 } else { /* MPEG data output is serial -> set ipr_mode[0] */
2984 fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
2985 }
2986
2987 /* Control slective inversion of output bits */
2988 if (cfg_data->invert_data == true)
2989 fec_oc_reg_ipr_invert |= invert_data_mask;
2990 else
2991 fec_oc_reg_ipr_invert &= (~(invert_data_mask));
2992
2993 if (cfg_data->invert_err == true)
2994 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
2995 else
2996 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2997
2998 if (cfg_data->invert_str == true)
2999 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
3000 else
3001 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
3002
3003 if (cfg_data->invert_val == true)
3004 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
3005 else
3006 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
3007
3008 if (cfg_data->invert_clk == true)
3009 fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
3010 else
3011 fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
3012
3013
3014 if (cfg_data->static_clk == true) { /* Static mode */
3015 u32 dto_rate = 0;
3016 u32 bit_rate = 0;
3017 u16 fec_oc_dto_burst_len = 0;
3018 u16 fec_oc_dto_period = 0;
3019
3020 fec_oc_dto_burst_len = FEC_OC_DTO_BURST_LEN__PRE;
3021
3022 switch (ext_attr->standard) {
3023 case DRX_STANDARD_8VSB:
3024 fec_oc_dto_period = 4;
3025 if (cfg_data->insert_rs_byte == true)
3026 fec_oc_dto_burst_len = 208;
3027 break;
3028 case DRX_STANDARD_ITU_A:
3029 {
3030 u32 symbol_rate_th = 6400000;
3031 if (cfg_data->insert_rs_byte == true) {
3032 fec_oc_dto_burst_len = 204;
3033 symbol_rate_th = 5900000;
3034 }
3035 if (ext_attr->curr_symbol_rate >=
3036 symbol_rate_th) {
3037 fec_oc_dto_period = 0;
3038 } else {
3039 fec_oc_dto_period = 1;
3040 }
3041 }
3042 break;
3043 case DRX_STANDARD_ITU_B:
3044 fec_oc_dto_period = 1;
3045 if (cfg_data->insert_rs_byte == true)
3046 fec_oc_dto_burst_len = 128;
3047 break;
3048 case DRX_STANDARD_ITU_C:
3049 fec_oc_dto_period = 1;
3050 if (cfg_data->insert_rs_byte == true)
3051 fec_oc_dto_burst_len = 204;
3052 break;
3053 default:
3054 return -EIO;
3055 }
3056 bit_rate =
3057 common_attr->sys_clock_freq * 1000 / (fec_oc_dto_period +
3058 2);
3059 dto_rate =
3060 frac28(bit_rate, common_attr->sys_clock_freq * 1000);
3061 dto_rate >>= 3;
3062 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_HI__A, (u16)((dto_rate >> 16) & FEC_OC_DTO_RATE_HI__M), 0);
3063 if (rc != 0) {
3064 pr_err("error %d\n", rc);
3065 goto rw_error;
3066 }
3067 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_RATE_LO__A, (u16)(dto_rate & FEC_OC_DTO_RATE_LO_RATE_LO__M), 0);
3068 if (rc != 0) {
3069 pr_err("error %d\n", rc);
3070 goto rw_error;
3071 }
3072 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M | FEC_OC_DTO_MODE_OFFSET_ENABLE__M, 0);
3073 if (rc != 0) {
3074 pr_err("error %d\n", rc);
3075 goto rw_error;
3076 }
3077 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, FEC_OC_FCT_MODE_RAT_ENA__M | FEC_OC_FCT_MODE_VIRT_ENA__M, 0);
3078 if (rc != 0) {
3079 pr_err("error %d\n", rc);
3080 goto rw_error;
3081 }
3082 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len, 0);
3083 if (rc != 0) {
3084 pr_err("error %d\n", rc);
3085 goto rw_error;
3086 }
3087 if (ext_attr->mpeg_output_clock_rate != DRXJ_MPEGOUTPUT_CLOCK_RATE_AUTO)
3088 fec_oc_dto_period = ext_attr->mpeg_output_clock_rate - 1;
3089 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period, 0);
3090 if (rc != 0) {
3091 pr_err("error %d\n", rc);
3092 goto rw_error;
3093 }
3094 } else { /* Dynamic mode */
3095
3096 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DTO_MODE__A, FEC_OC_DTO_MODE_DYNAMIC__M, 0);
3097 if (rc != 0) {
3098 pr_err("error %d\n", rc);
3099 goto rw_error;
3100 }
3101 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_FCT_MODE__A, 0, 0);
3102 if (rc != 0) {
3103 pr_err("error %d\n", rc);
3104 goto rw_error;
3105 }
3106 }
3107
3108 rc = drxdap_fasi_write_reg32(dev_addr, FEC_OC_RCN_CTL_RATE_LO__A, rcn_rate, 0);
3109 if (rc != 0) {
3110 pr_err("error %d\n", rc);
3111 goto rw_error;
3112 }
3113
3114 /* Write appropriate registers with requested configuration */
3115 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode, 0);
3116 if (rc != 0) {
3117 pr_err("error %d\n", rc);
3118 goto rw_error;
3119 }
3120 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode, 0);
3121 if (rc != 0) {
3122 pr_err("error %d\n", rc);
3123 goto rw_error;
3124 }
3125 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert, 0);
3126 if (rc != 0) {
3127 pr_err("error %d\n", rc);
3128 goto rw_error;
3129 }
3130
3131 /* enabling for both parallel and serial now */
3132 /* Write magic word to enable pdr reg write */
3133 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3134 if (rc != 0) {
3135 pr_err("error %d\n", rc);
3136 goto rw_error;
3137 }
3138 /* Set MPEG TS pads to outputmode */
3139 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0013, 0);
3140 if (rc != 0) {
3141 pr_err("error %d\n", rc);
3142 goto rw_error;
3143 }
3144 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0013, 0);
3145 if (rc != 0) {
3146 pr_err("error %d\n", rc);
3147 goto rw_error;
3148 }
3149 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, MPEG_OUTPUT_CLK_DRIVE_STRENGTH << SIO_PDR_MCLK_CFG_DRIVE__B | 0x03 << SIO_PDR_MCLK_CFG_MODE__B, 0);
3150 if (rc != 0) {
3151 pr_err("error %d\n", rc);
3152 goto rw_error;
3153 }
3154 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0013, 0);
3155 if (rc != 0) {
3156 pr_err("error %d\n", rc);
3157 goto rw_error;
3158 }
3159 sio_pdr_md_cfg =
3160 MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH <<
3161 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 << SIO_PDR_MD0_CFG_MODE__B;
3162 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3163 if (rc != 0) {
3164 pr_err("error %d\n", rc);
3165 goto rw_error;
3166 }
3167 if (cfg_data->enable_parallel == true) { /* MPEG data output is parallel -> set MD1 to MD7 to output mode */
3168 sio_pdr_md_cfg =
3169 MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH <<
3170 SIO_PDR_MD0_CFG_DRIVE__B | 0x03 <<
3171 SIO_PDR_MD0_CFG_MODE__B;
3172 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, sio_pdr_md_cfg, 0);
3173 if (rc != 0) {
3174 pr_err("error %d\n", rc);
3175 goto rw_error;
3176 }
3177 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, sio_pdr_md_cfg, 0);
3178 if (rc != 0) {
3179 pr_err("error %d\n", rc);
3180 goto rw_error;
3181 }
3182 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, sio_pdr_md_cfg, 0);
3183 if (rc != 0) {
3184 pr_err("error %d\n", rc);
3185 goto rw_error;
3186 }
3187 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, sio_pdr_md_cfg, 0);
3188 if (rc != 0) {
3189 pr_err("error %d\n", rc);
3190 goto rw_error;
3191 }
3192 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, sio_pdr_md_cfg, 0);
3193 if (rc != 0) {
3194 pr_err("error %d\n", rc);
3195 goto rw_error;
3196 }
3197 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, sio_pdr_md_cfg, 0);
3198 if (rc != 0) {
3199 pr_err("error %d\n", rc);
3200 goto rw_error;
3201 }
3202 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, sio_pdr_md_cfg, 0);
3203 if (rc != 0) {
3204 pr_err("error %d\n", rc);
3205 goto rw_error;
3206 }
3207 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, sio_pdr_md_cfg, 0);
3208 if (rc != 0) {
3209 pr_err("error %d\n", rc);
3210 goto rw_error;
3211 }
3212 } else { /* MPEG data output is serial -> set MD1 to MD7 to tri-state */
3213 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3214 if (rc != 0) {
3215 pr_err("error %d\n", rc);
3216 goto rw_error;
3217 }
3218 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3219 if (rc != 0) {
3220 pr_err("error %d\n", rc);
3221 goto rw_error;
3222 }
3223 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3224 if (rc != 0) {
3225 pr_err("error %d\n", rc);
3226 goto rw_error;
3227 }
3228 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3229 if (rc != 0) {
3230 pr_err("error %d\n", rc);
3231 goto rw_error;
3232 }
3233 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3234 if (rc != 0) {
3235 pr_err("error %d\n", rc);
3236 goto rw_error;
3237 }
3238 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3239 if (rc != 0) {
3240 pr_err("error %d\n", rc);
3241 goto rw_error;
3242 }
3243 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3244 if (rc != 0) {
3245 pr_err("error %d\n", rc);
3246 goto rw_error;
3247 }
3248 }
3249 /* Enable Monitor Bus output over MPEG pads and ctl input */
3250 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3251 if (rc != 0) {
3252 pr_err("error %d\n", rc);
3253 goto rw_error;
3254 }
3255 /* Write nomagic word to enable pdr reg write */
3256 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3257 if (rc != 0) {
3258 pr_err("error %d\n", rc);
3259 goto rw_error;
3260 }
3261 } else {
3262 /* Write magic word to enable pdr reg write */
3263 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
3264 if (rc != 0) {
3265 pr_err("error %d\n", rc);
3266 goto rw_error;
3267 }
3268 /* Set MPEG TS pads to inputmode */
3269 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MSTRT_CFG__A, 0x0000, 0);
3270 if (rc != 0) {
3271 pr_err("error %d\n", rc);
3272 goto rw_error;
3273 }
3274 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MERR_CFG__A, 0x0000, 0);
3275 if (rc != 0) {
3276 pr_err("error %d\n", rc);
3277 goto rw_error;
3278 }
3279 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MCLK_CFG__A, 0x0000, 0);
3280 if (rc != 0) {
3281 pr_err("error %d\n", rc);
3282 goto rw_error;
3283 }
3284 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MVAL_CFG__A, 0x0000, 0);
3285 if (rc != 0) {
3286 pr_err("error %d\n", rc);
3287 goto rw_error;
3288 }
3289 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD0_CFG__A, 0x0000, 0);
3290 if (rc != 0) {
3291 pr_err("error %d\n", rc);
3292 goto rw_error;
3293 }
3294 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD1_CFG__A, 0x0000, 0);
3295 if (rc != 0) {
3296 pr_err("error %d\n", rc);
3297 goto rw_error;
3298 }
3299 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD2_CFG__A, 0x0000, 0);
3300 if (rc != 0) {
3301 pr_err("error %d\n", rc);
3302 goto rw_error;
3303 }
3304 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD3_CFG__A, 0x0000, 0);
3305 if (rc != 0) {
3306 pr_err("error %d\n", rc);
3307 goto rw_error;
3308 }
3309 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD4_CFG__A, 0x0000, 0);
3310 if (rc != 0) {
3311 pr_err("error %d\n", rc);
3312 goto rw_error;
3313 }
3314 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD5_CFG__A, 0x0000, 0);
3315 if (rc != 0) {
3316 pr_err("error %d\n", rc);
3317 goto rw_error;
3318 }
3319 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD6_CFG__A, 0x0000, 0);
3320 if (rc != 0) {
3321 pr_err("error %d\n", rc);
3322 goto rw_error;
3323 }
3324 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MD7_CFG__A, 0x0000, 0);
3325 if (rc != 0) {
3326 pr_err("error %d\n", rc);
3327 goto rw_error;
3328 }
3329 /* Enable Monitor Bus output over MPEG pads and ctl input */
3330 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_MON_CFG__A, 0x0000, 0);
3331 if (rc != 0) {
3332 pr_err("error %d\n", rc);
3333 goto rw_error;
3334 }
3335 /* Write nomagic word to enable pdr reg write */
3336 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3337 if (rc != 0) {
3338 pr_err("error %d\n", rc);
3339 goto rw_error;
3340 }
3341 }
3342
3343 /* save values for restore after re-acquire */
3344 common_attr->mpeg_cfg.enable_mpeg_output = cfg_data->enable_mpeg_output;
3345
3346 return 0;
3347 rw_error:
3348 return rc;
3349 }
3350
3351 /*----------------------------------------------------------------------------*/
3352
3353
3354 /*----------------------------------------------------------------------------*/
3355 /* MPEG Output Configuration Functions - end */
3356 /*----------------------------------------------------------------------------*/
3357
3358 /*----------------------------------------------------------------------------*/
3359 /* miscellaneous configurations - begin */
3360 /*----------------------------------------------------------------------------*/
3361
3362 /*
3363 * \fn int set_mpegtei_handling()
3364 * \brief Activate MPEG TEI handling settings.
3365 * \param devmod Pointer to demodulator instance.
3366 * \return int.
3367 *
3368 * This routine should be called during a set channel of QAM/VSB
3369 *
3370 */
set_mpegtei_handling(struct drx_demod_instance * demod)3371 static int set_mpegtei_handling(struct drx_demod_instance *demod)
3372 {
3373 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3374 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3375 int rc;
3376 u16 fec_oc_dpr_mode = 0;
3377 u16 fec_oc_snc_mode = 0;
3378 u16 fec_oc_ems_mode = 0;
3379
3380 dev_addr = demod->my_i2c_dev_addr;
3381 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3382
3383 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_DPR_MODE__A, &fec_oc_dpr_mode, 0);
3384 if (rc != 0) {
3385 pr_err("error %d\n", rc);
3386 goto rw_error;
3387 }
3388 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
3389 if (rc != 0) {
3390 pr_err("error %d\n", rc);
3391 goto rw_error;
3392 }
3393 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_EMS_MODE__A, &fec_oc_ems_mode, 0);
3394 if (rc != 0) {
3395 pr_err("error %d\n", rc);
3396 goto rw_error;
3397 }
3398
3399 /* reset to default, allow TEI bit to be changed */
3400 fec_oc_dpr_mode &= (~FEC_OC_DPR_MODE_ERR_DISABLE__M);
3401 fec_oc_snc_mode &= (~(FEC_OC_SNC_MODE_ERROR_CTL__M |
3402 FEC_OC_SNC_MODE_CORR_DISABLE__M));
3403 fec_oc_ems_mode &= (~FEC_OC_EMS_MODE_MODE__M);
3404
3405 if (ext_attr->disable_te_ihandling) {
3406 /* do not change TEI bit */
3407 fec_oc_dpr_mode |= FEC_OC_DPR_MODE_ERR_DISABLE__M;
3408 fec_oc_snc_mode |= FEC_OC_SNC_MODE_CORR_DISABLE__M |
3409 ((0x2) << (FEC_OC_SNC_MODE_ERROR_CTL__B));
3410 fec_oc_ems_mode |= ((0x01) << (FEC_OC_EMS_MODE_MODE__B));
3411 }
3412
3413 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_DPR_MODE__A, fec_oc_dpr_mode, 0);
3414 if (rc != 0) {
3415 pr_err("error %d\n", rc);
3416 goto rw_error;
3417 }
3418 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode, 0);
3419 if (rc != 0) {
3420 pr_err("error %d\n", rc);
3421 goto rw_error;
3422 }
3423 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_EMS_MODE__A, fec_oc_ems_mode, 0);
3424 if (rc != 0) {
3425 pr_err("error %d\n", rc);
3426 goto rw_error;
3427 }
3428
3429 return 0;
3430 rw_error:
3431 return rc;
3432 }
3433
3434 /*----------------------------------------------------------------------------*/
3435 /*
3436 * \fn int bit_reverse_mpeg_output()
3437 * \brief Set MPEG output bit-endian settings.
3438 * \param devmod Pointer to demodulator instance.
3439 * \return int.
3440 *
3441 * This routine should be called during a set channel of QAM/VSB
3442 *
3443 */
bit_reverse_mpeg_output(struct drx_demod_instance * demod)3444 static int bit_reverse_mpeg_output(struct drx_demod_instance *demod)
3445 {
3446 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3447 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3448 int rc;
3449 u16 fec_oc_ipr_mode = 0;
3450
3451 dev_addr = demod->my_i2c_dev_addr;
3452 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3453
3454 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode, 0);
3455 if (rc != 0) {
3456 pr_err("error %d\n", rc);
3457 goto rw_error;
3458 }
3459
3460 /* reset to default (normal bit order) */
3461 fec_oc_ipr_mode &= (~FEC_OC_IPR_MODE_REVERSE_ORDER__M);
3462
3463 if (ext_attr->bit_reverse_mpeg_outout)
3464 fec_oc_ipr_mode |= FEC_OC_IPR_MODE_REVERSE_ORDER__M;
3465
3466 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode, 0);
3467 if (rc != 0) {
3468 pr_err("error %d\n", rc);
3469 goto rw_error;
3470 }
3471
3472 return 0;
3473 rw_error:
3474 return rc;
3475 }
3476
3477 /*----------------------------------------------------------------------------*/
3478 /*
3479 * \fn int set_mpeg_start_width()
3480 * \brief Set MPEG start width.
3481 * \param devmod Pointer to demodulator instance.
3482 * \return int.
3483 *
3484 * This routine should be called during a set channel of QAM/VSB
3485 *
3486 */
set_mpeg_start_width(struct drx_demod_instance * demod)3487 static int set_mpeg_start_width(struct drx_demod_instance *demod)
3488 {
3489 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3490 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)(NULL);
3491 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
3492 int rc;
3493 u16 fec_oc_comm_mb = 0;
3494
3495 dev_addr = demod->my_i2c_dev_addr;
3496 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3497 common_attr = demod->my_common_attr;
3498
3499 if ((common_attr->mpeg_cfg.static_clk == true)
3500 && (common_attr->mpeg_cfg.enable_parallel == false)) {
3501 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_COMM_MB__A, &fec_oc_comm_mb, 0);
3502 if (rc != 0) {
3503 pr_err("error %d\n", rc);
3504 goto rw_error;
3505 }
3506 fec_oc_comm_mb &= ~FEC_OC_COMM_MB_CTL_ON;
3507 if (ext_attr->mpeg_start_width == DRXJ_MPEG_START_WIDTH_8CLKCYC)
3508 fec_oc_comm_mb |= FEC_OC_COMM_MB_CTL_ON;
3509 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_COMM_MB__A, fec_oc_comm_mb, 0);
3510 if (rc != 0) {
3511 pr_err("error %d\n", rc);
3512 goto rw_error;
3513 }
3514 }
3515
3516 return 0;
3517 rw_error:
3518 return rc;
3519 }
3520
3521 /*----------------------------------------------------------------------------*/
3522 /* miscellaneous configurations - end */
3523 /*----------------------------------------------------------------------------*/
3524
3525 /*----------------------------------------------------------------------------*/
3526 /* UIO Configuration Functions - begin */
3527 /*----------------------------------------------------------------------------*/
3528 /*
3529 * \fn int ctrl_set_uio_cfg()
3530 * \brief Configure modus oprandi UIO.
3531 * \param demod Pointer to demodulator instance.
3532 * \param uio_cfg Pointer to a configuration setting for a certain UIO.
3533 * \return int.
3534 */
ctrl_set_uio_cfg(struct drx_demod_instance * demod,struct drxuio_cfg * uio_cfg)3535 static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg *uio_cfg)
3536 {
3537 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3538 int rc;
3539
3540 if ((uio_cfg == NULL) || (demod == NULL))
3541 return -EINVAL;
3542
3543 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3544
3545 /* Write magic word to enable pdr reg write */
3546 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3547 if (rc != 0) {
3548 pr_err("error %d\n", rc);
3549 goto rw_error;
3550 }
3551 switch (uio_cfg->uio) {
3552 /*====================================================================*/
3553 case DRX_UIO1:
3554 /* DRX_UIO1: SMA_TX UIO-1 */
3555 if (!ext_attr->has_smatx)
3556 return -EIO;
3557 switch (uio_cfg->mode) {
3558 case DRX_UIO_MODE_FIRMWARE_SMA:
3559 case DRX_UIO_MODE_FIRMWARE_SAW:
3560 case DRX_UIO_MODE_READWRITE:
3561 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3562 break;
3563 case DRX_UIO_MODE_DISABLE:
3564 ext_attr->uio_sma_tx_mode = uio_cfg->mode;
3565 /* pad configuration register is set 0 - input mode */
3566 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0, 0);
3567 if (rc != 0) {
3568 pr_err("error %d\n", rc);
3569 goto rw_error;
3570 }
3571 break;
3572 default:
3573 return -EINVAL;
3574 } /* switch ( uio_cfg->mode ) */
3575 break;
3576 /*====================================================================*/
3577 case DRX_UIO2:
3578 /* DRX_UIO2: SMA_RX UIO-2 */
3579 if (!ext_attr->has_smarx)
3580 return -EIO;
3581 switch (uio_cfg->mode) {
3582 case DRX_UIO_MODE_FIRMWARE0:
3583 case DRX_UIO_MODE_READWRITE:
3584 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3585 break;
3586 case DRX_UIO_MODE_DISABLE:
3587 ext_attr->uio_sma_rx_mode = uio_cfg->mode;
3588 /* pad configuration register is set 0 - input mode */
3589 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, 0, 0);
3590 if (rc != 0) {
3591 pr_err("error %d\n", rc);
3592 goto rw_error;
3593 }
3594 break;
3595 default:
3596 return -EINVAL;
3597 break;
3598 } /* switch ( uio_cfg->mode ) */
3599 break;
3600 /*====================================================================*/
3601 case DRX_UIO3:
3602 /* DRX_UIO3: GPIO UIO-3 */
3603 if (!ext_attr->has_gpio)
3604 return -EIO;
3605 switch (uio_cfg->mode) {
3606 case DRX_UIO_MODE_FIRMWARE0:
3607 case DRX_UIO_MODE_READWRITE:
3608 ext_attr->uio_gpio_mode = uio_cfg->mode;
3609 break;
3610 case DRX_UIO_MODE_DISABLE:
3611 ext_attr->uio_gpio_mode = uio_cfg->mode;
3612 /* pad configuration register is set 0 - input mode */
3613 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, 0, 0);
3614 if (rc != 0) {
3615 pr_err("error %d\n", rc);
3616 goto rw_error;
3617 }
3618 break;
3619 default:
3620 return -EINVAL;
3621 break;
3622 } /* switch ( uio_cfg->mode ) */
3623 break;
3624 /*====================================================================*/
3625 case DRX_UIO4:
3626 /* DRX_UIO4: IRQN UIO-4 */
3627 if (!ext_attr->has_irqn)
3628 return -EIO;
3629 switch (uio_cfg->mode) {
3630 case DRX_UIO_MODE_READWRITE:
3631 ext_attr->uio_irqn_mode = uio_cfg->mode;
3632 break;
3633 case DRX_UIO_MODE_DISABLE:
3634 /* pad configuration register is set 0 - input mode */
3635 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, 0, 0);
3636 if (rc != 0) {
3637 pr_err("error %d\n", rc);
3638 goto rw_error;
3639 }
3640 ext_attr->uio_irqn_mode = uio_cfg->mode;
3641 break;
3642 case DRX_UIO_MODE_FIRMWARE0:
3643 default:
3644 return -EINVAL;
3645 break;
3646 } /* switch ( uio_cfg->mode ) */
3647 break;
3648 /*====================================================================*/
3649 default:
3650 return -EINVAL;
3651 } /* switch ( uio_cfg->uio ) */
3652
3653 /* Write magic word to disable pdr reg write */
3654 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3655 if (rc != 0) {
3656 pr_err("error %d\n", rc);
3657 goto rw_error;
3658 }
3659
3660 return 0;
3661 rw_error:
3662 return rc;
3663 }
3664
3665 /*
3666 * \fn int ctrl_uio_write()
3667 * \brief Write to a UIO.
3668 * \param demod Pointer to demodulator instance.
3669 * \param uio_data Pointer to data container for a certain UIO.
3670 * \return int.
3671 */
3672 static int
ctrl_uio_write(struct drx_demod_instance * demod,struct drxuio_data * uio_data)3673 ctrl_uio_write(struct drx_demod_instance *demod, struct drxuio_data *uio_data)
3674 {
3675 struct drxj_data *ext_attr = (struct drxj_data *) (NULL);
3676 int rc;
3677 u16 pin_cfg_value = 0;
3678 u16 value = 0;
3679
3680 if ((uio_data == NULL) || (demod == NULL))
3681 return -EINVAL;
3682
3683 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3684
3685 /* Write magic word to enable pdr reg write */
3686 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3687 if (rc != 0) {
3688 pr_err("error %d\n", rc);
3689 goto rw_error;
3690 }
3691 switch (uio_data->uio) {
3692 /*====================================================================*/
3693 case DRX_UIO1:
3694 /* DRX_UIO1: SMA_TX UIO-1 */
3695 if (!ext_attr->has_smatx)
3696 return -EIO;
3697 if ((ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_READWRITE)
3698 && (ext_attr->uio_sma_tx_mode != DRX_UIO_MODE_FIRMWARE_SAW)) {
3699 return -EIO;
3700 }
3701 pin_cfg_value = 0;
3702 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3703 pin_cfg_value |= 0x0113;
3704 /* io_pad_cfg_mode output mode is drive always */
3705 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3706
3707 /* write to io pad configuration register - output mode */
3708 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, pin_cfg_value, 0);
3709 if (rc != 0) {
3710 pr_err("error %d\n", rc);
3711 goto rw_error;
3712 }
3713
3714 /* use corresponding bit in io data output registar */
3715 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3716 if (rc != 0) {
3717 pr_err("error %d\n", rc);
3718 goto rw_error;
3719 }
3720 if (!uio_data->value)
3721 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
3722 else
3723 value |= 0x8000; /* write one to 15th bit - 1st UIO */
3724
3725 /* write back to io data output register */
3726 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3727 if (rc != 0) {
3728 pr_err("error %d\n", rc);
3729 goto rw_error;
3730 }
3731 break;
3732 /*======================================================================*/
3733 case DRX_UIO2:
3734 /* DRX_UIO2: SMA_RX UIO-2 */
3735 if (!ext_attr->has_smarx)
3736 return -EIO;
3737 if (ext_attr->uio_sma_rx_mode != DRX_UIO_MODE_READWRITE)
3738 return -EIO;
3739
3740 pin_cfg_value = 0;
3741 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3742 pin_cfg_value |= 0x0113;
3743 /* io_pad_cfg_mode output mode is drive always */
3744 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3745
3746 /* write to io pad configuration register - output mode */
3747 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_RX_CFG__A, pin_cfg_value, 0);
3748 if (rc != 0) {
3749 pr_err("error %d\n", rc);
3750 goto rw_error;
3751 }
3752
3753 /* use corresponding bit in io data output registar */
3754 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3755 if (rc != 0) {
3756 pr_err("error %d\n", rc);
3757 goto rw_error;
3758 }
3759 if (!uio_data->value)
3760 value &= 0xBFFF; /* write zero to 14th bit - 2nd UIO */
3761 else
3762 value |= 0x4000; /* write one to 14th bit - 2nd UIO */
3763
3764 /* write back to io data output register */
3765 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3766 if (rc != 0) {
3767 pr_err("error %d\n", rc);
3768 goto rw_error;
3769 }
3770 break;
3771 /*====================================================================*/
3772 case DRX_UIO3:
3773 /* DRX_UIO3: ASEL UIO-3 */
3774 if (!ext_attr->has_gpio)
3775 return -EIO;
3776 if (ext_attr->uio_gpio_mode != DRX_UIO_MODE_READWRITE)
3777 return -EIO;
3778
3779 pin_cfg_value = 0;
3780 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3781 pin_cfg_value |= 0x0113;
3782 /* io_pad_cfg_mode output mode is drive always */
3783 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3784
3785 /* write to io pad configuration register - output mode */
3786 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_GPIO_CFG__A, pin_cfg_value, 0);
3787 if (rc != 0) {
3788 pr_err("error %d\n", rc);
3789 goto rw_error;
3790 }
3791
3792 /* use corresponding bit in io data output registar */
3793 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, &value, 0);
3794 if (rc != 0) {
3795 pr_err("error %d\n", rc);
3796 goto rw_error;
3797 }
3798 if (!uio_data->value)
3799 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
3800 else
3801 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
3802
3803 /* write back to io data output register */
3804 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_HI__A, value, 0);
3805 if (rc != 0) {
3806 pr_err("error %d\n", rc);
3807 goto rw_error;
3808 }
3809 break;
3810 /*=====================================================================*/
3811 case DRX_UIO4:
3812 /* DRX_UIO4: IRQN UIO-4 */
3813 if (!ext_attr->has_irqn)
3814 return -EIO;
3815
3816 if (ext_attr->uio_irqn_mode != DRX_UIO_MODE_READWRITE)
3817 return -EIO;
3818
3819 pin_cfg_value = 0;
3820 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
3821 pin_cfg_value |= 0x0113;
3822 /* io_pad_cfg_mode output mode is drive always */
3823 /* io_pad_cfg_drive is set to power 2 (23 mA) */
3824
3825 /* write to io pad configuration register - output mode */
3826 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_IRQN_CFG__A, pin_cfg_value, 0);
3827 if (rc != 0) {
3828 pr_err("error %d\n", rc);
3829 goto rw_error;
3830 }
3831
3832 /* use corresponding bit in io data output registar */
3833 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, &value, 0);
3834 if (rc != 0) {
3835 pr_err("error %d\n", rc);
3836 goto rw_error;
3837 }
3838 if (uio_data->value == false)
3839 value &= 0xEFFF; /* write zero to 12th bit - 4th UIO */
3840 else
3841 value |= 0x1000; /* write one to 12th bit - 4th UIO */
3842
3843 /* write back to io data output register */
3844 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_UIO_OUT_LO__A, value, 0);
3845 if (rc != 0) {
3846 pr_err("error %d\n", rc);
3847 goto rw_error;
3848 }
3849 break;
3850 /*=====================================================================*/
3851 default:
3852 return -EINVAL;
3853 } /* switch ( uio_data->uio ) */
3854
3855 /* Write magic word to disable pdr reg write */
3856 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3857 if (rc != 0) {
3858 pr_err("error %d\n", rc);
3859 goto rw_error;
3860 }
3861
3862 return 0;
3863 rw_error:
3864 return rc;
3865 }
3866
3867 /*---------------------------------------------------------------------------*/
3868 /* UIO Configuration Functions - end */
3869 /*---------------------------------------------------------------------------*/
3870
3871 /*----------------------------------------------------------------------------*/
3872 /* I2C Bridge Functions - begin */
3873 /*----------------------------------------------------------------------------*/
3874 /*
3875 * \fn int ctrl_i2c_bridge()
3876 * \brief Open or close the I2C switch to tuner.
3877 * \param demod Pointer to demodulator instance.
3878 * \param bridge_closed Pointer to bool indication if bridge is closed not.
3879 * \return int.
3880
3881 */
3882 static int
ctrl_i2c_bridge(struct drx_demod_instance * demod,bool * bridge_closed)3883 ctrl_i2c_bridge(struct drx_demod_instance *demod, bool *bridge_closed)
3884 {
3885 struct drxj_hi_cmd hi_cmd;
3886 u16 result = 0;
3887
3888 /* check arguments */
3889 if (bridge_closed == NULL)
3890 return -EINVAL;
3891
3892 hi_cmd.cmd = SIO_HI_RA_RAM_CMD_BRDCTRL;
3893 hi_cmd.param1 = SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY;
3894 if (*bridge_closed)
3895 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED;
3896 else
3897 hi_cmd.param2 = SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN;
3898
3899 return hi_command(demod->my_i2c_dev_addr, &hi_cmd, &result);
3900 }
3901
3902 /*----------------------------------------------------------------------------*/
3903 /* I2C Bridge Functions - end */
3904 /*----------------------------------------------------------------------------*/
3905
3906 /*----------------------------------------------------------------------------*/
3907 /* Smart antenna Functions - begin */
3908 /*----------------------------------------------------------------------------*/
3909 /*
3910 * \fn int smart_ant_init()
3911 * \brief Initialize Smart Antenna.
3912 * \param pointer to struct drx_demod_instance.
3913 * \return int.
3914 *
3915 */
smart_ant_init(struct drx_demod_instance * demod)3916 static int smart_ant_init(struct drx_demod_instance *demod)
3917 {
3918 struct drxj_data *ext_attr = NULL;
3919 struct i2c_device_addr *dev_addr = NULL;
3920 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SMA };
3921 int rc;
3922 u16 data = 0;
3923
3924 dev_addr = demod->my_i2c_dev_addr;
3925 ext_attr = (struct drxj_data *) demod->my_ext_attr;
3926
3927 /* Write magic word to enable pdr reg write */
3928 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY, 0);
3929 if (rc != 0) {
3930 pr_err("error %d\n", rc);
3931 goto rw_error;
3932 }
3933 /* init smart antenna */
3934 rc = drxj_dap_read_reg16(dev_addr, SIO_SA_TX_COMMAND__A, &data, 0);
3935 if (rc != 0) {
3936 pr_err("error %d\n", rc);
3937 goto rw_error;
3938 }
3939 if (ext_attr->smart_ant_inverted) {
3940 rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data | SIO_SA_TX_COMMAND_TX_INVERT__M) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
3941 if (rc != 0) {
3942 pr_err("error %d\n", rc);
3943 goto rw_error;
3944 }
3945 } else {
3946 rc = drxj_dap_write_reg16(dev_addr, SIO_SA_TX_COMMAND__A, (data & (~SIO_SA_TX_COMMAND_TX_INVERT__M)) | SIO_SA_TX_COMMAND_TX_ENABLE__M, 0);
3947 if (rc != 0) {
3948 pr_err("error %d\n", rc);
3949 goto rw_error;
3950 }
3951 }
3952
3953 /* config SMA_TX pin to smart antenna mode */
3954 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
3955 if (rc != 0) {
3956 pr_err("error %d\n", rc);
3957 goto rw_error;
3958 }
3959 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_CFG__A, 0x13, 0);
3960 if (rc != 0) {
3961 pr_err("error %d\n", rc);
3962 goto rw_error;
3963 }
3964 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_PDR_SMA_TX_GPIO_FNC__A, 0x03, 0);
3965 if (rc != 0) {
3966 pr_err("error %d\n", rc);
3967 goto rw_error;
3968 }
3969
3970 /* Write magic word to disable pdr reg write */
3971 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
3972 if (rc != 0) {
3973 pr_err("error %d\n", rc);
3974 goto rw_error;
3975 }
3976
3977 return 0;
3978 rw_error:
3979 return rc;
3980 }
3981
scu_command(struct i2c_device_addr * dev_addr,struct drxjscu_cmd * cmd)3982 static int scu_command(struct i2c_device_addr *dev_addr, struct drxjscu_cmd *cmd)
3983 {
3984 int rc;
3985 u16 cur_cmd = 0;
3986 unsigned long timeout;
3987
3988 /* Check param */
3989 if (cmd == NULL)
3990 return -EINVAL;
3991
3992 /* Wait until SCU command interface is ready to receive command */
3993 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
3994 if (rc != 0) {
3995 pr_err("error %d\n", rc);
3996 goto rw_error;
3997 }
3998 if (cur_cmd != DRX_SCU_READY)
3999 return -EIO;
4000
4001 switch (cmd->parameter_len) {
4002 case 5:
4003 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_4__A, *(cmd->parameter + 4), 0);
4004 if (rc != 0) {
4005 pr_err("error %d\n", rc);
4006 goto rw_error;
4007 }
4008 fallthrough;
4009 case 4:
4010 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_3__A, *(cmd->parameter + 3), 0);
4011 if (rc != 0) {
4012 pr_err("error %d\n", rc);
4013 goto rw_error;
4014 }
4015 fallthrough;
4016 case 3:
4017 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_2__A, *(cmd->parameter + 2), 0);
4018 if (rc != 0) {
4019 pr_err("error %d\n", rc);
4020 goto rw_error;
4021 }
4022 fallthrough;
4023 case 2:
4024 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_1__A, *(cmd->parameter + 1), 0);
4025 if (rc != 0) {
4026 pr_err("error %d\n", rc);
4027 goto rw_error;
4028 }
4029 fallthrough;
4030 case 1:
4031 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_PARAM_0__A, *(cmd->parameter + 0), 0);
4032 if (rc != 0) {
4033 pr_err("error %d\n", rc);
4034 goto rw_error;
4035 }
4036 fallthrough;
4037 case 0:
4038 /* do nothing */
4039 break;
4040 default:
4041 /* this number of parameters is not supported */
4042 return -EIO;
4043 }
4044 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_COMMAND__A, cmd->command, 0);
4045 if (rc != 0) {
4046 pr_err("error %d\n", rc);
4047 goto rw_error;
4048 }
4049
4050 /* Wait until SCU has processed command */
4051 timeout = jiffies + msecs_to_jiffies(DRXJ_MAX_WAITTIME);
4052 while (time_is_after_jiffies(timeout)) {
4053 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_COMMAND__A, &cur_cmd, 0);
4054 if (rc != 0) {
4055 pr_err("error %d\n", rc);
4056 goto rw_error;
4057 }
4058 if (cur_cmd == DRX_SCU_READY)
4059 break;
4060 usleep_range(1000, 2000);
4061 }
4062
4063 if (cur_cmd != DRX_SCU_READY)
4064 return -EIO;
4065
4066 /* read results */
4067 if ((cmd->result_len > 0) && (cmd->result != NULL)) {
4068 s16 err;
4069
4070 switch (cmd->result_len) {
4071 case 4:
4072 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_3__A, cmd->result + 3, 0);
4073 if (rc != 0) {
4074 pr_err("error %d\n", rc);
4075 goto rw_error;
4076 }
4077 fallthrough;
4078 case 3:
4079 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_2__A, cmd->result + 2, 0);
4080 if (rc != 0) {
4081 pr_err("error %d\n", rc);
4082 goto rw_error;
4083 }
4084 fallthrough;
4085 case 2:
4086 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_1__A, cmd->result + 1, 0);
4087 if (rc != 0) {
4088 pr_err("error %d\n", rc);
4089 goto rw_error;
4090 }
4091 fallthrough;
4092 case 1:
4093 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_PARAM_0__A, cmd->result + 0, 0);
4094 if (rc != 0) {
4095 pr_err("error %d\n", rc);
4096 goto rw_error;
4097 }
4098 fallthrough;
4099 case 0:
4100 /* do nothing */
4101 break;
4102 default:
4103 /* this number of parameters is not supported */
4104 return -EIO;
4105 }
4106
4107 /* Check if an error was reported by SCU */
4108 err = cmd->result[0];
4109
4110 /* check a few fixed error codes */
4111 if ((err == (s16) SCU_RAM_PARAM_0_RESULT_UNKSTD)
4112 || (err == (s16) SCU_RAM_PARAM_0_RESULT_UNKCMD)
4113 || (err == (s16) SCU_RAM_PARAM_0_RESULT_INVPAR)
4114 || (err == (s16) SCU_RAM_PARAM_0_RESULT_SIZE)
4115 ) {
4116 return -EINVAL;
4117 }
4118 /* here it is assumed that negative means error, and positive no error */
4119 else if (err < 0)
4120 return -EIO;
4121 else
4122 return 0;
4123 }
4124
4125 return 0;
4126
4127 rw_error:
4128 return rc;
4129 }
4130
4131 /*
4132 * \fn int DRXJ_DAP_SCUAtomicReadWriteBlock()
4133 * \brief Basic access routine for SCU atomic read or write access
4134 * \param dev_addr pointer to i2c dev address
4135 * \param addr destination/source address
4136 * \param datasize size of data buffer in bytes
4137 * \param data pointer to data buffer
4138 * \return int
4139 * \retval 0 Success
4140 * \retval -EIO Timeout, I2C error, illegal bank
4141 *
4142 */
4143 #define ADDR_AT_SCU_SPACE(x) ((x - 0x82E000) * 2)
4144 static
drxj_dap_scu_atomic_read_write_block(struct i2c_device_addr * dev_addr,u32 addr,u16 datasize,u8 * data,bool read_flag)4145 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 */
4146 u8 *data, bool read_flag)
4147 {
4148 struct drxjscu_cmd scu_cmd;
4149 int rc;
4150 u16 set_param_parameters[18];
4151 u16 cmd_result[15];
4152
4153 /* Parameter check */
4154 if (!data || !dev_addr || (datasize % 2) || ((datasize / 2) > 16))
4155 return -EINVAL;
4156
4157 set_param_parameters[1] = (u16) ADDR_AT_SCU_SPACE(addr);
4158 if (read_flag) { /* read */
4159 set_param_parameters[0] = ((~(0x0080)) & datasize);
4160 scu_cmd.parameter_len = 2;
4161 scu_cmd.result_len = datasize / 2 + 2;
4162 } else {
4163 int i = 0;
4164
4165 set_param_parameters[0] = 0x0080 | datasize;
4166 for (i = 0; i < (datasize / 2); i++) {
4167 set_param_parameters[i + 2] =
4168 (data[2 * i] | (data[(2 * i) + 1] << 8));
4169 }
4170 scu_cmd.parameter_len = datasize / 2 + 2;
4171 scu_cmd.result_len = 1;
4172 }
4173
4174 scu_cmd.command =
4175 SCU_RAM_COMMAND_STANDARD_TOP |
4176 SCU_RAM_COMMAND_CMD_AUX_SCU_ATOMIC_ACCESS;
4177 scu_cmd.result = cmd_result;
4178 scu_cmd.parameter = set_param_parameters;
4179 rc = scu_command(dev_addr, &scu_cmd);
4180 if (rc != 0) {
4181 pr_err("error %d\n", rc);
4182 goto rw_error;
4183 }
4184
4185 if (read_flag) {
4186 int i = 0;
4187 /* read data from buffer */
4188 for (i = 0; i < (datasize / 2); i++) {
4189 data[2 * i] = (u8) (scu_cmd.result[i + 2] & 0xFF);
4190 data[(2 * i) + 1] = (u8) (scu_cmd.result[i + 2] >> 8);
4191 }
4192 }
4193
4194 return 0;
4195
4196 rw_error:
4197 return rc;
4198
4199 }
4200
4201 /*============================================================================*/
4202
4203 /*
4204 * \fn int DRXJ_DAP_AtomicReadReg16()
4205 * \brief Atomic read of 16 bits words
4206 */
4207 static
drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr * dev_addr,u32 addr,u16 * data,u32 flags)4208 int drxj_dap_scu_atomic_read_reg16(struct i2c_device_addr *dev_addr,
4209 u32 addr,
4210 u16 *data, u32 flags)
4211 {
4212 u8 buf[2] = { 0 };
4213 int rc;
4214 u16 word = 0;
4215
4216 if (!data)
4217 return -EINVAL;
4218
4219 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, true);
4220 if (rc < 0)
4221 return rc;
4222
4223 word = (u16) (buf[0] + (buf[1] << 8));
4224
4225 *data = word;
4226
4227 return rc;
4228 }
4229
4230 /*============================================================================*/
4231 /*
4232 * \fn int drxj_dap_scu_atomic_write_reg16()
4233 * \brief Atomic read of 16 bits words
4234 */
4235 static
drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr * dev_addr,u32 addr,u16 data,u32 flags)4236 int drxj_dap_scu_atomic_write_reg16(struct i2c_device_addr *dev_addr,
4237 u32 addr,
4238 u16 data, u32 flags)
4239 {
4240 u8 buf[2];
4241 int rc;
4242
4243 buf[0] = (u8) (data & 0xff);
4244 buf[1] = (u8) ((data >> 8) & 0xff);
4245
4246 rc = drxj_dap_scu_atomic_read_write_block(dev_addr, addr, 2, buf, false);
4247
4248 return rc;
4249 }
4250
4251 /* -------------------------------------------------------------------------- */
4252 /*
4253 * \brief Measure result of ADC synchronisation
4254 * \param demod demod instance
4255 * \param count (returned) count
4256 * \return int.
4257 * \retval 0 Success
4258 * \retval -EIO Failure: I2C error
4259 *
4260 */
adc_sync_measurement(struct drx_demod_instance * demod,u16 * count)4261 static int adc_sync_measurement(struct drx_demod_instance *demod, u16 *count)
4262 {
4263 struct i2c_device_addr *dev_addr = NULL;
4264 int rc;
4265 u16 data = 0;
4266
4267 dev_addr = demod->my_i2c_dev_addr;
4268
4269 /* Start measurement */
4270 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE, 0);
4271 if (rc != 0) {
4272 pr_err("error %d\n", rc);
4273 goto rw_error;
4274 }
4275 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_START_LOCK__A, 1, 0);
4276 if (rc != 0) {
4277 pr_err("error %d\n", rc);
4278 goto rw_error;
4279 }
4280
4281 /* Wait at least 3*128*(1/sysclk) <<< 1 millisec */
4282 msleep(1);
4283
4284 *count = 0;
4285 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE0__A, &data, 0);
4286 if (rc != 0) {
4287 pr_err("error %d\n", rc);
4288 goto rw_error;
4289 }
4290 if (data == 127)
4291 *count = *count + 1;
4292 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE1__A, &data, 0);
4293 if (rc != 0) {
4294 pr_err("error %d\n", rc);
4295 goto rw_error;
4296 }
4297 if (data == 127)
4298 *count = *count + 1;
4299 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_PHASE2__A, &data, 0);
4300 if (rc != 0) {
4301 pr_err("error %d\n", rc);
4302 goto rw_error;
4303 }
4304 if (data == 127)
4305 *count = *count + 1;
4306
4307 return 0;
4308 rw_error:
4309 return rc;
4310 }
4311
4312 /*
4313 * \brief Synchronize analog and digital clock domains
4314 * \param demod demod instance
4315 * \return int.
4316 * \retval 0 Success
4317 * \retval -EIO Failure: I2C error or failure to synchronize
4318 *
4319 * An IQM reset will also reset the results of this synchronization.
4320 * After an IQM reset this routine needs to be called again.
4321 *
4322 */
4323
adc_synchronization(struct drx_demod_instance * demod)4324 static int adc_synchronization(struct drx_demod_instance *demod)
4325 {
4326 struct i2c_device_addr *dev_addr = NULL;
4327 int rc;
4328 u16 count = 0;
4329
4330 dev_addr = demod->my_i2c_dev_addr;
4331
4332 rc = adc_sync_measurement(demod, &count);
4333 if (rc != 0) {
4334 pr_err("error %d\n", rc);
4335 goto rw_error;
4336 }
4337
4338 if (count == 1) {
4339 /* Try sampling on a different edge */
4340 u16 clk_neg = 0;
4341
4342 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_CLKNEG__A, &clk_neg, 0);
4343 if (rc != 0) {
4344 pr_err("error %d\n", rc);
4345 goto rw_error;
4346 }
4347
4348 clk_neg ^= IQM_AF_CLKNEG_CLKNEGDATA__M;
4349 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLKNEG__A, clk_neg, 0);
4350 if (rc != 0) {
4351 pr_err("error %d\n", rc);
4352 goto rw_error;
4353 }
4354
4355 rc = adc_sync_measurement(demod, &count);
4356 if (rc != 0) {
4357 pr_err("error %d\n", rc);
4358 goto rw_error;
4359 }
4360 }
4361
4362 /* TODO: implement fallback scenarios */
4363 if (count < 2)
4364 return -EIO;
4365
4366 return 0;
4367 rw_error:
4368 return rc;
4369 }
4370
4371 /*============================================================================*/
4372 /*== END AUXILIARY FUNCTIONS ==*/
4373 /*============================================================================*/
4374
4375 /*============================================================================*/
4376 /*============================================================================*/
4377 /*== 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
4378 /*============================================================================*/
4379 /*============================================================================*/
4380 /*
4381 * \fn int init_agc ()
4382 * \brief Initialize AGC for all standards.
4383 * \param demod instance of demodulator.
4384 * \param channel pointer to channel data.
4385 * \return int.
4386 */
init_agc(struct drx_demod_instance * demod)4387 static int init_agc(struct drx_demod_instance *demod)
4388 {
4389 struct i2c_device_addr *dev_addr = NULL;
4390 struct drx_common_attr *common_attr = NULL;
4391 struct drxj_data *ext_attr = NULL;
4392 struct drxj_cfg_agc *p_agc_rf_settings = NULL;
4393 struct drxj_cfg_agc *p_agc_if_settings = NULL;
4394 int rc;
4395 u16 ingain_tgt_max = 0;
4396 u16 clp_dir_to = 0;
4397 u16 sns_sum_max = 0;
4398 u16 clp_sum_max = 0;
4399 u16 sns_dir_to = 0;
4400 u16 ki_innergain_min = 0;
4401 u16 agc_ki = 0;
4402 u16 ki_max = 0;
4403 u16 if_iaccu_hi_tgt_min = 0;
4404 u16 data = 0;
4405 u16 agc_ki_dgain = 0;
4406 u16 ki_min = 0;
4407 u16 clp_ctrl_mode = 0;
4408 u16 agc_rf = 0;
4409 u16 agc_if = 0;
4410
4411 dev_addr = demod->my_i2c_dev_addr;
4412 common_attr = (struct drx_common_attr *) demod->my_common_attr;
4413 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4414
4415 switch (ext_attr->standard) {
4416 case DRX_STANDARD_8VSB:
4417 clp_sum_max = 1023;
4418 clp_dir_to = (u16) (-9);
4419 sns_sum_max = 1023;
4420 sns_dir_to = (u16) (-9);
4421 ki_innergain_min = (u16) (-32768);
4422 ki_max = 0x032C;
4423 agc_ki_dgain = 0xC;
4424 if_iaccu_hi_tgt_min = 2047;
4425 ki_min = 0x0117;
4426 ingain_tgt_max = 16383;
4427 clp_ctrl_mode = 0;
4428 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
4429 if (rc != 0) {
4430 pr_err("error %d\n", rc);
4431 goto rw_error;
4432 }
4433 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
4434 if (rc != 0) {
4435 pr_err("error %d\n", rc);
4436 goto rw_error;
4437 }
4438 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
4439 if (rc != 0) {
4440 pr_err("error %d\n", rc);
4441 goto rw_error;
4442 }
4443 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
4444 if (rc != 0) {
4445 pr_err("error %d\n", rc);
4446 goto rw_error;
4447 }
4448 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
4449 if (rc != 0) {
4450 pr_err("error %d\n", rc);
4451 goto rw_error;
4452 }
4453 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
4454 if (rc != 0) {
4455 pr_err("error %d\n", rc);
4456 goto rw_error;
4457 }
4458 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
4459 if (rc != 0) {
4460 pr_err("error %d\n", rc);
4461 goto rw_error;
4462 }
4463 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
4464 if (rc != 0) {
4465 pr_err("error %d\n", rc);
4466 goto rw_error;
4467 }
4468 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
4469 if (rc != 0) {
4470 pr_err("error %d\n", rc);
4471 goto rw_error;
4472 }
4473 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
4474 if (rc != 0) {
4475 pr_err("error %d\n", rc);
4476 goto rw_error;
4477 }
4478 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, 1024, 0);
4479 if (rc != 0) {
4480 pr_err("error %d\n", rc);
4481 goto rw_error;
4482 }
4483 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_VSB_AGC_POW_TGT__A, 22600, 0);
4484 if (rc != 0) {
4485 pr_err("error %d\n", rc);
4486 goto rw_error;
4487 }
4488 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, 13200, 0);
4489 if (rc != 0) {
4490 pr_err("error %d\n", rc);
4491 goto rw_error;
4492 }
4493 p_agc_if_settings = &(ext_attr->vsb_if_agc_cfg);
4494 p_agc_rf_settings = &(ext_attr->vsb_rf_agc_cfg);
4495 break;
4496 #ifndef DRXJ_VSB_ONLY
4497 case DRX_STANDARD_ITU_A:
4498 case DRX_STANDARD_ITU_C:
4499 case DRX_STANDARD_ITU_B:
4500 ingain_tgt_max = 5119;
4501 clp_sum_max = 1023;
4502 clp_dir_to = (u16) (-5);
4503 sns_sum_max = 127;
4504 sns_dir_to = (u16) (-3);
4505 ki_innergain_min = 0;
4506 ki_max = 0x0657;
4507 if_iaccu_hi_tgt_min = 2047;
4508 agc_ki_dgain = 0x7;
4509 ki_min = 0x0117;
4510 clp_ctrl_mode = 0;
4511 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff, 0);
4512 if (rc != 0) {
4513 pr_err("error %d\n", rc);
4514 goto rw_error;
4515 }
4516 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0, 0);
4517 if (rc != 0) {
4518 pr_err("error %d\n", rc);
4519 goto rw_error;
4520 }
4521 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM__A, 0, 0);
4522 if (rc != 0) {
4523 pr_err("error %d\n", rc);
4524 goto rw_error;
4525 }
4526 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCCNT__A, 0, 0);
4527 if (rc != 0) {
4528 pr_err("error %d\n", rc);
4529 goto rw_error;
4530 }
4531 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_WD__A, 0, 0);
4532 if (rc != 0) {
4533 pr_err("error %d\n", rc);
4534 goto rw_error;
4535 }
4536 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_STP__A, 1, 0);
4537 if (rc != 0) {
4538 pr_err("error %d\n", rc);
4539 goto rw_error;
4540 }
4541 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM__A, 0, 0);
4542 if (rc != 0) {
4543 pr_err("error %d\n", rc);
4544 goto rw_error;
4545 }
4546 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCCNT__A, 0, 0);
4547 if (rc != 0) {
4548 pr_err("error %d\n", rc);
4549 goto rw_error;
4550 }
4551 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_WD__A, 0, 0);
4552 if (rc != 0) {
4553 pr_err("error %d\n", rc);
4554 goto rw_error;
4555 }
4556 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_STP__A, 1, 0);
4557 if (rc != 0) {
4558 pr_err("error %d\n", rc);
4559 goto rw_error;
4560 }
4561 p_agc_if_settings = &(ext_attr->qam_if_agc_cfg);
4562 p_agc_rf_settings = &(ext_attr->qam_rf_agc_cfg);
4563 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT__A, p_agc_if_settings->top, 0);
4564 if (rc != 0) {
4565 pr_err("error %d\n", rc);
4566 goto rw_error;
4567 }
4568
4569 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &agc_ki, 0);
4570 if (rc != 0) {
4571 pr_err("error %d\n", rc);
4572 goto rw_error;
4573 }
4574 agc_ki &= 0xf000;
4575 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, agc_ki, 0);
4576 if (rc != 0) {
4577 pr_err("error %d\n", rc);
4578 goto rw_error;
4579 }
4580 break;
4581 #endif
4582 default:
4583 return -EINVAL;
4584 }
4585
4586 /* for new AGC interface */
4587 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_if_settings->top, 0);
4588 if (rc != 0) {
4589 pr_err("error %d\n", rc);
4590 goto rw_error;
4591 }
4592 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN__A, p_agc_if_settings->top, 0);
4593 if (rc != 0) {
4594 pr_err("error %d\n", rc);
4595 goto rw_error;
4596 } /* Gain fed from inner to outer AGC */
4597 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max, 0);
4598 if (rc != 0) {
4599 pr_err("error %d\n", rc);
4600 goto rw_error;
4601 }
4602 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, if_iaccu_hi_tgt_min, 0);
4603 if (rc != 0) {
4604 pr_err("error %d\n", rc);
4605 goto rw_error;
4606 }
4607 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_HI__A, 0, 0);
4608 if (rc != 0) {
4609 pr_err("error %d\n", rc);
4610 goto rw_error;
4611 } /* set to p_agc_settings->top before */
4612 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_IF_IACCU_LO__A, 0, 0);
4613 if (rc != 0) {
4614 pr_err("error %d\n", rc);
4615 goto rw_error;
4616 }
4617 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, 0, 0);
4618 if (rc != 0) {
4619 pr_err("error %d\n", rc);
4620 goto rw_error;
4621 }
4622 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_IACCU_LO__A, 0, 0);
4623 if (rc != 0) {
4624 pr_err("error %d\n", rc);
4625 goto rw_error;
4626 }
4627 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_RF_MAX__A, 32767, 0);
4628 if (rc != 0) {
4629 pr_err("error %d\n", rc);
4630 goto rw_error;
4631 }
4632 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max, 0);
4633 if (rc != 0) {
4634 pr_err("error %d\n", rc);
4635 goto rw_error;
4636 }
4637 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max, 0);
4638 if (rc != 0) {
4639 pr_err("error %d\n", rc);
4640 goto rw_error;
4641 }
4642 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, ki_innergain_min, 0);
4643 if (rc != 0) {
4644 pr_err("error %d\n", rc);
4645 goto rw_error;
4646 }
4647 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50, 0);
4648 if (rc != 0) {
4649 pr_err("error %d\n", rc);
4650 goto rw_error;
4651 }
4652 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_CYCLEN__A, 500, 0);
4653 if (rc != 0) {
4654 pr_err("error %d\n", rc);
4655 goto rw_error;
4656 }
4657 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_CYCLEN__A, 500, 0);
4658 if (rc != 0) {
4659 pr_err("error %d\n", rc);
4660 goto rw_error;
4661 }
4662 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20, 0);
4663 if (rc != 0) {
4664 pr_err("error %d\n", rc);
4665 goto rw_error;
4666 }
4667 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MIN__A, ki_min, 0);
4668 if (rc != 0) {
4669 pr_err("error %d\n", rc);
4670 goto rw_error;
4671 }
4672 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_MAX__A, ki_max, 0);
4673 if (rc != 0) {
4674 pr_err("error %d\n", rc);
4675 goto rw_error;
4676 }
4677 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI_RED__A, 0, 0);
4678 if (rc != 0) {
4679 pr_err("error %d\n", rc);
4680 goto rw_error;
4681 }
4682 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_SUM_MIN__A, 8, 0);
4683 if (rc != 0) {
4684 pr_err("error %d\n", rc);
4685 goto rw_error;
4686 }
4687 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CYCLEN__A, 500, 0);
4688 if (rc != 0) {
4689 pr_err("error %d\n", rc);
4690 goto rw_error;
4691 }
4692 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to, 0);
4693 if (rc != 0) {
4694 pr_err("error %d\n", rc);
4695 goto rw_error;
4696 }
4697 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_SUM_MIN__A, 8, 0);
4698 if (rc != 0) {
4699 pr_err("error %d\n", rc);
4700 goto rw_error;
4701 }
4702 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to, 0);
4703 if (rc != 0) {
4704 pr_err("error %d\n", rc);
4705 goto rw_error;
4706 }
4707 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, 50, 0);
4708 if (rc != 0) {
4709 pr_err("error %d\n", rc);
4710 goto rw_error;
4711 }
4712 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode, 0);
4713 if (rc != 0) {
4714 pr_err("error %d\n", rc);
4715 goto rw_error;
4716 }
4717
4718 agc_rf = 0x800 + p_agc_rf_settings->cut_off_current;
4719 if (common_attr->tuner_rf_agc_pol == true)
4720 agc_rf = 0x87ff - agc_rf;
4721
4722 agc_if = 0x800;
4723 if (common_attr->tuner_if_agc_pol == true)
4724 agc_rf = 0x87ff - agc_rf;
4725
4726 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_RF__A, agc_rf, 0);
4727 if (rc != 0) {
4728 pr_err("error %d\n", rc);
4729 goto rw_error;
4730 }
4731 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AGC_IF__A, agc_if, 0);
4732 if (rc != 0) {
4733 pr_err("error %d\n", rc);
4734 goto rw_error;
4735 }
4736
4737 /* Set/restore Ki DGAIN factor */
4738 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
4739 if (rc != 0) {
4740 pr_err("error %d\n", rc);
4741 goto rw_error;
4742 }
4743 data &= ~SCU_RAM_AGC_KI_DGAIN__M;
4744 data |= (agc_ki_dgain << SCU_RAM_AGC_KI_DGAIN__B);
4745 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
4746 if (rc != 0) {
4747 pr_err("error %d\n", rc);
4748 goto rw_error;
4749 }
4750
4751 return 0;
4752 rw_error:
4753 return rc;
4754 }
4755
4756 /*
4757 * \fn int set_frequency ()
4758 * \brief Set frequency shift.
4759 * \param demod instance of demodulator.
4760 * \param channel pointer to channel data.
4761 * \param tuner_freq_offset residual frequency from tuner.
4762 * \return int.
4763 */
4764 static int
set_frequency(struct drx_demod_instance * demod,struct drx_channel * channel,s32 tuner_freq_offset)4765 set_frequency(struct drx_demod_instance *demod,
4766 struct drx_channel *channel, s32 tuner_freq_offset)
4767 {
4768 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
4769 struct drxj_data *ext_attr = demod->my_ext_attr;
4770 int rc;
4771 s32 sampling_frequency = 0;
4772 s32 frequency_shift = 0;
4773 s32 if_freq_actual = 0;
4774 s32 rf_freq_residual = -1 * tuner_freq_offset;
4775 s32 adc_freq = 0;
4776 s32 intermediate_freq = 0;
4777 u32 iqm_fs_rate_ofs = 0;
4778 bool adc_flip = true;
4779 bool select_pos_image = false;
4780 bool rf_mirror;
4781 bool tuner_mirror;
4782 bool image_to_select = true;
4783 s32 fm_frequency_shift = 0;
4784
4785 rf_mirror = (ext_attr->mirror == DRX_MIRROR_YES) ? true : false;
4786 tuner_mirror = demod->my_common_attr->mirror_freq_spect ? false : true;
4787 /*
4788 Program frequency shifter
4789 No need to account for mirroring on RF
4790 */
4791 switch (ext_attr->standard) {
4792 case DRX_STANDARD_ITU_A:
4793 case DRX_STANDARD_ITU_C:
4794 case DRX_STANDARD_PAL_SECAM_LP:
4795 case DRX_STANDARD_8VSB:
4796 select_pos_image = true;
4797 break;
4798 case DRX_STANDARD_FM:
4799 /* After IQM FS sound carrier must appear at 4 Mhz in spect.
4800 Sound carrier is already 3Mhz above centre frequency due
4801 to tuner setting so now add an extra shift of 1MHz... */
4802 fm_frequency_shift = 1000;
4803 fallthrough;
4804 case DRX_STANDARD_ITU_B:
4805 case DRX_STANDARD_NTSC:
4806 case DRX_STANDARD_PAL_SECAM_BG:
4807 case DRX_STANDARD_PAL_SECAM_DK:
4808 case DRX_STANDARD_PAL_SECAM_I:
4809 case DRX_STANDARD_PAL_SECAM_L:
4810 select_pos_image = false;
4811 break;
4812 default:
4813 return -EINVAL;
4814 }
4815 intermediate_freq = demod->my_common_attr->intermediate_freq;
4816 sampling_frequency = demod->my_common_attr->sys_clock_freq / 3;
4817 if (tuner_mirror)
4818 if_freq_actual = intermediate_freq + rf_freq_residual + fm_frequency_shift;
4819 else
4820 if_freq_actual = intermediate_freq - rf_freq_residual - fm_frequency_shift;
4821 if (if_freq_actual > sampling_frequency / 2) {
4822 /* adc mirrors */
4823 adc_freq = sampling_frequency - if_freq_actual;
4824 adc_flip = true;
4825 } else {
4826 /* adc doesn't mirror */
4827 adc_freq = if_freq_actual;
4828 adc_flip = false;
4829 }
4830
4831 frequency_shift = adc_freq;
4832 image_to_select =
4833 (bool) (rf_mirror ^ tuner_mirror ^ adc_flip ^ select_pos_image);
4834 iqm_fs_rate_ofs = frac28(frequency_shift, sampling_frequency);
4835
4836 if (image_to_select)
4837 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
4838
4839 /* Program frequency shifter with tuner offset compensation */
4840 /* frequency_shift += tuner_freq_offset; TODO */
4841 rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
4842 if (rc != 0) {
4843 pr_err("error %d\n", rc);
4844 goto rw_error;
4845 }
4846 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
4847 ext_attr->pos_image = (bool) (rf_mirror ^ tuner_mirror ^ select_pos_image);
4848
4849 return 0;
4850 rw_error:
4851 return rc;
4852 }
4853
4854 /*
4855 * \fn int get_acc_pkt_err()
4856 * \brief Retrieve signal strength for VSB and QAM.
4857 * \param demod Pointer to demod instance
4858 * \param packet_err Pointer to packet error
4859 * \return int.
4860 * \retval 0 sig_strength contains valid data.
4861 * \retval -EINVAL sig_strength is NULL.
4862 * \retval -EIO Erroneous data, sig_strength contains invalid data.
4863 */
4864 #ifdef DRXJ_SIGNAL_ACCUM_ERR
get_acc_pkt_err(struct drx_demod_instance * demod,u16 * packet_err)4865 static int get_acc_pkt_err(struct drx_demod_instance *demod, u16 *packet_err)
4866 {
4867 int rc;
4868 static u16 pkt_err;
4869 static u16 last_pkt_err;
4870 u16 data = 0;
4871 struct drxj_data *ext_attr = NULL;
4872 struct i2c_device_addr *dev_addr = NULL;
4873
4874 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4875 dev_addr = demod->my_i2c_dev_addr;
4876
4877 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, &data, 0);
4878 if (rc != 0) {
4879 pr_err("error %d\n", rc);
4880 goto rw_error;
4881 }
4882 if (ext_attr->reset_pkt_err_acc) {
4883 last_pkt_err = data;
4884 pkt_err = 0;
4885 ext_attr->reset_pkt_err_acc = false;
4886 }
4887
4888 if (data < last_pkt_err) {
4889 pkt_err += 0xffff - last_pkt_err;
4890 pkt_err += data;
4891 } else {
4892 pkt_err += (data - last_pkt_err);
4893 }
4894 *packet_err = pkt_err;
4895 last_pkt_err = data;
4896
4897 return 0;
4898 rw_error:
4899 return rc;
4900 }
4901 #endif
4902
4903
4904 /*============================================================================*/
4905
4906 /*
4907 * \fn int set_agc_rf ()
4908 * \brief Configure RF AGC
4909 * \param demod instance of demodulator.
4910 * \param agc_settings AGC configuration structure
4911 * \return int.
4912 */
4913 static int
set_agc_rf(struct drx_demod_instance * demod,struct drxj_cfg_agc * agc_settings,bool atomic)4914 set_agc_rf(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
4915 {
4916 struct i2c_device_addr *dev_addr = NULL;
4917 struct drxj_data *ext_attr = NULL;
4918 struct drxj_cfg_agc *p_agc_settings = NULL;
4919 struct drx_common_attr *common_attr = NULL;
4920 int rc;
4921 drx_write_reg16func_t scu_wr16 = NULL;
4922 drx_read_reg16func_t scu_rr16 = NULL;
4923
4924 common_attr = (struct drx_common_attr *) demod->my_common_attr;
4925 dev_addr = demod->my_i2c_dev_addr;
4926 ext_attr = (struct drxj_data *) demod->my_ext_attr;
4927
4928 if (atomic) {
4929 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
4930 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
4931 } else {
4932 scu_rr16 = drxj_dap_read_reg16;
4933 scu_wr16 = drxj_dap_write_reg16;
4934 }
4935
4936 /* Configure AGC only if standard is currently active */
4937 if ((ext_attr->standard == agc_settings->standard) ||
4938 (DRXJ_ISQAMSTD(ext_attr->standard) &&
4939 DRXJ_ISQAMSTD(agc_settings->standard)) ||
4940 (DRXJ_ISATVSTD(ext_attr->standard) &&
4941 DRXJ_ISATVSTD(agc_settings->standard))) {
4942 u16 data = 0;
4943
4944 switch (agc_settings->ctrl_mode) {
4945 case DRX_AGC_CTRL_AUTO:
4946
4947 /* Enable RF AGC DAC */
4948 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
4949 if (rc != 0) {
4950 pr_err("error %d\n", rc);
4951 goto rw_error;
4952 }
4953 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
4954 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
4955 if (rc != 0) {
4956 pr_err("error %d\n", rc);
4957 goto rw_error;
4958 }
4959
4960 /* Enable SCU RF AGC loop */
4961 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
4962 if (rc != 0) {
4963 pr_err("error %d\n", rc);
4964 goto rw_error;
4965 }
4966 data &= ~SCU_RAM_AGC_KI_RF__M;
4967 if (ext_attr->standard == DRX_STANDARD_8VSB)
4968 data |= (2 << SCU_RAM_AGC_KI_RF__B);
4969 else if (DRXJ_ISQAMSTD(ext_attr->standard))
4970 data |= (5 << SCU_RAM_AGC_KI_RF__B);
4971 else
4972 data |= (4 << SCU_RAM_AGC_KI_RF__B);
4973
4974 if (common_attr->tuner_rf_agc_pol)
4975 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
4976 else
4977 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
4978 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
4979 if (rc != 0) {
4980 pr_err("error %d\n", rc);
4981 goto rw_error;
4982 }
4983
4984 /* Set speed ( using complementary reduction value ) */
4985 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
4986 if (rc != 0) {
4987 pr_err("error %d\n", rc);
4988 goto rw_error;
4989 }
4990 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
4991 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);
4992 if (rc != 0) {
4993 pr_err("error %d\n", rc);
4994 goto rw_error;
4995 }
4996
4997 if (agc_settings->standard == DRX_STANDARD_8VSB)
4998 p_agc_settings = &(ext_attr->vsb_if_agc_cfg);
4999 else if (DRXJ_ISQAMSTD(agc_settings->standard))
5000 p_agc_settings = &(ext_attr->qam_if_agc_cfg);
5001 else if (DRXJ_ISATVSTD(agc_settings->standard))
5002 p_agc_settings = &(ext_attr->atv_if_agc_cfg);
5003 else
5004 return -EINVAL;
5005
5006 /* Set TOP, only if IF-AGC is in AUTO mode */
5007 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5008 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->top, 0);
5009 if (rc != 0) {
5010 pr_err("error %d\n", rc);
5011 goto rw_error;
5012 }
5013 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, agc_settings->top, 0);
5014 if (rc != 0) {
5015 pr_err("error %d\n", rc);
5016 goto rw_error;
5017 }
5018 }
5019
5020 /* Cut-Off current */
5021 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI_CO__A, agc_settings->cut_off_current, 0);
5022 if (rc != 0) {
5023 pr_err("error %d\n", rc);
5024 goto rw_error;
5025 }
5026 break;
5027 case DRX_AGC_CTRL_USER:
5028
5029 /* Enable RF AGC DAC */
5030 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5031 if (rc != 0) {
5032 pr_err("error %d\n", rc);
5033 goto rw_error;
5034 }
5035 data |= IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE;
5036 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5037 if (rc != 0) {
5038 pr_err("error %d\n", rc);
5039 goto rw_error;
5040 }
5041
5042 /* Disable SCU RF AGC loop */
5043 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5044 if (rc != 0) {
5045 pr_err("error %d\n", rc);
5046 goto rw_error;
5047 }
5048 data &= ~SCU_RAM_AGC_KI_RF__M;
5049 if (common_attr->tuner_rf_agc_pol)
5050 data |= SCU_RAM_AGC_KI_INV_RF_POL__M;
5051 else
5052 data &= ~SCU_RAM_AGC_KI_INV_RF_POL__M;
5053 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5054 if (rc != 0) {
5055 pr_err("error %d\n", rc);
5056 goto rw_error;
5057 }
5058
5059 /* Write value to output pin */
5060 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_RF_IACCU_HI__A, agc_settings->output_level, 0);
5061 if (rc != 0) {
5062 pr_err("error %d\n", rc);
5063 goto rw_error;
5064 }
5065 break;
5066 case DRX_AGC_CTRL_OFF:
5067
5068 /* Disable RF AGC DAC */
5069 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5070 if (rc != 0) {
5071 pr_err("error %d\n", rc);
5072 goto rw_error;
5073 }
5074 data &= (~IQM_AF_STDBY_STDBY_TAGC_RF_A2_ACTIVE);
5075 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5076 if (rc != 0) {
5077 pr_err("error %d\n", rc);
5078 goto rw_error;
5079 }
5080
5081 /* Disable SCU RF AGC loop */
5082 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5083 if (rc != 0) {
5084 pr_err("error %d\n", rc);
5085 goto rw_error;
5086 }
5087 data &= ~SCU_RAM_AGC_KI_RF__M;
5088 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5089 if (rc != 0) {
5090 pr_err("error %d\n", rc);
5091 goto rw_error;
5092 }
5093 break;
5094 default:
5095 return -EINVAL;
5096 } /* switch ( agcsettings->ctrl_mode ) */
5097 }
5098
5099 /* Store rf agc settings */
5100 switch (agc_settings->standard) {
5101 case DRX_STANDARD_8VSB:
5102 ext_attr->vsb_rf_agc_cfg = *agc_settings;
5103 break;
5104 #ifndef DRXJ_VSB_ONLY
5105 case DRX_STANDARD_ITU_A:
5106 case DRX_STANDARD_ITU_B:
5107 case DRX_STANDARD_ITU_C:
5108 ext_attr->qam_rf_agc_cfg = *agc_settings;
5109 break;
5110 #endif
5111 default:
5112 return -EIO;
5113 }
5114
5115 return 0;
5116 rw_error:
5117 return rc;
5118 }
5119
5120 /*
5121 * \fn int set_agc_if ()
5122 * \brief Configure If AGC
5123 * \param demod instance of demodulator.
5124 * \param agc_settings AGC configuration structure
5125 * \return int.
5126 */
5127 static int
set_agc_if(struct drx_demod_instance * demod,struct drxj_cfg_agc * agc_settings,bool atomic)5128 set_agc_if(struct drx_demod_instance *demod, struct drxj_cfg_agc *agc_settings, bool atomic)
5129 {
5130 struct i2c_device_addr *dev_addr = NULL;
5131 struct drxj_data *ext_attr = NULL;
5132 struct drxj_cfg_agc *p_agc_settings = NULL;
5133 struct drx_common_attr *common_attr = NULL;
5134 drx_write_reg16func_t scu_wr16 = NULL;
5135 drx_read_reg16func_t scu_rr16 = NULL;
5136 int rc;
5137
5138 common_attr = (struct drx_common_attr *) demod->my_common_attr;
5139 dev_addr = demod->my_i2c_dev_addr;
5140 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5141
5142 if (atomic) {
5143 scu_rr16 = drxj_dap_scu_atomic_read_reg16;
5144 scu_wr16 = drxj_dap_scu_atomic_write_reg16;
5145 } else {
5146 scu_rr16 = drxj_dap_read_reg16;
5147 scu_wr16 = drxj_dap_write_reg16;
5148 }
5149
5150 /* Configure AGC only if standard is currently active */
5151 if ((ext_attr->standard == agc_settings->standard) ||
5152 (DRXJ_ISQAMSTD(ext_attr->standard) &&
5153 DRXJ_ISQAMSTD(agc_settings->standard)) ||
5154 (DRXJ_ISATVSTD(ext_attr->standard) &&
5155 DRXJ_ISATVSTD(agc_settings->standard))) {
5156 u16 data = 0;
5157
5158 switch (agc_settings->ctrl_mode) {
5159 case DRX_AGC_CTRL_AUTO:
5160 /* Enable IF AGC DAC */
5161 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5162 if (rc != 0) {
5163 pr_err("error %d\n", rc);
5164 goto rw_error;
5165 }
5166 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5167 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5168 if (rc != 0) {
5169 pr_err("error %d\n", rc);
5170 goto rw_error;
5171 }
5172
5173 /* Enable SCU IF AGC loop */
5174 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5175 if (rc != 0) {
5176 pr_err("error %d\n", rc);
5177 goto rw_error;
5178 }
5179 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5180 data &= ~SCU_RAM_AGC_KI_IF__M;
5181 if (ext_attr->standard == DRX_STANDARD_8VSB)
5182 data |= (3 << SCU_RAM_AGC_KI_IF__B);
5183 else if (DRXJ_ISQAMSTD(ext_attr->standard))
5184 data |= (6 << SCU_RAM_AGC_KI_IF__B);
5185 else
5186 data |= (5 << SCU_RAM_AGC_KI_IF__B);
5187
5188 if (common_attr->tuner_if_agc_pol)
5189 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5190 else
5191 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5192 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5193 if (rc != 0) {
5194 pr_err("error %d\n", rc);
5195 goto rw_error;
5196 }
5197
5198 /* Set speed (using complementary reduction value) */
5199 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI_RED__A, &data, 0);
5200 if (rc != 0) {
5201 pr_err("error %d\n", rc);
5202 goto rw_error;
5203 }
5204 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
5205 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);
5206 if (rc != 0) {
5207 pr_err("error %d\n", rc);
5208 goto rw_error;
5209 }
5210
5211 if (agc_settings->standard == DRX_STANDARD_8VSB)
5212 p_agc_settings = &(ext_attr->vsb_rf_agc_cfg);
5213 else if (DRXJ_ISQAMSTD(agc_settings->standard))
5214 p_agc_settings = &(ext_attr->qam_rf_agc_cfg);
5215 else if (DRXJ_ISATVSTD(agc_settings->standard))
5216 p_agc_settings = &(ext_attr->atv_rf_agc_cfg);
5217 else
5218 return -EINVAL;
5219
5220 /* Restore TOP */
5221 if (p_agc_settings->ctrl_mode == DRX_AGC_CTRL_AUTO) {
5222 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, p_agc_settings->top, 0);
5223 if (rc != 0) {
5224 pr_err("error %d\n", rc);
5225 goto rw_error;
5226 }
5227 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, p_agc_settings->top, 0);
5228 if (rc != 0) {
5229 pr_err("error %d\n", rc);
5230 goto rw_error;
5231 }
5232 } else {
5233 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, 0, 0);
5234 if (rc != 0) {
5235 pr_err("error %d\n", rc);
5236 goto rw_error;
5237 }
5238 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, 0, 0);
5239 if (rc != 0) {
5240 pr_err("error %d\n", rc);
5241 goto rw_error;
5242 }
5243 }
5244 break;
5245
5246 case DRX_AGC_CTRL_USER:
5247
5248 /* Enable IF AGC DAC */
5249 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5250 if (rc != 0) {
5251 pr_err("error %d\n", rc);
5252 goto rw_error;
5253 }
5254 data |= IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE;
5255 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5256 if (rc != 0) {
5257 pr_err("error %d\n", rc);
5258 goto rw_error;
5259 }
5260
5261 /* Disable SCU IF AGC loop */
5262 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5263 if (rc != 0) {
5264 pr_err("error %d\n", rc);
5265 goto rw_error;
5266 }
5267 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5268 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5269 if (common_attr->tuner_if_agc_pol)
5270 data |= SCU_RAM_AGC_KI_INV_IF_POL__M;
5271 else
5272 data &= ~SCU_RAM_AGC_KI_INV_IF_POL__M;
5273 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5274 if (rc != 0) {
5275 pr_err("error %d\n", rc);
5276 goto rw_error;
5277 }
5278
5279 /* Write value to output pin */
5280 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, agc_settings->output_level, 0);
5281 if (rc != 0) {
5282 pr_err("error %d\n", rc);
5283 goto rw_error;
5284 }
5285 break;
5286
5287 case DRX_AGC_CTRL_OFF:
5288
5289 /* Disable If AGC DAC */
5290 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5291 if (rc != 0) {
5292 pr_err("error %d\n", rc);
5293 goto rw_error;
5294 }
5295 data &= (~IQM_AF_STDBY_STDBY_TAGC_IF_A2_ACTIVE);
5296 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5297 if (rc != 0) {
5298 pr_err("error %d\n", rc);
5299 goto rw_error;
5300 }
5301
5302 /* Disable SCU IF AGC loop */
5303 rc = (*scu_rr16)(dev_addr, SCU_RAM_AGC_KI__A, &data, 0);
5304 if (rc != 0) {
5305 pr_err("error %d\n", rc);
5306 goto rw_error;
5307 }
5308 data &= ~SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5309 data |= SCU_RAM_AGC_KI_IF_AGC_DISABLE__M;
5310 rc = (*scu_wr16)(dev_addr, SCU_RAM_AGC_KI__A, data, 0);
5311 if (rc != 0) {
5312 pr_err("error %d\n", rc);
5313 goto rw_error;
5314 }
5315 break;
5316 default:
5317 return -EINVAL;
5318 } /* switch ( agcsettings->ctrl_mode ) */
5319
5320 /* always set the top to support configurations without if-loop */
5321 rc = (*scu_wr16) (dev_addr, SCU_RAM_AGC_INGAIN_TGT_MIN__A, agc_settings->top, 0);
5322 if (rc != 0) {
5323 pr_err("error %d\n", rc);
5324 goto rw_error;
5325 }
5326 }
5327
5328 /* Store if agc settings */
5329 switch (agc_settings->standard) {
5330 case DRX_STANDARD_8VSB:
5331 ext_attr->vsb_if_agc_cfg = *agc_settings;
5332 break;
5333 #ifndef DRXJ_VSB_ONLY
5334 case DRX_STANDARD_ITU_A:
5335 case DRX_STANDARD_ITU_B:
5336 case DRX_STANDARD_ITU_C:
5337 ext_attr->qam_if_agc_cfg = *agc_settings;
5338 break;
5339 #endif
5340 default:
5341 return -EIO;
5342 }
5343
5344 return 0;
5345 rw_error:
5346 return rc;
5347 }
5348
5349 /*
5350 * \fn int set_iqm_af ()
5351 * \brief Configure IQM AF registers
5352 * \param demod instance of demodulator.
5353 * \param active
5354 * \return int.
5355 */
set_iqm_af(struct drx_demod_instance * demod,bool active)5356 static int set_iqm_af(struct drx_demod_instance *demod, bool active)
5357 {
5358 u16 data = 0;
5359 struct i2c_device_addr *dev_addr = NULL;
5360 int rc;
5361
5362 dev_addr = demod->my_i2c_dev_addr;
5363
5364 /* Configure IQM */
5365 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_STDBY__A, &data, 0);
5366 if (rc != 0) {
5367 pr_err("error %d\n", rc);
5368 goto rw_error;
5369 }
5370 if (!active)
5371 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));
5372 else
5373 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);
5374 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, data, 0);
5375 if (rc != 0) {
5376 pr_err("error %d\n", rc);
5377 goto rw_error;
5378 }
5379
5380 return 0;
5381 rw_error:
5382 return rc;
5383 }
5384
5385 /*============================================================================*/
5386 /*== END 8VSB & QAM COMMON DATAPATH FUNCTIONS ==*/
5387 /*============================================================================*/
5388
5389 /*============================================================================*/
5390 /*============================================================================*/
5391 /*== 8VSB DATAPATH FUNCTIONS ==*/
5392 /*============================================================================*/
5393 /*============================================================================*/
5394
5395 /*
5396 * \fn int power_down_vsb ()
5397 * \brief Powr down QAM related blocks.
5398 * \param demod instance of demodulator.
5399 * \param channel pointer to channel data.
5400 * \return int.
5401 */
power_down_vsb(struct drx_demod_instance * demod,bool primary)5402 static int power_down_vsb(struct drx_demod_instance *demod, bool primary)
5403 {
5404 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
5405 struct drxjscu_cmd cmd_scu = { /* command */ 0,
5406 /* parameter_len */ 0,
5407 /* result_len */ 0,
5408 /* *parameter */ NULL,
5409 /* *result */ NULL
5410 };
5411 struct drx_cfg_mpeg_output cfg_mpeg_output;
5412 int rc;
5413 u16 cmd_result = 0;
5414
5415 /*
5416 STOP demodulator
5417 reset of FEC and VSB HW
5418 */
5419 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
5420 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
5421 cmd_scu.parameter_len = 0;
5422 cmd_scu.result_len = 1;
5423 cmd_scu.parameter = NULL;
5424 cmd_scu.result = &cmd_result;
5425 rc = scu_command(dev_addr, &cmd_scu);
5426 if (rc != 0) {
5427 pr_err("error %d\n", rc);
5428 goto rw_error;
5429 }
5430
5431 /* stop all comm_exec */
5432 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
5433 if (rc != 0) {
5434 pr_err("error %d\n", rc);
5435 goto rw_error;
5436 }
5437 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
5438 if (rc != 0) {
5439 pr_err("error %d\n", rc);
5440 goto rw_error;
5441 }
5442 if (primary) {
5443 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
5444 if (rc != 0) {
5445 pr_err("error %d\n", rc);
5446 goto rw_error;
5447 }
5448 rc = set_iqm_af(demod, false);
5449 if (rc != 0) {
5450 pr_err("error %d\n", rc);
5451 goto rw_error;
5452 }
5453 } else {
5454 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
5455 if (rc != 0) {
5456 pr_err("error %d\n", rc);
5457 goto rw_error;
5458 }
5459 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
5460 if (rc != 0) {
5461 pr_err("error %d\n", rc);
5462 goto rw_error;
5463 }
5464 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
5465 if (rc != 0) {
5466 pr_err("error %d\n", rc);
5467 goto rw_error;
5468 }
5469 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
5470 if (rc != 0) {
5471 pr_err("error %d\n", rc);
5472 goto rw_error;
5473 }
5474 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
5475 if (rc != 0) {
5476 pr_err("error %d\n", rc);
5477 goto rw_error;
5478 }
5479 }
5480
5481 cfg_mpeg_output.enable_mpeg_output = false;
5482 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
5483 if (rc != 0) {
5484 pr_err("error %d\n", rc);
5485 goto rw_error;
5486 }
5487
5488 return 0;
5489 rw_error:
5490 return rc;
5491 }
5492
5493 /*
5494 * \fn int set_vsb_leak_n_gain ()
5495 * \brief Set ATSC demod.
5496 * \param demod instance of demodulator.
5497 * \return int.
5498 */
set_vsb_leak_n_gain(struct drx_demod_instance * demod)5499 static int set_vsb_leak_n_gain(struct drx_demod_instance *demod)
5500 {
5501 struct i2c_device_addr *dev_addr = NULL;
5502 int rc;
5503
5504 static const u8 vsb_ffe_leak_gain_ram0[] = {
5505 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO1 */
5506 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO2 */
5507 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO3 */
5508 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO4 */
5509 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO5 */
5510 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO6 */
5511 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO7 */
5512 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO8 */
5513 DRXJ_16TO8(0xf), /* FFETRAINLKRATIO9 */
5514 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO10 */
5515 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO11 */
5516 DRXJ_16TO8(0x8), /* FFETRAINLKRATIO12 */
5517 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO1 */
5518 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO2 */
5519 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO3 */
5520 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO4 */
5521 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO5 */
5522 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO6 */
5523 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO7 */
5524 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO8 */
5525 DRXJ_16TO8(0x20), /* FFERCA1TRAINLKRATIO9 */
5526 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO10 */
5527 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO11 */
5528 DRXJ_16TO8(0x10), /* FFERCA1TRAINLKRATIO12 */
5529 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO1 */
5530 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO2 */
5531 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO3 */
5532 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO4 */
5533 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO5 */
5534 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO6 */
5535 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO7 */
5536 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO8 */
5537 DRXJ_16TO8(0x20), /* FFERCA1DATALKRATIO9 */
5538 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO10 */
5539 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO11 */
5540 DRXJ_16TO8(0x10), /* FFERCA1DATALKRATIO12 */
5541 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO1 */
5542 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO2 */
5543 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO3 */
5544 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO4 */
5545 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO5 */
5546 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO6 */
5547 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO7 */
5548 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO8 */
5549 DRXJ_16TO8(0x20), /* FFERCA2TRAINLKRATIO9 */
5550 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO10 */
5551 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO11 */
5552 DRXJ_16TO8(0x10), /* FFERCA2TRAINLKRATIO12 */
5553 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO1 */
5554 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO2 */
5555 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO3 */
5556 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO4 */
5557 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO5 */
5558 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO6 */
5559 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO7 */
5560 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO8 */
5561 DRXJ_16TO8(0x20), /* FFERCA2DATALKRATIO9 */
5562 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO10 */
5563 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO11 */
5564 DRXJ_16TO8(0x10), /* FFERCA2DATALKRATIO12 */
5565 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO1 */
5566 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO2 */
5567 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO3 */
5568 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO4 */
5569 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO5 */
5570 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO6 */
5571 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO7 */
5572 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO8 */
5573 DRXJ_16TO8(0x0e), /* FFEDDM1TRAINLKRATIO9 */
5574 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO10 */
5575 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO11 */
5576 DRXJ_16TO8(0x07), /* FFEDDM1TRAINLKRATIO12 */
5577 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO1 */
5578 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO2 */
5579 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO3 */
5580 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO4 */
5581 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO5 */
5582 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO6 */
5583 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO7 */
5584 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO8 */
5585 DRXJ_16TO8(0x0e), /* FFEDDM1DATALKRATIO9 */
5586 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO10 */
5587 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO11 */
5588 DRXJ_16TO8(0x07), /* FFEDDM1DATALKRATIO12 */
5589 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO1 */
5590 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO2 */
5591 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO3 */
5592 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO4 */
5593 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO5 */
5594 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO6 */
5595 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO7 */
5596 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO8 */
5597 DRXJ_16TO8(0x0c), /* FFEDDM2TRAINLKRATIO9 */
5598 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO10 */
5599 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO11 */
5600 DRXJ_16TO8(0x06), /* FFEDDM2TRAINLKRATIO12 */
5601 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO1 */
5602 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO2 */
5603 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO3 */
5604 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO4 */
5605 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO5 */
5606 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO6 */
5607 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO7 */
5608 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO8 */
5609 DRXJ_16TO8(0x0c), /* FFEDDM2DATALKRATIO9 */
5610 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO10 */
5611 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO11 */
5612 DRXJ_16TO8(0x06), /* FFEDDM2DATALKRATIO12 */
5613 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN1 */
5614 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN2 */
5615 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN3 */
5616 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN4 */
5617 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN5 */
5618 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN6 */
5619 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN7 */
5620 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN8 */
5621 DRXJ_16TO8(0x4040), /* FIRTRAINGAIN9 */
5622 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN10 */
5623 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN11 */
5624 DRXJ_16TO8(0x2020), /* FIRTRAINGAIN12 */
5625 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN1 */
5626 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN2 */
5627 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN3 */
5628 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN4 */
5629 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN5 */
5630 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN6 */
5631 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN7 */
5632 DRXJ_16TO8(0x1010) /* FIRRCA1GAIN8 */
5633 };
5634
5635 static const u8 vsb_ffe_leak_gain_ram1[] = {
5636 DRXJ_16TO8(0x1010), /* FIRRCA1GAIN9 */
5637 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN10 */
5638 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN11 */
5639 DRXJ_16TO8(0x0808), /* FIRRCA1GAIN12 */
5640 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN1 */
5641 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN2 */
5642 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN3 */
5643 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN4 */
5644 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN5 */
5645 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN6 */
5646 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN7 */
5647 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN8 */
5648 DRXJ_16TO8(0x1010), /* FIRRCA2GAIN9 */
5649 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN10 */
5650 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN11 */
5651 DRXJ_16TO8(0x0808), /* FIRRCA2GAIN12 */
5652 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN1 */
5653 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN2 */
5654 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN3 */
5655 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN4 */
5656 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN5 */
5657 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN6 */
5658 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN7 */
5659 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN8 */
5660 DRXJ_16TO8(0x0606), /* FIRDDM1GAIN9 */
5661 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN10 */
5662 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN11 */
5663 DRXJ_16TO8(0x0303), /* FIRDDM1GAIN12 */
5664 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN1 */
5665 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN2 */
5666 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN3 */
5667 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN4 */
5668 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN5 */
5669 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN6 */
5670 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN7 */
5671 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN8 */
5672 DRXJ_16TO8(0x0505), /* FIRDDM2GAIN9 */
5673 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN10 */
5674 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN11 */
5675 DRXJ_16TO8(0x0303), /* FIRDDM2GAIN12 */
5676 DRXJ_16TO8(0x001f), /* DFETRAINLKRATIO */
5677 DRXJ_16TO8(0x01ff), /* DFERCA1TRAINLKRATIO */
5678 DRXJ_16TO8(0x01ff), /* DFERCA1DATALKRATIO */
5679 DRXJ_16TO8(0x004f), /* DFERCA2TRAINLKRATIO */
5680 DRXJ_16TO8(0x004f), /* DFERCA2DATALKRATIO */
5681 DRXJ_16TO8(0x01ff), /* DFEDDM1TRAINLKRATIO */
5682 DRXJ_16TO8(0x01ff), /* DFEDDM1DATALKRATIO */
5683 DRXJ_16TO8(0x0352), /* DFEDDM2TRAINLKRATIO */
5684 DRXJ_16TO8(0x0352), /* DFEDDM2DATALKRATIO */
5685 DRXJ_16TO8(0x0000), /* DFETRAINGAIN */
5686 DRXJ_16TO8(0x2020), /* DFERCA1GAIN */
5687 DRXJ_16TO8(0x1010), /* DFERCA2GAIN */
5688 DRXJ_16TO8(0x1818), /* DFEDDM1GAIN */
5689 DRXJ_16TO8(0x1212) /* DFEDDM2GAIN */
5690 };
5691
5692 dev_addr = demod->my_i2c_dev_addr;
5693 rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM0_FFETRAINLKRATIO1__A, sizeof(vsb_ffe_leak_gain_ram0), ((u8 *)vsb_ffe_leak_gain_ram0), 0);
5694 if (rc != 0) {
5695 pr_err("error %d\n", rc);
5696 goto rw_error;
5697 }
5698 rc = drxdap_fasi_write_block(dev_addr, VSB_SYSCTRL_RAM1_FIRRCA1GAIN9__A, sizeof(vsb_ffe_leak_gain_ram1), ((u8 *)vsb_ffe_leak_gain_ram1), 0);
5699 if (rc != 0) {
5700 pr_err("error %d\n", rc);
5701 goto rw_error;
5702 }
5703
5704 return 0;
5705 rw_error:
5706 return rc;
5707 }
5708
5709 /*
5710 * \fn int set_vsb()
5711 * \brief Set 8VSB demod.
5712 * \param demod instance of demodulator.
5713 * \return int.
5714 *
5715 */
set_vsb(struct drx_demod_instance * demod)5716 static int set_vsb(struct drx_demod_instance *demod)
5717 {
5718 struct i2c_device_addr *dev_addr = NULL;
5719 int rc;
5720 struct drx_common_attr *common_attr = NULL;
5721 struct drxjscu_cmd cmd_scu;
5722 struct drxj_data *ext_attr = NULL;
5723 u16 cmd_result = 0;
5724 u16 cmd_param = 0;
5725 static const u8 vsb_taps_re[] = {
5726 DRXJ_16TO8(-2), /* re0 */
5727 DRXJ_16TO8(4), /* re1 */
5728 DRXJ_16TO8(1), /* re2 */
5729 DRXJ_16TO8(-4), /* re3 */
5730 DRXJ_16TO8(1), /* re4 */
5731 DRXJ_16TO8(4), /* re5 */
5732 DRXJ_16TO8(-3), /* re6 */
5733 DRXJ_16TO8(-3), /* re7 */
5734 DRXJ_16TO8(6), /* re8 */
5735 DRXJ_16TO8(1), /* re9 */
5736 DRXJ_16TO8(-9), /* re10 */
5737 DRXJ_16TO8(3), /* re11 */
5738 DRXJ_16TO8(12), /* re12 */
5739 DRXJ_16TO8(-9), /* re13 */
5740 DRXJ_16TO8(-15), /* re14 */
5741 DRXJ_16TO8(17), /* re15 */
5742 DRXJ_16TO8(19), /* re16 */
5743 DRXJ_16TO8(-29), /* re17 */
5744 DRXJ_16TO8(-22), /* re18 */
5745 DRXJ_16TO8(45), /* re19 */
5746 DRXJ_16TO8(25), /* re20 */
5747 DRXJ_16TO8(-70), /* re21 */
5748 DRXJ_16TO8(-28), /* re22 */
5749 DRXJ_16TO8(111), /* re23 */
5750 DRXJ_16TO8(30), /* re24 */
5751 DRXJ_16TO8(-201), /* re25 */
5752 DRXJ_16TO8(-31), /* re26 */
5753 DRXJ_16TO8(629) /* re27 */
5754 };
5755
5756 dev_addr = demod->my_i2c_dev_addr;
5757 common_attr = (struct drx_common_attr *) demod->my_common_attr;
5758 ext_attr = (struct drxj_data *) demod->my_ext_attr;
5759
5760 /* stop all comm_exec */
5761 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
5762 if (rc != 0) {
5763 pr_err("error %d\n", rc);
5764 goto rw_error;
5765 }
5766 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_STOP, 0);
5767 if (rc != 0) {
5768 pr_err("error %d\n", rc);
5769 goto rw_error;
5770 }
5771 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
5772 if (rc != 0) {
5773 pr_err("error %d\n", rc);
5774 goto rw_error;
5775 }
5776 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
5777 if (rc != 0) {
5778 pr_err("error %d\n", rc);
5779 goto rw_error;
5780 }
5781 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
5782 if (rc != 0) {
5783 pr_err("error %d\n", rc);
5784 goto rw_error;
5785 }
5786 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
5787 if (rc != 0) {
5788 pr_err("error %d\n", rc);
5789 goto rw_error;
5790 }
5791 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
5792 if (rc != 0) {
5793 pr_err("error %d\n", rc);
5794 goto rw_error;
5795 }
5796
5797 /* reset demodulator */
5798 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
5799 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
5800 cmd_scu.parameter_len = 0;
5801 cmd_scu.result_len = 1;
5802 cmd_scu.parameter = NULL;
5803 cmd_scu.result = &cmd_result;
5804 rc = scu_command(dev_addr, &cmd_scu);
5805 if (rc != 0) {
5806 pr_err("error %d\n", rc);
5807 goto rw_error;
5808 }
5809
5810 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_DCF_BYPASS__A, 1, 0);
5811 if (rc != 0) {
5812 pr_err("error %d\n", rc);
5813 goto rw_error;
5814 }
5815 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, IQM_FS_ADJ_SEL_B_VSB, 0);
5816 if (rc != 0) {
5817 pr_err("error %d\n", rc);
5818 goto rw_error;
5819 }
5820 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, IQM_RC_ADJ_SEL_B_VSB, 0);
5821 if (rc != 0) {
5822 pr_err("error %d\n", rc);
5823 goto rw_error;
5824 }
5825 ext_attr->iqm_rc_rate_ofs = 0x00AD0D79;
5826 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, ext_attr->iqm_rc_rate_ofs, 0);
5827 if (rc != 0) {
5828 pr_err("error %d\n", rc);
5829 goto rw_error;
5830 }
5831 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CFAGC_GAINSHIFT__A, 4, 0);
5832 if (rc != 0) {
5833 pr_err("error %d\n", rc);
5834 goto rw_error;
5835 }
5836 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 1, 0);
5837 if (rc != 0) {
5838 pr_err("error %d\n", rc);
5839 goto rw_error;
5840 }
5841
5842 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_CROUT_ENA__A, 1, 0);
5843 if (rc != 0) {
5844 pr_err("error %d\n", rc);
5845 goto rw_error;
5846 }
5847 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, 28, 0);
5848 if (rc != 0) {
5849 pr_err("error %d\n", rc);
5850 goto rw_error;
5851 }
5852 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_ACTIVE__A, 0, 0);
5853 if (rc != 0) {
5854 pr_err("error %d\n", rc);
5855 goto rw_error;
5856 }
5857 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
5858 if (rc != 0) {
5859 pr_err("error %d\n", rc);
5860 goto rw_error;
5861 }
5862 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
5863 if (rc != 0) {
5864 pr_err("error %d\n", rc);
5865 goto rw_error;
5866 }
5867 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_VSB__M, 0);
5868 if (rc != 0) {
5869 pr_err("error %d\n", rc);
5870 goto rw_error;
5871 }
5872 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE__A, 1393, 0);
5873 if (rc != 0) {
5874 pr_err("error %d\n", rc);
5875 goto rw_error;
5876 }
5877 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
5878 if (rc != 0) {
5879 pr_err("error %d\n", rc);
5880 goto rw_error;
5881 }
5882 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
5883 if (rc != 0) {
5884 pr_err("error %d\n", rc);
5885 goto rw_error;
5886 }
5887
5888 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
5889 if (rc != 0) {
5890 pr_err("error %d\n", rc);
5891 goto rw_error;
5892 }
5893 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(vsb_taps_re), ((u8 *)vsb_taps_re), 0);
5894 if (rc != 0) {
5895 pr_err("error %d\n", rc);
5896 goto rw_error;
5897 }
5898
5899 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BNTHRESH__A, 330, 0);
5900 if (rc != 0) {
5901 pr_err("error %d\n", rc);
5902 goto rw_error;
5903 } /* set higher threshold */
5904 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CLPLASTNUM__A, 90, 0);
5905 if (rc != 0) {
5906 pr_err("error %d\n", rc);
5907 goto rw_error;
5908 } /* burst detection on */
5909 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA1__A, 0x0042, 0);
5910 if (rc != 0) {
5911 pr_err("error %d\n", rc);
5912 goto rw_error;
5913 } /* drop thresholds by 1 dB */
5914 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_RCA2__A, 0x0053, 0);
5915 if (rc != 0) {
5916 pr_err("error %d\n", rc);
5917 goto rw_error;
5918 } /* drop thresholds by 2 dB */
5919 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_EQCTRL__A, 0x1, 0);
5920 if (rc != 0) {
5921 pr_err("error %d\n", rc);
5922 goto rw_error;
5923 } /* cma on */
5924 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
5925 if (rc != 0) {
5926 pr_err("error %d\n", rc);
5927 goto rw_error;
5928 } /* GPIO */
5929
5930 /* Initialize the FEC Subsystem */
5931 rc = drxj_dap_write_reg16(dev_addr, FEC_TOP_ANNEX__A, FEC_TOP_ANNEX_D, 0);
5932 if (rc != 0) {
5933 pr_err("error %d\n", rc);
5934 goto rw_error;
5935 }
5936 {
5937 u16 fec_oc_snc_mode = 0;
5938 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode, 0);
5939 if (rc != 0) {
5940 pr_err("error %d\n", rc);
5941 goto rw_error;
5942 }
5943 /* output data even when not locked */
5944 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_MODE__A, fec_oc_snc_mode | FEC_OC_SNC_MODE_UNLOCK_ENABLE__M, 0);
5945 if (rc != 0) {
5946 pr_err("error %d\n", rc);
5947 goto rw_error;
5948 }
5949 }
5950
5951 /* set clip */
5952 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
5953 if (rc != 0) {
5954 pr_err("error %d\n", rc);
5955 goto rw_error;
5956 }
5957 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 470, 0);
5958 if (rc != 0) {
5959 pr_err("error %d\n", rc);
5960 goto rw_error;
5961 }
5962 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
5963 if (rc != 0) {
5964 pr_err("error %d\n", rc);
5965 goto rw_error;
5966 }
5967 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0xD4, 0);
5968 if (rc != 0) {
5969 pr_err("error %d\n", rc);
5970 goto rw_error;
5971 }
5972 /* no transparent, no A&C framing; parity is set in mpegoutput */
5973 {
5974 u16 fec_oc_reg_mode = 0;
5975 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_MODE__A, &fec_oc_reg_mode, 0);
5976 if (rc != 0) {
5977 pr_err("error %d\n", rc);
5978 goto rw_error;
5979 }
5980 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_MODE__A, fec_oc_reg_mode & (~(FEC_OC_MODE_TRANSPARENT__M | FEC_OC_MODE_CLEAR__M | FEC_OC_MODE_RETAIN_FRAMING__M)), 0);
5981 if (rc != 0) {
5982 pr_err("error %d\n", rc);
5983 goto rw_error;
5984 }
5985 }
5986
5987 rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_LO__A, 0, 0);
5988 if (rc != 0) {
5989 pr_err("error %d\n", rc);
5990 goto rw_error;
5991 } /* timeout counter for restarting */
5992 rc = drxj_dap_write_reg16(dev_addr, FEC_DI_TIMEOUT_HI__A, 3, 0);
5993 if (rc != 0) {
5994 pr_err("error %d\n", rc);
5995 goto rw_error;
5996 }
5997 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MODE__A, 0, 0);
5998 if (rc != 0) {
5999 pr_err("error %d\n", rc);
6000 goto rw_error;
6001 } /* bypass disabled */
6002 /* initialize RS packet error measurement parameters */
6003 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, FEC_RS_MEASUREMENT_PERIOD, 0);
6004 if (rc != 0) {
6005 pr_err("error %d\n", rc);
6006 goto rw_error;
6007 }
6008 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, FEC_RS_MEASUREMENT_PRESCALE, 0);
6009 if (rc != 0) {
6010 pr_err("error %d\n", rc);
6011 goto rw_error;
6012 }
6013
6014 /* init measurement period of MER/SER */
6015 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_MEASUREMENT_PERIOD__A, VSB_TOP_MEASUREMENT_PERIOD, 0);
6016 if (rc != 0) {
6017 pr_err("error %d\n", rc);
6018 goto rw_error;
6019 }
6020 rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
6021 if (rc != 0) {
6022 pr_err("error %d\n", rc);
6023 goto rw_error;
6024 }
6025 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
6026 if (rc != 0) {
6027 pr_err("error %d\n", rc);
6028 goto rw_error;
6029 }
6030 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
6031 if (rc != 0) {
6032 pr_err("error %d\n", rc);
6033 goto rw_error;
6034 }
6035
6036 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CKGN1TRK__A, 128, 0);
6037 if (rc != 0) {
6038 pr_err("error %d\n", rc);
6039 goto rw_error;
6040 }
6041 /* B-Input to ADC, PGA+filter in standby */
6042 if (!ext_attr->has_lna) {
6043 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
6044 if (rc != 0) {
6045 pr_err("error %d\n", rc);
6046 goto rw_error;
6047 }
6048 }
6049
6050 /* turn on IQMAF. It has to be in front of setAgc**() */
6051 rc = set_iqm_af(demod, true);
6052 if (rc != 0) {
6053 pr_err("error %d\n", rc);
6054 goto rw_error;
6055 }
6056 rc = adc_synchronization(demod);
6057 if (rc != 0) {
6058 pr_err("error %d\n", rc);
6059 goto rw_error;
6060 }
6061
6062 rc = init_agc(demod);
6063 if (rc != 0) {
6064 pr_err("error %d\n", rc);
6065 goto rw_error;
6066 }
6067 rc = set_agc_if(demod, &(ext_attr->vsb_if_agc_cfg), false);
6068 if (rc != 0) {
6069 pr_err("error %d\n", rc);
6070 goto rw_error;
6071 }
6072 rc = set_agc_rf(demod, &(ext_attr->vsb_rf_agc_cfg), false);
6073 if (rc != 0) {
6074 pr_err("error %d\n", rc);
6075 goto rw_error;
6076 }
6077 {
6078 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
6079 of only the gain */
6080 struct drxj_cfg_afe_gain vsb_pga_cfg = { DRX_STANDARD_8VSB, 0 };
6081
6082 vsb_pga_cfg.gain = ext_attr->vsb_pga_cfg;
6083 rc = ctrl_set_cfg_afe_gain(demod, &vsb_pga_cfg);
6084 if (rc != 0) {
6085 pr_err("error %d\n", rc);
6086 goto rw_error;
6087 }
6088 }
6089 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->vsb_pre_saw_cfg));
6090 if (rc != 0) {
6091 pr_err("error %d\n", rc);
6092 goto rw_error;
6093 }
6094
6095 /* Mpeg output has to be in front of FEC active */
6096 rc = set_mpegtei_handling(demod);
6097 if (rc != 0) {
6098 pr_err("error %d\n", rc);
6099 goto rw_error;
6100 }
6101 rc = bit_reverse_mpeg_output(demod);
6102 if (rc != 0) {
6103 pr_err("error %d\n", rc);
6104 goto rw_error;
6105 }
6106 rc = set_mpeg_start_width(demod);
6107 if (rc != 0) {
6108 pr_err("error %d\n", rc);
6109 goto rw_error;
6110 }
6111 {
6112 /* TODO: move to set_standard after hardware reset value problem is solved */
6113 /* Configure initial MPEG output */
6114 struct drx_cfg_mpeg_output cfg_mpeg_output;
6115
6116 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
6117 cfg_mpeg_output.enable_mpeg_output = true;
6118
6119 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6120 if (rc != 0) {
6121 pr_err("error %d\n", rc);
6122 goto rw_error;
6123 }
6124 }
6125
6126 /* TBD: what parameters should be set */
6127 cmd_param = 0x00; /* Default mode AGC on, etc */
6128 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6129 | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
6130 cmd_scu.parameter_len = 1;
6131 cmd_scu.result_len = 1;
6132 cmd_scu.parameter = &cmd_param;
6133 cmd_scu.result = &cmd_result;
6134 rc = scu_command(dev_addr, &cmd_scu);
6135 if (rc != 0) {
6136 pr_err("error %d\n", rc);
6137 goto rw_error;
6138 }
6139
6140 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEAGC_GAINSHIFT__A, 0x0004, 0);
6141 if (rc != 0) {
6142 pr_err("error %d\n", rc);
6143 goto rw_error;
6144 }
6145 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SNRTH_PT__A, 0x00D2, 0);
6146 if (rc != 0) {
6147 pr_err("error %d\n", rc);
6148 goto rw_error;
6149 }
6150 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_SYSSMTRNCTRL__A, VSB_TOP_SYSSMTRNCTRL__PRE | VSB_TOP_SYSSMTRNCTRL_NCOTIMEOUTCNTEN__M, 0);
6151 if (rc != 0) {
6152 pr_err("error %d\n", rc);
6153 goto rw_error;
6154 }
6155 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_BEDETCTRL__A, 0x142, 0);
6156 if (rc != 0) {
6157 pr_err("error %d\n", rc);
6158 goto rw_error;
6159 }
6160 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_LBAGCREFLVL__A, 640, 0);
6161 if (rc != 0) {
6162 pr_err("error %d\n", rc);
6163 goto rw_error;
6164 }
6165 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1ACQ__A, 4, 0);
6166 if (rc != 0) {
6167 pr_err("error %d\n", rc);
6168 goto rw_error;
6169 }
6170 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN1TRK__A, 2, 0);
6171 if (rc != 0) {
6172 pr_err("error %d\n", rc);
6173 goto rw_error;
6174 }
6175 rc = drxj_dap_write_reg16(dev_addr, VSB_TOP_CYGN2TRK__A, 3, 0);
6176 if (rc != 0) {
6177 pr_err("error %d\n", rc);
6178 goto rw_error;
6179 }
6180
6181 /* start demodulator */
6182 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB
6183 | SCU_RAM_COMMAND_CMD_DEMOD_START;
6184 cmd_scu.parameter_len = 0;
6185 cmd_scu.result_len = 1;
6186 cmd_scu.parameter = NULL;
6187 cmd_scu.result = &cmd_result;
6188 rc = scu_command(dev_addr, &cmd_scu);
6189 if (rc != 0) {
6190 pr_err("error %d\n", rc);
6191 goto rw_error;
6192 }
6193
6194 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
6195 if (rc != 0) {
6196 pr_err("error %d\n", rc);
6197 goto rw_error;
6198 }
6199 rc = drxj_dap_write_reg16(dev_addr, VSB_COMM_EXEC__A, VSB_COMM_EXEC_ACTIVE, 0);
6200 if (rc != 0) {
6201 pr_err("error %d\n", rc);
6202 goto rw_error;
6203 }
6204 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
6205 if (rc != 0) {
6206 pr_err("error %d\n", rc);
6207 goto rw_error;
6208 }
6209
6210 return 0;
6211 rw_error:
6212 return rc;
6213 }
6214
6215 /*
6216 * \fn static short get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr, u16 *PckErrs)
6217 * \brief Get the values of packet error in 8VSB mode
6218 * \return Error code
6219 */
get_vsb_post_rs_pck_err(struct i2c_device_addr * dev_addr,u32 * pck_errs,u32 * pck_count)6220 static int get_vsb_post_rs_pck_err(struct i2c_device_addr *dev_addr,
6221 u32 *pck_errs, u32 *pck_count)
6222 {
6223 int rc;
6224 u16 data = 0;
6225 u16 period = 0;
6226 u16 prescale = 0;
6227 u16 packet_errors_mant = 0;
6228 u16 packet_errors_exp = 0;
6229
6230 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &data, 0);
6231 if (rc != 0) {
6232 pr_err("error %d\n", rc);
6233 goto rw_error;
6234 }
6235 packet_errors_mant = data & FEC_RS_NR_FAILURES_FIXED_MANT__M;
6236 packet_errors_exp = (data & FEC_RS_NR_FAILURES_EXP__M)
6237 >> FEC_RS_NR_FAILURES_EXP__B;
6238 period = FEC_RS_MEASUREMENT_PERIOD;
6239 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6240 /* packet error rate = (error packet number) per second */
6241 /* 77.3 us is time for per packet */
6242 if (period * prescale == 0) {
6243 pr_err("error: period and/or prescale is zero!\n");
6244 return -EIO;
6245 }
6246 *pck_errs = packet_errors_mant * (1 << packet_errors_exp);
6247 *pck_count = period * prescale * 77;
6248
6249 return 0;
6250 rw_error:
6251 return rc;
6252 }
6253
6254 /*
6255 * \fn static short GetVSBBer(struct i2c_device_addr *dev_addr, u32 *ber)
6256 * \brief Get the values of ber in VSB mode
6257 * \return Error code
6258 */
get_vs_bpost_viterbi_ber(struct i2c_device_addr * dev_addr,u32 * ber,u32 * cnt)6259 static int get_vs_bpost_viterbi_ber(struct i2c_device_addr *dev_addr,
6260 u32 *ber, u32 *cnt)
6261 {
6262 int rc;
6263 u16 data = 0;
6264 u16 period = 0;
6265 u16 prescale = 0;
6266 u16 bit_errors_mant = 0;
6267 u16 bit_errors_exp = 0;
6268
6269 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &data, 0);
6270 if (rc != 0) {
6271 pr_err("error %d\n", rc);
6272 goto rw_error;
6273 }
6274 period = FEC_RS_MEASUREMENT_PERIOD;
6275 prescale = FEC_RS_MEASUREMENT_PRESCALE;
6276
6277 bit_errors_mant = data & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M;
6278 bit_errors_exp = (data & FEC_RS_NR_BIT_ERRORS_EXP__M)
6279 >> FEC_RS_NR_BIT_ERRORS_EXP__B;
6280
6281 *cnt = period * prescale * 207 * ((bit_errors_exp > 2) ? 1 : 8);
6282
6283 if (((bit_errors_mant << bit_errors_exp) >> 3) > 68700)
6284 *ber = (*cnt) * 26570;
6285 else {
6286 if (period * prescale == 0) {
6287 pr_err("error: period and/or prescale is zero!\n");
6288 return -EIO;
6289 }
6290 *ber = bit_errors_mant << ((bit_errors_exp > 2) ?
6291 (bit_errors_exp - 3) : bit_errors_exp);
6292 }
6293
6294 return 0;
6295 rw_error:
6296 return rc;
6297 }
6298
6299 /*
6300 * \fn static short get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr, u32 *ber)
6301 * \brief Get the values of ber in VSB mode
6302 * \return Error code
6303 */
get_vs_bpre_viterbi_ber(struct i2c_device_addr * dev_addr,u32 * ber,u32 * cnt)6304 static int get_vs_bpre_viterbi_ber(struct i2c_device_addr *dev_addr,
6305 u32 *ber, u32 *cnt)
6306 {
6307 u16 data = 0;
6308 int rc;
6309
6310 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_NR_SYM_ERRS__A, &data, 0);
6311 if (rc != 0) {
6312 pr_err("error %d\n", rc);
6313 return -EIO;
6314 }
6315 *ber = data;
6316 *cnt = VSB_TOP_MEASUREMENT_PERIOD * SYMBOLS_PER_SEGMENT;
6317
6318 return 0;
6319 }
6320
6321 /*
6322 * \fn static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6323 * \brief Get the values of MER
6324 * \return Error code
6325 */
get_vsbmer(struct i2c_device_addr * dev_addr,u16 * mer)6326 static int get_vsbmer(struct i2c_device_addr *dev_addr, u16 *mer)
6327 {
6328 int rc;
6329 u16 data_hi = 0;
6330
6331 rc = drxj_dap_read_reg16(dev_addr, VSB_TOP_ERR_ENERGY_H__A, &data_hi, 0);
6332 if (rc != 0) {
6333 pr_err("error %d\n", rc);
6334 goto rw_error;
6335 }
6336 *mer =
6337 (u16) (log1_times100(21504) - log1_times100((data_hi << 6) / 52));
6338
6339 return 0;
6340 rw_error:
6341 return rc;
6342 }
6343
6344
6345 /*============================================================================*/
6346 /*== END 8VSB DATAPATH FUNCTIONS ==*/
6347 /*============================================================================*/
6348
6349 /*============================================================================*/
6350 /*============================================================================*/
6351 /*== QAM DATAPATH FUNCTIONS ==*/
6352 /*============================================================================*/
6353 /*============================================================================*/
6354
6355 /*
6356 * \fn int power_down_qam ()
6357 * \brief Powr down QAM related blocks.
6358 * \param demod instance of demodulator.
6359 * \param channel pointer to channel data.
6360 * \return int.
6361 */
power_down_qam(struct drx_demod_instance * demod,bool primary)6362 static int power_down_qam(struct drx_demod_instance *demod, bool primary)
6363 {
6364 struct drxjscu_cmd cmd_scu = { /* command */ 0,
6365 /* parameter_len */ 0,
6366 /* result_len */ 0,
6367 /* *parameter */ NULL,
6368 /* *result */ NULL
6369 };
6370 int rc;
6371 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6372 struct drx_cfg_mpeg_output cfg_mpeg_output;
6373 struct drx_common_attr *common_attr = demod->my_common_attr;
6374 u16 cmd_result = 0;
6375
6376 /*
6377 STOP demodulator
6378 resets IQM, QAM and FEC HW blocks
6379 */
6380 /* stop all comm_exec */
6381 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
6382 if (rc != 0) {
6383 pr_err("error %d\n", rc);
6384 goto rw_error;
6385 }
6386 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
6387 if (rc != 0) {
6388 pr_err("error %d\n", rc);
6389 goto rw_error;
6390 }
6391
6392 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
6393 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
6394 cmd_scu.parameter_len = 0;
6395 cmd_scu.result_len = 1;
6396 cmd_scu.parameter = NULL;
6397 cmd_scu.result = &cmd_result;
6398 rc = scu_command(dev_addr, &cmd_scu);
6399 if (rc != 0) {
6400 pr_err("error %d\n", rc);
6401 goto rw_error;
6402 }
6403
6404 if (primary) {
6405 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
6406 if (rc != 0) {
6407 pr_err("error %d\n", rc);
6408 goto rw_error;
6409 }
6410 rc = set_iqm_af(demod, false);
6411 if (rc != 0) {
6412 pr_err("error %d\n", rc);
6413 goto rw_error;
6414 }
6415 } else {
6416 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
6417 if (rc != 0) {
6418 pr_err("error %d\n", rc);
6419 goto rw_error;
6420 }
6421 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
6422 if (rc != 0) {
6423 pr_err("error %d\n", rc);
6424 goto rw_error;
6425 }
6426 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
6427 if (rc != 0) {
6428 pr_err("error %d\n", rc);
6429 goto rw_error;
6430 }
6431 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
6432 if (rc != 0) {
6433 pr_err("error %d\n", rc);
6434 goto rw_error;
6435 }
6436 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
6437 if (rc != 0) {
6438 pr_err("error %d\n", rc);
6439 goto rw_error;
6440 }
6441 }
6442
6443 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
6444 cfg_mpeg_output.enable_mpeg_output = false;
6445
6446 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
6447 if (rc != 0) {
6448 pr_err("error %d\n", rc);
6449 goto rw_error;
6450 }
6451
6452 return 0;
6453 rw_error:
6454 return rc;
6455 }
6456
6457 /*============================================================================*/
6458
6459 /*
6460 * \fn int set_qam_measurement ()
6461 * \brief Setup of the QAM Measuremnt intervals for signal quality
6462 * \param demod instance of demod.
6463 * \param constellation current constellation.
6464 * \return int.
6465 *
6466 * NOTE:
6467 * Take into account that for certain settings the errorcounters can overflow.
6468 * The implementation does not check this.
6469 *
6470 * TODO: overriding the ext_attr->fec_bits_desired by constellation dependent
6471 * constants to get a measurement period of approx. 1 sec. Remove fec_bits_desired
6472 * field ?
6473 *
6474 */
6475 #ifndef DRXJ_VSB_ONLY
6476 static int
set_qam_measurement(struct drx_demod_instance * demod,enum drx_modulation constellation,u32 symbol_rate)6477 set_qam_measurement(struct drx_demod_instance *demod,
6478 enum drx_modulation constellation, u32 symbol_rate)
6479 {
6480 struct i2c_device_addr *dev_addr = NULL; /* device address for I2C writes */
6481 struct drxj_data *ext_attr = NULL; /* Global data container for DRXJ specific data */
6482 int rc;
6483 u32 fec_bits_desired = 0; /* BER accounting period */
6484 u16 fec_rs_plen = 0; /* defines RS BER measurement period */
6485 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
6486 u32 fec_rs_period = 0; /* Value for corresponding I2C register */
6487 u32 fec_rs_bit_cnt = 0; /* Actual precise amount of bits */
6488 u32 fec_oc_snc_fail_period = 0; /* Value for corresponding I2C register */
6489 u32 qam_vd_period = 0; /* Value for corresponding I2C register */
6490 u32 qam_vd_bit_cnt = 0; /* Actual precise amount of bits */
6491 u16 fec_vd_plen = 0; /* no of trellis symbols: VD SER measur period */
6492 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
6493
6494 dev_addr = demod->my_i2c_dev_addr;
6495 ext_attr = (struct drxj_data *) demod->my_ext_attr;
6496
6497 fec_bits_desired = ext_attr->fec_bits_desired;
6498 fec_rs_prescale = ext_attr->fec_rs_prescale;
6499
6500 switch (constellation) {
6501 case DRX_CONSTELLATION_QAM16:
6502 fec_bits_desired = 4 * symbol_rate;
6503 break;
6504 case DRX_CONSTELLATION_QAM32:
6505 fec_bits_desired = 5 * symbol_rate;
6506 break;
6507 case DRX_CONSTELLATION_QAM64:
6508 fec_bits_desired = 6 * symbol_rate;
6509 break;
6510 case DRX_CONSTELLATION_QAM128:
6511 fec_bits_desired = 7 * symbol_rate;
6512 break;
6513 case DRX_CONSTELLATION_QAM256:
6514 fec_bits_desired = 8 * symbol_rate;
6515 break;
6516 default:
6517 return -EINVAL;
6518 }
6519
6520 /* Parameters for Reed-Solomon Decoder */
6521 /* fecrs_period = (int)ceil(FEC_BITS_DESIRED/(fecrs_prescale*plen)) */
6522 /* rs_bit_cnt = fecrs_period*fecrs_prescale*plen */
6523 /* result is within 32 bit arithmetic -> */
6524 /* no need for mult or frac functions */
6525
6526 /* TODO: use constant instead of calculation and remove the fec_rs_plen in ext_attr */
6527 switch (ext_attr->standard) {
6528 case DRX_STANDARD_ITU_A:
6529 case DRX_STANDARD_ITU_C:
6530 fec_rs_plen = 204 * 8;
6531 break;
6532 case DRX_STANDARD_ITU_B:
6533 fec_rs_plen = 128 * 7;
6534 break;
6535 default:
6536 return -EINVAL;
6537 }
6538
6539 ext_attr->fec_rs_plen = fec_rs_plen; /* for getSigQual */
6540 fec_rs_bit_cnt = fec_rs_prescale * fec_rs_plen; /* temp storage */
6541 if (fec_rs_bit_cnt == 0) {
6542 pr_err("error: fec_rs_bit_cnt is zero!\n");
6543 return -EIO;
6544 }
6545 fec_rs_period = fec_bits_desired / fec_rs_bit_cnt + 1; /* ceil */
6546 if (ext_attr->standard != DRX_STANDARD_ITU_B)
6547 fec_oc_snc_fail_period = fec_rs_period;
6548
6549 /* limit to max 16 bit value (I2C register width) if needed */
6550 if (fec_rs_period > 0xFFFF)
6551 fec_rs_period = 0xFFFF;
6552
6553 /* write corresponding registers */
6554 switch (ext_attr->standard) {
6555 case DRX_STANDARD_ITU_A:
6556 case DRX_STANDARD_ITU_C:
6557 break;
6558 case DRX_STANDARD_ITU_B:
6559 switch (constellation) {
6560 case DRX_CONSTELLATION_QAM64:
6561 fec_rs_period = 31581;
6562 fec_oc_snc_fail_period = 17932;
6563 break;
6564 case DRX_CONSTELLATION_QAM256:
6565 fec_rs_period = 45446;
6566 fec_oc_snc_fail_period = 25805;
6567 break;
6568 default:
6569 return -EINVAL;
6570 }
6571 break;
6572 default:
6573 return -EINVAL;
6574 }
6575
6576 rc = drxj_dap_write_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, (u16)fec_oc_snc_fail_period, 0);
6577 if (rc != 0) {
6578 pr_err("error %d\n", rc);
6579 goto rw_error;
6580 }
6581 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PERIOD__A, (u16)fec_rs_period, 0);
6582 if (rc != 0) {
6583 pr_err("error %d\n", rc);
6584 goto rw_error;
6585 }
6586 rc = drxj_dap_write_reg16(dev_addr, FEC_RS_MEASUREMENT_PRESCALE__A, fec_rs_prescale, 0);
6587 if (rc != 0) {
6588 pr_err("error %d\n", rc);
6589 goto rw_error;
6590 }
6591 ext_attr->fec_rs_period = (u16) fec_rs_period;
6592 ext_attr->fec_rs_prescale = fec_rs_prescale;
6593 rc = drxdap_fasi_write_reg32(dev_addr, SCU_RAM_FEC_ACCUM_CW_CORRECTED_LO__A, 0, 0);
6594 if (rc != 0) {
6595 pr_err("error %d\n", rc);
6596 goto rw_error;
6597 }
6598 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_MEAS_COUNT__A, 0, 0);
6599 if (rc != 0) {
6600 pr_err("error %d\n", rc);
6601 goto rw_error;
6602 }
6603 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0, 0);
6604 if (rc != 0) {
6605 pr_err("error %d\n", rc);
6606 goto rw_error;
6607 }
6608
6609 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
6610 /* Parameters for Viterbi Decoder */
6611 /* qamvd_period = (int)ceil(FEC_BITS_DESIRED/ */
6612 /* (qamvd_prescale*plen*(qam_constellation+1))) */
6613 /* vd_bit_cnt = qamvd_period*qamvd_prescale*plen */
6614 /* result is within 32 bit arithmetic -> */
6615 /* no need for mult or frac functions */
6616
6617 /* a(8 bit) * b(8 bit) = 16 bit result => mult32 not needed */
6618 fec_vd_plen = ext_attr->fec_vd_plen;
6619 qam_vd_prescale = ext_attr->qam_vd_prescale;
6620 qam_vd_bit_cnt = qam_vd_prescale * fec_vd_plen; /* temp storage */
6621
6622 switch (constellation) {
6623 case DRX_CONSTELLATION_QAM64:
6624 /* a(16 bit) * b(4 bit) = 20 bit result => mult32 not needed */
6625 qam_vd_period =
6626 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM64 + 1)
6627 * (QAM_TOP_CONSTELLATION_QAM64 + 1);
6628 break;
6629 case DRX_CONSTELLATION_QAM256:
6630 /* a(16 bit) * b(5 bit) = 21 bit result => mult32 not needed */
6631 qam_vd_period =
6632 qam_vd_bit_cnt * (QAM_TOP_CONSTELLATION_QAM256 + 1)
6633 * (QAM_TOP_CONSTELLATION_QAM256 + 1);
6634 break;
6635 default:
6636 return -EINVAL;
6637 }
6638 if (qam_vd_period == 0) {
6639 pr_err("error: qam_vd_period is zero!\n");
6640 return -EIO;
6641 }
6642 qam_vd_period = fec_bits_desired / qam_vd_period;
6643 /* limit to max 16 bit value (I2C register width) if needed */
6644 if (qam_vd_period > 0xFFFF)
6645 qam_vd_period = 0xFFFF;
6646
6647 /* a(16 bit) * b(16 bit) = 32 bit result => mult32 not needed */
6648 qam_vd_bit_cnt *= qam_vd_period;
6649
6650 rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PERIOD__A, (u16)qam_vd_period, 0);
6651 if (rc != 0) {
6652 pr_err("error %d\n", rc);
6653 goto rw_error;
6654 }
6655 rc = drxj_dap_write_reg16(dev_addr, QAM_VD_MEASUREMENT_PRESCALE__A, qam_vd_prescale, 0);
6656 if (rc != 0) {
6657 pr_err("error %d\n", rc);
6658 goto rw_error;
6659 }
6660 ext_attr->qam_vd_period = (u16) qam_vd_period;
6661 ext_attr->qam_vd_prescale = qam_vd_prescale;
6662 }
6663
6664 return 0;
6665 rw_error:
6666 return rc;
6667 }
6668
6669 /*============================================================================*/
6670
6671 /*
6672 * \fn int set_qam16 ()
6673 * \brief QAM16 specific setup
6674 * \param demod instance of demod.
6675 * \return int.
6676 */
set_qam16(struct drx_demod_instance * demod)6677 static int set_qam16(struct drx_demod_instance *demod)
6678 {
6679 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6680 int rc;
6681 static const u8 qam_dq_qual_fun[] = {
6682 DRXJ_16TO8(2), /* fun0 */
6683 DRXJ_16TO8(2), /* fun1 */
6684 DRXJ_16TO8(2), /* fun2 */
6685 DRXJ_16TO8(2), /* fun3 */
6686 DRXJ_16TO8(3), /* fun4 */
6687 DRXJ_16TO8(3), /* fun5 */
6688 };
6689 static const u8 qam_eq_cma_rad[] = {
6690 DRXJ_16TO8(13517), /* RAD0 */
6691 DRXJ_16TO8(13517), /* RAD1 */
6692 DRXJ_16TO8(13517), /* RAD2 */
6693 DRXJ_16TO8(13517), /* RAD3 */
6694 DRXJ_16TO8(13517), /* RAD4 */
6695 DRXJ_16TO8(13517), /* RAD5 */
6696 };
6697
6698 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
6699 if (rc != 0) {
6700 pr_err("error %d\n", rc);
6701 goto rw_error;
6702 }
6703 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
6704 if (rc != 0) {
6705 pr_err("error %d\n", rc);
6706 goto rw_error;
6707 }
6708
6709 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 140, 0);
6710 if (rc != 0) {
6711 pr_err("error %d\n", rc);
6712 goto rw_error;
6713 }
6714 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
6715 if (rc != 0) {
6716 pr_err("error %d\n", rc);
6717 goto rw_error;
6718 }
6719 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 120, 0);
6720 if (rc != 0) {
6721 pr_err("error %d\n", rc);
6722 goto rw_error;
6723 }
6724 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 230, 0);
6725 if (rc != 0) {
6726 pr_err("error %d\n", rc);
6727 goto rw_error;
6728 }
6729 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 95, 0);
6730 if (rc != 0) {
6731 pr_err("error %d\n", rc);
6732 goto rw_error;
6733 }
6734 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 105, 0);
6735 if (rc != 0) {
6736 pr_err("error %d\n", rc);
6737 goto rw_error;
6738 }
6739
6740 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
6741 if (rc != 0) {
6742 pr_err("error %d\n", rc);
6743 goto rw_error;
6744 }
6745 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
6746 if (rc != 0) {
6747 pr_err("error %d\n", rc);
6748 goto rw_error;
6749 }
6750 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
6751 if (rc != 0) {
6752 pr_err("error %d\n", rc);
6753 goto rw_error;
6754 }
6755
6756 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 16, 0);
6757 if (rc != 0) {
6758 pr_err("error %d\n", rc);
6759 goto rw_error;
6760 }
6761 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 220, 0);
6762 if (rc != 0) {
6763 pr_err("error %d\n", rc);
6764 goto rw_error;
6765 }
6766 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 25, 0);
6767 if (rc != 0) {
6768 pr_err("error %d\n", rc);
6769 goto rw_error;
6770 }
6771 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 6, 0);
6772 if (rc != 0) {
6773 pr_err("error %d\n", rc);
6774 goto rw_error;
6775 }
6776 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-24), 0);
6777 if (rc != 0) {
6778 pr_err("error %d\n", rc);
6779 goto rw_error;
6780 }
6781 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-65), 0);
6782 if (rc != 0) {
6783 pr_err("error %d\n", rc);
6784 goto rw_error;
6785 }
6786 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-127), 0);
6787 if (rc != 0) {
6788 pr_err("error %d\n", rc);
6789 goto rw_error;
6790 }
6791
6792 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
6793 if (rc != 0) {
6794 pr_err("error %d\n", rc);
6795 goto rw_error;
6796 }
6797 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
6798 if (rc != 0) {
6799 pr_err("error %d\n", rc);
6800 goto rw_error;
6801 }
6802 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
6803 if (rc != 0) {
6804 pr_err("error %d\n", rc);
6805 goto rw_error;
6806 }
6807 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
6808 if (rc != 0) {
6809 pr_err("error %d\n", rc);
6810 goto rw_error;
6811 }
6812 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
6813 if (rc != 0) {
6814 pr_err("error %d\n", rc);
6815 goto rw_error;
6816 }
6817 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
6818 if (rc != 0) {
6819 pr_err("error %d\n", rc);
6820 goto rw_error;
6821 }
6822 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
6823 if (rc != 0) {
6824 pr_err("error %d\n", rc);
6825 goto rw_error;
6826 }
6827 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
6828 if (rc != 0) {
6829 pr_err("error %d\n", rc);
6830 goto rw_error;
6831 }
6832 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
6833 if (rc != 0) {
6834 pr_err("error %d\n", rc);
6835 goto rw_error;
6836 }
6837 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
6838 if (rc != 0) {
6839 pr_err("error %d\n", rc);
6840 goto rw_error;
6841 }
6842 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
6843 if (rc != 0) {
6844 pr_err("error %d\n", rc);
6845 goto rw_error;
6846 }
6847 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
6848 if (rc != 0) {
6849 pr_err("error %d\n", rc);
6850 goto rw_error;
6851 }
6852 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
6853 if (rc != 0) {
6854 pr_err("error %d\n", rc);
6855 goto rw_error;
6856 }
6857 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
6858 if (rc != 0) {
6859 pr_err("error %d\n", rc);
6860 goto rw_error;
6861 }
6862 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
6863 if (rc != 0) {
6864 pr_err("error %d\n", rc);
6865 goto rw_error;
6866 }
6867 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
6868 if (rc != 0) {
6869 pr_err("error %d\n", rc);
6870 goto rw_error;
6871 }
6872 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 240, 0);
6873 if (rc != 0) {
6874 pr_err("error %d\n", rc);
6875 goto rw_error;
6876 }
6877 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
6878 if (rc != 0) {
6879 pr_err("error %d\n", rc);
6880 goto rw_error;
6881 }
6882 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
6883 if (rc != 0) {
6884 pr_err("error %d\n", rc);
6885 goto rw_error;
6886 }
6887 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
6888 if (rc != 0) {
6889 pr_err("error %d\n", rc);
6890 goto rw_error;
6891 }
6892
6893 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 40960, 0);
6894 if (rc != 0) {
6895 pr_err("error %d\n", rc);
6896 goto rw_error;
6897 }
6898
6899 return 0;
6900 rw_error:
6901 return rc;
6902 }
6903
6904 /*============================================================================*/
6905
6906 /*
6907 * \fn int set_qam32 ()
6908 * \brief QAM32 specific setup
6909 * \param demod instance of demod.
6910 * \return int.
6911 */
set_qam32(struct drx_demod_instance * demod)6912 static int set_qam32(struct drx_demod_instance *demod)
6913 {
6914 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
6915 int rc;
6916 static const u8 qam_dq_qual_fun[] = {
6917 DRXJ_16TO8(3), /* fun0 */
6918 DRXJ_16TO8(3), /* fun1 */
6919 DRXJ_16TO8(3), /* fun2 */
6920 DRXJ_16TO8(3), /* fun3 */
6921 DRXJ_16TO8(4), /* fun4 */
6922 DRXJ_16TO8(4), /* fun5 */
6923 };
6924 static const u8 qam_eq_cma_rad[] = {
6925 DRXJ_16TO8(6707), /* RAD0 */
6926 DRXJ_16TO8(6707), /* RAD1 */
6927 DRXJ_16TO8(6707), /* RAD2 */
6928 DRXJ_16TO8(6707), /* RAD3 */
6929 DRXJ_16TO8(6707), /* RAD4 */
6930 DRXJ_16TO8(6707), /* RAD5 */
6931 };
6932
6933 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
6934 if (rc != 0) {
6935 pr_err("error %d\n", rc);
6936 goto rw_error;
6937 }
6938 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
6939 if (rc != 0) {
6940 pr_err("error %d\n", rc);
6941 goto rw_error;
6942 }
6943
6944 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 90, 0);
6945 if (rc != 0) {
6946 pr_err("error %d\n", rc);
6947 goto rw_error;
6948 }
6949 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 50, 0);
6950 if (rc != 0) {
6951 pr_err("error %d\n", rc);
6952 goto rw_error;
6953 }
6954 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
6955 if (rc != 0) {
6956 pr_err("error %d\n", rc);
6957 goto rw_error;
6958 }
6959 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 170, 0);
6960 if (rc != 0) {
6961 pr_err("error %d\n", rc);
6962 goto rw_error;
6963 }
6964 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
6965 if (rc != 0) {
6966 pr_err("error %d\n", rc);
6967 goto rw_error;
6968 }
6969 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
6970 if (rc != 0) {
6971 pr_err("error %d\n", rc);
6972 goto rw_error;
6973 }
6974
6975 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
6976 if (rc != 0) {
6977 pr_err("error %d\n", rc);
6978 goto rw_error;
6979 }
6980 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 56, 0);
6981 if (rc != 0) {
6982 pr_err("error %d\n", rc);
6983 goto rw_error;
6984 }
6985 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
6986 if (rc != 0) {
6987 pr_err("error %d\n", rc);
6988 goto rw_error;
6989 }
6990
6991 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
6992 if (rc != 0) {
6993 pr_err("error %d\n", rc);
6994 goto rw_error;
6995 }
6996 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 140, 0);
6997 if (rc != 0) {
6998 pr_err("error %d\n", rc);
6999 goto rw_error;
7000 }
7001 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16)(-8), 0);
7002 if (rc != 0) {
7003 pr_err("error %d\n", rc);
7004 goto rw_error;
7005 }
7006 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16)(-16), 0);
7007 if (rc != 0) {
7008 pr_err("error %d\n", rc);
7009 goto rw_error;
7010 }
7011 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-26), 0);
7012 if (rc != 0) {
7013 pr_err("error %d\n", rc);
7014 goto rw_error;
7015 }
7016 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-56), 0);
7017 if (rc != 0) {
7018 pr_err("error %d\n", rc);
7019 goto rw_error;
7020 }
7021 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-86), 0);
7022 if (rc != 0) {
7023 pr_err("error %d\n", rc);
7024 goto rw_error;
7025 }
7026
7027 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7028 if (rc != 0) {
7029 pr_err("error %d\n", rc);
7030 goto rw_error;
7031 }
7032 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7033 if (rc != 0) {
7034 pr_err("error %d\n", rc);
7035 goto rw_error;
7036 }
7037 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7038 if (rc != 0) {
7039 pr_err("error %d\n", rc);
7040 goto rw_error;
7041 }
7042 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20, 0);
7043 if (rc != 0) {
7044 pr_err("error %d\n", rc);
7045 goto rw_error;
7046 }
7047 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7048 if (rc != 0) {
7049 pr_err("error %d\n", rc);
7050 goto rw_error;
7051 }
7052 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7053 if (rc != 0) {
7054 pr_err("error %d\n", rc);
7055 goto rw_error;
7056 }
7057 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 10, 0);
7058 if (rc != 0) {
7059 pr_err("error %d\n", rc);
7060 goto rw_error;
7061 }
7062 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 50, 0);
7063 if (rc != 0) {
7064 pr_err("error %d\n", rc);
7065 goto rw_error;
7066 }
7067 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7068 if (rc != 0) {
7069 pr_err("error %d\n", rc);
7070 goto rw_error;
7071 }
7072 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7073 if (rc != 0) {
7074 pr_err("error %d\n", rc);
7075 goto rw_error;
7076 }
7077 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7078 if (rc != 0) {
7079 pr_err("error %d\n", rc);
7080 goto rw_error;
7081 }
7082 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7083 if (rc != 0) {
7084 pr_err("error %d\n", rc);
7085 goto rw_error;
7086 }
7087 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7088 if (rc != 0) {
7089 pr_err("error %d\n", rc);
7090 goto rw_error;
7091 }
7092 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7093 if (rc != 0) {
7094 pr_err("error %d\n", rc);
7095 goto rw_error;
7096 }
7097 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7098 if (rc != 0) {
7099 pr_err("error %d\n", rc);
7100 goto rw_error;
7101 }
7102 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
7103 if (rc != 0) {
7104 pr_err("error %d\n", rc);
7105 goto rw_error;
7106 }
7107 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 176, 0);
7108 if (rc != 0) {
7109 pr_err("error %d\n", rc);
7110 goto rw_error;
7111 }
7112 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7113 if (rc != 0) {
7114 pr_err("error %d\n", rc);
7115 goto rw_error;
7116 }
7117 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7118 if (rc != 0) {
7119 pr_err("error %d\n", rc);
7120 goto rw_error;
7121 }
7122 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 8, 0);
7123 if (rc != 0) {
7124 pr_err("error %d\n", rc);
7125 goto rw_error;
7126 }
7127
7128 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20480, 0);
7129 if (rc != 0) {
7130 pr_err("error %d\n", rc);
7131 goto rw_error;
7132 }
7133
7134 return 0;
7135 rw_error:
7136 return rc;
7137 }
7138
7139 /*============================================================================*/
7140
7141 /*
7142 * \fn int set_qam64 ()
7143 * \brief QAM64 specific setup
7144 * \param demod instance of demod.
7145 * \return int.
7146 */
set_qam64(struct drx_demod_instance * demod)7147 static int set_qam64(struct drx_demod_instance *demod)
7148 {
7149 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7150 int rc;
7151 static const u8 qam_dq_qual_fun[] = {
7152 /* this is hw reset value. no necessary to re-write */
7153 DRXJ_16TO8(4), /* fun0 */
7154 DRXJ_16TO8(4), /* fun1 */
7155 DRXJ_16TO8(4), /* fun2 */
7156 DRXJ_16TO8(4), /* fun3 */
7157 DRXJ_16TO8(6), /* fun4 */
7158 DRXJ_16TO8(6), /* fun5 */
7159 };
7160 static const u8 qam_eq_cma_rad[] = {
7161 DRXJ_16TO8(13336), /* RAD0 */
7162 DRXJ_16TO8(12618), /* RAD1 */
7163 DRXJ_16TO8(11988), /* RAD2 */
7164 DRXJ_16TO8(13809), /* RAD3 */
7165 DRXJ_16TO8(13809), /* RAD4 */
7166 DRXJ_16TO8(15609), /* RAD5 */
7167 };
7168
7169 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7170 if (rc != 0) {
7171 pr_err("error %d\n", rc);
7172 goto rw_error;
7173 }
7174 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7175 if (rc != 0) {
7176 pr_err("error %d\n", rc);
7177 goto rw_error;
7178 }
7179
7180 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 105, 0);
7181 if (rc != 0) {
7182 pr_err("error %d\n", rc);
7183 goto rw_error;
7184 }
7185 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7186 if (rc != 0) {
7187 pr_err("error %d\n", rc);
7188 goto rw_error;
7189 }
7190 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7191 if (rc != 0) {
7192 pr_err("error %d\n", rc);
7193 goto rw_error;
7194 }
7195 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 195, 0);
7196 if (rc != 0) {
7197 pr_err("error %d\n", rc);
7198 goto rw_error;
7199 }
7200 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7201 if (rc != 0) {
7202 pr_err("error %d\n", rc);
7203 goto rw_error;
7204 }
7205 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 84, 0);
7206 if (rc != 0) {
7207 pr_err("error %d\n", rc);
7208 goto rw_error;
7209 }
7210
7211 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7212 if (rc != 0) {
7213 pr_err("error %d\n", rc);
7214 goto rw_error;
7215 }
7216 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
7217 if (rc != 0) {
7218 pr_err("error %d\n", rc);
7219 goto rw_error;
7220 }
7221 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7222 if (rc != 0) {
7223 pr_err("error %d\n", rc);
7224 goto rw_error;
7225 }
7226
7227 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 12, 0);
7228 if (rc != 0) {
7229 pr_err("error %d\n", rc);
7230 goto rw_error;
7231 }
7232 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 141, 0);
7233 if (rc != 0) {
7234 pr_err("error %d\n", rc);
7235 goto rw_error;
7236 }
7237 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 7, 0);
7238 if (rc != 0) {
7239 pr_err("error %d\n", rc);
7240 goto rw_error;
7241 }
7242 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 0, 0);
7243 if (rc != 0) {
7244 pr_err("error %d\n", rc);
7245 goto rw_error;
7246 }
7247 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-15), 0);
7248 if (rc != 0) {
7249 pr_err("error %d\n", rc);
7250 goto rw_error;
7251 }
7252 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16)(-45), 0);
7253 if (rc != 0) {
7254 pr_err("error %d\n", rc);
7255 goto rw_error;
7256 }
7257 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-80), 0);
7258 if (rc != 0) {
7259 pr_err("error %d\n", rc);
7260 goto rw_error;
7261 }
7262
7263 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7264 if (rc != 0) {
7265 pr_err("error %d\n", rc);
7266 goto rw_error;
7267 }
7268 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7269 if (rc != 0) {
7270 pr_err("error %d\n", rc);
7271 goto rw_error;
7272 }
7273 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7274 if (rc != 0) {
7275 pr_err("error %d\n", rc);
7276 goto rw_error;
7277 }
7278 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30, 0);
7279 if (rc != 0) {
7280 pr_err("error %d\n", rc);
7281 goto rw_error;
7282 }
7283 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7284 if (rc != 0) {
7285 pr_err("error %d\n", rc);
7286 goto rw_error;
7287 }
7288 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7289 if (rc != 0) {
7290 pr_err("error %d\n", rc);
7291 goto rw_error;
7292 }
7293 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 15, 0);
7294 if (rc != 0) {
7295 pr_err("error %d\n", rc);
7296 goto rw_error;
7297 }
7298 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7299 if (rc != 0) {
7300 pr_err("error %d\n", rc);
7301 goto rw_error;
7302 }
7303 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7304 if (rc != 0) {
7305 pr_err("error %d\n", rc);
7306 goto rw_error;
7307 }
7308 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7309 if (rc != 0) {
7310 pr_err("error %d\n", rc);
7311 goto rw_error;
7312 }
7313 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7314 if (rc != 0) {
7315 pr_err("error %d\n", rc);
7316 goto rw_error;
7317 }
7318 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7319 if (rc != 0) {
7320 pr_err("error %d\n", rc);
7321 goto rw_error;
7322 }
7323 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7324 if (rc != 0) {
7325 pr_err("error %d\n", rc);
7326 goto rw_error;
7327 }
7328 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7329 if (rc != 0) {
7330 pr_err("error %d\n", rc);
7331 goto rw_error;
7332 }
7333 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7334 if (rc != 0) {
7335 pr_err("error %d\n", rc);
7336 goto rw_error;
7337 }
7338 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
7339 if (rc != 0) {
7340 pr_err("error %d\n", rc);
7341 goto rw_error;
7342 }
7343 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 160, 0);
7344 if (rc != 0) {
7345 pr_err("error %d\n", rc);
7346 goto rw_error;
7347 }
7348 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7349 if (rc != 0) {
7350 pr_err("error %d\n", rc);
7351 goto rw_error;
7352 }
7353 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7354 if (rc != 0) {
7355 pr_err("error %d\n", rc);
7356 goto rw_error;
7357 }
7358 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 32, 0);
7359 if (rc != 0) {
7360 pr_err("error %d\n", rc);
7361 goto rw_error;
7362 }
7363
7364 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43008, 0);
7365 if (rc != 0) {
7366 pr_err("error %d\n", rc);
7367 goto rw_error;
7368 }
7369
7370 return 0;
7371 rw_error:
7372 return rc;
7373 }
7374
7375 /*============================================================================*/
7376
7377 /*
7378 * \fn int set_qam128 ()
7379 * \brief QAM128 specific setup
7380 * \param demod: instance of demod.
7381 * \return int.
7382 */
set_qam128(struct drx_demod_instance * demod)7383 static int set_qam128(struct drx_demod_instance *demod)
7384 {
7385 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7386 int rc;
7387 static const u8 qam_dq_qual_fun[] = {
7388 DRXJ_16TO8(6), /* fun0 */
7389 DRXJ_16TO8(6), /* fun1 */
7390 DRXJ_16TO8(6), /* fun2 */
7391 DRXJ_16TO8(6), /* fun3 */
7392 DRXJ_16TO8(9), /* fun4 */
7393 DRXJ_16TO8(9), /* fun5 */
7394 };
7395 static const u8 qam_eq_cma_rad[] = {
7396 DRXJ_16TO8(6164), /* RAD0 */
7397 DRXJ_16TO8(6598), /* RAD1 */
7398 DRXJ_16TO8(6394), /* RAD2 */
7399 DRXJ_16TO8(6409), /* RAD3 */
7400 DRXJ_16TO8(6656), /* RAD4 */
7401 DRXJ_16TO8(7238), /* RAD5 */
7402 };
7403
7404 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7405 if (rc != 0) {
7406 pr_err("error %d\n", rc);
7407 goto rw_error;
7408 }
7409 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7410 if (rc != 0) {
7411 pr_err("error %d\n", rc);
7412 goto rw_error;
7413 }
7414
7415 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
7416 if (rc != 0) {
7417 pr_err("error %d\n", rc);
7418 goto rw_error;
7419 }
7420 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7421 if (rc != 0) {
7422 pr_err("error %d\n", rc);
7423 goto rw_error;
7424 }
7425 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7426 if (rc != 0) {
7427 pr_err("error %d\n", rc);
7428 goto rw_error;
7429 }
7430 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 140, 0);
7431 if (rc != 0) {
7432 pr_err("error %d\n", rc);
7433 goto rw_error;
7434 }
7435 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7436 if (rc != 0) {
7437 pr_err("error %d\n", rc);
7438 goto rw_error;
7439 }
7440 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 100, 0);
7441 if (rc != 0) {
7442 pr_err("error %d\n", rc);
7443 goto rw_error;
7444 }
7445
7446 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7447 if (rc != 0) {
7448 pr_err("error %d\n", rc);
7449 goto rw_error;
7450 }
7451 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 32, 0);
7452 if (rc != 0) {
7453 pr_err("error %d\n", rc);
7454 goto rw_error;
7455 }
7456 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7457 if (rc != 0) {
7458 pr_err("error %d\n", rc);
7459 goto rw_error;
7460 }
7461
7462 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
7463 if (rc != 0) {
7464 pr_err("error %d\n", rc);
7465 goto rw_error;
7466 }
7467 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 65, 0);
7468 if (rc != 0) {
7469 pr_err("error %d\n", rc);
7470 goto rw_error;
7471 }
7472 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 5, 0);
7473 if (rc != 0) {
7474 pr_err("error %d\n", rc);
7475 goto rw_error;
7476 }
7477 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 3, 0);
7478 if (rc != 0) {
7479 pr_err("error %d\n", rc);
7480 goto rw_error;
7481 }
7482 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16)(-1), 0);
7483 if (rc != 0) {
7484 pr_err("error %d\n", rc);
7485 goto rw_error;
7486 }
7487 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 12, 0);
7488 if (rc != 0) {
7489 pr_err("error %d\n", rc);
7490 goto rw_error;
7491 }
7492 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-23), 0);
7493 if (rc != 0) {
7494 pr_err("error %d\n", rc);
7495 goto rw_error;
7496 }
7497
7498 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7499 if (rc != 0) {
7500 pr_err("error %d\n", rc);
7501 goto rw_error;
7502 }
7503 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7504 if (rc != 0) {
7505 pr_err("error %d\n", rc);
7506 goto rw_error;
7507 }
7508 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7509 if (rc != 0) {
7510 pr_err("error %d\n", rc);
7511 goto rw_error;
7512 }
7513 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40, 0);
7514 if (rc != 0) {
7515 pr_err("error %d\n", rc);
7516 goto rw_error;
7517 }
7518 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7519 if (rc != 0) {
7520 pr_err("error %d\n", rc);
7521 goto rw_error;
7522 }
7523 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7524 if (rc != 0) {
7525 pr_err("error %d\n", rc);
7526 goto rw_error;
7527 }
7528 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20, 0);
7529 if (rc != 0) {
7530 pr_err("error %d\n", rc);
7531 goto rw_error;
7532 }
7533 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7534 if (rc != 0) {
7535 pr_err("error %d\n", rc);
7536 goto rw_error;
7537 }
7538 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7539 if (rc != 0) {
7540 pr_err("error %d\n", rc);
7541 goto rw_error;
7542 }
7543 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7544 if (rc != 0) {
7545 pr_err("error %d\n", rc);
7546 goto rw_error;
7547 }
7548 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7549 if (rc != 0) {
7550 pr_err("error %d\n", rc);
7551 goto rw_error;
7552 }
7553 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7554 if (rc != 0) {
7555 pr_err("error %d\n", rc);
7556 goto rw_error;
7557 }
7558 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7559 if (rc != 0) {
7560 pr_err("error %d\n", rc);
7561 goto rw_error;
7562 }
7563 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7564 if (rc != 0) {
7565 pr_err("error %d\n", rc);
7566 goto rw_error;
7567 }
7568 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7569 if (rc != 0) {
7570 pr_err("error %d\n", rc);
7571 goto rw_error;
7572 }
7573 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 32, 0);
7574 if (rc != 0) {
7575 pr_err("error %d\n", rc);
7576 goto rw_error;
7577 }
7578 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 144, 0);
7579 if (rc != 0) {
7580 pr_err("error %d\n", rc);
7581 goto rw_error;
7582 }
7583 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7584 if (rc != 0) {
7585 pr_err("error %d\n", rc);
7586 goto rw_error;
7587 }
7588 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7589 if (rc != 0) {
7590 pr_err("error %d\n", rc);
7591 goto rw_error;
7592 }
7593 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
7594 if (rc != 0) {
7595 pr_err("error %d\n", rc);
7596 goto rw_error;
7597 }
7598
7599 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 20992, 0);
7600 if (rc != 0) {
7601 pr_err("error %d\n", rc);
7602 goto rw_error;
7603 }
7604
7605 return 0;
7606 rw_error:
7607 return rc;
7608 }
7609
7610 /*============================================================================*/
7611
7612 /*
7613 * \fn int set_qam256 ()
7614 * \brief QAM256 specific setup
7615 * \param demod: instance of demod.
7616 * \return int.
7617 */
set_qam256(struct drx_demod_instance * demod)7618 static int set_qam256(struct drx_demod_instance *demod)
7619 {
7620 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
7621 int rc;
7622 static const u8 qam_dq_qual_fun[] = {
7623 DRXJ_16TO8(8), /* fun0 */
7624 DRXJ_16TO8(8), /* fun1 */
7625 DRXJ_16TO8(8), /* fun2 */
7626 DRXJ_16TO8(8), /* fun3 */
7627 DRXJ_16TO8(12), /* fun4 */
7628 DRXJ_16TO8(12), /* fun5 */
7629 };
7630 static const u8 qam_eq_cma_rad[] = {
7631 DRXJ_16TO8(12345), /* RAD0 */
7632 DRXJ_16TO8(12345), /* RAD1 */
7633 DRXJ_16TO8(13626), /* RAD2 */
7634 DRXJ_16TO8(12931), /* RAD3 */
7635 DRXJ_16TO8(14719), /* RAD4 */
7636 DRXJ_16TO8(15356), /* RAD5 */
7637 };
7638
7639 rc = drxdap_fasi_write_block(dev_addr, QAM_DQ_QUAL_FUN0__A, sizeof(qam_dq_qual_fun), ((u8 *)qam_dq_qual_fun), 0);
7640 if (rc != 0) {
7641 pr_err("error %d\n", rc);
7642 goto rw_error;
7643 }
7644 rc = drxdap_fasi_write_block(dev_addr, SCU_RAM_QAM_EQ_CMA_RAD0__A, sizeof(qam_eq_cma_rad), ((u8 *)qam_eq_cma_rad), 0);
7645 if (rc != 0) {
7646 pr_err("error %d\n", rc);
7647 goto rw_error;
7648 }
7649
7650 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RTH__A, 50, 0);
7651 if (rc != 0) {
7652 pr_err("error %d\n", rc);
7653 goto rw_error;
7654 }
7655 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FTH__A, 60, 0);
7656 if (rc != 0) {
7657 pr_err("error %d\n", rc);
7658 goto rw_error;
7659 }
7660 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_PTH__A, 100, 0);
7661 if (rc != 0) {
7662 pr_err("error %d\n", rc);
7663 goto rw_error;
7664 }
7665 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_QTH__A, 150, 0);
7666 if (rc != 0) {
7667 pr_err("error %d\n", rc);
7668 goto rw_error;
7669 }
7670 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_CTH__A, 80, 0);
7671 if (rc != 0) {
7672 pr_err("error %d\n", rc);
7673 goto rw_error;
7674 }
7675 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MTH__A, 110, 0);
7676 if (rc != 0) {
7677 pr_err("error %d\n", rc);
7678 goto rw_error;
7679 }
7680
7681 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RATE_LIM__A, 40, 0);
7682 if (rc != 0) {
7683 pr_err("error %d\n", rc);
7684 goto rw_error;
7685 }
7686 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_FREQ_LIM__A, 16, 0);
7687 if (rc != 0) {
7688 pr_err("error %d\n", rc);
7689 goto rw_error;
7690 }
7691 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_COUNT_LIM__A, 3, 0);
7692 if (rc != 0) {
7693 pr_err("error %d\n", rc);
7694 goto rw_error;
7695 }
7696
7697 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, 8, 0);
7698 if (rc != 0) {
7699 pr_err("error %d\n", rc);
7700 goto rw_error;
7701 }
7702 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, 74, 0);
7703 if (rc != 0) {
7704 pr_err("error %d\n", rc);
7705 goto rw_error;
7706 }
7707 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, 18, 0);
7708 if (rc != 0) {
7709 pr_err("error %d\n", rc);
7710 goto rw_error;
7711 }
7712 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, 13, 0);
7713 if (rc != 0) {
7714 pr_err("error %d\n", rc);
7715 goto rw_error;
7716 }
7717 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, 7, 0);
7718 if (rc != 0) {
7719 pr_err("error %d\n", rc);
7720 goto rw_error;
7721 }
7722 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, 0, 0);
7723 if (rc != 0) {
7724 pr_err("error %d\n", rc);
7725 goto rw_error;
7726 }
7727 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16)(-8), 0);
7728 if (rc != 0) {
7729 pr_err("error %d\n", rc);
7730 goto rw_error;
7731 }
7732
7733 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_FINE__A, 15, 0);
7734 if (rc != 0) {
7735 pr_err("error %d\n", rc);
7736 goto rw_error;
7737 }
7738 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CA_COARSE__A, 40, 0);
7739 if (rc != 0) {
7740 pr_err("error %d\n", rc);
7741 goto rw_error;
7742 }
7743 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_FINE__A, 2, 0);
7744 if (rc != 0) {
7745 pr_err("error %d\n", rc);
7746 goto rw_error;
7747 }
7748 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50, 0);
7749 if (rc != 0) {
7750 pr_err("error %d\n", rc);
7751 goto rw_error;
7752 }
7753 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CP_COARSE__A, 255, 0);
7754 if (rc != 0) {
7755 pr_err("error %d\n", rc);
7756 goto rw_error;
7757 }
7758 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_FINE__A, 2, 0);
7759 if (rc != 0) {
7760 pr_err("error %d\n", rc);
7761 goto rw_error;
7762 }
7763 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_MEDIUM__A, 25, 0);
7764 if (rc != 0) {
7765 pr_err("error %d\n", rc);
7766 goto rw_error;
7767 }
7768 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CI_COARSE__A, 80, 0);
7769 if (rc != 0) {
7770 pr_err("error %d\n", rc);
7771 goto rw_error;
7772 }
7773 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_FINE__A, 12, 0);
7774 if (rc != 0) {
7775 pr_err("error %d\n", rc);
7776 goto rw_error;
7777 }
7778 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24, 0);
7779 if (rc != 0) {
7780 pr_err("error %d\n", rc);
7781 goto rw_error;
7782 }
7783 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EP_COARSE__A, 24, 0);
7784 if (rc != 0) {
7785 pr_err("error %d\n", rc);
7786 goto rw_error;
7787 }
7788 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_FINE__A, 12, 0);
7789 if (rc != 0) {
7790 pr_err("error %d\n", rc);
7791 goto rw_error;
7792 }
7793 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16, 0);
7794 if (rc != 0) {
7795 pr_err("error %d\n", rc);
7796 goto rw_error;
7797 }
7798 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_EI_COARSE__A, 16, 0);
7799 if (rc != 0) {
7800 pr_err("error %d\n", rc);
7801 goto rw_error;
7802 }
7803 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_FINE__A, 16, 0);
7804 if (rc != 0) {
7805 pr_err("error %d\n", rc);
7806 goto rw_error;
7807 }
7808 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_MEDIUM__A, 48, 0);
7809 if (rc != 0) {
7810 pr_err("error %d\n", rc);
7811 goto rw_error;
7812 }
7813 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF_COARSE__A, 80, 0);
7814 if (rc != 0) {
7815 pr_err("error %d\n", rc);
7816 goto rw_error;
7817 }
7818 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_FINE__A, 5, 0);
7819 if (rc != 0) {
7820 pr_err("error %d\n", rc);
7821 goto rw_error;
7822 }
7823 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 15, 0);
7824 if (rc != 0) {
7825 pr_err("error %d\n", rc);
7826 goto rw_error;
7827 }
7828 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_LC_CF1_COARSE__A, 16, 0);
7829 if (rc != 0) {
7830 pr_err("error %d\n", rc);
7831 goto rw_error;
7832 }
7833
7834 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_SL_SIG_POWER__A, 43520, 0);
7835 if (rc != 0) {
7836 pr_err("error %d\n", rc);
7837 goto rw_error;
7838 }
7839
7840 return 0;
7841 rw_error:
7842 return rc;
7843 }
7844
7845 /*============================================================================*/
7846 #define QAM_SET_OP_ALL 0x1
7847 #define QAM_SET_OP_CONSTELLATION 0x2
7848 #define QAM_SET_OP_SPECTRUM 0X4
7849
7850 /*
7851 * \fn int set_qam ()
7852 * \brief Set QAM demod.
7853 * \param demod: instance of demod.
7854 * \param channel: pointer to channel data.
7855 * \return int.
7856 */
7857 static int
set_qam(struct drx_demod_instance * demod,struct drx_channel * channel,s32 tuner_freq_offset,u32 op)7858 set_qam(struct drx_demod_instance *demod,
7859 struct drx_channel *channel, s32 tuner_freq_offset, u32 op)
7860 {
7861 struct i2c_device_addr *dev_addr = NULL;
7862 struct drxj_data *ext_attr = NULL;
7863 struct drx_common_attr *common_attr = NULL;
7864 int rc;
7865 u32 adc_frequency = 0;
7866 u32 iqm_rc_rate = 0;
7867 u16 cmd_result = 0;
7868 u16 lc_symbol_freq = 0;
7869 u16 iqm_rc_stretch = 0;
7870 u16 set_env_parameters = 0;
7871 u16 set_param_parameters[2] = { 0 };
7872 struct drxjscu_cmd cmd_scu = { /* command */ 0,
7873 /* parameter_len */ 0,
7874 /* result_len */ 0,
7875 /* parameter */ NULL,
7876 /* result */ NULL
7877 };
7878 static const u8 qam_a_taps[] = {
7879 DRXJ_16TO8(-1), /* re0 */
7880 DRXJ_16TO8(1), /* re1 */
7881 DRXJ_16TO8(1), /* re2 */
7882 DRXJ_16TO8(-1), /* re3 */
7883 DRXJ_16TO8(-1), /* re4 */
7884 DRXJ_16TO8(2), /* re5 */
7885 DRXJ_16TO8(1), /* re6 */
7886 DRXJ_16TO8(-2), /* re7 */
7887 DRXJ_16TO8(0), /* re8 */
7888 DRXJ_16TO8(3), /* re9 */
7889 DRXJ_16TO8(-1), /* re10 */
7890 DRXJ_16TO8(-3), /* re11 */
7891 DRXJ_16TO8(4), /* re12 */
7892 DRXJ_16TO8(1), /* re13 */
7893 DRXJ_16TO8(-8), /* re14 */
7894 DRXJ_16TO8(4), /* re15 */
7895 DRXJ_16TO8(13), /* re16 */
7896 DRXJ_16TO8(-13), /* re17 */
7897 DRXJ_16TO8(-19), /* re18 */
7898 DRXJ_16TO8(28), /* re19 */
7899 DRXJ_16TO8(25), /* re20 */
7900 DRXJ_16TO8(-53), /* re21 */
7901 DRXJ_16TO8(-31), /* re22 */
7902 DRXJ_16TO8(96), /* re23 */
7903 DRXJ_16TO8(37), /* re24 */
7904 DRXJ_16TO8(-190), /* re25 */
7905 DRXJ_16TO8(-40), /* re26 */
7906 DRXJ_16TO8(619) /* re27 */
7907 };
7908 static const u8 qam_b64_taps[] = {
7909 DRXJ_16TO8(0), /* re0 */
7910 DRXJ_16TO8(-2), /* re1 */
7911 DRXJ_16TO8(1), /* re2 */
7912 DRXJ_16TO8(2), /* re3 */
7913 DRXJ_16TO8(-2), /* re4 */
7914 DRXJ_16TO8(0), /* re5 */
7915 DRXJ_16TO8(4), /* re6 */
7916 DRXJ_16TO8(-2), /* re7 */
7917 DRXJ_16TO8(-4), /* re8 */
7918 DRXJ_16TO8(4), /* re9 */
7919 DRXJ_16TO8(3), /* re10 */
7920 DRXJ_16TO8(-6), /* re11 */
7921 DRXJ_16TO8(0), /* re12 */
7922 DRXJ_16TO8(6), /* re13 */
7923 DRXJ_16TO8(-5), /* re14 */
7924 DRXJ_16TO8(-3), /* re15 */
7925 DRXJ_16TO8(11), /* re16 */
7926 DRXJ_16TO8(-4), /* re17 */
7927 DRXJ_16TO8(-19), /* re18 */
7928 DRXJ_16TO8(19), /* re19 */
7929 DRXJ_16TO8(28), /* re20 */
7930 DRXJ_16TO8(-45), /* re21 */
7931 DRXJ_16TO8(-36), /* re22 */
7932 DRXJ_16TO8(90), /* re23 */
7933 DRXJ_16TO8(42), /* re24 */
7934 DRXJ_16TO8(-185), /* re25 */
7935 DRXJ_16TO8(-46), /* re26 */
7936 DRXJ_16TO8(614) /* re27 */
7937 };
7938 static const u8 qam_b256_taps[] = {
7939 DRXJ_16TO8(-2), /* re0 */
7940 DRXJ_16TO8(4), /* re1 */
7941 DRXJ_16TO8(1), /* re2 */
7942 DRXJ_16TO8(-4), /* re3 */
7943 DRXJ_16TO8(0), /* re4 */
7944 DRXJ_16TO8(4), /* re5 */
7945 DRXJ_16TO8(-2), /* re6 */
7946 DRXJ_16TO8(-4), /* re7 */
7947 DRXJ_16TO8(5), /* re8 */
7948 DRXJ_16TO8(2), /* re9 */
7949 DRXJ_16TO8(-8), /* re10 */
7950 DRXJ_16TO8(2), /* re11 */
7951 DRXJ_16TO8(11), /* re12 */
7952 DRXJ_16TO8(-8), /* re13 */
7953 DRXJ_16TO8(-15), /* re14 */
7954 DRXJ_16TO8(16), /* re15 */
7955 DRXJ_16TO8(19), /* re16 */
7956 DRXJ_16TO8(-27), /* re17 */
7957 DRXJ_16TO8(-22), /* re18 */
7958 DRXJ_16TO8(44), /* re19 */
7959 DRXJ_16TO8(26), /* re20 */
7960 DRXJ_16TO8(-69), /* re21 */
7961 DRXJ_16TO8(-28), /* re22 */
7962 DRXJ_16TO8(110), /* re23 */
7963 DRXJ_16TO8(31), /* re24 */
7964 DRXJ_16TO8(-201), /* re25 */
7965 DRXJ_16TO8(-32), /* re26 */
7966 DRXJ_16TO8(628) /* re27 */
7967 };
7968 static const u8 qam_c_taps[] = {
7969 DRXJ_16TO8(-3), /* re0 */
7970 DRXJ_16TO8(3), /* re1 */
7971 DRXJ_16TO8(2), /* re2 */
7972 DRXJ_16TO8(-4), /* re3 */
7973 DRXJ_16TO8(0), /* re4 */
7974 DRXJ_16TO8(4), /* re5 */
7975 DRXJ_16TO8(-1), /* re6 */
7976 DRXJ_16TO8(-4), /* re7 */
7977 DRXJ_16TO8(3), /* re8 */
7978 DRXJ_16TO8(3), /* re9 */
7979 DRXJ_16TO8(-5), /* re10 */
7980 DRXJ_16TO8(0), /* re11 */
7981 DRXJ_16TO8(9), /* re12 */
7982 DRXJ_16TO8(-4), /* re13 */
7983 DRXJ_16TO8(-12), /* re14 */
7984 DRXJ_16TO8(10), /* re15 */
7985 DRXJ_16TO8(16), /* re16 */
7986 DRXJ_16TO8(-21), /* re17 */
7987 DRXJ_16TO8(-20), /* re18 */
7988 DRXJ_16TO8(37), /* re19 */
7989 DRXJ_16TO8(25), /* re20 */
7990 DRXJ_16TO8(-62), /* re21 */
7991 DRXJ_16TO8(-28), /* re22 */
7992 DRXJ_16TO8(105), /* re23 */
7993 DRXJ_16TO8(31), /* re24 */
7994 DRXJ_16TO8(-197), /* re25 */
7995 DRXJ_16TO8(-33), /* re26 */
7996 DRXJ_16TO8(626) /* re27 */
7997 };
7998
7999 dev_addr = demod->my_i2c_dev_addr;
8000 ext_attr = (struct drxj_data *) demod->my_ext_attr;
8001 common_attr = (struct drx_common_attr *) demod->my_common_attr;
8002
8003 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8004 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8005 switch (channel->constellation) {
8006 case DRX_CONSTELLATION_QAM256:
8007 iqm_rc_rate = 0x00AE3562;
8008 lc_symbol_freq =
8009 QAM_LC_SYMBOL_FREQ_FREQ_QAM_B_256;
8010 channel->symbolrate = 5360537;
8011 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_256;
8012 break;
8013 case DRX_CONSTELLATION_QAM64:
8014 iqm_rc_rate = 0x00C05A0E;
8015 lc_symbol_freq = 409;
8016 channel->symbolrate = 5056941;
8017 iqm_rc_stretch = IQM_RC_STRETCH_QAM_B_64;
8018 break;
8019 default:
8020 return -EINVAL;
8021 }
8022 } else {
8023 adc_frequency = (common_attr->sys_clock_freq * 1000) / 3;
8024 if (channel->symbolrate == 0) {
8025 pr_err("error: channel symbolrate is zero!\n");
8026 return -EIO;
8027 }
8028 iqm_rc_rate =
8029 (adc_frequency / channel->symbolrate) * (1 << 21) +
8030 (frac28
8031 ((adc_frequency % channel->symbolrate),
8032 channel->symbolrate) >> 7) - (1 << 23);
8033 lc_symbol_freq =
8034 (u16) (frac28
8035 (channel->symbolrate +
8036 (adc_frequency >> 13),
8037 adc_frequency) >> 16);
8038 if (lc_symbol_freq > 511)
8039 lc_symbol_freq = 511;
8040
8041 iqm_rc_stretch = 21;
8042 }
8043
8044 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8045 set_env_parameters = QAM_TOP_ANNEX_A; /* annex */
8046 set_param_parameters[0] = channel->constellation; /* constellation */
8047 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
8048 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8049 set_env_parameters = QAM_TOP_ANNEX_B; /* annex */
8050 set_param_parameters[0] = channel->constellation; /* constellation */
8051 set_param_parameters[1] = channel->interleavemode; /* interleave mode */
8052 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8053 set_env_parameters = QAM_TOP_ANNEX_C; /* annex */
8054 set_param_parameters[0] = channel->constellation; /* constellation */
8055 set_param_parameters[1] = DRX_INTERLEAVEMODE_I12_J17; /* interleave mode */
8056 } else {
8057 return -EINVAL;
8058 }
8059 }
8060
8061 if (op & QAM_SET_OP_ALL) {
8062 /*
8063 STEP 1: reset demodulator
8064 resets IQM, QAM and FEC HW blocks
8065 resets SCU variables
8066 */
8067 /* stop all comm_exec */
8068 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP, 0);
8069 if (rc != 0) {
8070 pr_err("error %d\n", rc);
8071 goto rw_error;
8072 }
8073 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP, 0);
8074 if (rc != 0) {
8075 pr_err("error %d\n", rc);
8076 goto rw_error;
8077 }
8078 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
8079 if (rc != 0) {
8080 pr_err("error %d\n", rc);
8081 goto rw_error;
8082 }
8083 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
8084 if (rc != 0) {
8085 pr_err("error %d\n", rc);
8086 goto rw_error;
8087 }
8088 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
8089 if (rc != 0) {
8090 pr_err("error %d\n", rc);
8091 goto rw_error;
8092 }
8093 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
8094 if (rc != 0) {
8095 pr_err("error %d\n", rc);
8096 goto rw_error;
8097 }
8098 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
8099 if (rc != 0) {
8100 pr_err("error %d\n", rc);
8101 goto rw_error;
8102 }
8103
8104 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8105 SCU_RAM_COMMAND_CMD_DEMOD_RESET;
8106 cmd_scu.parameter_len = 0;
8107 cmd_scu.result_len = 1;
8108 cmd_scu.parameter = NULL;
8109 cmd_scu.result = &cmd_result;
8110 rc = scu_command(dev_addr, &cmd_scu);
8111 if (rc != 0) {
8112 pr_err("error %d\n", rc);
8113 goto rw_error;
8114 }
8115 }
8116
8117 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8118 /*
8119 STEP 2: configure demodulator
8120 -set env
8121 -set params (resets IQM,QAM,FEC HW; initializes some SCU variables )
8122 */
8123 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8124 SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
8125 cmd_scu.parameter_len = 1;
8126 cmd_scu.result_len = 1;
8127 cmd_scu.parameter = &set_env_parameters;
8128 cmd_scu.result = &cmd_result;
8129 rc = scu_command(dev_addr, &cmd_scu);
8130 if (rc != 0) {
8131 pr_err("error %d\n", rc);
8132 goto rw_error;
8133 }
8134
8135 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8136 SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM;
8137 cmd_scu.parameter_len = 2;
8138 cmd_scu.result_len = 1;
8139 cmd_scu.parameter = set_param_parameters;
8140 cmd_scu.result = &cmd_result;
8141 rc = scu_command(dev_addr, &cmd_scu);
8142 if (rc != 0) {
8143 pr_err("error %d\n", rc);
8144 goto rw_error;
8145 }
8146 /* set symbol rate */
8147 rc = drxdap_fasi_write_reg32(dev_addr, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate, 0);
8148 if (rc != 0) {
8149 pr_err("error %d\n", rc);
8150 goto rw_error;
8151 }
8152 ext_attr->iqm_rc_rate_ofs = iqm_rc_rate;
8153 rc = set_qam_measurement(demod, channel->constellation, channel->symbolrate);
8154 if (rc != 0) {
8155 pr_err("error %d\n", rc);
8156 goto rw_error;
8157 }
8158 }
8159 /* STEP 3: enable the system in a mode where the ADC provides valid signal
8160 setup constellation independent registers */
8161 /* from qam_cmd.py script (qam_driver_b) */
8162 /* TODO: remove re-writes of HW reset values */
8163 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_SPECTRUM)) {
8164 rc = set_frequency(demod, channel, tuner_freq_offset);
8165 if (rc != 0) {
8166 pr_err("error %d\n", rc);
8167 goto rw_error;
8168 }
8169 }
8170
8171 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8172
8173 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_SYMBOL_FREQ__A, lc_symbol_freq, 0);
8174 if (rc != 0) {
8175 pr_err("error %d\n", rc);
8176 goto rw_error;
8177 }
8178 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_STRETCH__A, iqm_rc_stretch, 0);
8179 if (rc != 0) {
8180 pr_err("error %d\n", rc);
8181 goto rw_error;
8182 }
8183 }
8184
8185 if (op & QAM_SET_OP_ALL) {
8186 if (!ext_attr->has_lna) {
8187 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_AMUX__A, 0x02, 0);
8188 if (rc != 0) {
8189 pr_err("error %d\n", rc);
8190 goto rw_error;
8191 }
8192 }
8193 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SYMMETRIC__A, 0, 0);
8194 if (rc != 0) {
8195 pr_err("error %d\n", rc);
8196 goto rw_error;
8197 }
8198 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_MIDTAP__A, 3, 0);
8199 if (rc != 0) {
8200 pr_err("error %d\n", rc);
8201 goto rw_error;
8202 }
8203 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_OUT_ENA__A, IQM_CF_OUT_ENA_QAM__M, 0);
8204 if (rc != 0) {
8205 pr_err("error %d\n", rc);
8206 goto rw_error;
8207 }
8208
8209 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_WR_RSV_0__A, 0x5f, 0);
8210 if (rc != 0) {
8211 pr_err("error %d\n", rc);
8212 goto rw_error;
8213 } /* scu temporary shut down agc */
8214
8215 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SYNC_SEL__A, 3, 0);
8216 if (rc != 0) {
8217 pr_err("error %d\n", rc);
8218 goto rw_error;
8219 }
8220 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_LEN__A, 0, 0);
8221 if (rc != 0) {
8222 pr_err("error %d\n", rc);
8223 goto rw_error;
8224 }
8225 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_CLP_TH__A, 448, 0);
8226 if (rc != 0) {
8227 pr_err("error %d\n", rc);
8228 goto rw_error;
8229 }
8230 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_SNS_LEN__A, 0, 0);
8231 if (rc != 0) {
8232 pr_err("error %d\n", rc);
8233 goto rw_error;
8234 }
8235 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, 4, 0);
8236 if (rc != 0) {
8237 pr_err("error %d\n", rc);
8238 goto rw_error;
8239 }
8240 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_STDBY__A, 0x10, 0);
8241 if (rc != 0) {
8242 pr_err("error %d\n", rc);
8243 goto rw_error;
8244 }
8245 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, 11, 0);
8246 if (rc != 0) {
8247 pr_err("error %d\n", rc);
8248 goto rw_error;
8249 }
8250
8251 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 1, 0);
8252 if (rc != 0) {
8253 pr_err("error %d\n", rc);
8254 goto rw_error;
8255 }
8256 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE, 0);
8257 if (rc != 0) {
8258 pr_err("error %d\n", rc);
8259 goto rw_error;
8260 } /*! reset default val ! */
8261
8262 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE, 0);
8263 if (rc != 0) {
8264 pr_err("error %d\n", rc);
8265 goto rw_error;
8266 } /*! reset default val ! */
8267 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8268 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, QAM_SY_SYNC_LWM__PRE, 0);
8269 if (rc != 0) {
8270 pr_err("error %d\n", rc);
8271 goto rw_error;
8272 } /*! reset default val ! */
8273 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, QAM_SY_SYNC_AWM__PRE, 0);
8274 if (rc != 0) {
8275 pr_err("error %d\n", rc);
8276 goto rw_error;
8277 } /*! reset default val ! */
8278 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
8279 if (rc != 0) {
8280 pr_err("error %d\n", rc);
8281 goto rw_error;
8282 } /*! reset default val ! */
8283 } else {
8284 switch (channel->constellation) {
8285 case DRX_CONSTELLATION_QAM16:
8286 case DRX_CONSTELLATION_QAM64:
8287 case DRX_CONSTELLATION_QAM256:
8288 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
8289 if (rc != 0) {
8290 pr_err("error %d\n", rc);
8291 goto rw_error;
8292 }
8293 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x04, 0);
8294 if (rc != 0) {
8295 pr_err("error %d\n", rc);
8296 goto rw_error;
8297 }
8298 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, QAM_SY_SYNC_HWM__PRE, 0);
8299 if (rc != 0) {
8300 pr_err("error %d\n", rc);
8301 goto rw_error;
8302 } /*! reset default val ! */
8303 break;
8304 case DRX_CONSTELLATION_QAM32:
8305 case DRX_CONSTELLATION_QAM128:
8306 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_LWM__A, 0x03, 0);
8307 if (rc != 0) {
8308 pr_err("error %d\n", rc);
8309 goto rw_error;
8310 }
8311 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_AWM__A, 0x05, 0);
8312 if (rc != 0) {
8313 pr_err("error %d\n", rc);
8314 goto rw_error;
8315 }
8316 rc = drxj_dap_write_reg16(dev_addr, QAM_SY_SYNC_HWM__A, 0x06, 0);
8317 if (rc != 0) {
8318 pr_err("error %d\n", rc);
8319 goto rw_error;
8320 }
8321 break;
8322 default:
8323 return -EIO;
8324 } /* switch */
8325 }
8326
8327 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, QAM_LC_MODE__PRE, 0);
8328 if (rc != 0) {
8329 pr_err("error %d\n", rc);
8330 goto rw_error;
8331 } /*! reset default val ! */
8332 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_RATE_LIMIT__A, 3, 0);
8333 if (rc != 0) {
8334 pr_err("error %d\n", rc);
8335 goto rw_error;
8336 }
8337 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORP__A, 4, 0);
8338 if (rc != 0) {
8339 pr_err("error %d\n", rc);
8340 goto rw_error;
8341 }
8342 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_LPF_FACTORI__A, 4, 0);
8343 if (rc != 0) {
8344 pr_err("error %d\n", rc);
8345 goto rw_error;
8346 }
8347 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_MODE__A, 7, 0);
8348 if (rc != 0) {
8349 pr_err("error %d\n", rc);
8350 goto rw_error;
8351 }
8352 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB0__A, 1, 0);
8353 if (rc != 0) {
8354 pr_err("error %d\n", rc);
8355 goto rw_error;
8356 }
8357 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB1__A, 1, 0);
8358 if (rc != 0) {
8359 pr_err("error %d\n", rc);
8360 goto rw_error;
8361 }
8362 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB2__A, 1, 0);
8363 if (rc != 0) {
8364 pr_err("error %d\n", rc);
8365 goto rw_error;
8366 }
8367 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB3__A, 1, 0);
8368 if (rc != 0) {
8369 pr_err("error %d\n", rc);
8370 goto rw_error;
8371 }
8372 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB4__A, 2, 0);
8373 if (rc != 0) {
8374 pr_err("error %d\n", rc);
8375 goto rw_error;
8376 }
8377 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB5__A, 2, 0);
8378 if (rc != 0) {
8379 pr_err("error %d\n", rc);
8380 goto rw_error;
8381 }
8382 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB6__A, 2, 0);
8383 if (rc != 0) {
8384 pr_err("error %d\n", rc);
8385 goto rw_error;
8386 }
8387 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB8__A, 2, 0);
8388 if (rc != 0) {
8389 pr_err("error %d\n", rc);
8390 goto rw_error;
8391 }
8392 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB9__A, 2, 0);
8393 if (rc != 0) {
8394 pr_err("error %d\n", rc);
8395 goto rw_error;
8396 }
8397 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB10__A, 2, 0);
8398 if (rc != 0) {
8399 pr_err("error %d\n", rc);
8400 goto rw_error;
8401 }
8402 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB12__A, 2, 0);
8403 if (rc != 0) {
8404 pr_err("error %d\n", rc);
8405 goto rw_error;
8406 }
8407 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB15__A, 3, 0);
8408 if (rc != 0) {
8409 pr_err("error %d\n", rc);
8410 goto rw_error;
8411 }
8412 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB16__A, 3, 0);
8413 if (rc != 0) {
8414 pr_err("error %d\n", rc);
8415 goto rw_error;
8416 }
8417 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB20__A, 4, 0);
8418 if (rc != 0) {
8419 pr_err("error %d\n", rc);
8420 goto rw_error;
8421 }
8422 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_QUAL_TAB25__A, 4, 0);
8423 if (rc != 0) {
8424 pr_err("error %d\n", rc);
8425 goto rw_error;
8426 }
8427
8428 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_ADJ_SEL__A, 1, 0);
8429 if (rc != 0) {
8430 pr_err("error %d\n", rc);
8431 goto rw_error;
8432 }
8433 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_ADJ_SEL__A, 1, 0);
8434 if (rc != 0) {
8435 pr_err("error %d\n", rc);
8436 goto rw_error;
8437 }
8438 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_ADJ_SEL__A, 1, 0);
8439 if (rc != 0) {
8440 pr_err("error %d\n", rc);
8441 goto rw_error;
8442 }
8443 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_POW_MEAS_LEN__A, 0, 0);
8444 if (rc != 0) {
8445 pr_err("error %d\n", rc);
8446 goto rw_error;
8447 }
8448 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_GPIO__A, 0, 0);
8449 if (rc != 0) {
8450 pr_err("error %d\n", rc);
8451 goto rw_error;
8452 }
8453
8454 /* No more resets of the IQM, current standard correctly set =>
8455 now AGCs can be configured. */
8456 /* turn on IQMAF. It has to be in front of setAgc**() */
8457 rc = set_iqm_af(demod, true);
8458 if (rc != 0) {
8459 pr_err("error %d\n", rc);
8460 goto rw_error;
8461 }
8462 rc = adc_synchronization(demod);
8463 if (rc != 0) {
8464 pr_err("error %d\n", rc);
8465 goto rw_error;
8466 }
8467
8468 rc = init_agc(demod);
8469 if (rc != 0) {
8470 pr_err("error %d\n", rc);
8471 goto rw_error;
8472 }
8473 rc = set_agc_if(demod, &(ext_attr->qam_if_agc_cfg), false);
8474 if (rc != 0) {
8475 pr_err("error %d\n", rc);
8476 goto rw_error;
8477 }
8478 rc = set_agc_rf(demod, &(ext_attr->qam_rf_agc_cfg), false);
8479 if (rc != 0) {
8480 pr_err("error %d\n", rc);
8481 goto rw_error;
8482 }
8483 {
8484 /* TODO fix this, store a struct drxj_cfg_afe_gain structure in struct drxj_data instead
8485 of only the gain */
8486 struct drxj_cfg_afe_gain qam_pga_cfg = { DRX_STANDARD_ITU_B, 0 };
8487
8488 qam_pga_cfg.gain = ext_attr->qam_pga_cfg;
8489 rc = ctrl_set_cfg_afe_gain(demod, &qam_pga_cfg);
8490 if (rc != 0) {
8491 pr_err("error %d\n", rc);
8492 goto rw_error;
8493 }
8494 }
8495 rc = ctrl_set_cfg_pre_saw(demod, &(ext_attr->qam_pre_saw_cfg));
8496 if (rc != 0) {
8497 pr_err("error %d\n", rc);
8498 goto rw_error;
8499 }
8500 }
8501
8502 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8503 if (ext_attr->standard == DRX_STANDARD_ITU_A) {
8504 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
8505 if (rc != 0) {
8506 pr_err("error %d\n", rc);
8507 goto rw_error;
8508 }
8509 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_a_taps), ((u8 *)qam_a_taps), 0);
8510 if (rc != 0) {
8511 pr_err("error %d\n", rc);
8512 goto rw_error;
8513 }
8514 } else if (ext_attr->standard == DRX_STANDARD_ITU_B) {
8515 switch (channel->constellation) {
8516 case DRX_CONSTELLATION_QAM64:
8517 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
8518 if (rc != 0) {
8519 pr_err("error %d\n", rc);
8520 goto rw_error;
8521 }
8522 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b64_taps), ((u8 *)qam_b64_taps), 0);
8523 if (rc != 0) {
8524 pr_err("error %d\n", rc);
8525 goto rw_error;
8526 }
8527 break;
8528 case DRX_CONSTELLATION_QAM256:
8529 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
8530 if (rc != 0) {
8531 pr_err("error %d\n", rc);
8532 goto rw_error;
8533 }
8534 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_b256_taps), ((u8 *)qam_b256_taps), 0);
8535 if (rc != 0) {
8536 pr_err("error %d\n", rc);
8537 goto rw_error;
8538 }
8539 break;
8540 default:
8541 return -EIO;
8542 }
8543 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
8544 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_RE0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
8545 if (rc != 0) {
8546 pr_err("error %d\n", rc);
8547 goto rw_error;
8548 }
8549 rc = drxdap_fasi_write_block(dev_addr, IQM_CF_TAP_IM0__A, sizeof(qam_c_taps), ((u8 *)qam_c_taps), 0);
8550 if (rc != 0) {
8551 pr_err("error %d\n", rc);
8552 goto rw_error;
8553 }
8554 }
8555
8556 /* SETP 4: constellation specific setup */
8557 switch (channel->constellation) {
8558 case DRX_CONSTELLATION_QAM16:
8559 rc = set_qam16(demod);
8560 if (rc != 0) {
8561 pr_err("error %d\n", rc);
8562 goto rw_error;
8563 }
8564 break;
8565 case DRX_CONSTELLATION_QAM32:
8566 rc = set_qam32(demod);
8567 if (rc != 0) {
8568 pr_err("error %d\n", rc);
8569 goto rw_error;
8570 }
8571 break;
8572 case DRX_CONSTELLATION_QAM64:
8573 rc = set_qam64(demod);
8574 if (rc != 0) {
8575 pr_err("error %d\n", rc);
8576 goto rw_error;
8577 }
8578 break;
8579 case DRX_CONSTELLATION_QAM128:
8580 rc = set_qam128(demod);
8581 if (rc != 0) {
8582 pr_err("error %d\n", rc);
8583 goto rw_error;
8584 }
8585 break;
8586 case DRX_CONSTELLATION_QAM256:
8587 rc = set_qam256(demod);
8588 if (rc != 0) {
8589 pr_err("error %d\n", rc);
8590 goto rw_error;
8591 }
8592 break;
8593 default:
8594 return -EIO;
8595 } /* switch */
8596 }
8597
8598 if ((op & QAM_SET_OP_ALL)) {
8599 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_SCALE_SH__A, 0, 0);
8600 if (rc != 0) {
8601 pr_err("error %d\n", rc);
8602 goto rw_error;
8603 }
8604
8605 /* Mpeg output has to be in front of FEC active */
8606 rc = set_mpegtei_handling(demod);
8607 if (rc != 0) {
8608 pr_err("error %d\n", rc);
8609 goto rw_error;
8610 }
8611 rc = bit_reverse_mpeg_output(demod);
8612 if (rc != 0) {
8613 pr_err("error %d\n", rc);
8614 goto rw_error;
8615 }
8616 rc = set_mpeg_start_width(demod);
8617 if (rc != 0) {
8618 pr_err("error %d\n", rc);
8619 goto rw_error;
8620 }
8621 {
8622 /* TODO: move to set_standard after hardware reset value problem is solved */
8623 /* Configure initial MPEG output */
8624 struct drx_cfg_mpeg_output cfg_mpeg_output;
8625
8626 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
8627 cfg_mpeg_output.enable_mpeg_output = true;
8628
8629 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
8630 if (rc != 0) {
8631 pr_err("error %d\n", rc);
8632 goto rw_error;
8633 }
8634 }
8635 }
8636
8637 if ((op & QAM_SET_OP_ALL) || (op & QAM_SET_OP_CONSTELLATION)) {
8638
8639 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
8640 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
8641 SCU_RAM_COMMAND_CMD_DEMOD_START;
8642 cmd_scu.parameter_len = 0;
8643 cmd_scu.result_len = 1;
8644 cmd_scu.parameter = NULL;
8645 cmd_scu.result = &cmd_result;
8646 rc = scu_command(dev_addr, &cmd_scu);
8647 if (rc != 0) {
8648 pr_err("error %d\n", rc);
8649 goto rw_error;
8650 }
8651 }
8652
8653 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_ACTIVE, 0);
8654 if (rc != 0) {
8655 pr_err("error %d\n", rc);
8656 goto rw_error;
8657 }
8658 rc = drxj_dap_write_reg16(dev_addr, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE, 0);
8659 if (rc != 0) {
8660 pr_err("error %d\n", rc);
8661 goto rw_error;
8662 }
8663 rc = drxj_dap_write_reg16(dev_addr, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE, 0);
8664 if (rc != 0) {
8665 pr_err("error %d\n", rc);
8666 goto rw_error;
8667 }
8668
8669 return 0;
8670 rw_error:
8671 return rc;
8672 }
8673
8674 /*============================================================================*/
8675 static int ctrl_get_qam_sig_quality(struct drx_demod_instance *demod);
8676
qam_flip_spec(struct drx_demod_instance * demod,struct drx_channel * channel)8677 static int qam_flip_spec(struct drx_demod_instance *demod, struct drx_channel *channel)
8678 {
8679 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8680 struct drxj_data *ext_attr = demod->my_ext_attr;
8681 int rc;
8682 u32 iqm_fs_rate_ofs = 0;
8683 u32 iqm_fs_rate_lo = 0;
8684 u16 qam_ctl_ena = 0;
8685 u16 data = 0;
8686 u16 equ_mode = 0;
8687 u16 fsm_state = 0;
8688 int i = 0;
8689 int ofsofs = 0;
8690
8691 /* Silence the controlling of lc, equ, and the acquisition state machine */
8692 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, &qam_ctl_ena, 0);
8693 if (rc != 0) {
8694 pr_err("error %d\n", rc);
8695 goto rw_error;
8696 }
8697 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, qam_ctl_ena & ~(SCU_RAM_QAM_CTL_ENA_ACQ__M | SCU_RAM_QAM_CTL_ENA_EQU__M | SCU_RAM_QAM_CTL_ENA_LC__M), 0);
8698 if (rc != 0) {
8699 pr_err("error %d\n", rc);
8700 goto rw_error;
8701 }
8702
8703 /* freeze the frequency control loop */
8704 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF__A, 0, 0);
8705 if (rc != 0) {
8706 pr_err("error %d\n", rc);
8707 goto rw_error;
8708 }
8709 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CF1__A, 0, 0);
8710 if (rc != 0) {
8711 pr_err("error %d\n", rc);
8712 goto rw_error;
8713 }
8714
8715 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, &iqm_fs_rate_ofs, 0);
8716 if (rc != 0) {
8717 pr_err("error %d\n", rc);
8718 goto rw_error;
8719 }
8720 rc = drxj_dap_atomic_read_reg32(dev_addr, IQM_FS_RATE_LO__A, &iqm_fs_rate_lo, 0);
8721 if (rc != 0) {
8722 pr_err("error %d\n", rc);
8723 goto rw_error;
8724 }
8725 ofsofs = iqm_fs_rate_lo - iqm_fs_rate_ofs;
8726 iqm_fs_rate_ofs = ~iqm_fs_rate_ofs + 1;
8727 iqm_fs_rate_ofs -= 2 * ofsofs;
8728
8729 /* freeze dq/fq updating */
8730 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
8731 if (rc != 0) {
8732 pr_err("error %d\n", rc);
8733 goto rw_error;
8734 }
8735 data = (data & 0xfff9);
8736 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8737 if (rc != 0) {
8738 pr_err("error %d\n", rc);
8739 goto rw_error;
8740 }
8741 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8742 if (rc != 0) {
8743 pr_err("error %d\n", rc);
8744 goto rw_error;
8745 }
8746
8747 /* lc_cp / _ci / _ca */
8748 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_CI__A, 0, 0);
8749 if (rc != 0) {
8750 pr_err("error %d\n", rc);
8751 goto rw_error;
8752 }
8753 rc = drxj_dap_write_reg16(dev_addr, QAM_LC_EP__A, 0, 0);
8754 if (rc != 0) {
8755 pr_err("error %d\n", rc);
8756 goto rw_error;
8757 }
8758 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_LA_FACTOR__A, 0, 0);
8759 if (rc != 0) {
8760 pr_err("error %d\n", rc);
8761 goto rw_error;
8762 }
8763
8764 /* flip the spec */
8765 rc = drxdap_fasi_write_reg32(dev_addr, IQM_FS_RATE_OFS_LO__A, iqm_fs_rate_ofs, 0);
8766 if (rc != 0) {
8767 pr_err("error %d\n", rc);
8768 goto rw_error;
8769 }
8770 ext_attr->iqm_fs_rate_ofs = iqm_fs_rate_ofs;
8771 ext_attr->pos_image = (ext_attr->pos_image) ? false : true;
8772
8773 /* freeze dq/fq updating */
8774 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_MODE__A, &data, 0);
8775 if (rc != 0) {
8776 pr_err("error %d\n", rc);
8777 goto rw_error;
8778 }
8779 equ_mode = data;
8780 data = (data & 0xfff9);
8781 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8782 if (rc != 0) {
8783 pr_err("error %d\n", rc);
8784 goto rw_error;
8785 }
8786 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8787 if (rc != 0) {
8788 pr_err("error %d\n", rc);
8789 goto rw_error;
8790 }
8791
8792 for (i = 0; i < 28; i++) {
8793 rc = drxj_dap_read_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), &data, 0);
8794 if (rc != 0) {
8795 pr_err("error %d\n", rc);
8796 goto rw_error;
8797 }
8798 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_TAP_IM_EL0__A + (2 * i), -data, 0);
8799 if (rc != 0) {
8800 pr_err("error %d\n", rc);
8801 goto rw_error;
8802 }
8803 }
8804
8805 for (i = 0; i < 24; i++) {
8806 rc = drxj_dap_read_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), &data, 0);
8807 if (rc != 0) {
8808 pr_err("error %d\n", rc);
8809 goto rw_error;
8810 }
8811 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_TAP_IM_EL0__A + (2 * i), -data, 0);
8812 if (rc != 0) {
8813 pr_err("error %d\n", rc);
8814 goto rw_error;
8815 }
8816 }
8817
8818 data = equ_mode;
8819 rc = drxj_dap_write_reg16(dev_addr, QAM_DQ_MODE__A, data, 0);
8820 if (rc != 0) {
8821 pr_err("error %d\n", rc);
8822 goto rw_error;
8823 }
8824 rc = drxj_dap_write_reg16(dev_addr, QAM_FQ_MODE__A, data, 0);
8825 if (rc != 0) {
8826 pr_err("error %d\n", rc);
8827 goto rw_error;
8828 }
8829
8830 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE_TGT__A, 4, 0);
8831 if (rc != 0) {
8832 pr_err("error %d\n", rc);
8833 goto rw_error;
8834 }
8835
8836 i = 0;
8837 while ((fsm_state != 4) && (i++ < 100)) {
8838 rc = drxj_dap_read_reg16(dev_addr, SCU_RAM_QAM_FSM_STATE__A, &fsm_state, 0);
8839 if (rc != 0) {
8840 pr_err("error %d\n", rc);
8841 goto rw_error;
8842 }
8843 }
8844 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_QAM_CTL_ENA__A, (qam_ctl_ena | 0x0016), 0);
8845 if (rc != 0) {
8846 pr_err("error %d\n", rc);
8847 goto rw_error;
8848 }
8849
8850 return 0;
8851 rw_error:
8852 return rc;
8853
8854 }
8855
8856 #define NO_LOCK 0x0
8857 #define DEMOD_LOCKED 0x1
8858 #define SYNC_FLIPPED 0x2
8859 #define SPEC_MIRRORED 0x4
8860 /*
8861 * \fn int qam64auto ()
8862 * \brief auto do sync pattern switching and mirroring.
8863 * \param demod: instance of demod.
8864 * \param channel: pointer to channel data.
8865 * \param tuner_freq_offset: tuner frequency offset.
8866 * \param lock_status: pointer to lock status.
8867 * \return int.
8868 */
8869 static int
qam64auto(struct drx_demod_instance * demod,struct drx_channel * channel,s32 tuner_freq_offset,enum drx_lock_status * lock_status)8870 qam64auto(struct drx_demod_instance *demod,
8871 struct drx_channel *channel,
8872 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
8873 {
8874 struct drxj_data *ext_attr = demod->my_ext_attr;
8875 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
8876 struct drx39xxj_state *state = dev_addr->user_data;
8877 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
8878 int rc;
8879 u32 lck_state = NO_LOCK;
8880 u32 start_time = 0;
8881 u32 d_locked_time = 0;
8882 u32 timeout_ofs = 0;
8883 u16 data = 0;
8884
8885 /* external attributes for storing acquired channel constellation */
8886 *lock_status = DRX_NOT_LOCKED;
8887 start_time = jiffies_to_msecs(jiffies);
8888 lck_state = NO_LOCK;
8889 do {
8890 rc = ctrl_lock_status(demod, lock_status);
8891 if (rc != 0) {
8892 pr_err("error %d\n", rc);
8893 goto rw_error;
8894 }
8895
8896 switch (lck_state) {
8897 case NO_LOCK:
8898 if (*lock_status == DRXJ_DEMOD_LOCK) {
8899 rc = ctrl_get_qam_sig_quality(demod);
8900 if (rc != 0) {
8901 pr_err("error %d\n", rc);
8902 goto rw_error;
8903 }
8904 if (p->cnr.stat[0].svalue > 20800) {
8905 lck_state = DEMOD_LOCKED;
8906 /* some delay to see if fec_lock possible TODO find the right value */
8907 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, waiting longer */
8908 d_locked_time = jiffies_to_msecs(jiffies);
8909 }
8910 }
8911 break;
8912 case DEMOD_LOCKED:
8913 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
8914 ((jiffies_to_msecs(jiffies) - d_locked_time) >
8915 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8916 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8917 if (rc != 0) {
8918 pr_err("error %d\n", rc);
8919 goto rw_error;
8920 }
8921 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
8922 if (rc != 0) {
8923 pr_err("error %d\n", rc);
8924 goto rw_error;
8925 }
8926 lck_state = SYNC_FLIPPED;
8927 msleep(10);
8928 }
8929 break;
8930 case SYNC_FLIPPED:
8931 if (*lock_status == DRXJ_DEMOD_LOCK) {
8932 if (channel->mirror == DRX_MIRROR_AUTO) {
8933 /* flip sync pattern back */
8934 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8935 if (rc != 0) {
8936 pr_err("error %d\n", rc);
8937 goto rw_error;
8938 }
8939 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data & 0xFFFE, 0);
8940 if (rc != 0) {
8941 pr_err("error %d\n", rc);
8942 goto rw_error;
8943 }
8944 /* flip spectrum */
8945 ext_attr->mirror = DRX_MIRROR_YES;
8946 rc = qam_flip_spec(demod, channel);
8947 if (rc != 0) {
8948 pr_err("error %d\n", rc);
8949 goto rw_error;
8950 }
8951 lck_state = SPEC_MIRRORED;
8952 /* reset timer TODO: still need 500ms? */
8953 start_time = d_locked_time =
8954 jiffies_to_msecs(jiffies);
8955 timeout_ofs = 0;
8956 } else { /* no need to wait lock */
8957
8958 start_time =
8959 jiffies_to_msecs(jiffies) -
8960 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
8961 }
8962 }
8963 break;
8964 case SPEC_MIRRORED:
8965 if ((*lock_status == DRXJ_DEMOD_LOCK) && /* still demod_lock in 150ms */
8966 ((jiffies_to_msecs(jiffies) - d_locked_time) >
8967 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
8968 rc = ctrl_get_qam_sig_quality(demod);
8969 if (rc != 0) {
8970 pr_err("error %d\n", rc);
8971 goto rw_error;
8972 }
8973 if (p->cnr.stat[0].svalue > 20800) {
8974 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, &data, 0);
8975 if (rc != 0) {
8976 pr_err("error %d\n", rc);
8977 goto rw_error;
8978 }
8979 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr, QAM_SY_TIMEOUT__A, data | 0x1, 0);
8980 if (rc != 0) {
8981 pr_err("error %d\n", rc);
8982 goto rw_error;
8983 }
8984 /* no need to wait lock */
8985 start_time =
8986 jiffies_to_msecs(jiffies) -
8987 DRXJ_QAM_MAX_WAITTIME - timeout_ofs;
8988 }
8989 }
8990 break;
8991 default:
8992 break;
8993 }
8994 msleep(10);
8995 } while
8996 ((*lock_status != DRX_LOCKED) &&
8997 (*lock_status != DRX_NEVER_LOCK) &&
8998 ((jiffies_to_msecs(jiffies) - start_time) <
8999 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs))
9000 );
9001 /* Returning control to application ... */
9002
9003 return 0;
9004 rw_error:
9005 return rc;
9006 }
9007
9008 /*
9009 * \fn int qam256auto ()
9010 * \brief auto do sync pattern switching and mirroring.
9011 * \param demod: instance of demod.
9012 * \param channel: pointer to channel data.
9013 * \param tuner_freq_offset: tuner frequency offset.
9014 * \param lock_status: pointer to lock status.
9015 * \return int.
9016 */
9017 static int
qam256auto(struct drx_demod_instance * demod,struct drx_channel * channel,s32 tuner_freq_offset,enum drx_lock_status * lock_status)9018 qam256auto(struct drx_demod_instance *demod,
9019 struct drx_channel *channel,
9020 s32 tuner_freq_offset, enum drx_lock_status *lock_status)
9021 {
9022 struct drxj_data *ext_attr = demod->my_ext_attr;
9023 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9024 struct drx39xxj_state *state = dev_addr->user_data;
9025 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9026 int rc;
9027 u32 lck_state = NO_LOCK;
9028 u32 start_time = 0;
9029 u32 d_locked_time = 0;
9030 u32 timeout_ofs = DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME;
9031
9032 /* external attributes for storing acquired channel constellation */
9033 *lock_status = DRX_NOT_LOCKED;
9034 start_time = jiffies_to_msecs(jiffies);
9035 lck_state = NO_LOCK;
9036 do {
9037 rc = ctrl_lock_status(demod, lock_status);
9038 if (rc != 0) {
9039 pr_err("error %d\n", rc);
9040 goto rw_error;
9041 }
9042 switch (lck_state) {
9043 case NO_LOCK:
9044 if (*lock_status == DRXJ_DEMOD_LOCK) {
9045 rc = ctrl_get_qam_sig_quality(demod);
9046 if (rc != 0) {
9047 pr_err("error %d\n", rc);
9048 goto rw_error;
9049 }
9050 if (p->cnr.stat[0].svalue > 26800) {
9051 lck_state = DEMOD_LOCKED;
9052 timeout_ofs += DRXJ_QAM_DEMOD_LOCK_EXT_WAITTIME; /* see something, wait longer */
9053 d_locked_time = jiffies_to_msecs(jiffies);
9054 }
9055 }
9056 break;
9057 case DEMOD_LOCKED:
9058 if (*lock_status == DRXJ_DEMOD_LOCK) {
9059 if ((channel->mirror == DRX_MIRROR_AUTO) &&
9060 ((jiffies_to_msecs(jiffies) - d_locked_time) >
9061 DRXJ_QAM_FEC_LOCK_WAITTIME)) {
9062 ext_attr->mirror = DRX_MIRROR_YES;
9063 rc = qam_flip_spec(demod, channel);
9064 if (rc != 0) {
9065 pr_err("error %d\n", rc);
9066 goto rw_error;
9067 }
9068 lck_state = SPEC_MIRRORED;
9069 /* reset timer TODO: still need 300ms? */
9070 start_time = jiffies_to_msecs(jiffies);
9071 timeout_ofs = -DRXJ_QAM_MAX_WAITTIME / 2;
9072 }
9073 }
9074 break;
9075 case SPEC_MIRRORED:
9076 break;
9077 default:
9078 break;
9079 }
9080 msleep(10);
9081 } while
9082 ((*lock_status < DRX_LOCKED) &&
9083 (*lock_status != DRX_NEVER_LOCK) &&
9084 ((jiffies_to_msecs(jiffies) - start_time) <
9085 (DRXJ_QAM_MAX_WAITTIME + timeout_ofs)));
9086
9087 return 0;
9088 rw_error:
9089 return rc;
9090 }
9091
9092 /*
9093 * \fn int set_qam_channel ()
9094 * \brief Set QAM channel according to the requested constellation.
9095 * \param demod: instance of demod.
9096 * \param channel: pointer to channel data.
9097 * \return int.
9098 */
9099 static int
set_qam_channel(struct drx_demod_instance * demod,struct drx_channel * channel,s32 tuner_freq_offset)9100 set_qam_channel(struct drx_demod_instance *demod,
9101 struct drx_channel *channel, s32 tuner_freq_offset)
9102 {
9103 struct drxj_data *ext_attr = NULL;
9104 int rc;
9105 enum drx_lock_status lock_status = DRX_NOT_LOCKED;
9106 bool auto_flag = false;
9107
9108 /* external attributes for storing acquired channel constellation */
9109 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9110
9111 /* set QAM channel constellation */
9112 switch (channel->constellation) {
9113 case DRX_CONSTELLATION_QAM16:
9114 case DRX_CONSTELLATION_QAM32:
9115 case DRX_CONSTELLATION_QAM128:
9116 return -EINVAL;
9117 case DRX_CONSTELLATION_QAM64:
9118 case DRX_CONSTELLATION_QAM256:
9119 if (ext_attr->standard != DRX_STANDARD_ITU_B)
9120 return -EINVAL;
9121
9122 ext_attr->constellation = channel->constellation;
9123 if (channel->mirror == DRX_MIRROR_AUTO)
9124 ext_attr->mirror = DRX_MIRROR_NO;
9125 else
9126 ext_attr->mirror = channel->mirror;
9127
9128 rc = set_qam(demod, channel, tuner_freq_offset, QAM_SET_OP_ALL);
9129 if (rc != 0) {
9130 pr_err("error %d\n", rc);
9131 goto rw_error;
9132 }
9133
9134 if (channel->constellation == DRX_CONSTELLATION_QAM64)
9135 rc = qam64auto(demod, channel, tuner_freq_offset,
9136 &lock_status);
9137 else
9138 rc = qam256auto(demod, channel, tuner_freq_offset,
9139 &lock_status);
9140 if (rc != 0) {
9141 pr_err("error %d\n", rc);
9142 goto rw_error;
9143 }
9144 break;
9145 case DRX_CONSTELLATION_AUTO: /* for channel scan */
9146 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9147 u16 qam_ctl_ena = 0;
9148
9149 auto_flag = true;
9150
9151 /* try to lock default QAM constellation: QAM256 */
9152 channel->constellation = DRX_CONSTELLATION_QAM256;
9153 ext_attr->constellation = DRX_CONSTELLATION_QAM256;
9154 if (channel->mirror == DRX_MIRROR_AUTO)
9155 ext_attr->mirror = DRX_MIRROR_NO;
9156 else
9157 ext_attr->mirror = channel->mirror;
9158 rc = set_qam(demod, channel, tuner_freq_offset,
9159 QAM_SET_OP_ALL);
9160 if (rc != 0) {
9161 pr_err("error %d\n", rc);
9162 goto rw_error;
9163 }
9164 rc = qam256auto(demod, channel, tuner_freq_offset,
9165 &lock_status);
9166 if (rc != 0) {
9167 pr_err("error %d\n", rc);
9168 goto rw_error;
9169 }
9170
9171 if (lock_status >= DRX_LOCKED) {
9172 channel->constellation = DRX_CONSTELLATION_AUTO;
9173 break;
9174 }
9175
9176 /* QAM254 not locked. Try QAM64 constellation */
9177 channel->constellation = DRX_CONSTELLATION_QAM64;
9178 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9179 if (channel->mirror == DRX_MIRROR_AUTO)
9180 ext_attr->mirror = DRX_MIRROR_NO;
9181 else
9182 ext_attr->mirror = channel->mirror;
9183
9184 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
9185 SCU_RAM_QAM_CTL_ENA__A,
9186 &qam_ctl_ena, 0);
9187 if (rc != 0) {
9188 pr_err("error %d\n", rc);
9189 goto rw_error;
9190 }
9191 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9192 SCU_RAM_QAM_CTL_ENA__A,
9193 qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9194 if (rc != 0) {
9195 pr_err("error %d\n", rc);
9196 goto rw_error;
9197 }
9198 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9199 SCU_RAM_QAM_FSM_STATE_TGT__A,
9200 0x2, 0);
9201 if (rc != 0) {
9202 pr_err("error %d\n", rc);
9203 goto rw_error;
9204 } /* force to rate hunting */
9205
9206 rc = set_qam(demod, channel, tuner_freq_offset,
9207 QAM_SET_OP_CONSTELLATION);
9208 if (rc != 0) {
9209 pr_err("error %d\n", rc);
9210 goto rw_error;
9211 }
9212 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9213 SCU_RAM_QAM_CTL_ENA__A,
9214 qam_ctl_ena, 0);
9215 if (rc != 0) {
9216 pr_err("error %d\n", rc);
9217 goto rw_error;
9218 }
9219
9220 rc = qam64auto(demod, channel, tuner_freq_offset,
9221 &lock_status);
9222 if (rc != 0) {
9223 pr_err("error %d\n", rc);
9224 goto rw_error;
9225 }
9226
9227 channel->constellation = DRX_CONSTELLATION_AUTO;
9228 } else if (ext_attr->standard == DRX_STANDARD_ITU_C) {
9229 u16 qam_ctl_ena = 0;
9230
9231 channel->constellation = DRX_CONSTELLATION_QAM64;
9232 ext_attr->constellation = DRX_CONSTELLATION_QAM64;
9233 auto_flag = true;
9234
9235 if (channel->mirror == DRX_MIRROR_AUTO)
9236 ext_attr->mirror = DRX_MIRROR_NO;
9237 else
9238 ext_attr->mirror = channel->mirror;
9239 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr,
9240 SCU_RAM_QAM_CTL_ENA__A,
9241 &qam_ctl_ena, 0);
9242 if (rc != 0) {
9243 pr_err("error %d\n", rc);
9244 goto rw_error;
9245 }
9246 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9247 SCU_RAM_QAM_CTL_ENA__A,
9248 qam_ctl_ena & ~SCU_RAM_QAM_CTL_ENA_ACQ__M, 0);
9249 if (rc != 0) {
9250 pr_err("error %d\n", rc);
9251 goto rw_error;
9252 }
9253 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9254 SCU_RAM_QAM_FSM_STATE_TGT__A,
9255 0x2, 0);
9256 if (rc != 0) {
9257 pr_err("error %d\n", rc);
9258 goto rw_error;
9259 } /* force to rate hunting */
9260
9261 rc = set_qam(demod, channel, tuner_freq_offset,
9262 QAM_SET_OP_CONSTELLATION);
9263 if (rc != 0) {
9264 pr_err("error %d\n", rc);
9265 goto rw_error;
9266 }
9267 rc = drxj_dap_write_reg16(demod->my_i2c_dev_addr,
9268 SCU_RAM_QAM_CTL_ENA__A,
9269 qam_ctl_ena, 0);
9270 if (rc != 0) {
9271 pr_err("error %d\n", rc);
9272 goto rw_error;
9273 }
9274 rc = qam64auto(demod, channel, tuner_freq_offset,
9275 &lock_status);
9276 if (rc != 0) {
9277 pr_err("error %d\n", rc);
9278 goto rw_error;
9279 }
9280 channel->constellation = DRX_CONSTELLATION_AUTO;
9281 } else {
9282 return -EINVAL;
9283 }
9284 break;
9285 default:
9286 return -EINVAL;
9287 }
9288
9289 return 0;
9290 rw_error:
9291 /* restore starting value */
9292 if (auto_flag)
9293 channel->constellation = DRX_CONSTELLATION_AUTO;
9294 return rc;
9295 }
9296
9297 /*============================================================================*/
9298
9299 /*
9300 * \fn static short get_qamrs_err_count(struct i2c_device_addr *dev_addr)
9301 * \brief Get RS error count in QAM mode (used for post RS BER calculation)
9302 * \return Error code
9303 *
9304 * precondition: measurement period & measurement prescale must be set
9305 *
9306 */
9307 static int
get_qamrs_err_count(struct i2c_device_addr * dev_addr,struct drxjrs_errors * rs_errors)9308 get_qamrs_err_count(struct i2c_device_addr *dev_addr,
9309 struct drxjrs_errors *rs_errors)
9310 {
9311 int rc;
9312 u16 nr_bit_errors = 0,
9313 nr_symbol_errors = 0,
9314 nr_packet_errors = 0, nr_failures = 0, nr_snc_par_fail_count = 0;
9315
9316 /* check arguments */
9317 if (dev_addr == NULL)
9318 return -EINVAL;
9319
9320 /* all reported errors are received in the */
9321 /* most recently finished measurement period */
9322 /* no of pre RS bit errors */
9323 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_BIT_ERRORS__A, &nr_bit_errors, 0);
9324 if (rc != 0) {
9325 pr_err("error %d\n", rc);
9326 goto rw_error;
9327 }
9328 /* no of symbol errors */
9329 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_SYMBOL_ERRORS__A, &nr_symbol_errors, 0);
9330 if (rc != 0) {
9331 pr_err("error %d\n", rc);
9332 goto rw_error;
9333 }
9334 /* no of packet errors */
9335 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_PACKET_ERRORS__A, &nr_packet_errors, 0);
9336 if (rc != 0) {
9337 pr_err("error %d\n", rc);
9338 goto rw_error;
9339 }
9340 /* no of failures to decode */
9341 rc = drxj_dap_read_reg16(dev_addr, FEC_RS_NR_FAILURES__A, &nr_failures, 0);
9342 if (rc != 0) {
9343 pr_err("error %d\n", rc);
9344 goto rw_error;
9345 }
9346 /* no of post RS bit erros */
9347 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_COUNT__A, &nr_snc_par_fail_count, 0);
9348 if (rc != 0) {
9349 pr_err("error %d\n", rc);
9350 goto rw_error;
9351 }
9352 /* TODO: NOTE */
9353 /* These register values are fetched in non-atomic fashion */
9354 /* It is possible that the read values contain unrelated information */
9355
9356 rs_errors->nr_bit_errors = nr_bit_errors & FEC_RS_NR_BIT_ERRORS__M;
9357 rs_errors->nr_symbol_errors = nr_symbol_errors & FEC_RS_NR_SYMBOL_ERRORS__M;
9358 rs_errors->nr_packet_errors = nr_packet_errors & FEC_RS_NR_PACKET_ERRORS__M;
9359 rs_errors->nr_failures = nr_failures & FEC_RS_NR_FAILURES__M;
9360 rs_errors->nr_snc_par_fail_count =
9361 nr_snc_par_fail_count & FEC_OC_SNC_FAIL_COUNT__M;
9362
9363 return 0;
9364 rw_error:
9365 return rc;
9366 }
9367
9368 /*============================================================================*/
9369
9370 /*
9371 * \fn int get_sig_strength()
9372 * \brief Retrieve signal strength for VSB and QAM.
9373 * \param demod Pointer to demod instance
9374 * \param u16-t Pointer to signal strength data; range 0, .. , 100.
9375 * \return int.
9376 * \retval 0 sig_strength contains valid data.
9377 * \retval -EINVAL sig_strength is NULL.
9378 * \retval -EIO Erroneous data, sig_strength contains invalid data.
9379 */
9380 #define DRXJ_AGC_TOP 0x2800
9381 #define DRXJ_AGC_SNS 0x1600
9382 #define DRXJ_RFAGC_MAX 0x3fff
9383 #define DRXJ_RFAGC_MIN 0x800
9384
get_sig_strength(struct drx_demod_instance * demod,u16 * sig_strength)9385 static int get_sig_strength(struct drx_demod_instance *demod, u16 *sig_strength)
9386 {
9387 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9388 int rc;
9389 u16 rf_gain = 0;
9390 u16 if_gain = 0;
9391 u16 if_agc_sns = 0;
9392 u16 if_agc_top = 0;
9393 u16 rf_agc_max = 0;
9394 u16 rf_agc_min = 0;
9395
9396 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_IF__A, &if_gain, 0);
9397 if (rc != 0) {
9398 pr_err("error %d\n", rc);
9399 goto rw_error;
9400 }
9401 if_gain &= IQM_AF_AGC_IF__M;
9402 rc = drxj_dap_read_reg16(dev_addr, IQM_AF_AGC_RF__A, &rf_gain, 0);
9403 if (rc != 0) {
9404 pr_err("error %d\n", rc);
9405 goto rw_error;
9406 }
9407 rf_gain &= IQM_AF_AGC_RF__M;
9408
9409 if_agc_sns = DRXJ_AGC_SNS;
9410 if_agc_top = DRXJ_AGC_TOP;
9411 rf_agc_max = DRXJ_RFAGC_MAX;
9412 rf_agc_min = DRXJ_RFAGC_MIN;
9413
9414 if (if_gain > if_agc_top) {
9415 if (rf_gain > rf_agc_max)
9416 *sig_strength = 100;
9417 else if (rf_gain > rf_agc_min) {
9418 if (rf_agc_max == rf_agc_min) {
9419 pr_err("error: rf_agc_max == rf_agc_min\n");
9420 return -EIO;
9421 }
9422 *sig_strength =
9423 75 + 25 * (rf_gain - rf_agc_min) / (rf_agc_max -
9424 rf_agc_min);
9425 } else
9426 *sig_strength = 75;
9427 } else if (if_gain > if_agc_sns) {
9428 if (if_agc_top == if_agc_sns) {
9429 pr_err("error: if_agc_top == if_agc_sns\n");
9430 return -EIO;
9431 }
9432 *sig_strength =
9433 20 + 55 * (if_gain - if_agc_sns) / (if_agc_top - if_agc_sns);
9434 } else {
9435 if (!if_agc_sns) {
9436 pr_err("error: if_agc_sns is zero!\n");
9437 return -EIO;
9438 }
9439 *sig_strength = (20 * if_gain / if_agc_sns);
9440 }
9441
9442 if (*sig_strength <= 7)
9443 *sig_strength = 0;
9444
9445 return 0;
9446 rw_error:
9447 return rc;
9448 }
9449
9450 /*
9451 * \fn int ctrl_get_qam_sig_quality()
9452 * \brief Retrieve QAM signal quality from device.
9453 * \param devmod Pointer to demodulator instance.
9454 * \param sig_quality Pointer to signal quality data.
9455 * \return int.
9456 * \retval 0 sig_quality contains valid data.
9457 * \retval -EINVAL sig_quality is NULL.
9458 * \retval -EIO Erroneous data, sig_quality contains invalid data.
9459
9460 * Pre-condition: Device must be started and in lock.
9461 */
9462 static int
ctrl_get_qam_sig_quality(struct drx_demod_instance * demod)9463 ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
9464 {
9465 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9466 struct drxj_data *ext_attr = demod->my_ext_attr;
9467 struct drx39xxj_state *state = dev_addr->user_data;
9468 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
9469 struct drxjrs_errors measuredrs_errors = { 0, 0, 0, 0, 0 };
9470 enum drx_modulation constellation = ext_attr->constellation;
9471 int rc;
9472
9473 u32 pre_bit_err_rs = 0; /* pre RedSolomon Bit Error Rate */
9474 u32 post_bit_err_rs = 0; /* post RedSolomon Bit Error Rate */
9475 u32 pkt_errs = 0; /* no of packet errors in RS */
9476 u16 qam_sl_err_power = 0; /* accumulated error between raw and sliced symbols */
9477 u16 qsym_err_vd = 0; /* quadrature symbol errors in QAM_VD */
9478 u16 fec_oc_period = 0; /* SNC sync failure measurement period */
9479 u16 fec_rs_prescale = 0; /* ReedSolomon Measurement Prescale */
9480 u16 fec_rs_period = 0; /* Value for corresponding I2C register */
9481 /* calculation constants */
9482 u32 rs_bit_cnt = 0; /* RedSolomon Bit Count */
9483 u32 qam_sl_sig_power = 0; /* used for MER, depends of QAM constellation */
9484 /* intermediate results */
9485 u32 e = 0; /* exponent value used for QAM BER/SER */
9486 u32 m = 0; /* mantisa value used for QAM BER/SER */
9487 u32 ber_cnt = 0; /* BER count */
9488 /* signal quality info */
9489 u32 qam_sl_mer = 0; /* QAM MER */
9490 u32 qam_pre_rs_ber = 0; /* Pre RedSolomon BER */
9491 u32 qam_post_rs_ber = 0; /* Post RedSolomon BER */
9492 u32 qam_vd_ser = 0; /* ViterbiDecoder SER */
9493 u16 qam_vd_prescale = 0; /* Viterbi Measurement Prescale */
9494 u16 qam_vd_period = 0; /* Viterbi Measurement period */
9495 u32 vd_bit_cnt = 0; /* ViterbiDecoder Bit Count */
9496
9497 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9498
9499 /* read the physical registers */
9500 /* Get the RS error data */
9501 rc = get_qamrs_err_count(dev_addr, &measuredrs_errors);
9502 if (rc != 0) {
9503 pr_err("error %d\n", rc);
9504 goto rw_error;
9505 }
9506 /* get the register value needed for MER */
9507 rc = drxj_dap_read_reg16(dev_addr, QAM_SL_ERR_POWER__A, &qam_sl_err_power, 0);
9508 if (rc != 0) {
9509 pr_err("error %d\n", rc);
9510 goto rw_error;
9511 }
9512 /* get the register value needed for post RS BER */
9513 rc = drxj_dap_read_reg16(dev_addr, FEC_OC_SNC_FAIL_PERIOD__A, &fec_oc_period, 0);
9514 if (rc != 0) {
9515 pr_err("error %d\n", rc);
9516 goto rw_error;
9517 }
9518
9519 /* get constants needed for signal quality calculation */
9520 fec_rs_period = ext_attr->fec_rs_period;
9521 fec_rs_prescale = ext_attr->fec_rs_prescale;
9522 rs_bit_cnt = fec_rs_period * fec_rs_prescale * ext_attr->fec_rs_plen;
9523 qam_vd_period = ext_attr->qam_vd_period;
9524 qam_vd_prescale = ext_attr->qam_vd_prescale;
9525 vd_bit_cnt = qam_vd_period * qam_vd_prescale * ext_attr->fec_vd_plen;
9526
9527 /* DRXJ_QAM_SL_SIG_POWER_QAMxxx * 4 */
9528 switch (constellation) {
9529 case DRX_CONSTELLATION_QAM16:
9530 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM16 << 2;
9531 break;
9532 case DRX_CONSTELLATION_QAM32:
9533 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM32 << 2;
9534 break;
9535 case DRX_CONSTELLATION_QAM64:
9536 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM64 << 2;
9537 break;
9538 case DRX_CONSTELLATION_QAM128:
9539 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM128 << 2;
9540 break;
9541 case DRX_CONSTELLATION_QAM256:
9542 qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
9543 break;
9544 default:
9545 return -EIO;
9546 }
9547
9548 /* ------------------------------ */
9549 /* MER Calculation */
9550 /* ------------------------------ */
9551 /* MER is good if it is above 27.5 for QAM256 or 21.5 for QAM64 */
9552
9553 /* 10.0*log10(qam_sl_sig_power * 4.0 / qam_sl_err_power); */
9554 if (qam_sl_err_power == 0)
9555 qam_sl_mer = 0;
9556 else
9557 qam_sl_mer = log1_times100(qam_sl_sig_power) - log1_times100((u32)qam_sl_err_power);
9558
9559 /* ----------------------------------------- */
9560 /* Pre Viterbi Symbol Error Rate Calculation */
9561 /* ----------------------------------------- */
9562 /* pre viterbi SER is good if it is below 0.025 */
9563
9564 /* get the register value */
9565 /* no of quadrature symbol errors */
9566 rc = drxj_dap_read_reg16(dev_addr, QAM_VD_NR_QSYM_ERRORS__A, &qsym_err_vd, 0);
9567 if (rc != 0) {
9568 pr_err("error %d\n", rc);
9569 goto rw_error;
9570 }
9571 /* Extract the Exponent and the Mantisa */
9572 /* of number of quadrature symbol errors */
9573 e = (qsym_err_vd & QAM_VD_NR_QSYM_ERRORS_EXP__M) >>
9574 QAM_VD_NR_QSYM_ERRORS_EXP__B;
9575 m = (qsym_err_vd & QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__M) >>
9576 QAM_VD_NR_SYMBOL_ERRORS_FIXED_MANT__B;
9577
9578 if ((m << e) >> 3 > 549752)
9579 qam_vd_ser = 500000 * vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9580 else
9581 qam_vd_ser = m << ((e > 2) ? (e - 3) : e);
9582
9583 /* --------------------------------------- */
9584 /* pre and post RedSolomon BER Calculation */
9585 /* --------------------------------------- */
9586 /* pre RS BER is good if it is below 3.5e-4 */
9587
9588 /* get the register values */
9589 pre_bit_err_rs = (u32) measuredrs_errors.nr_bit_errors;
9590 pkt_errs = post_bit_err_rs = (u32) measuredrs_errors.nr_snc_par_fail_count;
9591
9592 /* Extract the Exponent and the Mantisa of the */
9593 /* pre Reed-Solomon bit error count */
9594 e = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_EXP__M) >>
9595 FEC_RS_NR_BIT_ERRORS_EXP__B;
9596 m = (pre_bit_err_rs & FEC_RS_NR_BIT_ERRORS_FIXED_MANT__M) >>
9597 FEC_RS_NR_BIT_ERRORS_FIXED_MANT__B;
9598
9599 ber_cnt = m << e;
9600
9601 /*qam_pre_rs_ber = frac_times1e6( ber_cnt, rs_bit_cnt ); */
9602 if (m > (rs_bit_cnt >> (e + 1)) || (rs_bit_cnt >> e) == 0)
9603 qam_pre_rs_ber = 500000 * rs_bit_cnt >> e;
9604 else
9605 qam_pre_rs_ber = ber_cnt;
9606
9607 /* post RS BER = 1000000* (11.17 * FEC_OC_SNC_FAIL_COUNT__A) / */
9608 /* (1504.0 * FEC_OC_SNC_FAIL_PERIOD__A) */
9609 /*
9610 => c = (1000000*100*11.17)/1504 =
9611 post RS BER = (( c* FEC_OC_SNC_FAIL_COUNT__A) /
9612 (100 * FEC_OC_SNC_FAIL_PERIOD__A)
9613 *100 and /100 is for more precision.
9614 => (20 bits * 12 bits) /(16 bits * 7 bits) => safe in 32 bits computation
9615
9616 Precision errors still possible.
9617 */
9618 if (!fec_oc_period) {
9619 qam_post_rs_ber = 0xFFFFFFFF;
9620 } else {
9621 e = post_bit_err_rs * 742686;
9622 m = fec_oc_period * 100;
9623 qam_post_rs_ber = e / m;
9624 }
9625
9626 /* fill signal quality data structure */
9627 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9628 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
9629 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9630 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
9631 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
9632 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
9633
9634 p->cnr.stat[0].svalue = ((u16) qam_sl_mer) * 100;
9635 if (ext_attr->standard == DRX_STANDARD_ITU_B) {
9636 p->pre_bit_error.stat[0].uvalue += qam_vd_ser;
9637 p->pre_bit_count.stat[0].uvalue += vd_bit_cnt * ((e > 2) ? 1 : 8) / 8;
9638 } else {
9639 p->pre_bit_error.stat[0].uvalue += qam_pre_rs_ber;
9640 p->pre_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9641 }
9642
9643 p->post_bit_error.stat[0].uvalue += qam_post_rs_ber;
9644 p->post_bit_count.stat[0].uvalue += rs_bit_cnt >> e;
9645
9646 p->block_error.stat[0].uvalue += pkt_errs;
9647
9648 #ifdef DRXJ_SIGNAL_ACCUM_ERR
9649 rc = get_acc_pkt_err(demod, &sig_quality->packet_error);
9650 if (rc != 0) {
9651 pr_err("error %d\n", rc);
9652 goto rw_error;
9653 }
9654 #endif
9655
9656 return 0;
9657 rw_error:
9658 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9659 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9660 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9661 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9662 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9663 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
9664
9665 return rc;
9666 }
9667
9668 #endif /* #ifndef DRXJ_VSB_ONLY */
9669
9670 /*============================================================================*/
9671 /*== END QAM DATAPATH FUNCTIONS ==*/
9672 /*============================================================================*/
9673
9674 /*============================================================================*/
9675 /*============================================================================*/
9676 /*== ATV DATAPATH FUNCTIONS ==*/
9677 /*============================================================================*/
9678 /*============================================================================*/
9679
9680 /*
9681 Implementation notes.
9682
9683 NTSC/FM AGCs
9684
9685 Four AGCs are used for NTSC:
9686 (1) RF (used to attenuate the input signal in case of to much power)
9687 (2) IF (used to attenuate the input signal in case of to much power)
9688 (3) Video AGC (used to amplify the output signal in case input to low)
9689 (4) SIF AGC (used to amplify the output signal in case input to low)
9690
9691 Video AGC is coupled to RF and IF. SIF AGC is not coupled. It is assumed
9692 that the coupling between Video AGC and the RF and IF AGCs also works in
9693 favor of the SIF AGC.
9694
9695 Three AGCs are used for FM:
9696 (1) RF (used to attenuate the input signal in case of to much power)
9697 (2) IF (used to attenuate the input signal in case of to much power)
9698 (3) SIF AGC (used to amplify the output signal in case input to low)
9699
9700 The SIF AGC is now coupled to the RF/IF AGCs.
9701 The SIF AGC is needed for both SIF output and the internal SIF signal to
9702 the AUD block.
9703
9704 RF and IF AGCs DACs are part of AFE, Video and SIF AGC DACs are part of
9705 the ATV block. The AGC control algorithms are all implemented in
9706 microcode.
9707
9708 ATV SETTINGS
9709
9710 (Shadow settings will not be used for now, they will be implemented
9711 later on because of the schedule)
9712
9713 Several HW/SCU "settings" can be used for ATV. The standard selection
9714 will reset most of these settings. To avoid that the end user application
9715 has to perform these settings each time the ATV or FM standards is
9716 selected the driver will shadow these settings. This enables the end user
9717 to perform the settings only once after a drx_open(). The driver must
9718 write the shadow settings to HW/SCU in case:
9719 ( setstandard FM/ATV) ||
9720 ( settings have changed && FM/ATV standard is active)
9721 The shadow settings will be stored in the device specific data container.
9722 A set of flags will be defined to flag changes in shadow settings.
9723 A routine will be implemented to write all changed shadow settings to
9724 HW/SCU.
9725
9726 The "settings" will consist of: AGC settings, filter settings etc.
9727
9728 Disadvantage of use of shadow settings:
9729 Direct changes in HW/SCU registers will not be reflected in the
9730 shadow settings and these changes will be overwritten during a next
9731 update. This can happen during evaluation. This will not be a problem
9732 for normal customer usage.
9733 */
9734 /* -------------------------------------------------------------------------- */
9735
9736 /*
9737 * \fn int power_down_atv ()
9738 * \brief Power down ATV.
9739 * \param demod instance of demodulator
9740 * \param standard either NTSC or FM (sub strandard for ATV )
9741 * \return int.
9742 *
9743 * Stops and thus resets ATV and IQM block
9744 * SIF and CVBS ADC are powered down
9745 * Calls audio power down
9746 */
9747 static int
power_down_atv(struct drx_demod_instance * demod,enum drx_standard standard,bool primary)9748 power_down_atv(struct drx_demod_instance *demod, enum drx_standard standard, bool primary)
9749 {
9750 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9751 struct drxjscu_cmd cmd_scu = { /* command */ 0,
9752 /* parameter_len */ 0,
9753 /* result_len */ 0,
9754 /* *parameter */ NULL,
9755 /* *result */ NULL
9756 };
9757 int rc;
9758 u16 cmd_result = 0;
9759
9760 /* ATV NTSC */
9761
9762 /* Stop ATV SCU (will reset ATV and IQM hardware */
9763 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_ATV |
9764 SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9765 cmd_scu.parameter_len = 0;
9766 cmd_scu.result_len = 1;
9767 cmd_scu.parameter = NULL;
9768 cmd_scu.result = &cmd_result;
9769 rc = scu_command(dev_addr, &cmd_scu);
9770 if (rc != 0) {
9771 pr_err("error %d\n", rc);
9772 goto rw_error;
9773 }
9774 /* Disable ATV outputs (ATV reset enables CVBS, undo this) */
9775 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (ATV_TOP_STDBY_SIF_STDBY_STANDBY & (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE)), 0);
9776 if (rc != 0) {
9777 pr_err("error %d\n", rc);
9778 goto rw_error;
9779 }
9780
9781 rc = drxj_dap_write_reg16(dev_addr, ATV_COMM_EXEC__A, ATV_COMM_EXEC_STOP, 0);
9782 if (rc != 0) {
9783 pr_err("error %d\n", rc);
9784 goto rw_error;
9785 }
9786 if (primary) {
9787 rc = drxj_dap_write_reg16(dev_addr, IQM_COMM_EXEC__A, IQM_COMM_EXEC_STOP, 0);
9788 if (rc != 0) {
9789 pr_err("error %d\n", rc);
9790 goto rw_error;
9791 }
9792 rc = set_iqm_af(demod, false);
9793 if (rc != 0) {
9794 pr_err("error %d\n", rc);
9795 goto rw_error;
9796 }
9797 } else {
9798 rc = drxj_dap_write_reg16(dev_addr, IQM_FS_COMM_EXEC__A, IQM_FS_COMM_EXEC_STOP, 0);
9799 if (rc != 0) {
9800 pr_err("error %d\n", rc);
9801 goto rw_error;
9802 }
9803 rc = drxj_dap_write_reg16(dev_addr, IQM_FD_COMM_EXEC__A, IQM_FD_COMM_EXEC_STOP, 0);
9804 if (rc != 0) {
9805 pr_err("error %d\n", rc);
9806 goto rw_error;
9807 }
9808 rc = drxj_dap_write_reg16(dev_addr, IQM_RC_COMM_EXEC__A, IQM_RC_COMM_EXEC_STOP, 0);
9809 if (rc != 0) {
9810 pr_err("error %d\n", rc);
9811 goto rw_error;
9812 }
9813 rc = drxj_dap_write_reg16(dev_addr, IQM_RT_COMM_EXEC__A, IQM_RT_COMM_EXEC_STOP, 0);
9814 if (rc != 0) {
9815 pr_err("error %d\n", rc);
9816 goto rw_error;
9817 }
9818 rc = drxj_dap_write_reg16(dev_addr, IQM_CF_COMM_EXEC__A, IQM_CF_COMM_EXEC_STOP, 0);
9819 if (rc != 0) {
9820 pr_err("error %d\n", rc);
9821 goto rw_error;
9822 }
9823 }
9824 rc = power_down_aud(demod);
9825 if (rc != 0) {
9826 pr_err("error %d\n", rc);
9827 goto rw_error;
9828 }
9829
9830 return 0;
9831 rw_error:
9832 return rc;
9833 }
9834
9835 /*============================================================================*/
9836
9837 /*
9838 * \brief Power up AUD.
9839 * \param demod instance of demodulator
9840 * \return int.
9841 *
9842 */
power_down_aud(struct drx_demod_instance * demod)9843 static int power_down_aud(struct drx_demod_instance *demod)
9844 {
9845 struct i2c_device_addr *dev_addr = NULL;
9846 struct drxj_data *ext_attr = NULL;
9847 int rc;
9848
9849 dev_addr = (struct i2c_device_addr *)demod->my_i2c_dev_addr;
9850 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9851
9852 rc = drxj_dap_write_reg16(dev_addr, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP, 0);
9853 if (rc != 0) {
9854 pr_err("error %d\n", rc);
9855 goto rw_error;
9856 }
9857
9858 ext_attr->aud_data.audio_is_active = false;
9859
9860 return 0;
9861 rw_error:
9862 return rc;
9863 }
9864
9865 /*
9866 * \fn int set_orx_nsu_aox()
9867 * \brief Configure OrxNsuAox for OOB
9868 * \param demod instance of demodulator.
9869 * \param active
9870 * \return int.
9871 */
set_orx_nsu_aox(struct drx_demod_instance * demod,bool active)9872 static int set_orx_nsu_aox(struct drx_demod_instance *demod, bool active)
9873 {
9874 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
9875 int rc;
9876 u16 data = 0;
9877
9878 /* Configure NSU_AOX */
9879 rc = drxj_dap_read_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, &data, 0);
9880 if (rc != 0) {
9881 pr_err("error %d\n", rc);
9882 goto rw_error;
9883 }
9884 if (!active)
9885 data &= ((~ORX_NSU_AOX_STDBY_W_STDBYADC_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYAMP_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYBIAS_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPLL_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYPD_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_IF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYTAGC_RF_A2_ON) & (~ORX_NSU_AOX_STDBY_W_STDBYFLT_A2_ON));
9886 else
9887 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);
9888 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STDBY_W__A, data, 0);
9889 if (rc != 0) {
9890 pr_err("error %d\n", rc);
9891 goto rw_error;
9892 }
9893
9894 return 0;
9895 rw_error:
9896 return rc;
9897 }
9898
9899 /*
9900 * \fn int ctrl_set_oob()
9901 * \brief Set OOB channel to be used.
9902 * \param demod instance of demodulator
9903 * \param oob_param OOB parameters for channel setting.
9904 * \frequency should be in KHz
9905 * \return int.
9906 *
9907 * Accepts only. Returns error otherwise.
9908 * Demapper value is written after scu_command START
9909 * because START command causes COMM_EXEC transition
9910 * from 0 to 1 which causes all registers to be
9911 * overwritten with initial value
9912 *
9913 */
9914
9915 /* Nyquist filter impulse response */
9916 #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 */
9917 #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 */
9918 #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) */
9919
9920 /* Coefficients for the nyquist filter (total: 27 taps) */
9921 #define NYQFILTERLEN 27
9922
ctrl_set_oob(struct drx_demod_instance * demod,struct drxoob * oob_param)9923 static int ctrl_set_oob(struct drx_demod_instance *demod, struct drxoob *oob_param)
9924 {
9925 int rc;
9926 s32 freq = 0; /* KHz */
9927 struct i2c_device_addr *dev_addr = NULL;
9928 struct drxj_data *ext_attr = NULL;
9929 u16 i = 0;
9930 bool mirror_freq_spect_oob = false;
9931 u16 trk_filter_value = 0;
9932 struct drxjscu_cmd scu_cmd;
9933 u16 set_param_parameters[3];
9934 u16 cmd_result[2] = { 0, 0 };
9935 s16 nyquist_coeffs[4][(NYQFILTERLEN + 1) / 2] = {
9936 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 0 */
9937 IMPULSE_COSINE_ALPHA_0_3, /* Target Mode 1 */
9938 IMPULSE_COSINE_ALPHA_0_5, /* Target Mode 2 */
9939 IMPULSE_COSINE_ALPHA_RO_0_5 /* Target Mode 3 */
9940 };
9941 u8 mode_val[4] = { 2, 2, 0, 1 };
9942 u8 pfi_coeffs[4][6] = {
9943 {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) */
9944 {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) */
9945 {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) */
9946 {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) */
9947 };
9948 u16 mode_index;
9949
9950 dev_addr = demod->my_i2c_dev_addr;
9951 ext_attr = (struct drxj_data *) demod->my_ext_attr;
9952 mirror_freq_spect_oob = ext_attr->mirror_freq_spect_oob;
9953
9954 /* Check parameters */
9955 if (oob_param == NULL) {
9956 /* power off oob module */
9957 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
9958 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
9959 scu_cmd.parameter_len = 0;
9960 scu_cmd.result_len = 1;
9961 scu_cmd.result = cmd_result;
9962 rc = scu_command(dev_addr, &scu_cmd);
9963 if (rc != 0) {
9964 pr_err("error %d\n", rc);
9965 goto rw_error;
9966 }
9967 rc = set_orx_nsu_aox(demod, false);
9968 if (rc != 0) {
9969 pr_err("error %d\n", rc);
9970 goto rw_error;
9971 }
9972 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
9973 if (rc != 0) {
9974 pr_err("error %d\n", rc);
9975 goto rw_error;
9976 }
9977
9978 ext_attr->oob_power_on = false;
9979 return 0;
9980 }
9981
9982 freq = oob_param->frequency;
9983 if ((freq < 70000) || (freq > 130000))
9984 return -EIO;
9985 freq = (freq - 50000) / 50;
9986
9987 {
9988 u16 index = 0;
9989 u16 remainder = 0;
9990 u16 *trk_filtercfg = ext_attr->oob_trk_filter_cfg;
9991
9992 index = (u16) ((freq - 400) / 200);
9993 remainder = (u16) ((freq - 400) % 200);
9994 trk_filter_value =
9995 trk_filtercfg[index] - (trk_filtercfg[index] -
9996 trk_filtercfg[index +
9997 1]) / 10 * remainder /
9998 20;
9999 }
10000
10001 /********/
10002 /* Stop */
10003 /********/
10004 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_STOP, 0);
10005 if (rc != 0) {
10006 pr_err("error %d\n", rc);
10007 goto rw_error;
10008 }
10009 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10010 | SCU_RAM_COMMAND_CMD_DEMOD_STOP;
10011 scu_cmd.parameter_len = 0;
10012 scu_cmd.result_len = 1;
10013 scu_cmd.result = cmd_result;
10014 rc = scu_command(dev_addr, &scu_cmd);
10015 if (rc != 0) {
10016 pr_err("error %d\n", rc);
10017 goto rw_error;
10018 }
10019 /********/
10020 /* Reset */
10021 /********/
10022 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10023 | SCU_RAM_COMMAND_CMD_DEMOD_RESET;
10024 scu_cmd.parameter_len = 0;
10025 scu_cmd.result_len = 1;
10026 scu_cmd.result = cmd_result;
10027 rc = scu_command(dev_addr, &scu_cmd);
10028 if (rc != 0) {
10029 pr_err("error %d\n", rc);
10030 goto rw_error;
10031 }
10032 /**********/
10033 /* SET_ENV */
10034 /**********/
10035 /* set frequency, spectrum inversion and data rate */
10036 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10037 | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV;
10038 scu_cmd.parameter_len = 3;
10039 /* 1-data rate;2-frequency */
10040 switch (oob_param->standard) {
10041 case DRX_OOB_MODE_A:
10042 if (
10043 /* signal is transmitted inverted */
10044 ((oob_param->spectrum_inverted == true) &&
10045 /* and tuner is not mirroring the signal */
10046 (!mirror_freq_spect_oob)) |
10047 /* or */
10048 /* signal is transmitted noninverted */
10049 ((oob_param->spectrum_inverted == false) &&
10050 /* and tuner is mirroring the signal */
10051 (mirror_freq_spect_oob))
10052 )
10053 set_param_parameters[0] =
10054 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_INVSPEC;
10055 else
10056 set_param_parameters[0] =
10057 SCU_RAM_ORX_RF_RX_DATA_RATE_2048KBPS_REGSPEC;
10058 break;
10059 case DRX_OOB_MODE_B_GRADE_A:
10060 if (
10061 /* signal is transmitted inverted */
10062 ((oob_param->spectrum_inverted == true) &&
10063 /* and tuner is not mirroring the signal */
10064 (!mirror_freq_spect_oob)) |
10065 /* or */
10066 /* signal is transmitted noninverted */
10067 ((oob_param->spectrum_inverted == false) &&
10068 /* and tuner is mirroring the signal */
10069 (mirror_freq_spect_oob))
10070 )
10071 set_param_parameters[0] =
10072 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_INVSPEC;
10073 else
10074 set_param_parameters[0] =
10075 SCU_RAM_ORX_RF_RX_DATA_RATE_1544KBPS_REGSPEC;
10076 break;
10077 case DRX_OOB_MODE_B_GRADE_B:
10078 default:
10079 if (
10080 /* signal is transmitted inverted */
10081 ((oob_param->spectrum_inverted == true) &&
10082 /* and tuner is not mirroring the signal */
10083 (!mirror_freq_spect_oob)) |
10084 /* or */
10085 /* signal is transmitted noninverted */
10086 ((oob_param->spectrum_inverted == false) &&
10087 /* and tuner is mirroring the signal */
10088 (mirror_freq_spect_oob))
10089 )
10090 set_param_parameters[0] =
10091 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_INVSPEC;
10092 else
10093 set_param_parameters[0] =
10094 SCU_RAM_ORX_RF_RX_DATA_RATE_3088KBPS_REGSPEC;
10095 break;
10096 }
10097 set_param_parameters[1] = (u16) (freq & 0xFFFF);
10098 set_param_parameters[2] = trk_filter_value;
10099 scu_cmd.parameter = set_param_parameters;
10100 scu_cmd.result_len = 1;
10101 scu_cmd.result = cmd_result;
10102 mode_index = mode_val[(set_param_parameters[0] & 0xC0) >> 6];
10103 rc = scu_command(dev_addr, &scu_cmd);
10104 if (rc != 0) {
10105 pr_err("error %d\n", rc);
10106 goto rw_error;
10107 }
10108
10109 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0xFABA, 0);
10110 if (rc != 0) {
10111 pr_err("error %d\n", rc);
10112 goto rw_error;
10113 } /* Write magic word to enable pdr reg write */
10114 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_CRX_CFG__A, OOB_CRX_DRIVE_STRENGTH << SIO_PDR_OOB_CRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_CRX_CFG_MODE__B, 0);
10115 if (rc != 0) {
10116 pr_err("error %d\n", rc);
10117 goto rw_error;
10118 }
10119 rc = drxj_dap_write_reg16(dev_addr, SIO_PDR_OOB_DRX_CFG__A, OOB_DRX_DRIVE_STRENGTH << SIO_PDR_OOB_DRX_CFG_DRIVE__B | 0x03 << SIO_PDR_OOB_DRX_CFG_MODE__B, 0);
10120 if (rc != 0) {
10121 pr_err("error %d\n", rc);
10122 goto rw_error;
10123 }
10124 rc = drxj_dap_write_reg16(dev_addr, SIO_TOP_COMM_KEY__A, 0x0000, 0);
10125 if (rc != 0) {
10126 pr_err("error %d\n", rc);
10127 goto rw_error;
10128 } /* Write magic word to disable pdr reg write */
10129
10130 rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_COMM_KEY__A, 0, 0);
10131 if (rc != 0) {
10132 pr_err("error %d\n", rc);
10133 goto rw_error;
10134 }
10135 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_LEN_W__A, 16000, 0);
10136 if (rc != 0) {
10137 pr_err("error %d\n", rc);
10138 goto rw_error;
10139 }
10140 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_AAG_THR_W__A, 40, 0);
10141 if (rc != 0) {
10142 pr_err("error %d\n", rc);
10143 goto rw_error;
10144 }
10145
10146 /* ddc */
10147 rc = drxj_dap_write_reg16(dev_addr, ORX_DDC_OFO_SET_W__A, ORX_DDC_OFO_SET_W__PRE, 0);
10148 if (rc != 0) {
10149 pr_err("error %d\n", rc);
10150 goto rw_error;
10151 }
10152
10153 /* nsu */
10154 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_LOPOW_W__A, ext_attr->oob_lo_pow, 0);
10155 if (rc != 0) {
10156 pr_err("error %d\n", rc);
10157 goto rw_error;
10158 }
10159
10160 /* initialization for target mode */
10161 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TARGET_MODE__A, SCU_RAM_ORX_TARGET_MODE_2048KBPS_SQRT, 0);
10162 if (rc != 0) {
10163 pr_err("error %d\n", rc);
10164 goto rw_error;
10165 }
10166 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FREQ_GAIN_CORR__A, SCU_RAM_ORX_FREQ_GAIN_CORR_2048KBPS, 0);
10167 if (rc != 0) {
10168 pr_err("error %d\n", rc);
10169 goto rw_error;
10170 }
10171
10172 /* Reset bits for timing and freq. recovery */
10173 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CPH__A, 0x0001, 0);
10174 if (rc != 0) {
10175 pr_err("error %d\n", rc);
10176 goto rw_error;
10177 }
10178 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_CTI__A, 0x0002, 0);
10179 if (rc != 0) {
10180 pr_err("error %d\n", rc);
10181 goto rw_error;
10182 }
10183 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRN__A, 0x0004, 0);
10184 if (rc != 0) {
10185 pr_err("error %d\n", rc);
10186 goto rw_error;
10187 }
10188 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_RST_KRP__A, 0x0008, 0);
10189 if (rc != 0) {
10190 pr_err("error %d\n", rc);
10191 goto rw_error;
10192 }
10193
10194 /* AGN_LOCK = {2048>>3, -2048, 8, -8, 0, 1}; */
10195 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TH__A, 2048 >> 3, 0);
10196 if (rc != 0) {
10197 pr_err("error %d\n", rc);
10198 goto rw_error;
10199 }
10200 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_TOTH__A, (u16)(-2048), 0);
10201 if (rc != 0) {
10202 pr_err("error %d\n", rc);
10203 goto rw_error;
10204 }
10205 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_ONLOCK_TTH__A, 8, 0);
10206 if (rc != 0) {
10207 pr_err("error %d\n", rc);
10208 goto rw_error;
10209 }
10210 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_UNLOCK_TTH__A, (u16)(-8), 0);
10211 if (rc != 0) {
10212 pr_err("error %d\n", rc);
10213 goto rw_error;
10214 }
10215 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_AGN_LOCK_MASK__A, 1, 0);
10216 if (rc != 0) {
10217 pr_err("error %d\n", rc);
10218 goto rw_error;
10219 }
10220
10221 /* DGN_LOCK = {10, -2048, 8, -8, 0, 1<<1}; */
10222 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TH__A, 10, 0);
10223 if (rc != 0) {
10224 pr_err("error %d\n", rc);
10225 goto rw_error;
10226 }
10227 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_TOTH__A, (u16)(-2048), 0);
10228 if (rc != 0) {
10229 pr_err("error %d\n", rc);
10230 goto rw_error;
10231 }
10232 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_ONLOCK_TTH__A, 8, 0);
10233 if (rc != 0) {
10234 pr_err("error %d\n", rc);
10235 goto rw_error;
10236 }
10237 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_UNLOCK_TTH__A, (u16)(-8), 0);
10238 if (rc != 0) {
10239 pr_err("error %d\n", rc);
10240 goto rw_error;
10241 }
10242 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_DGN_LOCK_MASK__A, 1 << 1, 0);
10243 if (rc != 0) {
10244 pr_err("error %d\n", rc);
10245 goto rw_error;
10246 }
10247
10248 /* FRQ_LOCK = {15,-2048, 8, -8, 0, 1<<2}; */
10249 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TH__A, 17, 0);
10250 if (rc != 0) {
10251 pr_err("error %d\n", rc);
10252 goto rw_error;
10253 }
10254 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_TOTH__A, (u16)(-2048), 0);
10255 if (rc != 0) {
10256 pr_err("error %d\n", rc);
10257 goto rw_error;
10258 }
10259 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_ONLOCK_TTH__A, 8, 0);
10260 if (rc != 0) {
10261 pr_err("error %d\n", rc);
10262 goto rw_error;
10263 }
10264 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_UNLOCK_TTH__A, (u16)(-8), 0);
10265 if (rc != 0) {
10266 pr_err("error %d\n", rc);
10267 goto rw_error;
10268 }
10269 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_FRQ_LOCK_MASK__A, 1 << 2, 0);
10270 if (rc != 0) {
10271 pr_err("error %d\n", rc);
10272 goto rw_error;
10273 }
10274
10275 /* PHA_LOCK = {5000, -2048, 8, -8, 0, 1<<3}; */
10276 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TH__A, 3000, 0);
10277 if (rc != 0) {
10278 pr_err("error %d\n", rc);
10279 goto rw_error;
10280 }
10281 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_TOTH__A, (u16)(-2048), 0);
10282 if (rc != 0) {
10283 pr_err("error %d\n", rc);
10284 goto rw_error;
10285 }
10286 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_ONLOCK_TTH__A, 8, 0);
10287 if (rc != 0) {
10288 pr_err("error %d\n", rc);
10289 goto rw_error;
10290 }
10291 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_UNLOCK_TTH__A, (u16)(-8), 0);
10292 if (rc != 0) {
10293 pr_err("error %d\n", rc);
10294 goto rw_error;
10295 }
10296 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_PHA_LOCK_MASK__A, 1 << 3, 0);
10297 if (rc != 0) {
10298 pr_err("error %d\n", rc);
10299 goto rw_error;
10300 }
10301
10302 /* TIM_LOCK = {300, -2048, 8, -8, 0, 1<<4}; */
10303 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TH__A, 400, 0);
10304 if (rc != 0) {
10305 pr_err("error %d\n", rc);
10306 goto rw_error;
10307 }
10308 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_TOTH__A, (u16)(-2048), 0);
10309 if (rc != 0) {
10310 pr_err("error %d\n", rc);
10311 goto rw_error;
10312 }
10313 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_ONLOCK_TTH__A, 8, 0);
10314 if (rc != 0) {
10315 pr_err("error %d\n", rc);
10316 goto rw_error;
10317 }
10318 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_UNLOCK_TTH__A, (u16)(-8), 0);
10319 if (rc != 0) {
10320 pr_err("error %d\n", rc);
10321 goto rw_error;
10322 }
10323 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_TIM_LOCK_MASK__A, 1 << 4, 0);
10324 if (rc != 0) {
10325 pr_err("error %d\n", rc);
10326 goto rw_error;
10327 }
10328
10329 /* EQU_LOCK = {20, -2048, 8, -8, 0, 1<<5}; */
10330 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TH__A, 20, 0);
10331 if (rc != 0) {
10332 pr_err("error %d\n", rc);
10333 goto rw_error;
10334 }
10335 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_TOTH__A, (u16)(-2048), 0);
10336 if (rc != 0) {
10337 pr_err("error %d\n", rc);
10338 goto rw_error;
10339 }
10340 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_ONLOCK_TTH__A, 4, 0);
10341 if (rc != 0) {
10342 pr_err("error %d\n", rc);
10343 goto rw_error;
10344 }
10345 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_UNLOCK_TTH__A, (u16)(-4), 0);
10346 if (rc != 0) {
10347 pr_err("error %d\n", rc);
10348 goto rw_error;
10349 }
10350 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_ORX_EQU_LOCK_MASK__A, 1 << 5, 0);
10351 if (rc != 0) {
10352 pr_err("error %d\n", rc);
10353 goto rw_error;
10354 }
10355
10356 /* PRE-Filter coefficients (PFI) */
10357 rc = drxdap_fasi_write_block(dev_addr, ORX_FWP_PFI_A_W__A, sizeof(pfi_coeffs[mode_index]), ((u8 *)pfi_coeffs[mode_index]), 0);
10358 if (rc != 0) {
10359 pr_err("error %d\n", rc);
10360 goto rw_error;
10361 }
10362 rc = drxj_dap_write_reg16(dev_addr, ORX_TOP_MDE_W__A, mode_index, 0);
10363 if (rc != 0) {
10364 pr_err("error %d\n", rc);
10365 goto rw_error;
10366 }
10367
10368 /* NYQUIST-Filter coefficients (NYQ) */
10369 for (i = 0; i < (NYQFILTERLEN + 1) / 2; i++) {
10370 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, i, 0);
10371 if (rc != 0) {
10372 pr_err("error %d\n", rc);
10373 goto rw_error;
10374 }
10375 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_COF_RW__A, nyquist_coeffs[mode_index][i], 0);
10376 if (rc != 0) {
10377 pr_err("error %d\n", rc);
10378 goto rw_error;
10379 }
10380 }
10381 rc = drxj_dap_write_reg16(dev_addr, ORX_FWP_NYQ_ADR_W__A, 31, 0);
10382 if (rc != 0) {
10383 pr_err("error %d\n", rc);
10384 goto rw_error;
10385 }
10386 rc = drxj_dap_write_reg16(dev_addr, ORX_COMM_EXEC__A, ORX_COMM_EXEC_ACTIVE, 0);
10387 if (rc != 0) {
10388 pr_err("error %d\n", rc);
10389 goto rw_error;
10390 }
10391 /********/
10392 /* Start */
10393 /********/
10394 scu_cmd.command = SCU_RAM_COMMAND_STANDARD_OOB
10395 | SCU_RAM_COMMAND_CMD_DEMOD_START;
10396 scu_cmd.parameter_len = 0;
10397 scu_cmd.result_len = 1;
10398 scu_cmd.result = cmd_result;
10399 rc = scu_command(dev_addr, &scu_cmd);
10400 if (rc != 0) {
10401 pr_err("error %d\n", rc);
10402 goto rw_error;
10403 }
10404
10405 rc = set_orx_nsu_aox(demod, true);
10406 if (rc != 0) {
10407 pr_err("error %d\n", rc);
10408 goto rw_error;
10409 }
10410 rc = drxj_dap_write_reg16(dev_addr, ORX_NSU_AOX_STHR_W__A, ext_attr->oob_pre_saw, 0);
10411 if (rc != 0) {
10412 pr_err("error %d\n", rc);
10413 goto rw_error;
10414 }
10415
10416 ext_attr->oob_power_on = true;
10417
10418 return 0;
10419 rw_error:
10420 return rc;
10421 }
10422
10423 /*============================================================================*/
10424 /*== END OOB DATAPATH FUNCTIONS ==*/
10425 /*============================================================================*/
10426
10427 /*=============================================================================
10428 ===== MC command related functions ==========================================
10429 ===========================================================================*/
10430
10431 /*=============================================================================
10432 ===== ctrl_set_channel() ==========================================================
10433 ===========================================================================*/
10434 /*
10435 * \fn int ctrl_set_channel()
10436 * \brief Select a new transmission channel.
10437 * \param demod instance of demod.
10438 * \param channel Pointer to channel data.
10439 * \return int.
10440 *
10441 * In case the tuner module is not used and in case of NTSC/FM the pogrammer
10442 * must tune the tuner to the centre frequency of the NTSC/FM channel.
10443 *
10444 */
10445 static int
ctrl_set_channel(struct drx_demod_instance * demod,struct drx_channel * channel)10446 ctrl_set_channel(struct drx_demod_instance *demod, struct drx_channel *channel)
10447 {
10448 int rc;
10449 s32 tuner_freq_offset = 0;
10450 struct drxj_data *ext_attr = NULL;
10451 struct i2c_device_addr *dev_addr = NULL;
10452 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10453 #ifndef DRXJ_VSB_ONLY
10454 u32 min_symbol_rate = 0;
10455 u32 max_symbol_rate = 0;
10456 int bandwidth_temp = 0;
10457 int bandwidth = 0;
10458 #endif
10459 /*== check arguments ======================================================*/
10460 if ((demod == NULL) || (channel == NULL))
10461 return -EINVAL;
10462
10463 dev_addr = demod->my_i2c_dev_addr;
10464 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10465 standard = ext_attr->standard;
10466
10467 /* check valid standards */
10468 switch (standard) {
10469 case DRX_STANDARD_8VSB:
10470 #ifndef DRXJ_VSB_ONLY
10471 case DRX_STANDARD_ITU_A:
10472 case DRX_STANDARD_ITU_B:
10473 case DRX_STANDARD_ITU_C:
10474 #endif /* DRXJ_VSB_ONLY */
10475 break;
10476 case DRX_STANDARD_UNKNOWN:
10477 default:
10478 return -EINVAL;
10479 }
10480
10481 /* check bandwidth QAM annex B, NTSC and 8VSB */
10482 if ((standard == DRX_STANDARD_ITU_B) ||
10483 (standard == DRX_STANDARD_8VSB) ||
10484 (standard == DRX_STANDARD_NTSC)) {
10485 switch (channel->bandwidth) {
10486 case DRX_BANDWIDTH_6MHZ:
10487 case DRX_BANDWIDTH_UNKNOWN:
10488 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10489 break;
10490 case DRX_BANDWIDTH_8MHZ:
10491 case DRX_BANDWIDTH_7MHZ:
10492 default:
10493 return -EINVAL;
10494 }
10495 }
10496
10497 /* For QAM annex A and annex C:
10498 -check symbolrate and constellation
10499 -derive bandwidth from symbolrate (input bandwidth is ignored)
10500 */
10501 #ifndef DRXJ_VSB_ONLY
10502 if ((standard == DRX_STANDARD_ITU_A) ||
10503 (standard == DRX_STANDARD_ITU_C)) {
10504 struct drxuio_cfg uio_cfg = { DRX_UIO1, DRX_UIO_MODE_FIRMWARE_SAW };
10505 int bw_rolloff_factor = 0;
10506
10507 bw_rolloff_factor = (standard == DRX_STANDARD_ITU_A) ? 115 : 113;
10508 min_symbol_rate = DRXJ_QAM_SYMBOLRATE_MIN;
10509 max_symbol_rate = DRXJ_QAM_SYMBOLRATE_MAX;
10510 /* config SMA_TX pin to SAW switch mode */
10511 rc = ctrl_set_uio_cfg(demod, &uio_cfg);
10512 if (rc != 0) {
10513 pr_err("error %d\n", rc);
10514 goto rw_error;
10515 }
10516
10517 if (channel->symbolrate < min_symbol_rate ||
10518 channel->symbolrate > max_symbol_rate) {
10519 return -EINVAL;
10520 }
10521
10522 switch (channel->constellation) {
10523 case DRX_CONSTELLATION_QAM16:
10524 case DRX_CONSTELLATION_QAM32:
10525 case DRX_CONSTELLATION_QAM64:
10526 case DRX_CONSTELLATION_QAM128:
10527 case DRX_CONSTELLATION_QAM256:
10528 bandwidth_temp = channel->symbolrate * bw_rolloff_factor;
10529 bandwidth = bandwidth_temp / 100;
10530
10531 if ((bandwidth_temp % 100) >= 50)
10532 bandwidth++;
10533
10534 if (bandwidth <= 6100000) {
10535 channel->bandwidth = DRX_BANDWIDTH_6MHZ;
10536 } else if ((bandwidth > 6100000)
10537 && (bandwidth <= 7100000)) {
10538 channel->bandwidth = DRX_BANDWIDTH_7MHZ;
10539 } else if (bandwidth > 7100000) {
10540 channel->bandwidth = DRX_BANDWIDTH_8MHZ;
10541 }
10542 break;
10543 default:
10544 return -EINVAL;
10545 }
10546 }
10547
10548 /* For QAM annex B:
10549 -check constellation
10550 */
10551 if (standard == DRX_STANDARD_ITU_B) {
10552 switch (channel->constellation) {
10553 case DRX_CONSTELLATION_AUTO:
10554 case DRX_CONSTELLATION_QAM256:
10555 case DRX_CONSTELLATION_QAM64:
10556 break;
10557 default:
10558 return -EINVAL;
10559 }
10560
10561 switch (channel->interleavemode) {
10562 case DRX_INTERLEAVEMODE_I128_J1:
10563 case DRX_INTERLEAVEMODE_I128_J1_V2:
10564 case DRX_INTERLEAVEMODE_I128_J2:
10565 case DRX_INTERLEAVEMODE_I64_J2:
10566 case DRX_INTERLEAVEMODE_I128_J3:
10567 case DRX_INTERLEAVEMODE_I32_J4:
10568 case DRX_INTERLEAVEMODE_I128_J4:
10569 case DRX_INTERLEAVEMODE_I16_J8:
10570 case DRX_INTERLEAVEMODE_I128_J5:
10571 case DRX_INTERLEAVEMODE_I8_J16:
10572 case DRX_INTERLEAVEMODE_I128_J6:
10573 case DRX_INTERLEAVEMODE_I128_J7:
10574 case DRX_INTERLEAVEMODE_I128_J8:
10575 case DRX_INTERLEAVEMODE_I12_J17:
10576 case DRX_INTERLEAVEMODE_I5_J4:
10577 case DRX_INTERLEAVEMODE_B52_M240:
10578 case DRX_INTERLEAVEMODE_B52_M720:
10579 case DRX_INTERLEAVEMODE_UNKNOWN:
10580 case DRX_INTERLEAVEMODE_AUTO:
10581 break;
10582 default:
10583 return -EINVAL;
10584 }
10585 }
10586
10587 if ((ext_attr->uio_sma_tx_mode) == DRX_UIO_MODE_FIRMWARE_SAW) {
10588 /* SAW SW, user UIO is used for switchable SAW */
10589 struct drxuio_data uio1 = { DRX_UIO1, false };
10590
10591 switch (channel->bandwidth) {
10592 case DRX_BANDWIDTH_8MHZ:
10593 uio1.value = true;
10594 break;
10595 case DRX_BANDWIDTH_7MHZ:
10596 uio1.value = false;
10597 break;
10598 case DRX_BANDWIDTH_6MHZ:
10599 uio1.value = false;
10600 break;
10601 case DRX_BANDWIDTH_UNKNOWN:
10602 default:
10603 return -EINVAL;
10604 }
10605
10606 rc = ctrl_uio_write(demod, &uio1);
10607 if (rc != 0) {
10608 pr_err("error %d\n", rc);
10609 goto rw_error;
10610 }
10611 }
10612 #endif /* DRXJ_VSB_ONLY */
10613 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
10614 if (rc != 0) {
10615 pr_err("error %d\n", rc);
10616 goto rw_error;
10617 }
10618
10619 tuner_freq_offset = 0;
10620
10621 /*== Setup demod for specific standard ====================================*/
10622 switch (standard) {
10623 case DRX_STANDARD_8VSB:
10624 if (channel->mirror == DRX_MIRROR_AUTO)
10625 ext_attr->mirror = DRX_MIRROR_NO;
10626 else
10627 ext_attr->mirror = channel->mirror;
10628 rc = set_vsb(demod);
10629 if (rc != 0) {
10630 pr_err("error %d\n", rc);
10631 goto rw_error;
10632 }
10633 rc = set_frequency(demod, channel, tuner_freq_offset);
10634 if (rc != 0) {
10635 pr_err("error %d\n", rc);
10636 goto rw_error;
10637 }
10638 break;
10639 #ifndef DRXJ_VSB_ONLY
10640 case DRX_STANDARD_ITU_A:
10641 case DRX_STANDARD_ITU_B:
10642 case DRX_STANDARD_ITU_C:
10643 rc = set_qam_channel(demod, channel, tuner_freq_offset);
10644 if (rc != 0) {
10645 pr_err("error %d\n", rc);
10646 goto rw_error;
10647 }
10648 break;
10649 #endif
10650 case DRX_STANDARD_UNKNOWN:
10651 default:
10652 return -EIO;
10653 }
10654
10655 /* flag the packet error counter reset */
10656 ext_attr->reset_pkt_err_acc = true;
10657
10658 return 0;
10659 rw_error:
10660 return rc;
10661 }
10662
10663 /*=============================================================================
10664 ===== SigQuality() ==========================================================
10665 ===========================================================================*/
10666
10667 /*
10668 * \fn int ctrl_sig_quality()
10669 * \brief Retrieve signal quality form device.
10670 * \param devmod Pointer to demodulator instance.
10671 * \param sig_quality Pointer to signal quality data.
10672 * \return int.
10673 * \retval 0 sig_quality contains valid data.
10674 * \retval -EINVAL sig_quality is NULL.
10675 * \retval -EIO Erroneous data, sig_quality contains invalid data.
10676
10677 */
10678 static int
ctrl_sig_quality(struct drx_demod_instance * demod,enum drx_lock_status lock_status)10679 ctrl_sig_quality(struct drx_demod_instance *demod,
10680 enum drx_lock_status lock_status)
10681 {
10682 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
10683 struct drxj_data *ext_attr = demod->my_ext_attr;
10684 struct drx39xxj_state *state = dev_addr->user_data;
10685 struct dtv_frontend_properties *p = &state->frontend.dtv_property_cache;
10686 enum drx_standard standard = ext_attr->standard;
10687 int rc;
10688 u32 ber, cnt, err, pkt;
10689 u16 mer, strength = 0;
10690
10691 rc = get_sig_strength(demod, &strength);
10692 if (rc < 0) {
10693 pr_err("error getting signal strength %d\n", rc);
10694 p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10695 } else {
10696 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
10697 p->strength.stat[0].uvalue = 65535UL * strength/ 100;
10698 }
10699
10700 switch (standard) {
10701 case DRX_STANDARD_8VSB:
10702 #ifdef DRXJ_SIGNAL_ACCUM_ERR
10703 rc = get_acc_pkt_err(demod, &pkt);
10704 if (rc != 0) {
10705 pr_err("error %d\n", rc);
10706 goto rw_error;
10707 }
10708 #endif
10709 if (lock_status != DRXJ_DEMOD_LOCK && lock_status != DRX_LOCKED) {
10710 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10711 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10712 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10713 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10714 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10715 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10716 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10717 } else {
10718 rc = get_vsb_post_rs_pck_err(dev_addr, &err, &pkt);
10719 if (rc != 0) {
10720 pr_err("error %d getting UCB\n", rc);
10721 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10722 } else {
10723 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
10724 p->block_error.stat[0].uvalue += err;
10725 p->block_count.stat[0].scale = FE_SCALE_COUNTER;
10726 p->block_count.stat[0].uvalue += pkt;
10727 }
10728
10729 /* PostViterbi is compute in steps of 10^(-6) */
10730 rc = get_vs_bpre_viterbi_ber(dev_addr, &ber, &cnt);
10731 if (rc != 0) {
10732 pr_err("error %d getting pre-ber\n", rc);
10733 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10734 } else {
10735 p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10736 p->pre_bit_error.stat[0].uvalue += ber;
10737 p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10738 p->pre_bit_count.stat[0].uvalue += cnt;
10739 }
10740
10741 rc = get_vs_bpost_viterbi_ber(dev_addr, &ber, &cnt);
10742 if (rc != 0) {
10743 pr_err("error %d getting post-ber\n", rc);
10744 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10745 } else {
10746 p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
10747 p->post_bit_error.stat[0].uvalue += ber;
10748 p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
10749 p->post_bit_count.stat[0].uvalue += cnt;
10750 }
10751 rc = get_vsbmer(dev_addr, &mer);
10752 if (rc != 0) {
10753 pr_err("error %d getting MER\n", rc);
10754 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
10755 } else {
10756 p->cnr.stat[0].svalue = mer * 100;
10757 p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
10758 }
10759 }
10760 break;
10761 #ifndef DRXJ_VSB_ONLY
10762 case DRX_STANDARD_ITU_A:
10763 case DRX_STANDARD_ITU_B:
10764 case DRX_STANDARD_ITU_C:
10765 rc = ctrl_get_qam_sig_quality(demod);
10766 if (rc != 0) {
10767 pr_err("error %d\n", rc);
10768 goto rw_error;
10769 }
10770 break;
10771 #endif
10772 default:
10773 return -EIO;
10774 }
10775
10776 return 0;
10777 rw_error:
10778 return rc;
10779 }
10780
10781 /*============================================================================*/
10782
10783 /*
10784 * \fn int ctrl_lock_status()
10785 * \brief Retrieve lock status .
10786 * \param dev_addr Pointer to demodulator device address.
10787 * \param lock_stat Pointer to lock status structure.
10788 * \return int.
10789 *
10790 */
10791 static int
ctrl_lock_status(struct drx_demod_instance * demod,enum drx_lock_status * lock_stat)10792 ctrl_lock_status(struct drx_demod_instance *demod, enum drx_lock_status *lock_stat)
10793 {
10794 enum drx_standard standard = DRX_STANDARD_UNKNOWN;
10795 struct drxj_data *ext_attr = NULL;
10796 struct i2c_device_addr *dev_addr = NULL;
10797 struct drxjscu_cmd cmd_scu = { /* command */ 0,
10798 /* parameter_len */ 0,
10799 /* result_len */ 0,
10800 /* *parameter */ NULL,
10801 /* *result */ NULL
10802 };
10803 int rc;
10804 u16 cmd_result[2] = { 0, 0 };
10805 u16 demod_lock = SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_DEMOD_LOCKED;
10806
10807 /* check arguments */
10808 if ((demod == NULL) || (lock_stat == NULL))
10809 return -EINVAL;
10810
10811 dev_addr = demod->my_i2c_dev_addr;
10812 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10813 standard = ext_attr->standard;
10814
10815 *lock_stat = DRX_NOT_LOCKED;
10816
10817 /* define the SCU command code */
10818 switch (standard) {
10819 case DRX_STANDARD_8VSB:
10820 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_VSB |
10821 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10822 demod_lock |= 0x6;
10823 break;
10824 #ifndef DRXJ_VSB_ONLY
10825 case DRX_STANDARD_ITU_A:
10826 case DRX_STANDARD_ITU_B:
10827 case DRX_STANDARD_ITU_C:
10828 cmd_scu.command = SCU_RAM_COMMAND_STANDARD_QAM |
10829 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK;
10830 break;
10831 #endif
10832 case DRX_STANDARD_UNKNOWN:
10833 default:
10834 return -EIO;
10835 }
10836
10837 /* define the SCU command parameters and execute the command */
10838 cmd_scu.parameter_len = 0;
10839 cmd_scu.result_len = 2;
10840 cmd_scu.parameter = NULL;
10841 cmd_scu.result = cmd_result;
10842 rc = scu_command(dev_addr, &cmd_scu);
10843 if (rc != 0) {
10844 pr_err("error %d\n", rc);
10845 goto rw_error;
10846 }
10847
10848 /* set the lock status */
10849 if (cmd_scu.result[1] < demod_lock) {
10850 /* 0x0000 NOT LOCKED */
10851 *lock_stat = DRX_NOT_LOCKED;
10852 } else if (cmd_scu.result[1] < SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_LOCKED) {
10853 *lock_stat = DRXJ_DEMOD_LOCK;
10854 } else if (cmd_scu.result[1] <
10855 SCU_RAM_PARAM_1_RES_DEMOD_GET_LOCK_NEVER_LOCK) {
10856 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
10857 *lock_stat = DRX_LOCKED;
10858 } else {
10859 /* 0xC000 NEVER LOCKED */
10860 /* (system will never be able to lock to the signal) */
10861 *lock_stat = DRX_NEVER_LOCK;
10862 }
10863
10864 return 0;
10865 rw_error:
10866 return rc;
10867 }
10868
10869 /*============================================================================*/
10870
10871 /*
10872 * \fn int ctrl_set_standard()
10873 * \brief Set modulation standard to be used.
10874 * \param standard Modulation standard.
10875 * \return int.
10876 *
10877 * Setup stuff for the desired demodulation standard.
10878 * Disable and power down the previous selected demodulation standard
10879 *
10880 */
10881 static int
ctrl_set_standard(struct drx_demod_instance * demod,enum drx_standard * standard)10882 ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
10883 {
10884 struct drxj_data *ext_attr = NULL;
10885 int rc;
10886 enum drx_standard prev_standard;
10887
10888 /* check arguments */
10889 if ((standard == NULL) || (demod == NULL))
10890 return -EINVAL;
10891
10892 ext_attr = (struct drxj_data *) demod->my_ext_attr;
10893 prev_standard = ext_attr->standard;
10894
10895 /*
10896 Stop and power down previous standard
10897 */
10898 switch (prev_standard) {
10899 #ifndef DRXJ_VSB_ONLY
10900 case DRX_STANDARD_ITU_A:
10901 case DRX_STANDARD_ITU_B:
10902 case DRX_STANDARD_ITU_C:
10903 rc = power_down_qam(demod, false);
10904 if (rc != 0) {
10905 pr_err("error %d\n", rc);
10906 goto rw_error;
10907 }
10908 break;
10909 #endif
10910 case DRX_STANDARD_8VSB:
10911 rc = power_down_vsb(demod, false);
10912 if (rc != 0) {
10913 pr_err("error %d\n", rc);
10914 goto rw_error;
10915 }
10916 break;
10917 case DRX_STANDARD_UNKNOWN:
10918 /* Do nothing */
10919 break;
10920 case DRX_STANDARD_AUTO:
10921 default:
10922 return -EINVAL;
10923 }
10924
10925 /*
10926 Initialize channel independent registers
10927 Power up new standard
10928 */
10929 ext_attr->standard = *standard;
10930
10931 switch (*standard) {
10932 #ifndef DRXJ_VSB_ONLY
10933 case DRX_STANDARD_ITU_A:
10934 case DRX_STANDARD_ITU_B:
10935 case DRX_STANDARD_ITU_C:
10936 do {
10937 u16 dummy;
10938 rc = drxj_dap_read_reg16(demod->my_i2c_dev_addr, SCU_RAM_VERSION_HI__A, &dummy, 0);
10939 if (rc != 0) {
10940 pr_err("error %d\n", rc);
10941 goto rw_error;
10942 }
10943 } while (0);
10944 break;
10945 #endif
10946 case DRX_STANDARD_8VSB:
10947 rc = set_vsb_leak_n_gain(demod);
10948 if (rc != 0) {
10949 pr_err("error %d\n", rc);
10950 goto rw_error;
10951 }
10952 break;
10953 default:
10954 ext_attr->standard = DRX_STANDARD_UNKNOWN;
10955 return -EINVAL;
10956 break;
10957 }
10958
10959 return 0;
10960 rw_error:
10961 /* Don't know what the standard is now ... try again */
10962 ext_attr->standard = DRX_STANDARD_UNKNOWN;
10963 return rc;
10964 }
10965
10966 /*============================================================================*/
10967
drxj_reset_mode(struct drxj_data * ext_attr)10968 static void drxj_reset_mode(struct drxj_data *ext_attr)
10969 {
10970 /* Initialize default AFE configuration for QAM */
10971 if (ext_attr->has_lna) {
10972 /* IF AGC off, PGA active */
10973 #ifndef DRXJ_VSB_ONLY
10974 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10975 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10976 ext_attr->qam_pga_cfg = 140 + (11 * 13);
10977 #endif
10978 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10979 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_OFF;
10980 ext_attr->vsb_pga_cfg = 140 + (11 * 13);
10981 } else {
10982 /* IF AGC on, PGA not active */
10983 #ifndef DRXJ_VSB_ONLY
10984 ext_attr->qam_if_agc_cfg.standard = DRX_STANDARD_ITU_B;
10985 ext_attr->qam_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10986 ext_attr->qam_if_agc_cfg.min_output_level = 0;
10987 ext_attr->qam_if_agc_cfg.max_output_level = 0x7FFF;
10988 ext_attr->qam_if_agc_cfg.speed = 3;
10989 ext_attr->qam_if_agc_cfg.top = 1297;
10990 ext_attr->qam_pga_cfg = 140;
10991 #endif
10992 ext_attr->vsb_if_agc_cfg.standard = DRX_STANDARD_8VSB;
10993 ext_attr->vsb_if_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
10994 ext_attr->vsb_if_agc_cfg.min_output_level = 0;
10995 ext_attr->vsb_if_agc_cfg.max_output_level = 0x7FFF;
10996 ext_attr->vsb_if_agc_cfg.speed = 3;
10997 ext_attr->vsb_if_agc_cfg.top = 1024;
10998 ext_attr->vsb_pga_cfg = 140;
10999 }
11000 /* TODO: remove min_output_level and max_output_level for both QAM and VSB after */
11001 /* mc has not used them */
11002 #ifndef DRXJ_VSB_ONLY
11003 ext_attr->qam_rf_agc_cfg.standard = DRX_STANDARD_ITU_B;
11004 ext_attr->qam_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11005 ext_attr->qam_rf_agc_cfg.min_output_level = 0;
11006 ext_attr->qam_rf_agc_cfg.max_output_level = 0x7FFF;
11007 ext_attr->qam_rf_agc_cfg.speed = 3;
11008 ext_attr->qam_rf_agc_cfg.top = 9500;
11009 ext_attr->qam_rf_agc_cfg.cut_off_current = 4000;
11010 ext_attr->qam_pre_saw_cfg.standard = DRX_STANDARD_ITU_B;
11011 ext_attr->qam_pre_saw_cfg.reference = 0x07;
11012 ext_attr->qam_pre_saw_cfg.use_pre_saw = true;
11013 #endif
11014 /* Initialize default AFE configuration for VSB */
11015 ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB;
11016 ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO;
11017 ext_attr->vsb_rf_agc_cfg.min_output_level = 0;
11018 ext_attr->vsb_rf_agc_cfg.max_output_level = 0x7FFF;
11019 ext_attr->vsb_rf_agc_cfg.speed = 3;
11020 ext_attr->vsb_rf_agc_cfg.top = 9500;
11021 ext_attr->vsb_rf_agc_cfg.cut_off_current = 4000;
11022 ext_attr->vsb_pre_saw_cfg.standard = DRX_STANDARD_8VSB;
11023 ext_attr->vsb_pre_saw_cfg.reference = 0x07;
11024 ext_attr->vsb_pre_saw_cfg.use_pre_saw = true;
11025 }
11026
11027 /*
11028 * \fn int ctrl_power_mode()
11029 * \brief Set the power mode of the device to the specified power mode
11030 * \param demod Pointer to demodulator instance.
11031 * \param mode Pointer to new power mode.
11032 * \return int.
11033 * \retval 0 Success
11034 * \retval -EIO I2C error or other failure
11035 * \retval -EINVAL Invalid mode argument.
11036 *
11037 *
11038 */
11039 static int
ctrl_power_mode(struct drx_demod_instance * demod,enum drx_power_mode * mode)11040 ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
11041 {
11042 struct drx_common_attr *common_attr = (struct drx_common_attr *) NULL;
11043 struct drxj_data *ext_attr = (struct drxj_data *) NULL;
11044 struct i2c_device_addr *dev_addr = (struct i2c_device_addr *)NULL;
11045 int rc;
11046 u16 sio_cc_pwd_mode = 0;
11047
11048 common_attr = (struct drx_common_attr *) demod->my_common_attr;
11049 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11050 dev_addr = demod->my_i2c_dev_addr;
11051
11052 /* Check arguments */
11053 if (mode == NULL)
11054 return -EINVAL;
11055
11056 /* If already in requested power mode, do nothing */
11057 if (common_attr->current_power_mode == *mode)
11058 return 0;
11059
11060 switch (*mode) {
11061 case DRX_POWER_UP:
11062 case DRXJ_POWER_DOWN_MAIN_PATH:
11063 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
11064 break;
11065 case DRXJ_POWER_DOWN_CORE:
11066 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
11067 break;
11068 case DRXJ_POWER_DOWN_PLL:
11069 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
11070 break;
11071 case DRX_POWER_DOWN:
11072 sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
11073 break;
11074 default:
11075 /* Unknow sleep mode */
11076 return -EINVAL;
11077 break;
11078 }
11079
11080 /* Check if device needs to be powered up */
11081 if ((common_attr->current_power_mode != DRX_POWER_UP)) {
11082 rc = power_up_device(demod);
11083 if (rc != 0) {
11084 pr_err("error %d\n", rc);
11085 goto rw_error;
11086 }
11087 }
11088
11089 if (*mode == DRX_POWER_UP) {
11090 /* Restore analog & pin configuration */
11091
11092 /* Initialize default AFE configuration for VSB */
11093 drxj_reset_mode(ext_attr);
11094 } else {
11095 /* Power down to requested mode */
11096 /* Backup some register settings */
11097 /* Set pins with possible pull-ups connected to them in input mode */
11098 /* Analog power down */
11099 /* ADC power down */
11100 /* Power down device */
11101 /* stop all comm_exec */
11102 /*
11103 Stop and power down previous standard
11104 */
11105
11106 switch (ext_attr->standard) {
11107 case DRX_STANDARD_ITU_A:
11108 case DRX_STANDARD_ITU_B:
11109 case DRX_STANDARD_ITU_C:
11110 rc = power_down_qam(demod, true);
11111 if (rc != 0) {
11112 pr_err("error %d\n", rc);
11113 goto rw_error;
11114 }
11115 break;
11116 case DRX_STANDARD_8VSB:
11117 rc = power_down_vsb(demod, true);
11118 if (rc != 0) {
11119 pr_err("error %d\n", rc);
11120 goto rw_error;
11121 }
11122 break;
11123 case DRX_STANDARD_PAL_SECAM_BG:
11124 case DRX_STANDARD_PAL_SECAM_DK:
11125 case DRX_STANDARD_PAL_SECAM_I:
11126 case DRX_STANDARD_PAL_SECAM_L:
11127 case DRX_STANDARD_PAL_SECAM_LP:
11128 case DRX_STANDARD_NTSC:
11129 case DRX_STANDARD_FM:
11130 rc = power_down_atv(demod, ext_attr->standard, true);
11131 if (rc != 0) {
11132 pr_err("error %d\n", rc);
11133 goto rw_error;
11134 }
11135 break;
11136 case DRX_STANDARD_UNKNOWN:
11137 /* Do nothing */
11138 break;
11139 case DRX_STANDARD_AUTO:
11140 default:
11141 return -EIO;
11142 }
11143 ext_attr->standard = DRX_STANDARD_UNKNOWN;
11144 }
11145
11146 if (*mode != DRXJ_POWER_DOWN_MAIN_PATH) {
11147 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode, 0);
11148 if (rc != 0) {
11149 pr_err("error %d\n", rc);
11150 goto rw_error;
11151 }
11152 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
11153 if (rc != 0) {
11154 pr_err("error %d\n", rc);
11155 goto rw_error;
11156 }
11157
11158 if ((*mode != DRX_POWER_UP)) {
11159 /* Initialize HI, wakeup key especially before put IC to sleep */
11160 rc = init_hi(demod);
11161 if (rc != 0) {
11162 pr_err("error %d\n", rc);
11163 goto rw_error;
11164 }
11165
11166 ext_attr->hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
11167 rc = hi_cfg_command(demod);
11168 if (rc != 0) {
11169 pr_err("error %d\n", rc);
11170 goto rw_error;
11171 }
11172 }
11173 }
11174
11175 common_attr->current_power_mode = *mode;
11176
11177 return 0;
11178 rw_error:
11179 return rc;
11180 }
11181
11182 /*============================================================================*/
11183 /*== CTRL Set/Get Config related functions ===================================*/
11184 /*============================================================================*/
11185
11186 /*
11187 * \fn int ctrl_set_cfg_pre_saw()
11188 * \brief Set Pre-saw reference.
11189 * \param demod demod instance
11190 * \param u16 *
11191 * \return int.
11192 *
11193 * Check arguments
11194 * Dispatch handling to standard specific function.
11195 *
11196 */
11197 static int
ctrl_set_cfg_pre_saw(struct drx_demod_instance * demod,struct drxj_cfg_pre_saw * pre_saw)11198 ctrl_set_cfg_pre_saw(struct drx_demod_instance *demod, struct drxj_cfg_pre_saw *pre_saw)
11199 {
11200 struct i2c_device_addr *dev_addr = NULL;
11201 struct drxj_data *ext_attr = NULL;
11202 int rc;
11203
11204 dev_addr = demod->my_i2c_dev_addr;
11205 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11206
11207 /* check arguments */
11208 if ((pre_saw == NULL) || (pre_saw->reference > IQM_AF_PDREF__M)
11209 ) {
11210 return -EINVAL;
11211 }
11212
11213 /* Only if standard is currently active */
11214 if ((ext_attr->standard == pre_saw->standard) ||
11215 (DRXJ_ISQAMSTD(ext_attr->standard) &&
11216 DRXJ_ISQAMSTD(pre_saw->standard)) ||
11217 (DRXJ_ISATVSTD(ext_attr->standard) &&
11218 DRXJ_ISATVSTD(pre_saw->standard))) {
11219 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PDREF__A, pre_saw->reference, 0);
11220 if (rc != 0) {
11221 pr_err("error %d\n", rc);
11222 goto rw_error;
11223 }
11224 }
11225
11226 /* Store pre-saw settings */
11227 switch (pre_saw->standard) {
11228 case DRX_STANDARD_8VSB:
11229 ext_attr->vsb_pre_saw_cfg = *pre_saw;
11230 break;
11231 #ifndef DRXJ_VSB_ONLY
11232 case DRX_STANDARD_ITU_A:
11233 case DRX_STANDARD_ITU_B:
11234 case DRX_STANDARD_ITU_C:
11235 ext_attr->qam_pre_saw_cfg = *pre_saw;
11236 break;
11237 #endif
11238 default:
11239 return -EINVAL;
11240 }
11241
11242 return 0;
11243 rw_error:
11244 return rc;
11245 }
11246
11247 /*============================================================================*/
11248
11249 /*
11250 * \fn int ctrl_set_cfg_afe_gain()
11251 * \brief Set AFE Gain.
11252 * \param demod demod instance
11253 * \param u16 *
11254 * \return int.
11255 *
11256 * Check arguments
11257 * Dispatch handling to standard specific function.
11258 *
11259 */
11260 static int
ctrl_set_cfg_afe_gain(struct drx_demod_instance * demod,struct drxj_cfg_afe_gain * afe_gain)11261 ctrl_set_cfg_afe_gain(struct drx_demod_instance *demod, struct drxj_cfg_afe_gain *afe_gain)
11262 {
11263 struct i2c_device_addr *dev_addr = NULL;
11264 struct drxj_data *ext_attr = NULL;
11265 int rc;
11266 u8 gain = 0;
11267
11268 /* check arguments */
11269 if (afe_gain == NULL)
11270 return -EINVAL;
11271
11272 dev_addr = demod->my_i2c_dev_addr;
11273 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11274
11275 switch (afe_gain->standard) {
11276 case DRX_STANDARD_8VSB: fallthrough;
11277 #ifndef DRXJ_VSB_ONLY
11278 case DRX_STANDARD_ITU_A:
11279 case DRX_STANDARD_ITU_B:
11280 case DRX_STANDARD_ITU_C:
11281 #endif
11282 /* Do nothing */
11283 break;
11284 default:
11285 return -EINVAL;
11286 }
11287
11288 /* TODO PGA gain is also written by microcode (at least by QAM and VSB)
11289 So I (PJ) think interface requires choice between auto, user mode */
11290
11291 if (afe_gain->gain >= 329)
11292 gain = 15;
11293 else if (afe_gain->gain <= 147)
11294 gain = 0;
11295 else
11296 gain = (afe_gain->gain - 140 + 6) / 13;
11297
11298 /* Only if standard is currently active */
11299 if (ext_attr->standard == afe_gain->standard) {
11300 rc = drxj_dap_write_reg16(dev_addr, IQM_AF_PGA_GAIN__A, gain, 0);
11301 if (rc != 0) {
11302 pr_err("error %d\n", rc);
11303 goto rw_error;
11304 }
11305 }
11306
11307 /* Store AFE Gain settings */
11308 switch (afe_gain->standard) {
11309 case DRX_STANDARD_8VSB:
11310 ext_attr->vsb_pga_cfg = gain * 13 + 140;
11311 break;
11312 #ifndef DRXJ_VSB_ONLY
11313 case DRX_STANDARD_ITU_A:
11314 case DRX_STANDARD_ITU_B:
11315 case DRX_STANDARD_ITU_C:
11316 ext_attr->qam_pga_cfg = gain * 13 + 140;
11317 break;
11318 #endif
11319 default:
11320 return -EIO;
11321 }
11322
11323 return 0;
11324 rw_error:
11325 return rc;
11326 }
11327
11328 /*============================================================================*/
11329
11330
11331 /*=============================================================================
11332 ===== EXPORTED FUNCTIONS ====================================================*/
11333
11334 static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11335 struct drxu_code_info *mc_info,
11336 enum drxu_code_action action);
11337 static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state);
11338
11339 /*
11340 * \fn drxj_open()
11341 * \brief Open the demod instance, configure device, configure drxdriver
11342 * \return Status_t Return status.
11343 *
11344 * drxj_open() can be called with a NULL ucode image => no ucode upload.
11345 * This means that drxj_open() must NOT contain SCU commands or, in general,
11346 * rely on SCU or AUD ucode to be present.
11347 *
11348 */
11349
drxj_open(struct drx_demod_instance * demod)11350 static int drxj_open(struct drx_demod_instance *demod)
11351 {
11352 struct i2c_device_addr *dev_addr = NULL;
11353 struct drxj_data *ext_attr = NULL;
11354 struct drx_common_attr *common_attr = NULL;
11355 u32 driver_version = 0;
11356 struct drxu_code_info ucode_info;
11357 struct drx_cfg_mpeg_output cfg_mpeg_output;
11358 int rc;
11359 enum drx_power_mode power_mode = DRX_POWER_UP;
11360
11361 if ((demod == NULL) ||
11362 (demod->my_common_attr == NULL) ||
11363 (demod->my_ext_attr == NULL) ||
11364 (demod->my_i2c_dev_addr == NULL) ||
11365 (demod->my_common_attr->is_opened)) {
11366 return -EINVAL;
11367 }
11368
11369 /* Check arguments */
11370 if (demod->my_ext_attr == NULL)
11371 return -EINVAL;
11372
11373 dev_addr = demod->my_i2c_dev_addr;
11374 ext_attr = (struct drxj_data *) demod->my_ext_attr;
11375 common_attr = (struct drx_common_attr *) demod->my_common_attr;
11376
11377 rc = ctrl_power_mode(demod, &power_mode);
11378 if (rc != 0) {
11379 pr_err("error %d\n", rc);
11380 goto rw_error;
11381 }
11382 if (power_mode != DRX_POWER_UP) {
11383 rc = -EINVAL;
11384 pr_err("failed to powerup device\n");
11385 goto rw_error;
11386 }
11387
11388 /* has to be in front of setIqmAf and setOrxNsuAox */
11389 rc = get_device_capabilities(demod);
11390 if (rc != 0) {
11391 pr_err("error %d\n", rc);
11392 goto rw_error;
11393 }
11394
11395 /*
11396 * Soft reset of sys- and osc-clockdomain
11397 *
11398 * HACK: On windows, it writes a 0x07 here, instead of just 0x03.
11399 * As we didn't load the firmware here yet, we should do the same.
11400 * Btw, this is coherent with DRX-K, where we send reset codes
11401 * for modulation (OFTM, in DRX-k), SYS and OSC clock domains.
11402 */
11403 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_SOFT_RST__A, (0x04 | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M), 0);
11404 if (rc != 0) {
11405 pr_err("error %d\n", rc);
11406 goto rw_error;
11407 }
11408 rc = drxj_dap_write_reg16(dev_addr, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY, 0);
11409 if (rc != 0) {
11410 pr_err("error %d\n", rc);
11411 goto rw_error;
11412 }
11413 msleep(1);
11414
11415 /* TODO first make sure that everything keeps working before enabling this */
11416 /* PowerDownAnalogBlocks() */
11417 rc = drxj_dap_write_reg16(dev_addr, ATV_TOP_STDBY__A, (~ATV_TOP_STDBY_CVBS_STDBY_A2_ACTIVE) | ATV_TOP_STDBY_SIF_STDBY_STANDBY, 0);
11418 if (rc != 0) {
11419 pr_err("error %d\n", rc);
11420 goto rw_error;
11421 }
11422
11423 rc = set_iqm_af(demod, false);
11424 if (rc != 0) {
11425 pr_err("error %d\n", rc);
11426 goto rw_error;
11427 }
11428 rc = set_orx_nsu_aox(demod, false);
11429 if (rc != 0) {
11430 pr_err("error %d\n", rc);
11431 goto rw_error;
11432 }
11433
11434 rc = init_hi(demod);
11435 if (rc != 0) {
11436 pr_err("error %d\n", rc);
11437 goto rw_error;
11438 }
11439
11440 /* disable mpegoutput pins */
11441 memcpy(&cfg_mpeg_output, &common_attr->mpeg_cfg, sizeof(cfg_mpeg_output));
11442 cfg_mpeg_output.enable_mpeg_output = false;
11443
11444 rc = ctrl_set_cfg_mpeg_output(demod, &cfg_mpeg_output);
11445 if (rc != 0) {
11446 pr_err("error %d\n", rc);
11447 goto rw_error;
11448 }
11449 /* Stop AUD Inform SetAudio it will need to do all setting */
11450 rc = power_down_aud(demod);
11451 if (rc != 0) {
11452 pr_err("error %d\n", rc);
11453 goto rw_error;
11454 }
11455 /* Stop SCU */
11456 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP, 0);
11457 if (rc != 0) {
11458 pr_err("error %d\n", rc);
11459 goto rw_error;
11460 }
11461
11462 /* Upload microcode */
11463 if (common_attr->microcode_file != NULL) {
11464 /* Dirty trick to use common ucode upload & verify,
11465 pretend device is already open */
11466 common_attr->is_opened = true;
11467 ucode_info.mc_file = common_attr->microcode_file;
11468
11469 if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
11470 pr_err("Should powerup before loading the firmware.");
11471 return -EINVAL;
11472 }
11473
11474 rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);
11475 if (rc != 0) {
11476 pr_err("error %d while uploading the firmware\n", rc);
11477 goto rw_error;
11478 }
11479 if (common_attr->verify_microcode == true) {
11480 rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_VERIFY);
11481 if (rc != 0) {
11482 pr_err("error %d while verifying the firmware\n",
11483 rc);
11484 goto rw_error;
11485 }
11486 }
11487 common_attr->is_opened = false;
11488 }
11489
11490 /* Run SCU for a little while to initialize microcode version numbers */
11491 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
11492 if (rc != 0) {
11493 pr_err("error %d\n", rc);
11494 goto rw_error;
11495 }
11496
11497 /* Initialize scan timeout */
11498 common_attr->scan_demod_lock_timeout = DRXJ_SCAN_TIMEOUT;
11499 common_attr->scan_desired_lock = DRX_LOCKED;
11500
11501 drxj_reset_mode(ext_attr);
11502 ext_attr->standard = DRX_STANDARD_UNKNOWN;
11503
11504 rc = smart_ant_init(demod);
11505 if (rc != 0) {
11506 pr_err("error %d\n", rc);
11507 goto rw_error;
11508 }
11509
11510 /* Stamp driver version number in SCU data RAM in BCD code
11511 Done to enable field application engineers to retrieve drxdriver version
11512 via I2C from SCU RAM
11513 */
11514 driver_version = (VERSION_MAJOR / 100) % 10;
11515 driver_version <<= 4;
11516 driver_version += (VERSION_MAJOR / 10) % 10;
11517 driver_version <<= 4;
11518 driver_version += (VERSION_MAJOR % 10);
11519 driver_version <<= 4;
11520 driver_version += (VERSION_MINOR % 10);
11521 driver_version <<= 4;
11522 driver_version += (VERSION_PATCH / 1000) % 10;
11523 driver_version <<= 4;
11524 driver_version += (VERSION_PATCH / 100) % 10;
11525 driver_version <<= 4;
11526 driver_version += (VERSION_PATCH / 10) % 10;
11527 driver_version <<= 4;
11528 driver_version += (VERSION_PATCH % 10);
11529 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_HI__A, (u16)(driver_version >> 16), 0);
11530 if (rc != 0) {
11531 pr_err("error %d\n", rc);
11532 goto rw_error;
11533 }
11534 rc = drxj_dap_write_reg16(dev_addr, SCU_RAM_DRIVER_VER_LO__A, (u16)(driver_version & 0xFFFF), 0);
11535 if (rc != 0) {
11536 pr_err("error %d\n", rc);
11537 goto rw_error;
11538 }
11539
11540 rc = ctrl_set_oob(demod, NULL);
11541 if (rc != 0) {
11542 pr_err("error %d\n", rc);
11543 goto rw_error;
11544 }
11545
11546 /* refresh the audio data structure with default */
11547 ext_attr->aud_data = drxj_default_aud_data_g;
11548
11549 demod->my_common_attr->is_opened = true;
11550 drxj_set_lna_state(demod, false);
11551 return 0;
11552 rw_error:
11553 common_attr->is_opened = false;
11554 return rc;
11555 }
11556
11557 /*============================================================================*/
11558 /*
11559 * \fn drxj_close()
11560 * \brief Close the demod instance, power down the device
11561 * \return Status_t Return status.
11562 *
11563 */
drxj_close(struct drx_demod_instance * demod)11564 static int drxj_close(struct drx_demod_instance *demod)
11565 {
11566 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11567 int rc;
11568 enum drx_power_mode power_mode = DRX_POWER_UP;
11569
11570 if ((demod->my_common_attr == NULL) ||
11571 (demod->my_ext_attr == NULL) ||
11572 (demod->my_i2c_dev_addr == NULL) ||
11573 (!demod->my_common_attr->is_opened)) {
11574 return -EINVAL;
11575 }
11576
11577 /* power up */
11578 rc = ctrl_power_mode(demod, &power_mode);
11579 if (rc != 0) {
11580 pr_err("error %d\n", rc);
11581 goto rw_error;
11582 }
11583
11584 rc = drxj_dap_write_reg16(dev_addr, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE, 0);
11585 if (rc != 0) {
11586 pr_err("error %d\n", rc);
11587 goto rw_error;
11588 }
11589 power_mode = DRX_POWER_DOWN;
11590 rc = ctrl_power_mode(demod, &power_mode);
11591 if (rc != 0) {
11592 pr_err("error %d\n", rc);
11593 goto rw_error;
11594 }
11595
11596 DRX_ATTR_ISOPENED(demod) = false;
11597
11598 return 0;
11599 rw_error:
11600 DRX_ATTR_ISOPENED(demod) = false;
11601
11602 return rc;
11603 }
11604
11605 /*
11606 * Microcode related functions
11607 */
11608
11609 /*
11610 * drx_u_code_compute_crc - Compute CRC of block of microcode data.
11611 * @block_data: Pointer to microcode data.
11612 * @nr_words: Size of microcode block (number of 16 bits words).
11613 *
11614 * returns The computed CRC residue.
11615 */
drx_u_code_compute_crc(u8 * block_data,u16 nr_words)11616 static u16 drx_u_code_compute_crc(u8 *block_data, u16 nr_words)
11617 {
11618 u16 i = 0;
11619 u16 j = 0;
11620 u32 crc_word = 0;
11621 u32 carry = 0;
11622
11623 while (i < nr_words) {
11624 crc_word |= (u32)be16_to_cpu(*(__be16 *)(block_data));
11625 for (j = 0; j < 16; j++) {
11626 crc_word <<= 1;
11627 if (carry != 0)
11628 crc_word ^= 0x80050000UL;
11629 carry = crc_word & 0x80000000UL;
11630 }
11631 i++;
11632 block_data += (sizeof(u16));
11633 }
11634 return (u16)(crc_word >> 16);
11635 }
11636
11637 /*
11638 * drx_check_firmware - checks if the loaded firmware is valid
11639 *
11640 * @demod: demod structure
11641 * @mc_data: pointer to the start of the firmware
11642 * @size: firmware size
11643 */
drx_check_firmware(struct drx_demod_instance * demod,u8 * mc_data,unsigned size)11644 static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
11645 unsigned size)
11646 {
11647 struct drxu_code_block_hdr block_hdr;
11648 int i;
11649 unsigned count = 2 * sizeof(u16);
11650 u32 mc_dev_type, mc_version, mc_base_version;
11651 u16 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data + sizeof(u16)));
11652
11653 /*
11654 * Scan microcode blocks first for version info
11655 * and firmware check
11656 */
11657
11658 /* Clear version block */
11659 DRX_ATTR_MCRECORD(demod).aux_type = 0;
11660 DRX_ATTR_MCRECORD(demod).mc_dev_type = 0;
11661 DRX_ATTR_MCRECORD(demod).mc_version = 0;
11662 DRX_ATTR_MCRECORD(demod).mc_base_version = 0;
11663
11664 for (i = 0; i < mc_nr_of_blks; i++) {
11665 if (count + 3 * sizeof(u16) + sizeof(u32) > size)
11666 goto eof;
11667
11668 /* Process block header */
11669 block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data + count));
11670 count += sizeof(u32);
11671 block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data + count));
11672 count += sizeof(u16);
11673 block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data + count));
11674 count += sizeof(u16);
11675 block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data + count));
11676 count += sizeof(u16);
11677
11678 pr_debug("%u: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11679 count, block_hdr.addr, block_hdr.size, block_hdr.flags,
11680 block_hdr.CRC);
11681
11682 if (block_hdr.flags & 0x8) {
11683 u8 *auxblk = ((void *)mc_data) + block_hdr.addr;
11684 u16 auxtype;
11685
11686 if (block_hdr.addr + sizeof(u16) > size)
11687 goto eof;
11688
11689 auxtype = be16_to_cpu(*(__be16 *)(auxblk));
11690
11691 /* Aux block. Check type */
11692 if (DRX_ISMCVERTYPE(auxtype)) {
11693 if (block_hdr.addr + 2 * sizeof(u16) + 2 * sizeof (u32) > size)
11694 goto eof;
11695
11696 auxblk += sizeof(u16);
11697 mc_dev_type = be32_to_cpu(*(__be32 *)(auxblk));
11698 auxblk += sizeof(u32);
11699 mc_version = be32_to_cpu(*(__be32 *)(auxblk));
11700 auxblk += sizeof(u32);
11701 mc_base_version = be32_to_cpu(*(__be32 *)(auxblk));
11702
11703 DRX_ATTR_MCRECORD(demod).aux_type = auxtype;
11704 DRX_ATTR_MCRECORD(demod).mc_dev_type = mc_dev_type;
11705 DRX_ATTR_MCRECORD(demod).mc_version = mc_version;
11706 DRX_ATTR_MCRECORD(demod).mc_base_version = mc_base_version;
11707
11708 pr_info("Firmware dev %x, ver %x, base ver %x\n",
11709 mc_dev_type, mc_version, mc_base_version);
11710
11711 }
11712 } else if (count + block_hdr.size * sizeof(u16) > size)
11713 goto eof;
11714
11715 count += block_hdr.size * sizeof(u16);
11716 }
11717 return 0;
11718 eof:
11719 pr_err("Firmware is truncated at pos %u/%u\n", count, size);
11720 return -EINVAL;
11721 }
11722
11723 /*
11724 * drx_ctrl_u_code - Handle microcode upload or verify.
11725 * @dev_addr: Address of device.
11726 * @mc_info: Pointer to information about microcode data.
11727 * @action: Either UCODE_UPLOAD or UCODE_VERIFY
11728 *
11729 * This function returns:
11730 * 0:
11731 * - In case of UCODE_UPLOAD: code is successfully uploaded.
11732 * - In case of UCODE_VERIFY: image on device is equal to
11733 * image provided to this control function.
11734 * -EIO:
11735 * - In case of UCODE_UPLOAD: I2C error.
11736 * - In case of UCODE_VERIFY: I2C error or image on device
11737 * is not equal to image provided to this control function.
11738 * -EINVAL:
11739 * - Invalid arguments.
11740 * - Provided image is corrupt
11741 */
drx_ctrl_u_code(struct drx_demod_instance * demod,struct drxu_code_info * mc_info,enum drxu_code_action action)11742 static int drx_ctrl_u_code(struct drx_demod_instance *demod,
11743 struct drxu_code_info *mc_info,
11744 enum drxu_code_action action)
11745 {
11746 struct i2c_device_addr *dev_addr = demod->my_i2c_dev_addr;
11747 int rc;
11748 u16 i = 0;
11749 u16 mc_nr_of_blks = 0;
11750 u16 mc_magic_word = 0;
11751 const u8 *mc_data_init = NULL;
11752 u8 *mc_data = NULL;
11753 unsigned size;
11754 char *mc_file;
11755
11756 /* Check arguments */
11757 if (!mc_info || !mc_info->mc_file)
11758 return -EINVAL;
11759
11760 mc_file = mc_info->mc_file;
11761
11762 if (!demod->firmware) {
11763 const struct firmware *fw = NULL;
11764
11765 rc = request_firmware(&fw, mc_file, demod->i2c->dev.parent);
11766 if (rc < 0) {
11767 pr_err("Couldn't read firmware %s\n", mc_file);
11768 return rc;
11769 }
11770 demod->firmware = fw;
11771
11772 if (demod->firmware->size < 2 * sizeof(u16)) {
11773 rc = -EINVAL;
11774 pr_err("Firmware is too short!\n");
11775 goto release;
11776 }
11777
11778 pr_info("Firmware %s, size %zu\n",
11779 mc_file, demod->firmware->size);
11780 }
11781
11782 mc_data_init = demod->firmware->data;
11783 size = demod->firmware->size;
11784
11785 mc_data = (void *)mc_data_init;
11786 /* Check data */
11787 mc_magic_word = be16_to_cpu(*(__be16 *)(mc_data));
11788 mc_data += sizeof(u16);
11789 mc_nr_of_blks = be16_to_cpu(*(__be16 *)(mc_data));
11790 mc_data += sizeof(u16);
11791
11792 if ((mc_magic_word != DRX_UCODE_MAGIC_WORD) || (mc_nr_of_blks == 0)) {
11793 rc = -EINVAL;
11794 pr_err("Firmware magic word doesn't match\n");
11795 goto release;
11796 }
11797
11798 if (action == UCODE_UPLOAD) {
11799 rc = drx_check_firmware(demod, (u8 *)mc_data_init, size);
11800 if (rc)
11801 goto release;
11802 pr_info("Uploading firmware %s\n", mc_file);
11803 } else {
11804 pr_info("Verifying if firmware upload was ok.\n");
11805 }
11806
11807 /* Process microcode blocks */
11808 for (i = 0; i < mc_nr_of_blks; i++) {
11809 struct drxu_code_block_hdr block_hdr;
11810 u16 mc_block_nr_bytes = 0;
11811
11812 /* Process block header */
11813 block_hdr.addr = be32_to_cpu(*(__be32 *)(mc_data));
11814 mc_data += sizeof(u32);
11815 block_hdr.size = be16_to_cpu(*(__be16 *)(mc_data));
11816 mc_data += sizeof(u16);
11817 block_hdr.flags = be16_to_cpu(*(__be16 *)(mc_data));
11818 mc_data += sizeof(u16);
11819 block_hdr.CRC = be16_to_cpu(*(__be16 *)(mc_data));
11820 mc_data += sizeof(u16);
11821
11822 pr_debug("%zd: addr %u, size %u, flags 0x%04x, CRC 0x%04x\n",
11823 (mc_data - mc_data_init), block_hdr.addr,
11824 block_hdr.size, block_hdr.flags, block_hdr.CRC);
11825
11826 /* Check block header on:
11827 - data larger than 64Kb
11828 - if CRC enabled check CRC
11829 */
11830 if ((block_hdr.size > 0x7FFF) ||
11831 (((block_hdr.flags & DRX_UCODE_CRC_FLAG) != 0) &&
11832 (block_hdr.CRC != drx_u_code_compute_crc(mc_data, block_hdr.size)))
11833 ) {
11834 /* Wrong data ! */
11835 rc = -EINVAL;
11836 pr_err("firmware CRC is wrong\n");
11837 goto release;
11838 }
11839
11840 if (!block_hdr.size)
11841 continue;
11842
11843 mc_block_nr_bytes = block_hdr.size * ((u16) sizeof(u16));
11844
11845 /* Perform the desired action */
11846 switch (action) {
11847 case UCODE_UPLOAD: /* Upload microcode */
11848 if (drxdap_fasi_write_block(dev_addr,
11849 block_hdr.addr,
11850 mc_block_nr_bytes,
11851 mc_data, 0x0000)) {
11852 rc = -EIO;
11853 pr_err("error writing firmware at pos %zd\n",
11854 mc_data - mc_data_init);
11855 goto release;
11856 }
11857 break;
11858 case UCODE_VERIFY: { /* Verify uploaded microcode */
11859 int result = 0;
11860 u8 mc_data_buffer[DRX_UCODE_MAX_BUF_SIZE];
11861 u32 bytes_to_comp = 0;
11862 u32 bytes_left = mc_block_nr_bytes;
11863 u32 curr_addr = block_hdr.addr;
11864 u8 *curr_ptr = mc_data;
11865
11866 while (bytes_left != 0) {
11867 if (bytes_left > DRX_UCODE_MAX_BUF_SIZE)
11868 bytes_to_comp = DRX_UCODE_MAX_BUF_SIZE;
11869 else
11870 bytes_to_comp = bytes_left;
11871
11872 if (drxdap_fasi_read_block(dev_addr,
11873 curr_addr,
11874 (u16)bytes_to_comp,
11875 (u8 *)mc_data_buffer,
11876 0x0000)) {
11877 pr_err("error reading firmware at pos %zd\n",
11878 mc_data - mc_data_init);
11879 return -EIO;
11880 }
11881
11882 result = memcmp(curr_ptr, mc_data_buffer,
11883 bytes_to_comp);
11884
11885 if (result) {
11886 pr_err("error verifying firmware at pos %zd\n",
11887 mc_data - mc_data_init);
11888 return -EIO;
11889 }
11890
11891 curr_addr += ((dr_xaddr_t)(bytes_to_comp / 2));
11892 curr_ptr =&(curr_ptr[bytes_to_comp]);
11893 bytes_left -=((u32) bytes_to_comp);
11894 }
11895 break;
11896 }
11897 default:
11898 return -EINVAL;
11899 break;
11900
11901 }
11902 mc_data += mc_block_nr_bytes;
11903 }
11904
11905 return 0;
11906
11907 release:
11908 release_firmware(demod->firmware);
11909 demod->firmware = NULL;
11910
11911 return rc;
11912 }
11913
11914 /* caller is expected to check if lna is supported before enabling */
drxj_set_lna_state(struct drx_demod_instance * demod,bool state)11915 static int drxj_set_lna_state(struct drx_demod_instance *demod, bool state)
11916 {
11917 struct drxuio_cfg uio_cfg;
11918 struct drxuio_data uio_data;
11919 int result;
11920
11921 uio_cfg.uio = DRX_UIO1;
11922 uio_cfg.mode = DRX_UIO_MODE_READWRITE;
11923 /* Configure user-I/O #3: enable read/write */
11924 result = ctrl_set_uio_cfg(demod, &uio_cfg);
11925 if (result) {
11926 pr_err("Failed to setup LNA GPIO!\n");
11927 return result;
11928 }
11929
11930 uio_data.uio = DRX_UIO1;
11931 uio_data.value = state;
11932 result = ctrl_uio_write(demod, &uio_data);
11933 if (result != 0) {
11934 pr_err("Failed to %sable LNA!\n",
11935 state ? "en" : "dis");
11936 return result;
11937 }
11938 return 0;
11939 }
11940
11941 /*
11942 * The Linux DVB Driver for Micronas DRX39xx family (drx3933j)
11943 *
11944 * Written by Devin Heitmueller <devin.heitmueller@kernellabs.com>
11945 */
11946
drx39xxj_set_powerstate(struct dvb_frontend * fe,int enable)11947 static int drx39xxj_set_powerstate(struct dvb_frontend *fe, int enable)
11948 {
11949 struct drx39xxj_state *state = fe->demodulator_priv;
11950 struct drx_demod_instance *demod = state->demod;
11951 int result;
11952 enum drx_power_mode power_mode;
11953
11954 if (enable)
11955 power_mode = DRX_POWER_UP;
11956 else
11957 power_mode = DRX_POWER_DOWN;
11958
11959 result = ctrl_power_mode(demod, &power_mode);
11960 if (result != 0) {
11961 pr_err("Power state change failed\n");
11962 return 0;
11963 }
11964
11965 return 0;
11966 }
11967
drx39xxj_read_status(struct dvb_frontend * fe,enum fe_status * status)11968 static int drx39xxj_read_status(struct dvb_frontend *fe, enum fe_status *status)
11969 {
11970 struct drx39xxj_state *state = fe->demodulator_priv;
11971 struct drx_demod_instance *demod = state->demod;
11972 int result;
11973 enum drx_lock_status lock_status;
11974
11975 *status = 0;
11976
11977 result = ctrl_lock_status(demod, &lock_status);
11978 if (result != 0) {
11979 pr_err("drx39xxj: could not get lock status!\n");
11980 *status = 0;
11981 }
11982
11983 switch (lock_status) {
11984 case DRX_NEVER_LOCK:
11985 *status = 0;
11986 pr_err("drx says NEVER_LOCK\n");
11987 break;
11988 case DRX_NOT_LOCKED:
11989 *status = 0;
11990 break;
11991 case DRX_LOCK_STATE_1:
11992 case DRX_LOCK_STATE_2:
11993 case DRX_LOCK_STATE_3:
11994 case DRX_LOCK_STATE_4:
11995 case DRX_LOCK_STATE_5:
11996 case DRX_LOCK_STATE_6:
11997 case DRX_LOCK_STATE_7:
11998 case DRX_LOCK_STATE_8:
11999 case DRX_LOCK_STATE_9:
12000 *status = FE_HAS_SIGNAL
12001 | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
12002 break;
12003 case DRX_LOCKED:
12004 *status = FE_HAS_SIGNAL
12005 | FE_HAS_CARRIER
12006 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
12007 break;
12008 default:
12009 pr_err("Lock state unknown %d\n", lock_status);
12010 }
12011 ctrl_sig_quality(demod, lock_status);
12012
12013 return 0;
12014 }
12015
drx39xxj_read_ber(struct dvb_frontend * fe,u32 * ber)12016 static int drx39xxj_read_ber(struct dvb_frontend *fe, u32 *ber)
12017 {
12018 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12019
12020 if (p->pre_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12021 *ber = 0;
12022 return 0;
12023 }
12024
12025 if (!p->pre_bit_count.stat[0].uvalue) {
12026 if (!p->pre_bit_error.stat[0].uvalue)
12027 *ber = 0;
12028 else
12029 *ber = 1000000;
12030 } else {
12031 *ber = frac_times1e6(p->pre_bit_error.stat[0].uvalue,
12032 p->pre_bit_count.stat[0].uvalue);
12033 }
12034 return 0;
12035 }
12036
drx39xxj_read_signal_strength(struct dvb_frontend * fe,u16 * strength)12037 static int drx39xxj_read_signal_strength(struct dvb_frontend *fe,
12038 u16 *strength)
12039 {
12040 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12041
12042 if (p->strength.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12043 *strength = 0;
12044 return 0;
12045 }
12046
12047 *strength = p->strength.stat[0].uvalue;
12048 return 0;
12049 }
12050
drx39xxj_read_snr(struct dvb_frontend * fe,u16 * snr)12051 static int drx39xxj_read_snr(struct dvb_frontend *fe, u16 *snr)
12052 {
12053 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12054 u64 tmp64;
12055
12056 if (p->cnr.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12057 *snr = 0;
12058 return 0;
12059 }
12060
12061 tmp64 = p->cnr.stat[0].svalue;
12062 do_div(tmp64, 10);
12063 *snr = tmp64;
12064 return 0;
12065 }
12066
drx39xxj_read_ucblocks(struct dvb_frontend * fe,u32 * ucb)12067 static int drx39xxj_read_ucblocks(struct dvb_frontend *fe, u32 *ucb)
12068 {
12069 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12070
12071 if (p->block_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
12072 *ucb = 0;
12073 return 0;
12074 }
12075
12076 *ucb = p->block_error.stat[0].uvalue;
12077 return 0;
12078 }
12079
drx39xxj_set_frontend(struct dvb_frontend * fe)12080 static int drx39xxj_set_frontend(struct dvb_frontend *fe)
12081 {
12082 #ifdef DJH_DEBUG
12083 int i;
12084 #endif
12085 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
12086 struct drx39xxj_state *state = fe->demodulator_priv;
12087 struct drx_demod_instance *demod = state->demod;
12088 enum drx_standard standard = DRX_STANDARD_8VSB;
12089 struct drx_channel channel;
12090 int result;
12091 static const struct drx_channel def_channel = {
12092 /* frequency */ 0,
12093 /* bandwidth */ DRX_BANDWIDTH_6MHZ,
12094 /* mirror */ DRX_MIRROR_NO,
12095 /* constellation */ DRX_CONSTELLATION_AUTO,
12096 /* hierarchy */ DRX_HIERARCHY_UNKNOWN,
12097 /* priority */ DRX_PRIORITY_UNKNOWN,
12098 /* coderate */ DRX_CODERATE_UNKNOWN,
12099 /* guard */ DRX_GUARD_UNKNOWN,
12100 /* fftmode */ DRX_FFTMODE_UNKNOWN,
12101 /* classification */ DRX_CLASSIFICATION_AUTO,
12102 /* symbolrate */ 5057000,
12103 /* interleavemode */ DRX_INTERLEAVEMODE_UNKNOWN,
12104 /* ldpc */ DRX_LDPC_UNKNOWN,
12105 /* carrier */ DRX_CARRIER_UNKNOWN,
12106 /* frame mode */ DRX_FRAMEMODE_UNKNOWN
12107 };
12108 u32 constellation = DRX_CONSTELLATION_AUTO;
12109
12110 /* Bring the demod out of sleep */
12111 drx39xxj_set_powerstate(fe, 1);
12112
12113 if (fe->ops.tuner_ops.set_params) {
12114 u32 int_freq;
12115
12116 if (fe->ops.i2c_gate_ctrl)
12117 fe->ops.i2c_gate_ctrl(fe, 1);
12118
12119 /* Set tuner to desired frequency and standard */
12120 fe->ops.tuner_ops.set_params(fe);
12121
12122 /* Use the tuner's IF */
12123 if (fe->ops.tuner_ops.get_if_frequency) {
12124 fe->ops.tuner_ops.get_if_frequency(fe, &int_freq);
12125 demod->my_common_attr->intermediate_freq = int_freq / 1000;
12126 }
12127
12128 if (fe->ops.i2c_gate_ctrl)
12129 fe->ops.i2c_gate_ctrl(fe, 0);
12130 }
12131
12132 switch (p->delivery_system) {
12133 case SYS_ATSC:
12134 standard = DRX_STANDARD_8VSB;
12135 break;
12136 case SYS_DVBC_ANNEX_B:
12137 standard = DRX_STANDARD_ITU_B;
12138
12139 switch (p->modulation) {
12140 case QAM_64:
12141 constellation = DRX_CONSTELLATION_QAM64;
12142 break;
12143 case QAM_256:
12144 constellation = DRX_CONSTELLATION_QAM256;
12145 break;
12146 default:
12147 constellation = DRX_CONSTELLATION_AUTO;
12148 break;
12149 }
12150 break;
12151 default:
12152 return -EINVAL;
12153 }
12154 /* Set the standard (will be powered up if necessary */
12155 result = ctrl_set_standard(demod, &standard);
12156 if (result != 0) {
12157 pr_err("Failed to set standard! result=%02x\n",
12158 result);
12159 return -EINVAL;
12160 }
12161
12162 /* set channel parameters */
12163 channel = def_channel;
12164 channel.frequency = p->frequency / 1000;
12165 channel.bandwidth = DRX_BANDWIDTH_6MHZ;
12166 channel.constellation = constellation;
12167
12168 /* program channel */
12169 result = ctrl_set_channel(demod, &channel);
12170 if (result != 0) {
12171 pr_err("Failed to set channel!\n");
12172 return -EINVAL;
12173 }
12174 /* Just for giggles, let's shut off the LNA again.... */
12175 drxj_set_lna_state(demod, false);
12176
12177 /* After set_frontend, except for strength, stats aren't available */
12178 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12179
12180 return 0;
12181 }
12182
drx39xxj_sleep(struct dvb_frontend * fe)12183 static int drx39xxj_sleep(struct dvb_frontend *fe)
12184 {
12185 /* power-down the demodulator */
12186 return drx39xxj_set_powerstate(fe, 0);
12187 }
12188
drx39xxj_i2c_gate_ctrl(struct dvb_frontend * fe,int enable)12189 static int drx39xxj_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
12190 {
12191 struct drx39xxj_state *state = fe->demodulator_priv;
12192 struct drx_demod_instance *demod = state->demod;
12193 bool i2c_gate_state;
12194 int result;
12195
12196 #ifdef DJH_DEBUG
12197 pr_debug("i2c gate call: enable=%d state=%d\n", enable,
12198 state->i2c_gate_open);
12199 #endif
12200
12201 if (enable)
12202 i2c_gate_state = true;
12203 else
12204 i2c_gate_state = false;
12205
12206 if (state->i2c_gate_open == enable) {
12207 /* We're already in the desired state */
12208 return 0;
12209 }
12210
12211 result = ctrl_i2c_bridge(demod, &i2c_gate_state);
12212 if (result != 0) {
12213 pr_err("drx39xxj: could not open i2c gate [%d]\n",
12214 result);
12215 dump_stack();
12216 } else {
12217 state->i2c_gate_open = enable;
12218 }
12219 return 0;
12220 }
12221
drx39xxj_init(struct dvb_frontend * fe)12222 static int drx39xxj_init(struct dvb_frontend *fe)
12223 {
12224 struct drx39xxj_state *state = fe->demodulator_priv;
12225 struct drx_demod_instance *demod = state->demod;
12226 int rc = 0;
12227
12228 if (fe->exit == DVB_FE_DEVICE_RESUME) {
12229 /* so drxj_open() does what it needs to do */
12230 demod->my_common_attr->is_opened = false;
12231 rc = drxj_open(demod);
12232 if (rc != 0)
12233 pr_err("drx39xxj_init(): DRX open failed rc=%d!\n", rc);
12234 } else
12235 drx39xxj_set_powerstate(fe, 1);
12236
12237 return rc;
12238 }
12239
drx39xxj_set_lna(struct dvb_frontend * fe)12240 static int drx39xxj_set_lna(struct dvb_frontend *fe)
12241 {
12242 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
12243 struct drx39xxj_state *state = fe->demodulator_priv;
12244 struct drx_demod_instance *demod = state->demod;
12245 struct drxj_data *ext_attr = demod->my_ext_attr;
12246
12247 if (c->lna) {
12248 if (!ext_attr->has_lna) {
12249 pr_err("LNA is not supported on this device!\n");
12250 return -EINVAL;
12251
12252 }
12253 }
12254
12255 return drxj_set_lna_state(demod, c->lna);
12256 }
12257
drx39xxj_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * tune)12258 static int drx39xxj_get_tune_settings(struct dvb_frontend *fe,
12259 struct dvb_frontend_tune_settings *tune)
12260 {
12261 tune->min_delay_ms = 1000;
12262 return 0;
12263 }
12264
drx39xxj_release(struct dvb_frontend * fe)12265 static void drx39xxj_release(struct dvb_frontend *fe)
12266 {
12267 struct drx39xxj_state *state = fe->demodulator_priv;
12268 struct drx_demod_instance *demod = state->demod;
12269
12270 /* if device is removed don't access it */
12271 if (fe->exit != DVB_FE_DEVICE_REMOVED)
12272 drxj_close(demod);
12273
12274 kfree(demod->my_ext_attr);
12275 kfree(demod->my_common_attr);
12276 kfree(demod->my_i2c_dev_addr);
12277 release_firmware(demod->firmware);
12278 kfree(demod);
12279 kfree(state);
12280 }
12281
12282 static const struct dvb_frontend_ops drx39xxj_ops;
12283
drx39xxj_attach(struct i2c_adapter * i2c)12284 struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c)
12285 {
12286 struct drx39xxj_state *state = NULL;
12287 struct i2c_device_addr *demod_addr = NULL;
12288 struct drx_common_attr *demod_comm_attr = NULL;
12289 struct drxj_data *demod_ext_attr = NULL;
12290 struct drx_demod_instance *demod = NULL;
12291 struct dtv_frontend_properties *p;
12292 int result;
12293
12294 /* allocate memory for the internal state */
12295 state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL);
12296 if (state == NULL)
12297 goto error;
12298
12299 demod = kmemdup(&drxj_default_demod_g,
12300 sizeof(struct drx_demod_instance), GFP_KERNEL);
12301 if (demod == NULL)
12302 goto error;
12303
12304 demod_addr = kmemdup(&drxj_default_addr_g,
12305 sizeof(struct i2c_device_addr), GFP_KERNEL);
12306 if (demod_addr == NULL)
12307 goto error;
12308
12309 demod_comm_attr = kmemdup(&drxj_default_comm_attr_g,
12310 sizeof(struct drx_common_attr), GFP_KERNEL);
12311 if (demod_comm_attr == NULL)
12312 goto error;
12313
12314 demod_ext_attr = kmemdup(&drxj_data_g, sizeof(struct drxj_data),
12315 GFP_KERNEL);
12316 if (demod_ext_attr == NULL)
12317 goto error;
12318
12319 /* setup the state */
12320 state->i2c = i2c;
12321 state->demod = demod;
12322
12323 /* setup the demod data */
12324 demod->my_i2c_dev_addr = demod_addr;
12325 demod->my_common_attr = demod_comm_attr;
12326 demod->my_i2c_dev_addr->user_data = state;
12327 demod->my_common_attr->microcode_file = DRX39XX_MAIN_FIRMWARE;
12328 demod->my_common_attr->verify_microcode = true;
12329 demod->my_common_attr->intermediate_freq = 5000;
12330 demod->my_common_attr->current_power_mode = DRX_POWER_DOWN;
12331 demod->my_ext_attr = demod_ext_attr;
12332 ((struct drxj_data *)demod_ext_attr)->uio_sma_tx_mode = DRX_UIO_MODE_READWRITE;
12333 demod->i2c = i2c;
12334
12335 result = drxj_open(demod);
12336 if (result != 0) {
12337 pr_err("DRX open failed! Aborting\n");
12338 goto error;
12339 }
12340
12341 /* create dvb_frontend */
12342 memcpy(&state->frontend.ops, &drx39xxj_ops,
12343 sizeof(struct dvb_frontend_ops));
12344
12345 state->frontend.demodulator_priv = state;
12346
12347 /* Initialize stats - needed for DVBv5 stats to work */
12348 p = &state->frontend.dtv_property_cache;
12349 p->strength.len = 1;
12350 p->pre_bit_count.len = 1;
12351 p->pre_bit_error.len = 1;
12352 p->post_bit_count.len = 1;
12353 p->post_bit_error.len = 1;
12354 p->block_count.len = 1;
12355 p->block_error.len = 1;
12356 p->cnr.len = 1;
12357
12358 p->strength.stat[0].scale = FE_SCALE_RELATIVE;
12359 p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12360 p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12361 p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12362 p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12363 p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12364 p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12365 p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
12366
12367 return &state->frontend;
12368
12369 error:
12370 kfree(demod_ext_attr);
12371 kfree(demod_comm_attr);
12372 kfree(demod_addr);
12373 kfree(demod);
12374 kfree(state);
12375
12376 return NULL;
12377 }
12378 EXPORT_SYMBOL(drx39xxj_attach);
12379
12380 static const struct dvb_frontend_ops drx39xxj_ops = {
12381 .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
12382 .info = {
12383 .name = "Micronas DRX39xxj family Frontend",
12384 .frequency_min_hz = 51 * MHz,
12385 .frequency_max_hz = 858 * MHz,
12386 .frequency_stepsize_hz = 62500,
12387 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
12388 },
12389
12390 .init = drx39xxj_init,
12391 .i2c_gate_ctrl = drx39xxj_i2c_gate_ctrl,
12392 .sleep = drx39xxj_sleep,
12393 .set_frontend = drx39xxj_set_frontend,
12394 .get_tune_settings = drx39xxj_get_tune_settings,
12395 .read_status = drx39xxj_read_status,
12396 .read_ber = drx39xxj_read_ber,
12397 .read_signal_strength = drx39xxj_read_signal_strength,
12398 .read_snr = drx39xxj_read_snr,
12399 .read_ucblocks = drx39xxj_read_ucblocks,
12400 .release = drx39xxj_release,
12401 .set_lna = drx39xxj_set_lna,
12402 };
12403
12404 MODULE_DESCRIPTION("Micronas DRX39xxj Frontend");
12405 MODULE_AUTHOR("Devin Heitmueller");
12406 MODULE_LICENSE("GPL");
12407 MODULE_FIRMWARE(DRX39XX_MAIN_FIRMWARE);
12408