blob: 458772739423234388c50940bccbae9c3bb63bb6 [file] [log] [blame]
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001/*
2 * stv0367.c
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30#include <linux/i2c.h>
31
32#include "stv0367.h"
33#include "stv0367_regs.h"
34#include "stv0367_priv.h"
35
Mauro Carvalho Chehab9aca4fb2013-11-02 05:17:01 -030036/* Max transfer size done by I2C transfer functions */
37#define MAX_XFER_SIZE 64
38
Igor M. Liplianin17cce932011-01-25 17:02:00 -030039static int stvdebug;
40module_param_named(debug, stvdebug, int, 0644);
41
42static int i2cdebug;
43module_param_named(i2c_debug, i2cdebug, int, 0644);
44
45#define dprintk(args...) \
46 do { \
47 if (stvdebug) \
48 printk(KERN_DEBUG args); \
49 } while (0)
50 /* DVB-C */
51
52struct stv0367cab_state {
53 enum stv0367_cab_signal_type state;
54 u32 mclk;
55 u32 adc_clk;
56 s32 search_range;
57 s32 derot_offset;
58 /* results */
59 int locked; /* channel found */
60 u32 freq_khz; /* found frequency (in kHz) */
61 u32 symbol_rate; /* found symbol rate (in Bds) */
62 enum stv0367cab_mod modulation; /* modulation */
63 fe_spectral_inversion_t spect_inv; /* Spectrum Inversion */
64};
65
66struct stv0367ter_state {
67 /* DVB-T */
68 enum stv0367_ter_signal_type state;
69 enum stv0367_ter_if_iq_mode if_iq_mode;
70 enum stv0367_ter_mode mode;/* mode 2K or 8K */
71 fe_guard_interval_t guard;
72 enum stv0367_ter_hierarchy hierarchy;
73 u32 frequency;
74 fe_spectral_inversion_t sense; /* current search spectrum */
75 u8 force; /* force mode/guard */
76 u8 bw; /* channel width 6, 7 or 8 in MHz */
77 u8 pBW; /* channel width used during previous lock */
78 u32 pBER;
79 u32 pPER;
80 u32 ucblocks;
81 s8 echo_pos; /* echo position */
82 u8 first_lock;
83 u8 unlock_counter;
84 u32 agc_val;
85};
86
87struct stv0367_state {
88 struct dvb_frontend fe;
89 struct i2c_adapter *i2c;
90 /* config settings */
91 const struct stv0367_config *config;
92 u8 chip_id;
93 /* DVB-C */
94 struct stv0367cab_state *cab_state;
95 /* DVB-T */
96 struct stv0367ter_state *ter_state;
97};
98
99struct st_register {
100 u16 addr;
101 u8 value;
102};
103
104/* values for STV4100 XTAL=30M int clk=53.125M*/
105static struct st_register def0367ter[STV0367TER_NBREGS] = {
106 {R367TER_ID, 0x60},
107 {R367TER_I2CRPT, 0xa0},
108 /* {R367TER_I2CRPT, 0x22},*/
109 {R367TER_TOPCTRL, 0x00},/* for xc5000; was 0x02 */
110 {R367TER_IOCFG0, 0x40},
111 {R367TER_DAC0R, 0x00},
112 {R367TER_IOCFG1, 0x00},
113 {R367TER_DAC1R, 0x00},
114 {R367TER_IOCFG2, 0x62},
115 {R367TER_SDFR, 0x00},
116 {R367TER_STATUS, 0xf8},
117 {R367TER_AUX_CLK, 0x0a},
118 {R367TER_FREESYS1, 0x00},
119 {R367TER_FREESYS2, 0x00},
120 {R367TER_FREESYS3, 0x00},
121 {R367TER_GPIO_CFG, 0x55},
122 {R367TER_GPIO_CMD, 0x00},
123 {R367TER_AGC2MAX, 0xff},
124 {R367TER_AGC2MIN, 0x00},
125 {R367TER_AGC1MAX, 0xff},
126 {R367TER_AGC1MIN, 0x00},
127 {R367TER_AGCR, 0xbc},
128 {R367TER_AGC2TH, 0x00},
129 {R367TER_AGC12C, 0x00},
130 {R367TER_AGCCTRL1, 0x85},
131 {R367TER_AGCCTRL2, 0x1f},
132 {R367TER_AGC1VAL1, 0x00},
133 {R367TER_AGC1VAL2, 0x00},
134 {R367TER_AGC2VAL1, 0x6f},
135 {R367TER_AGC2VAL2, 0x05},
136 {R367TER_AGC2PGA, 0x00},
137 {R367TER_OVF_RATE1, 0x00},
138 {R367TER_OVF_RATE2, 0x00},
139 {R367TER_GAIN_SRC1, 0xaa},/* for xc5000; was 0x2b */
140 {R367TER_GAIN_SRC2, 0xd6},/* for xc5000; was 0x04 */
141 {R367TER_INC_DEROT1, 0x55},
142 {R367TER_INC_DEROT2, 0x55},
143 {R367TER_PPM_CPAMP_DIR, 0x2c},
144 {R367TER_PPM_CPAMP_INV, 0x00},
145 {R367TER_FREESTFE_1, 0x00},
146 {R367TER_FREESTFE_2, 0x1c},
147 {R367TER_DCOFFSET, 0x00},
148 {R367TER_EN_PROCESS, 0x05},
149 {R367TER_SDI_SMOOTHER, 0x80},
150 {R367TER_FE_LOOP_OPEN, 0x1c},
151 {R367TER_FREQOFF1, 0x00},
152 {R367TER_FREQOFF2, 0x00},
153 {R367TER_FREQOFF3, 0x00},
154 {R367TER_TIMOFF1, 0x00},
155 {R367TER_TIMOFF2, 0x00},
156 {R367TER_EPQ, 0x02},
157 {R367TER_EPQAUTO, 0x01},
158 {R367TER_SYR_UPDATE, 0xf5},
159 {R367TER_CHPFREE, 0x00},
160 {R367TER_PPM_STATE_MAC, 0x23},
161 {R367TER_INR_THRESHOLD, 0xff},
162 {R367TER_EPQ_TPS_ID_CELL, 0xf9},
163 {R367TER_EPQ_CFG, 0x00},
164 {R367TER_EPQ_STATUS, 0x01},
165 {R367TER_AUTORELOCK, 0x81},
166 {R367TER_BER_THR_VMSB, 0x00},
167 {R367TER_BER_THR_MSB, 0x00},
168 {R367TER_BER_THR_LSB, 0x00},
169 {R367TER_CCD, 0x83},
170 {R367TER_SPECTR_CFG, 0x00},
171 {R367TER_CHC_DUMMY, 0x18},
172 {R367TER_INC_CTL, 0x88},
173 {R367TER_INCTHRES_COR1, 0xb4},
174 {R367TER_INCTHRES_COR2, 0x96},
175 {R367TER_INCTHRES_DET1, 0x0e},
176 {R367TER_INCTHRES_DET2, 0x11},
177 {R367TER_IIR_CELLNB, 0x8d},
178 {R367TER_IIRCX_COEFF1_MSB, 0x00},
179 {R367TER_IIRCX_COEFF1_LSB, 0x00},
180 {R367TER_IIRCX_COEFF2_MSB, 0x09},
181 {R367TER_IIRCX_COEFF2_LSB, 0x18},
182 {R367TER_IIRCX_COEFF3_MSB, 0x14},
183 {R367TER_IIRCX_COEFF3_LSB, 0x9c},
184 {R367TER_IIRCX_COEFF4_MSB, 0x00},
185 {R367TER_IIRCX_COEFF4_LSB, 0x00},
186 {R367TER_IIRCX_COEFF5_MSB, 0x36},
187 {R367TER_IIRCX_COEFF5_LSB, 0x42},
188 {R367TER_FEPATH_CFG, 0x00},
189 {R367TER_PMC1_FUNC, 0x65},
190 {R367TER_PMC1_FOR, 0x00},
191 {R367TER_PMC2_FUNC, 0x00},
192 {R367TER_STATUS_ERR_DA, 0xe0},
193 {R367TER_DIG_AGC_R, 0xfe},
194 {R367TER_COMAGC_TARMSB, 0x0b},
195 {R367TER_COM_AGC_TAR_ENMODE, 0x41},
196 {R367TER_COM_AGC_CFG, 0x3e},
197 {R367TER_COM_AGC_GAIN1, 0x39},
198 {R367TER_AUT_AGC_TARGETMSB, 0x0b},
199 {R367TER_LOCK_DET_MSB, 0x01},
200 {R367TER_AGCTAR_LOCK_LSBS, 0x40},
201 {R367TER_AUT_GAIN_EN, 0xf4},
202 {R367TER_AUT_CFG, 0xf0},
203 {R367TER_LOCKN, 0x23},
204 {R367TER_INT_X_3, 0x00},
205 {R367TER_INT_X_2, 0x03},
206 {R367TER_INT_X_1, 0x8d},
207 {R367TER_INT_X_0, 0xa0},
208 {R367TER_MIN_ERRX_MSB, 0x00},
209 {R367TER_COR_CTL, 0x23},
210 {R367TER_COR_STAT, 0xf6},
211 {R367TER_COR_INTEN, 0x00},
212 {R367TER_COR_INTSTAT, 0x3f},
213 {R367TER_COR_MODEGUARD, 0x03},
214 {R367TER_AGC_CTL, 0x08},
215 {R367TER_AGC_MANUAL1, 0x00},
216 {R367TER_AGC_MANUAL2, 0x00},
217 {R367TER_AGC_TARG, 0x16},
218 {R367TER_AGC_GAIN1, 0x53},
219 {R367TER_AGC_GAIN2, 0x1d},
220 {R367TER_RESERVED_1, 0x00},
221 {R367TER_RESERVED_2, 0x00},
222 {R367TER_RESERVED_3, 0x00},
223 {R367TER_CAS_CTL, 0x44},
224 {R367TER_CAS_FREQ, 0xb3},
225 {R367TER_CAS_DAGCGAIN, 0x12},
226 {R367TER_SYR_CTL, 0x04},
227 {R367TER_SYR_STAT, 0x10},
228 {R367TER_SYR_NCO1, 0x00},
229 {R367TER_SYR_NCO2, 0x00},
230 {R367TER_SYR_OFFSET1, 0x00},
231 {R367TER_SYR_OFFSET2, 0x00},
232 {R367TER_FFT_CTL, 0x00},
233 {R367TER_SCR_CTL, 0x70},
234 {R367TER_PPM_CTL1, 0xf8},
235 {R367TER_TRL_CTL, 0x14},/* for xc5000; was 0xac */
236 {R367TER_TRL_NOMRATE1, 0xae},/* for xc5000; was 0x1e */
237 {R367TER_TRL_NOMRATE2, 0x56},/* for xc5000; was 0x58 */
238 {R367TER_TRL_TIME1, 0x1d},
239 {R367TER_TRL_TIME2, 0xfc},
240 {R367TER_CRL_CTL, 0x24},
241 {R367TER_CRL_FREQ1, 0xad},
242 {R367TER_CRL_FREQ2, 0x9d},
243 {R367TER_CRL_FREQ3, 0xff},
244 {R367TER_CHC_CTL, 0x01},
245 {R367TER_CHC_SNR, 0xf0},
246 {R367TER_BDI_CTL, 0x00},
247 {R367TER_DMP_CTL, 0x00},
248 {R367TER_TPS_RCVD1, 0x30},
249 {R367TER_TPS_RCVD2, 0x02},
250 {R367TER_TPS_RCVD3, 0x01},
251 {R367TER_TPS_RCVD4, 0x00},
252 {R367TER_TPS_ID_CELL1, 0x00},
253 {R367TER_TPS_ID_CELL2, 0x00},
254 {R367TER_TPS_RCVD5_SET1, 0x02},
255 {R367TER_TPS_SET2, 0x02},
256 {R367TER_TPS_SET3, 0x01},
257 {R367TER_TPS_CTL, 0x00},
258 {R367TER_CTL_FFTOSNUM, 0x34},
259 {R367TER_TESTSELECT, 0x09},
260 {R367TER_MSC_REV, 0x0a},
261 {R367TER_PIR_CTL, 0x00},
262 {R367TER_SNR_CARRIER1, 0xa1},
263 {R367TER_SNR_CARRIER2, 0x9a},
264 {R367TER_PPM_CPAMP, 0x2c},
265 {R367TER_TSM_AP0, 0x00},
266 {R367TER_TSM_AP1, 0x00},
267 {R367TER_TSM_AP2 , 0x00},
268 {R367TER_TSM_AP3, 0x00},
269 {R367TER_TSM_AP4, 0x00},
270 {R367TER_TSM_AP5, 0x00},
271 {R367TER_TSM_AP6, 0x00},
272 {R367TER_TSM_AP7, 0x00},
273 {R367TER_TSTRES, 0x00},
274 {R367TER_ANACTRL, 0x0D},/* PLL stoped, restart at init!!! */
275 {R367TER_TSTBUS, 0x00},
276 {R367TER_TSTRATE, 0x00},
277 {R367TER_CONSTMODE, 0x01},
278 {R367TER_CONSTCARR1, 0x00},
279 {R367TER_CONSTCARR2, 0x00},
280 {R367TER_ICONSTEL, 0x0a},
281 {R367TER_QCONSTEL, 0x15},
282 {R367TER_TSTBISTRES0, 0x00},
283 {R367TER_TSTBISTRES1, 0x00},
284 {R367TER_TSTBISTRES2, 0x28},
285 {R367TER_TSTBISTRES3, 0x00},
286 {R367TER_RF_AGC1, 0xff},
287 {R367TER_RF_AGC2, 0x83},
288 {R367TER_ANADIGCTRL, 0x19},
289 {R367TER_PLLMDIV, 0x01},/* for xc5000; was 0x0c */
290 {R367TER_PLLNDIV, 0x06},/* for xc5000; was 0x55 */
291 {R367TER_PLLSETUP, 0x18},
Abylay Ospan01a475d2011-01-02 09:11:00 -0300292 {R367TER_DUAL_AD12, 0x0C},/* for xc5000 AGC voltage 1.6V */
Igor M. Liplianin17cce932011-01-25 17:02:00 -0300293 {R367TER_TSTBIST, 0x00},
294 {R367TER_PAD_COMP_CTRL, 0x00},
295 {R367TER_PAD_COMP_WR, 0x00},
296 {R367TER_PAD_COMP_RD, 0xe0},
297 {R367TER_SYR_TARGET_FFTADJT_MSB, 0x00},
298 {R367TER_SYR_TARGET_FFTADJT_LSB, 0x00},
299 {R367TER_SYR_TARGET_CHCADJT_MSB, 0x00},
300 {R367TER_SYR_TARGET_CHCADJT_LSB, 0x00},
301 {R367TER_SYR_FLAG, 0x00},
302 {R367TER_CRL_TARGET1, 0x00},
303 {R367TER_CRL_TARGET2, 0x00},
304 {R367TER_CRL_TARGET3, 0x00},
305 {R367TER_CRL_TARGET4, 0x00},
306 {R367TER_CRL_FLAG, 0x00},
307 {R367TER_TRL_TARGET1, 0x00},
308 {R367TER_TRL_TARGET2, 0x00},
309 {R367TER_TRL_CHC, 0x00},
310 {R367TER_CHC_SNR_TARG, 0x00},
311 {R367TER_TOP_TRACK, 0x00},
312 {R367TER_TRACKER_FREE1, 0x00},
313 {R367TER_ERROR_CRL1, 0x00},
314 {R367TER_ERROR_CRL2, 0x00},
315 {R367TER_ERROR_CRL3, 0x00},
316 {R367TER_ERROR_CRL4, 0x00},
317 {R367TER_DEC_NCO1, 0x2c},
318 {R367TER_DEC_NCO2, 0x0f},
319 {R367TER_DEC_NCO3, 0x20},
320 {R367TER_SNR, 0xf1},
321 {R367TER_SYR_FFTADJ1, 0x00},
322 {R367TER_SYR_FFTADJ2, 0x00},
323 {R367TER_SYR_CHCADJ1, 0x00},
324 {R367TER_SYR_CHCADJ2, 0x00},
325 {R367TER_SYR_OFF, 0x00},
326 {R367TER_PPM_OFFSET1, 0x00},
327 {R367TER_PPM_OFFSET2, 0x03},
328 {R367TER_TRACKER_FREE2, 0x00},
329 {R367TER_DEBG_LT10, 0x00},
330 {R367TER_DEBG_LT11, 0x00},
331 {R367TER_DEBG_LT12, 0x00},
332 {R367TER_DEBG_LT13, 0x00},
333 {R367TER_DEBG_LT14, 0x00},
334 {R367TER_DEBG_LT15, 0x00},
335 {R367TER_DEBG_LT16, 0x00},
336 {R367TER_DEBG_LT17, 0x00},
337 {R367TER_DEBG_LT18, 0x00},
338 {R367TER_DEBG_LT19, 0x00},
339 {R367TER_DEBG_LT1A, 0x00},
340 {R367TER_DEBG_LT1B, 0x00},
341 {R367TER_DEBG_LT1C, 0x00},
342 {R367TER_DEBG_LT1D, 0x00},
343 {R367TER_DEBG_LT1E, 0x00},
344 {R367TER_DEBG_LT1F, 0x00},
345 {R367TER_RCCFGH, 0x00},
346 {R367TER_RCCFGM, 0x00},
347 {R367TER_RCCFGL, 0x00},
348 {R367TER_RCINSDELH, 0x00},
349 {R367TER_RCINSDELM, 0x00},
350 {R367TER_RCINSDELL, 0x00},
351 {R367TER_RCSTATUS, 0x00},
352 {R367TER_RCSPEED, 0x6f},
353 {R367TER_RCDEBUGM, 0xe7},
354 {R367TER_RCDEBUGL, 0x9b},
355 {R367TER_RCOBSCFG, 0x00},
356 {R367TER_RCOBSM, 0x00},
357 {R367TER_RCOBSL, 0x00},
358 {R367TER_RCFECSPY, 0x00},
359 {R367TER_RCFSPYCFG, 0x00},
360 {R367TER_RCFSPYDATA, 0x00},
361 {R367TER_RCFSPYOUT, 0x00},
362 {R367TER_RCFSTATUS, 0x00},
363 {R367TER_RCFGOODPACK, 0x00},
364 {R367TER_RCFPACKCNT, 0x00},
365 {R367TER_RCFSPYMISC, 0x00},
366 {R367TER_RCFBERCPT4, 0x00},
367 {R367TER_RCFBERCPT3, 0x00},
368 {R367TER_RCFBERCPT2, 0x00},
369 {R367TER_RCFBERCPT1, 0x00},
370 {R367TER_RCFBERCPT0, 0x00},
371 {R367TER_RCFBERERR2, 0x00},
372 {R367TER_RCFBERERR1, 0x00},
373 {R367TER_RCFBERERR0, 0x00},
374 {R367TER_RCFSTATESM, 0x00},
375 {R367TER_RCFSTATESL, 0x00},
376 {R367TER_RCFSPYBER, 0x00},
377 {R367TER_RCFSPYDISTM, 0x00},
378 {R367TER_RCFSPYDISTL, 0x00},
379 {R367TER_RCFSPYOBS7, 0x00},
380 {R367TER_RCFSPYOBS6, 0x00},
381 {R367TER_RCFSPYOBS5, 0x00},
382 {R367TER_RCFSPYOBS4, 0x00},
383 {R367TER_RCFSPYOBS3, 0x00},
384 {R367TER_RCFSPYOBS2, 0x00},
385 {R367TER_RCFSPYOBS1, 0x00},
386 {R367TER_RCFSPYOBS0, 0x00},
387 {R367TER_TSGENERAL, 0x00},
388 {R367TER_RC1SPEED, 0x6f},
389 {R367TER_TSGSTATUS, 0x18},
390 {R367TER_FECM, 0x01},
391 {R367TER_VTH12, 0xff},
392 {R367TER_VTH23, 0xa1},
393 {R367TER_VTH34, 0x64},
394 {R367TER_VTH56, 0x40},
395 {R367TER_VTH67, 0x00},
396 {R367TER_VTH78, 0x2c},
397 {R367TER_VITCURPUN, 0x12},
398 {R367TER_VERROR, 0x01},
399 {R367TER_PRVIT, 0x3f},
400 {R367TER_VAVSRVIT, 0x00},
401 {R367TER_VSTATUSVIT, 0xbd},
402 {R367TER_VTHINUSE, 0xa1},
403 {R367TER_KDIV12, 0x20},
404 {R367TER_KDIV23, 0x40},
405 {R367TER_KDIV34, 0x20},
406 {R367TER_KDIV56, 0x30},
407 {R367TER_KDIV67, 0x00},
408 {R367TER_KDIV78, 0x30},
409 {R367TER_SIGPOWER, 0x54},
410 {R367TER_DEMAPVIT, 0x40},
411 {R367TER_VITSCALE, 0x00},
412 {R367TER_FFEC1PRG, 0x00},
413 {R367TER_FVITCURPUN, 0x12},
414 {R367TER_FVERROR, 0x01},
415 {R367TER_FVSTATUSVIT, 0xbd},
416 {R367TER_DEBUG_LT1, 0x00},
417 {R367TER_DEBUG_LT2, 0x00},
418 {R367TER_DEBUG_LT3, 0x00},
419 {R367TER_TSTSFMET, 0x00},
420 {R367TER_SELOUT, 0x00},
421 {R367TER_TSYNC, 0x00},
422 {R367TER_TSTERR, 0x00},
423 {R367TER_TSFSYNC, 0x00},
424 {R367TER_TSTSFERR, 0x00},
425 {R367TER_TSTTSSF1, 0x01},
426 {R367TER_TSTTSSF2, 0x1f},
427 {R367TER_TSTTSSF3, 0x00},
428 {R367TER_TSTTS1, 0x00},
429 {R367TER_TSTTS2, 0x1f},
430 {R367TER_TSTTS3, 0x01},
431 {R367TER_TSTTS4, 0x00},
432 {R367TER_TSTTSRC, 0x00},
433 {R367TER_TSTTSRS, 0x00},
434 {R367TER_TSSTATEM, 0xb0},
435 {R367TER_TSSTATEL, 0x40},
436 {R367TER_TSCFGH, 0xC0},
437 {R367TER_TSCFGM, 0xc0},/* for xc5000; was 0x00 */
438 {R367TER_TSCFGL, 0x20},
439 {R367TER_TSSYNC, 0x00},
440 {R367TER_TSINSDELH, 0x00},
441 {R367TER_TSINSDELM, 0x00},
442 {R367TER_TSINSDELL, 0x00},
443 {R367TER_TSDIVN, 0x03},
444 {R367TER_TSDIVPM, 0x00},
445 {R367TER_TSDIVPL, 0x00},
446 {R367TER_TSDIVQM, 0x00},
447 {R367TER_TSDIVQL, 0x00},
448 {R367TER_TSDILSTKM, 0x00},
449 {R367TER_TSDILSTKL, 0x00},
450 {R367TER_TSSPEED, 0x40},/* for xc5000; was 0x6f */
451 {R367TER_TSSTATUS, 0x81},
452 {R367TER_TSSTATUS2, 0x6a},
453 {R367TER_TSBITRATEM, 0x0f},
454 {R367TER_TSBITRATEL, 0xc6},
455 {R367TER_TSPACKLENM, 0x00},
456 {R367TER_TSPACKLENL, 0xfc},
457 {R367TER_TSBLOCLENM, 0x0a},
458 {R367TER_TSBLOCLENL, 0x80},
459 {R367TER_TSDLYH, 0x90},
460 {R367TER_TSDLYM, 0x68},
461 {R367TER_TSDLYL, 0x01},
462 {R367TER_TSNPDAV, 0x00},
463 {R367TER_TSBUFSTATH, 0x00},
464 {R367TER_TSBUFSTATM, 0x00},
465 {R367TER_TSBUFSTATL, 0x00},
466 {R367TER_TSDEBUGM, 0xcf},
467 {R367TER_TSDEBUGL, 0x1e},
468 {R367TER_TSDLYSETH, 0x00},
469 {R367TER_TSDLYSETM, 0x68},
470 {R367TER_TSDLYSETL, 0x00},
471 {R367TER_TSOBSCFG, 0x00},
472 {R367TER_TSOBSM, 0x47},
473 {R367TER_TSOBSL, 0x1f},
474 {R367TER_ERRCTRL1, 0x95},
475 {R367TER_ERRCNT1H, 0x80},
476 {R367TER_ERRCNT1M, 0x00},
477 {R367TER_ERRCNT1L, 0x00},
478 {R367TER_ERRCTRL2, 0x95},
479 {R367TER_ERRCNT2H, 0x00},
480 {R367TER_ERRCNT2M, 0x00},
481 {R367TER_ERRCNT2L, 0x00},
482 {R367TER_FECSPY, 0x88},
483 {R367TER_FSPYCFG, 0x2c},
484 {R367TER_FSPYDATA, 0x3a},
485 {R367TER_FSPYOUT, 0x06},
486 {R367TER_FSTATUS, 0x61},
487 {R367TER_FGOODPACK, 0xff},
488 {R367TER_FPACKCNT, 0xff},
489 {R367TER_FSPYMISC, 0x66},
490 {R367TER_FBERCPT4, 0x00},
491 {R367TER_FBERCPT3, 0x00},
492 {R367TER_FBERCPT2, 0x36},
493 {R367TER_FBERCPT1, 0x36},
494 {R367TER_FBERCPT0, 0x14},
495 {R367TER_FBERERR2, 0x00},
496 {R367TER_FBERERR1, 0x03},
497 {R367TER_FBERERR0, 0x28},
498 {R367TER_FSTATESM, 0x00},
499 {R367TER_FSTATESL, 0x02},
500 {R367TER_FSPYBER, 0x00},
501 {R367TER_FSPYDISTM, 0x01},
502 {R367TER_FSPYDISTL, 0x9f},
503 {R367TER_FSPYOBS7, 0xc9},
504 {R367TER_FSPYOBS6, 0x99},
505 {R367TER_FSPYOBS5, 0x08},
506 {R367TER_FSPYOBS4, 0xec},
507 {R367TER_FSPYOBS3, 0x01},
508 {R367TER_FSPYOBS2, 0x0f},
509 {R367TER_FSPYOBS1, 0xf5},
510 {R367TER_FSPYOBS0, 0x08},
511 {R367TER_SFDEMAP, 0x40},
512 {R367TER_SFERROR, 0x00},
513 {R367TER_SFAVSR, 0x30},
514 {R367TER_SFECSTATUS, 0xcc},
515 {R367TER_SFKDIV12, 0x20},
516 {R367TER_SFKDIV23, 0x40},
517 {R367TER_SFKDIV34, 0x20},
518 {R367TER_SFKDIV56, 0x20},
519 {R367TER_SFKDIV67, 0x00},
520 {R367TER_SFKDIV78, 0x20},
521 {R367TER_SFDILSTKM, 0x00},
522 {R367TER_SFDILSTKL, 0x00},
523 {R367TER_SFSTATUS, 0xb5},
524 {R367TER_SFDLYH, 0x90},
525 {R367TER_SFDLYM, 0x60},
526 {R367TER_SFDLYL, 0x01},
527 {R367TER_SFDLYSETH, 0xc0},
528 {R367TER_SFDLYSETM, 0x60},
529 {R367TER_SFDLYSETL, 0x00},
530 {R367TER_SFOBSCFG, 0x00},
531 {R367TER_SFOBSM, 0x47},
532 {R367TER_SFOBSL, 0x05},
533 {R367TER_SFECINFO, 0x40},
534 {R367TER_SFERRCTRL, 0x74},
535 {R367TER_SFERRCNTH, 0x80},
536 {R367TER_SFERRCNTM , 0x00},
537 {R367TER_SFERRCNTL, 0x00},
538 {R367TER_SYMBRATEM, 0x2f},
539 {R367TER_SYMBRATEL, 0x50},
540 {R367TER_SYMBSTATUS, 0x7f},
541 {R367TER_SYMBCFG, 0x00},
542 {R367TER_SYMBFIFOM, 0xf4},
543 {R367TER_SYMBFIFOL, 0x0d},
544 {R367TER_SYMBOFFSM, 0xf0},
545 {R367TER_SYMBOFFSL, 0x2d},
546 {R367TER_DEBUG_LT4, 0x00},
547 {R367TER_DEBUG_LT5, 0x00},
548 {R367TER_DEBUG_LT6, 0x00},
549 {R367TER_DEBUG_LT7, 0x00},
550 {R367TER_DEBUG_LT8, 0x00},
551 {R367TER_DEBUG_LT9, 0x00},
552};
553
554#define RF_LOOKUP_TABLE_SIZE 31
555#define RF_LOOKUP_TABLE2_SIZE 16
556/* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
557s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
558 {/*AGC1*/
559 48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
560 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
561 76, 77, 78, 80, 83, 85, 88,
562 }, {/*RF(dbm)*/
563 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
564 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 47,
565 49, 50, 52, 53, 54, 55, 56,
566 }
567};
568/* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
569s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
570 {/*AGC2*/
571 28, 29, 31, 32, 34, 35, 36, 37,
572 38, 39, 40, 41, 42, 43, 44, 45,
573 }, {/*RF(dbm)*/
574 57, 58, 59, 60, 61, 62, 63, 64,
575 65, 66, 67, 68, 69, 70, 71, 72,
576 }
577};
578
579static struct st_register def0367cab[STV0367CAB_NBREGS] = {
580 {R367CAB_ID, 0x60},
581 {R367CAB_I2CRPT, 0xa0},
582 /*{R367CAB_I2CRPT, 0x22},*/
583 {R367CAB_TOPCTRL, 0x10},
584 {R367CAB_IOCFG0, 0x80},
585 {R367CAB_DAC0R, 0x00},
586 {R367CAB_IOCFG1, 0x00},
587 {R367CAB_DAC1R, 0x00},
588 {R367CAB_IOCFG2, 0x00},
589 {R367CAB_SDFR, 0x00},
590 {R367CAB_AUX_CLK, 0x00},
591 {R367CAB_FREESYS1, 0x00},
592 {R367CAB_FREESYS2, 0x00},
593 {R367CAB_FREESYS3, 0x00},
594 {R367CAB_GPIO_CFG, 0x55},
595 {R367CAB_GPIO_CMD, 0x01},
596 {R367CAB_TSTRES, 0x00},
597 {R367CAB_ANACTRL, 0x0d},/* was 0x00 need to check - I.M.L.*/
598 {R367CAB_TSTBUS, 0x00},
599 {R367CAB_RF_AGC1, 0xea},
600 {R367CAB_RF_AGC2, 0x82},
601 {R367CAB_ANADIGCTRL, 0x0b},
602 {R367CAB_PLLMDIV, 0x01},
603 {R367CAB_PLLNDIV, 0x08},
604 {R367CAB_PLLSETUP, 0x18},
Abylay Ospan01a475d2011-01-02 09:11:00 -0300605 {R367CAB_DUAL_AD12, 0x0C}, /* for xc5000 AGC voltage 1.6V */
Igor M. Liplianin17cce932011-01-25 17:02:00 -0300606 {R367CAB_TSTBIST, 0x00},
607 {R367CAB_CTRL_1, 0x00},
608 {R367CAB_CTRL_2, 0x03},
609 {R367CAB_IT_STATUS1, 0x2b},
610 {R367CAB_IT_STATUS2, 0x08},
611 {R367CAB_IT_EN1, 0x00},
612 {R367CAB_IT_EN2, 0x00},
613 {R367CAB_CTRL_STATUS, 0x04},
614 {R367CAB_TEST_CTL, 0x00},
615 {R367CAB_AGC_CTL, 0x73},
616 {R367CAB_AGC_IF_CFG, 0x50},
617 {R367CAB_AGC_RF_CFG, 0x00},
618 {R367CAB_AGC_PWM_CFG, 0x03},
619 {R367CAB_AGC_PWR_REF_L, 0x5a},
620 {R367CAB_AGC_PWR_REF_H, 0x00},
621 {R367CAB_AGC_RF_TH_L, 0xff},
622 {R367CAB_AGC_RF_TH_H, 0x07},
623 {R367CAB_AGC_IF_LTH_L, 0x00},
624 {R367CAB_AGC_IF_LTH_H, 0x08},
625 {R367CAB_AGC_IF_HTH_L, 0xff},
626 {R367CAB_AGC_IF_HTH_H, 0x07},
627 {R367CAB_AGC_PWR_RD_L, 0xa0},
628 {R367CAB_AGC_PWR_RD_M, 0xe9},
629 {R367CAB_AGC_PWR_RD_H, 0x03},
630 {R367CAB_AGC_PWM_IFCMD_L, 0xe4},
631 {R367CAB_AGC_PWM_IFCMD_H, 0x00},
632 {R367CAB_AGC_PWM_RFCMD_L, 0xff},
633 {R367CAB_AGC_PWM_RFCMD_H, 0x07},
634 {R367CAB_IQDEM_CFG, 0x01},
635 {R367CAB_MIX_NCO_LL, 0x22},
636 {R367CAB_MIX_NCO_HL, 0x96},
637 {R367CAB_MIX_NCO_HH, 0x55},
638 {R367CAB_SRC_NCO_LL, 0xff},
639 {R367CAB_SRC_NCO_LH, 0x0c},
640 {R367CAB_SRC_NCO_HL, 0xf5},
641 {R367CAB_SRC_NCO_HH, 0x20},
642 {R367CAB_IQDEM_GAIN_SRC_L, 0x06},
643 {R367CAB_IQDEM_GAIN_SRC_H, 0x01},
644 {R367CAB_IQDEM_DCRM_CFG_LL, 0xfe},
645 {R367CAB_IQDEM_DCRM_CFG_LH, 0xff},
646 {R367CAB_IQDEM_DCRM_CFG_HL, 0x0f},
647 {R367CAB_IQDEM_DCRM_CFG_HH, 0x00},
648 {R367CAB_IQDEM_ADJ_COEFF0, 0x34},
649 {R367CAB_IQDEM_ADJ_COEFF1, 0xae},
650 {R367CAB_IQDEM_ADJ_COEFF2, 0x46},
651 {R367CAB_IQDEM_ADJ_COEFF3, 0x77},
652 {R367CAB_IQDEM_ADJ_COEFF4, 0x96},
653 {R367CAB_IQDEM_ADJ_COEFF5, 0x69},
654 {R367CAB_IQDEM_ADJ_COEFF6, 0xc7},
655 {R367CAB_IQDEM_ADJ_COEFF7, 0x01},
656 {R367CAB_IQDEM_ADJ_EN, 0x04},
657 {R367CAB_IQDEM_ADJ_AGC_REF, 0x94},
658 {R367CAB_ALLPASSFILT1, 0xc9},
659 {R367CAB_ALLPASSFILT2, 0x2d},
660 {R367CAB_ALLPASSFILT3, 0xa3},
661 {R367CAB_ALLPASSFILT4, 0xfb},
662 {R367CAB_ALLPASSFILT5, 0xf6},
663 {R367CAB_ALLPASSFILT6, 0x45},
664 {R367CAB_ALLPASSFILT7, 0x6f},
665 {R367CAB_ALLPASSFILT8, 0x7e},
666 {R367CAB_ALLPASSFILT9, 0x05},
667 {R367CAB_ALLPASSFILT10, 0x0a},
668 {R367CAB_ALLPASSFILT11, 0x51},
669 {R367CAB_TRL_AGC_CFG, 0x20},
670 {R367CAB_TRL_LPF_CFG, 0x28},
671 {R367CAB_TRL_LPF_ACQ_GAIN, 0x44},
672 {R367CAB_TRL_LPF_TRK_GAIN, 0x22},
673 {R367CAB_TRL_LPF_OUT_GAIN, 0x03},
674 {R367CAB_TRL_LOCKDET_LTH, 0x04},
675 {R367CAB_TRL_LOCKDET_HTH, 0x11},
676 {R367CAB_TRL_LOCKDET_TRGVAL, 0x20},
677 {R367CAB_IQ_QAM, 0x01},
678 {R367CAB_FSM_STATE, 0xa0},
679 {R367CAB_FSM_CTL, 0x08},
680 {R367CAB_FSM_STS, 0x0c},
681 {R367CAB_FSM_SNR0_HTH, 0x00},
682 {R367CAB_FSM_SNR1_HTH, 0x00},
683 {R367CAB_FSM_SNR2_HTH, 0x23},/* 0x00 */
684 {R367CAB_FSM_SNR0_LTH, 0x00},
685 {R367CAB_FSM_SNR1_LTH, 0x00},
686 {R367CAB_FSM_EQA1_HTH, 0x00},
687 {R367CAB_FSM_TEMPO, 0x32},
688 {R367CAB_FSM_CONFIG, 0x03},
689 {R367CAB_EQU_I_TESTTAP_L, 0x11},
690 {R367CAB_EQU_I_TESTTAP_M, 0x00},
691 {R367CAB_EQU_I_TESTTAP_H, 0x00},
692 {R367CAB_EQU_TESTAP_CFG, 0x00},
693 {R367CAB_EQU_Q_TESTTAP_L, 0xff},
694 {R367CAB_EQU_Q_TESTTAP_M, 0x00},
695 {R367CAB_EQU_Q_TESTTAP_H, 0x00},
696 {R367CAB_EQU_TAP_CTRL, 0x00},
697 {R367CAB_EQU_CTR_CRL_CONTROL_L, 0x11},
698 {R367CAB_EQU_CTR_CRL_CONTROL_H, 0x05},
699 {R367CAB_EQU_CTR_HIPOW_L, 0x00},
700 {R367CAB_EQU_CTR_HIPOW_H, 0x00},
701 {R367CAB_EQU_I_EQU_LO, 0xef},
702 {R367CAB_EQU_I_EQU_HI, 0x00},
703 {R367CAB_EQU_Q_EQU_LO, 0xee},
704 {R367CAB_EQU_Q_EQU_HI, 0x00},
705 {R367CAB_EQU_MAPPER, 0xc5},
706 {R367CAB_EQU_SWEEP_RATE, 0x80},
707 {R367CAB_EQU_SNR_LO, 0x64},
708 {R367CAB_EQU_SNR_HI, 0x03},
709 {R367CAB_EQU_GAMMA_LO, 0x00},
710 {R367CAB_EQU_GAMMA_HI, 0x00},
711 {R367CAB_EQU_ERR_GAIN, 0x36},
712 {R367CAB_EQU_RADIUS, 0xaa},
713 {R367CAB_EQU_FFE_MAINTAP, 0x00},
714 {R367CAB_EQU_FFE_LEAKAGE, 0x63},
715 {R367CAB_EQU_FFE_MAINTAP_POS, 0xdf},
716 {R367CAB_EQU_GAIN_WIDE, 0x88},
717 {R367CAB_EQU_GAIN_NARROW, 0x41},
718 {R367CAB_EQU_CTR_LPF_GAIN, 0xd1},
719 {R367CAB_EQU_CRL_LPF_GAIN, 0xa7},
720 {R367CAB_EQU_GLOBAL_GAIN, 0x06},
721 {R367CAB_EQU_CRL_LD_SEN, 0x85},
722 {R367CAB_EQU_CRL_LD_VAL, 0xe2},
723 {R367CAB_EQU_CRL_TFR, 0x20},
724 {R367CAB_EQU_CRL_BISTH_LO, 0x00},
725 {R367CAB_EQU_CRL_BISTH_HI, 0x00},
726 {R367CAB_EQU_SWEEP_RANGE_LO, 0x00},
727 {R367CAB_EQU_SWEEP_RANGE_HI, 0x00},
728 {R367CAB_EQU_CRL_LIMITER, 0x40},
729 {R367CAB_EQU_MODULUS_MAP, 0x90},
730 {R367CAB_EQU_PNT_GAIN, 0xa7},
731 {R367CAB_FEC_AC_CTR_0, 0x16},
732 {R367CAB_FEC_AC_CTR_1, 0x0b},
733 {R367CAB_FEC_AC_CTR_2, 0x88},
734 {R367CAB_FEC_AC_CTR_3, 0x02},
735 {R367CAB_FEC_STATUS, 0x12},
736 {R367CAB_RS_COUNTER_0, 0x7d},
737 {R367CAB_RS_COUNTER_1, 0xd0},
738 {R367CAB_RS_COUNTER_2, 0x19},
739 {R367CAB_RS_COUNTER_3, 0x0b},
740 {R367CAB_RS_COUNTER_4, 0xa3},
741 {R367CAB_RS_COUNTER_5, 0x00},
742 {R367CAB_BERT_0, 0x01},
743 {R367CAB_BERT_1, 0x25},
744 {R367CAB_BERT_2, 0x41},
745 {R367CAB_BERT_3, 0x39},
746 {R367CAB_OUTFORMAT_0, 0xc2},
747 {R367CAB_OUTFORMAT_1, 0x22},
748 {R367CAB_SMOOTHER_2, 0x28},
749 {R367CAB_TSMF_CTRL_0, 0x01},
750 {R367CAB_TSMF_CTRL_1, 0xc6},
751 {R367CAB_TSMF_CTRL_3, 0x43},
752 {R367CAB_TS_ON_ID_0, 0x00},
753 {R367CAB_TS_ON_ID_1, 0x00},
754 {R367CAB_TS_ON_ID_2, 0x00},
755 {R367CAB_TS_ON_ID_3, 0x00},
756 {R367CAB_RE_STATUS_0, 0x00},
757 {R367CAB_RE_STATUS_1, 0x00},
758 {R367CAB_RE_STATUS_2, 0x00},
759 {R367CAB_RE_STATUS_3, 0x00},
760 {R367CAB_TS_STATUS_0, 0x00},
761 {R367CAB_TS_STATUS_1, 0x00},
762 {R367CAB_TS_STATUS_2, 0xa0},
763 {R367CAB_TS_STATUS_3, 0x00},
764 {R367CAB_T_O_ID_0, 0x00},
765 {R367CAB_T_O_ID_1, 0x00},
766 {R367CAB_T_O_ID_2, 0x00},
767 {R367CAB_T_O_ID_3, 0x00},
768};
769
770static
771int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
772{
Mauro Carvalho Chehab9aca4fb2013-11-02 05:17:01 -0300773 u8 buf[MAX_XFER_SIZE];
Igor M. Liplianin17cce932011-01-25 17:02:00 -0300774 struct i2c_msg msg = {
775 .addr = state->config->demod_address,
776 .flags = 0,
777 .buf = buf,
778 .len = len + 2
779 };
780 int ret;
781
Mauro Carvalho Chehab9aca4fb2013-11-02 05:17:01 -0300782 if (2 + len > sizeof(buf)) {
783 printk(KERN_WARNING
784 "%s: i2c wr reg=%04x: len=%d is too big!\n",
785 KBUILD_MODNAME, reg, len);
786 return -EINVAL;
787 }
788
789
Igor M. Liplianin17cce932011-01-25 17:02:00 -0300790 buf[0] = MSB(reg);
791 buf[1] = LSB(reg);
792 memcpy(buf + 2, data, len);
793
794 if (i2cdebug)
795 printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, buf[2]);
796
797 ret = i2c_transfer(state->i2c, &msg, 1);
798 if (ret != 1)
799 printk(KERN_ERR "%s: i2c write error!\n", __func__);
800
801 return (ret != 1) ? -EREMOTEIO : 0;
802}
803
804static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
805{
806 return stv0367_writeregs(state, reg, &data, 1);
807}
808
809static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
810{
811 u8 b0[] = { 0, 0 };
812 u8 b1[] = { 0 };
813 struct i2c_msg msg[] = {
814 {
815 .addr = state->config->demod_address,
816 .flags = 0,
817 .buf = b0,
818 .len = 2
819 }, {
820 .addr = state->config->demod_address,
821 .flags = I2C_M_RD,
822 .buf = b1,
823 .len = 1
824 }
825 };
826 int ret;
827
828 b0[0] = MSB(reg);
829 b0[1] = LSB(reg);
830
831 ret = i2c_transfer(state->i2c, msg, 2);
832 if (ret != 2)
833 printk(KERN_ERR "%s: i2c read error\n", __func__);
834
835 if (i2cdebug)
836 printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, b1[0]);
837
838 return b1[0];
839}
840
841static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
842{
843 u8 position = 0, i = 0;
844
845 (*mask) = label & 0xff;
846
847 while ((position == 0) && (i < 8)) {
848 position = ((*mask) >> i) & 0x01;
849 i++;
850 }
851
852 (*pos) = (i - 1);
853}
854
855static void stv0367_writebits(struct stv0367_state *state, u32 label, u8 val)
856{
857 u8 reg, mask, pos;
858
859 reg = stv0367_readreg(state, (label >> 16) & 0xffff);
860 extract_mask_pos(label, &mask, &pos);
861
862 val = mask & (val << pos);
863
864 reg = (reg & (~mask)) | val;
865 stv0367_writereg(state, (label >> 16) & 0xffff, reg);
866
867}
868
869static void stv0367_setbits(u8 *reg, u32 label, u8 val)
870{
871 u8 mask, pos;
872
873 extract_mask_pos(label, &mask, &pos);
874
875 val = mask & (val << pos);
876
877 (*reg) = ((*reg) & (~mask)) | val;
878}
879
880static u8 stv0367_readbits(struct stv0367_state *state, u32 label)
881{
882 u8 val = 0xff;
883 u8 mask, pos;
884
885 extract_mask_pos(label, &mask, &pos);
886
887 val = stv0367_readreg(state, label >> 16);
888 val = (val & mask) >> pos;
889
890 return val;
891}
892
Mauro Carvalho Chehab8c8ca1c2012-10-27 11:26:42 -0300893#if 0 /* Currently, unused */
894static u8 stv0367_getbits(u8 reg, u32 label)
Igor M. Liplianin17cce932011-01-25 17:02:00 -0300895{
896 u8 mask, pos;
897
898 extract_mask_pos(label, &mask, &pos);
899
900 return (reg & mask) >> pos;
901}
Mauro Carvalho Chehab8c8ca1c2012-10-27 11:26:42 -0300902#endif
Igor M. Liplianin17cce932011-01-25 17:02:00 -0300903static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
904{
905 struct stv0367_state *state = fe->demodulator_priv;
906 u8 tmp = stv0367_readreg(state, R367TER_I2CRPT);
907
908 dprintk("%s:\n", __func__);
909
910 if (enable) {
911 stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 0);
912 stv0367_setbits(&tmp, F367TER_I2CT_ON, 1);
913 } else {
914 stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 1);
915 stv0367_setbits(&tmp, F367TER_I2CT_ON, 0);
916 }
917
918 stv0367_writereg(state, R367TER_I2CRPT, tmp);
919
920 return 0;
921}
922
923static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe)
924{
925 struct dvb_frontend_ops *frontend_ops = NULL;
926 struct dvb_tuner_ops *tuner_ops = NULL;
927 u32 freq = 0;
Dan Carpenterbf512b22011-03-06 10:40:11 -0300928 int err = 0;
Igor M. Liplianin17cce932011-01-25 17:02:00 -0300929
930 dprintk("%s:\n", __func__);
931
932
933 if (&fe->ops)
934 frontend_ops = &fe->ops;
935 if (&frontend_ops->tuner_ops)
936 tuner_ops = &frontend_ops->tuner_ops;
937 if (tuner_ops->get_frequency) {
938 err = tuner_ops->get_frequency(fe, &freq);
939 if (err < 0) {
940 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
941 return err;
942 }
943
944 dprintk("%s: frequency=%d\n", __func__, freq);
945
946 } else
947 return -1;
948
949 return freq;
950}
951
952static u16 CellsCoeffs_8MHz_367cofdm[3][6][5] = {
953 {
954 {0x10EF, 0xE205, 0x10EF, 0xCE49, 0x6DA7}, /* CELL 1 COEFFS 27M*/
955 {0x2151, 0xc557, 0x2151, 0xc705, 0x6f93}, /* CELL 2 COEFFS */
956 {0x2503, 0xc000, 0x2503, 0xc375, 0x7194}, /* CELL 3 COEFFS */
957 {0x20E9, 0xca94, 0x20e9, 0xc153, 0x7194}, /* CELL 4 COEFFS */
958 {0x06EF, 0xF852, 0x06EF, 0xC057, 0x7207}, /* CELL 5 COEFFS */
959 {0x0000, 0x0ECC, 0x0ECC, 0x0000, 0x3647} /* CELL 6 COEFFS */
960 }, {
961 {0x10A0, 0xE2AF, 0x10A1, 0xCE76, 0x6D6D}, /* CELL 1 COEFFS 25M*/
962 {0x20DC, 0xC676, 0x20D9, 0xC80A, 0x6F29},
963 {0x2532, 0xC000, 0x251D, 0xC391, 0x706F},
964 {0x1F7A, 0xCD2B, 0x2032, 0xC15E, 0x711F},
965 {0x0698, 0xFA5E, 0x0568, 0xC059, 0x7193},
966 {0x0000, 0x0918, 0x149C, 0x0000, 0x3642} /* CELL 6 COEFFS */
967 }, {
968 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
969 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
970 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
971 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
972 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
973 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
974 }
975};
976
977static u16 CellsCoeffs_7MHz_367cofdm[3][6][5] = {
978 {
979 {0x12CA, 0xDDAF, 0x12CA, 0xCCEB, 0x6FB1}, /* CELL 1 COEFFS 27M*/
980 {0x2329, 0xC000, 0x2329, 0xC6B0, 0x725F}, /* CELL 2 COEFFS */
981 {0x2394, 0xC000, 0x2394, 0xC2C7, 0x7410}, /* CELL 3 COEFFS */
982 {0x251C, 0xC000, 0x251C, 0xC103, 0x74D9}, /* CELL 4 COEFFS */
983 {0x0804, 0xF546, 0x0804, 0xC040, 0x7544}, /* CELL 5 COEFFS */
984 {0x0000, 0x0CD9, 0x0CD9, 0x0000, 0x370A} /* CELL 6 COEFFS */
985 }, {
986 {0x1285, 0xDE47, 0x1285, 0xCD17, 0x6F76}, /*25M*/
987 {0x234C, 0xC000, 0x2348, 0xC6DA, 0x7206},
988 {0x23B4, 0xC000, 0x23AC, 0xC2DB, 0x73B3},
989 {0x253D, 0xC000, 0x25B6, 0xC10B, 0x747F},
990 {0x0721, 0xF79C, 0x065F, 0xC041, 0x74EB},
991 {0x0000, 0x08FA, 0x1162, 0x0000, 0x36FF}
992 }, {
993 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
994 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
995 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
996 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
997 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
998 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
999 }
1000};
1001
1002static u16 CellsCoeffs_6MHz_367cofdm[3][6][5] = {
1003 {
1004 {0x1699, 0xD5B8, 0x1699, 0xCBC3, 0x713B}, /* CELL 1 COEFFS 27M*/
1005 {0x2245, 0xC000, 0x2245, 0xC568, 0x74D5}, /* CELL 2 COEFFS */
1006 {0x227F, 0xC000, 0x227F, 0xC1FC, 0x76C6}, /* CELL 3 COEFFS */
1007 {0x235E, 0xC000, 0x235E, 0xC0A7, 0x778A}, /* CELL 4 COEFFS */
1008 {0x0ECB, 0xEA0B, 0x0ECB, 0xC027, 0x77DD}, /* CELL 5 COEFFS */
1009 {0x0000, 0x0B68, 0x0B68, 0x0000, 0xC89A}, /* CELL 6 COEFFS */
1010 }, {
1011 {0x1655, 0xD64E, 0x1658, 0xCBEF, 0x70FE}, /*25M*/
1012 {0x225E, 0xC000, 0x2256, 0xC589, 0x7489},
1013 {0x2293, 0xC000, 0x2295, 0xC209, 0x767E},
1014 {0x2377, 0xC000, 0x23AA, 0xC0AB, 0x7746},
1015 {0x0DC7, 0xEBC8, 0x0D07, 0xC027, 0x7799},
1016 {0x0000, 0x0888, 0x0E9C, 0x0000, 0x3757}
1017
1018 }, {
1019 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
1020 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1021 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1022 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1023 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1024 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
1025 }
1026};
1027
1028static u32 stv0367ter_get_mclk(struct stv0367_state *state, u32 ExtClk_Hz)
1029{
1030 u32 mclk_Hz = 0; /* master clock frequency (Hz) */
1031 u32 m, n, p;
1032
1033 dprintk("%s:\n", __func__);
1034
1035 if (stv0367_readbits(state, F367TER_BYPASS_PLLXN) == 0) {
1036 n = (u32)stv0367_readbits(state, F367TER_PLL_NDIV);
1037 if (n == 0)
1038 n = n + 1;
1039
1040 m = (u32)stv0367_readbits(state, F367TER_PLL_MDIV);
1041 if (m == 0)
1042 m = m + 1;
1043
1044 p = (u32)stv0367_readbits(state, F367TER_PLL_PDIV);
1045 if (p > 5)
1046 p = 5;
1047
1048 mclk_Hz = ((ExtClk_Hz / 2) * n) / (m * (1 << p));
1049
1050 dprintk("N=%d M=%d P=%d mclk_Hz=%d ExtClk_Hz=%d\n",
1051 n, m, p, mclk_Hz, ExtClk_Hz);
1052 } else
1053 mclk_Hz = ExtClk_Hz;
1054
1055 dprintk("%s: mclk_Hz=%d\n", __func__, mclk_Hz);
1056
1057 return mclk_Hz;
1058}
1059
1060static int stv0367ter_filt_coeff_init(struct stv0367_state *state,
Dan Carpenterbc4b18c2011-03-06 10:41:23 -03001061 u16 CellsCoeffs[3][6][5], u32 DemodXtal)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001062{
1063 int i, j, k, freq;
1064
1065 dprintk("%s:\n", __func__);
1066
1067 freq = stv0367ter_get_mclk(state, DemodXtal);
1068
1069 if (freq == 53125000)
1070 k = 1; /* equivalent to Xtal 25M on 362*/
1071 else if (freq == 54000000)
1072 k = 0; /* equivalent to Xtal 27M on 362*/
1073 else if (freq == 52500000)
1074 k = 2; /* equivalent to Xtal 30M on 362*/
1075 else
1076 return 0;
1077
1078 for (i = 1; i <= 6; i++) {
1079 stv0367_writebits(state, F367TER_IIR_CELL_NB, i - 1);
1080
1081 for (j = 1; j <= 5; j++) {
1082 stv0367_writereg(state,
1083 (R367TER_IIRCX_COEFF1_MSB + 2 * (j - 1)),
1084 MSB(CellsCoeffs[k][i-1][j-1]));
1085 stv0367_writereg(state,
1086 (R367TER_IIRCX_COEFF1_LSB + 2 * (j - 1)),
1087 LSB(CellsCoeffs[k][i-1][j-1]));
1088 }
1089 }
1090
1091 return 1;
1092
1093}
1094
1095static void stv0367ter_agc_iir_lock_detect_set(struct stv0367_state *state)
1096{
1097 dprintk("%s:\n", __func__);
1098
1099 stv0367_writebits(state, F367TER_LOCK_DETECT_LSB, 0x00);
1100
1101 /* Lock detect 1 */
1102 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x00);
1103 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
1104 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
1105
1106 /* Lock detect 2 */
1107 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x01);
1108 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
1109 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
1110
1111 /* Lock detect 3 */
1112 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x02);
1113 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
1114 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
1115
1116 /* Lock detect 4 */
1117 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x03);
1118 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
1119 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
1120
1121}
1122
1123static int stv0367_iir_filt_init(struct stv0367_state *state, u8 Bandwidth,
1124 u32 DemodXtalValue)
1125{
1126 dprintk("%s:\n", __func__);
1127
1128 stv0367_writebits(state, F367TER_NRST_IIR, 0);
1129
1130 switch (Bandwidth) {
1131 case 6:
1132 if (!stv0367ter_filt_coeff_init(state,
1133 CellsCoeffs_6MHz_367cofdm,
1134 DemodXtalValue))
1135 return 0;
1136 break;
1137 case 7:
1138 if (!stv0367ter_filt_coeff_init(state,
1139 CellsCoeffs_7MHz_367cofdm,
1140 DemodXtalValue))
1141 return 0;
1142 break;
1143 case 8:
1144 if (!stv0367ter_filt_coeff_init(state,
1145 CellsCoeffs_8MHz_367cofdm,
1146 DemodXtalValue))
1147 return 0;
1148 break;
1149 default:
1150 return 0;
1151 }
1152
1153 stv0367_writebits(state, F367TER_NRST_IIR, 1);
1154
1155 return 1;
1156}
1157
1158static void stv0367ter_agc_iir_rst(struct stv0367_state *state)
1159{
1160
1161 u8 com_n;
1162
1163 dprintk("%s:\n", __func__);
1164
1165 com_n = stv0367_readbits(state, F367TER_COM_N);
1166
1167 stv0367_writebits(state, F367TER_COM_N, 0x07);
1168
1169 stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x00);
1170 stv0367_writebits(state, F367TER_COM_AGC_ON, 0x00);
1171
1172 stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x01);
1173 stv0367_writebits(state, F367TER_COM_AGC_ON, 0x01);
1174
1175 stv0367_writebits(state, F367TER_COM_N, com_n);
1176
1177}
1178
1179static int stv0367ter_duration(s32 mode, int tempo1, int tempo2, int tempo3)
1180{
1181 int local_tempo = 0;
1182 switch (mode) {
1183 case 0:
1184 local_tempo = tempo1;
1185 break;
1186 case 1:
1187 local_tempo = tempo2;
1188 break ;
1189
1190 case 2:
1191 local_tempo = tempo3;
1192 break;
1193
1194 default:
1195 break;
1196 }
1197 /* msleep(local_tempo); */
1198 return local_tempo;
1199}
1200
1201static enum
1202stv0367_ter_signal_type stv0367ter_check_syr(struct stv0367_state *state)
1203{
1204 int wd = 100;
1205 unsigned short int SYR_var;
1206 s32 SYRStatus;
1207
1208 dprintk("%s:\n", __func__);
1209
1210 SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
1211
1212 while ((!SYR_var) && (wd > 0)) {
1213 usleep_range(2000, 3000);
1214 wd -= 2;
1215 SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
1216 }
1217
1218 if (!SYR_var)
1219 SYRStatus = FE_TER_NOSYMBOL;
1220 else
1221 SYRStatus = FE_TER_SYMBOLOK;
1222
1223 dprintk("stv0367ter_check_syr SYRStatus %s\n",
1224 SYR_var == 0 ? "No Symbol" : "OK");
1225
1226 return SYRStatus;
1227}
1228
1229static enum
1230stv0367_ter_signal_type stv0367ter_check_cpamp(struct stv0367_state *state,
1231 s32 FFTmode)
1232{
1233
1234 s32 CPAMPvalue = 0, CPAMPStatus, CPAMPMin;
1235 int wd = 0;
1236
1237 dprintk("%s:\n", __func__);
1238
1239 switch (FFTmode) {
1240 case 0: /*2k mode*/
1241 CPAMPMin = 20;
1242 wd = 10;
1243 break;
1244 case 1: /*8k mode*/
1245 CPAMPMin = 80;
1246 wd = 55;
1247 break;
1248 case 2: /*4k mode*/
1249 CPAMPMin = 40;
1250 wd = 30;
1251 break;
1252 default:
1253 CPAMPMin = 0xffff; /*drives to NOCPAMP */
1254 break;
1255 }
1256
1257 dprintk("%s: CPAMPMin=%d wd=%d\n", __func__, CPAMPMin, wd);
1258
1259 CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
1260 while ((CPAMPvalue < CPAMPMin) && (wd > 0)) {
1261 usleep_range(1000, 2000);
1262 wd -= 1;
1263 CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
1264 /*dprintk("CPAMPvalue= %d at wd=%d\n",CPAMPvalue,wd); */
1265 }
1266 dprintk("******last CPAMPvalue= %d at wd=%d\n", CPAMPvalue, wd);
1267 if (CPAMPvalue < CPAMPMin) {
1268 CPAMPStatus = FE_TER_NOCPAMP;
1269 printk(KERN_ERR "CPAMP failed\n");
1270 } else {
1271 printk(KERN_ERR "CPAMP OK !\n");
1272 CPAMPStatus = FE_TER_CPAMPOK;
1273 }
1274
1275 return CPAMPStatus;
1276}
1277
Mauro Carvalho Chehab8c8ca1c2012-10-27 11:26:42 -03001278static enum stv0367_ter_signal_type
1279stv0367ter_lock_algo(struct stv0367_state *state)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001280{
1281 enum stv0367_ter_signal_type ret_flag;
1282 short int wd, tempo;
1283 u8 try, u_var1 = 0, u_var2 = 0, u_var3 = 0, u_var4 = 0, mode, guard;
1284 u8 tmp, tmp2;
1285
1286 dprintk("%s:\n", __func__);
1287
1288 if (state == NULL)
1289 return FE_TER_SWNOK;
1290
1291 try = 0;
1292 do {
1293 ret_flag = FE_TER_LOCKOK;
1294
1295 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1296
1297 if (state->config->if_iq_mode != 0)
1298 stv0367_writebits(state, F367TER_COM_N, 0x07);
1299
1300 stv0367_writebits(state, F367TER_GUARD, 3);/* suggest 2k 1/4 */
1301 stv0367_writebits(state, F367TER_MODE, 0);
1302 stv0367_writebits(state, F367TER_SYR_TR_DIS, 0);
1303 usleep_range(5000, 10000);
1304
1305 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1306
1307
1308 if (stv0367ter_check_syr(state) == FE_TER_NOSYMBOL)
1309 return FE_TER_NOSYMBOL;
1310 else { /*
1311 if chip locked on wrong mode first try,
1312 it must lock correctly second try */
1313 mode = stv0367_readbits(state, F367TER_SYR_MODE);
1314 if (stv0367ter_check_cpamp(state, mode) ==
1315 FE_TER_NOCPAMP) {
1316 if (try == 0)
1317 ret_flag = FE_TER_NOCPAMP;
1318
1319 }
1320 }
1321
1322 try++;
1323 } while ((try < 10) && (ret_flag != FE_TER_LOCKOK));
1324
1325 tmp = stv0367_readreg(state, R367TER_SYR_STAT);
1326 tmp2 = stv0367_readreg(state, R367TER_STATUS);
Hans Verkuilfb661a72011-03-06 09:26:24 -03001327 dprintk("state=%p\n", state);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001328 dprintk("LOCK OK! mode=%d SYR_STAT=0x%x R367TER_STATUS=0x%x\n",
1329 mode, tmp, tmp2);
1330
1331 tmp = stv0367_readreg(state, R367TER_PRVIT);
1332 tmp2 = stv0367_readreg(state, R367TER_I2CRPT);
1333 dprintk("PRVIT=0x%x I2CRPT=0x%x\n", tmp, tmp2);
1334
1335 tmp = stv0367_readreg(state, R367TER_GAIN_SRC1);
1336 dprintk("GAIN_SRC1=0x%x\n", tmp);
1337
1338 if ((mode != 0) && (mode != 1) && (mode != 2))
1339 return FE_TER_SWNOK;
1340
1341 /*guard=stv0367_readbits(state,F367TER_SYR_GUARD); */
1342
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001343 /*suppress EPQ auto for SYR_GARD 1/16 or 1/32
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001344 and set channel predictor in automatic */
1345#if 0
1346 switch (guard) {
1347
1348 case 0:
1349 case 1:
1350 stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
1351 stv0367_writereg(state, R367TER_CHC_CTL, 0x01);
1352 break;
1353 case 2:
1354 case 3:
1355 stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
1356 stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
1357 break;
1358
1359 default:
1360 return FE_TER_SWNOK;
1361 }
1362#endif
1363
1364 /*reset fec an reedsolo FOR 367 only*/
1365 stv0367_writebits(state, F367TER_RST_SFEC, 1);
1366 stv0367_writebits(state, F367TER_RST_REEDSOLO, 1);
1367 usleep_range(1000, 2000);
1368 stv0367_writebits(state, F367TER_RST_SFEC, 0);
1369 stv0367_writebits(state, F367TER_RST_REEDSOLO, 0);
1370
1371 u_var1 = stv0367_readbits(state, F367TER_LK);
1372 u_var2 = stv0367_readbits(state, F367TER_PRF);
1373 u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
1374 /* u_var4=stv0367_readbits(state,F367TER_TSFIFO_LINEOK); */
1375
1376 wd = stv0367ter_duration(mode, 125, 500, 250);
1377 tempo = stv0367ter_duration(mode, 4, 16, 8);
1378
1379 /*while ( ((!u_var1)||(!u_var2)||(!u_var3)||(!u_var4)) && (wd>=0)) */
1380 while (((!u_var1) || (!u_var2) || (!u_var3)) && (wd >= 0)) {
1381 usleep_range(1000 * tempo, 1000 * (tempo + 1));
1382 wd -= tempo;
1383 u_var1 = stv0367_readbits(state, F367TER_LK);
1384 u_var2 = stv0367_readbits(state, F367TER_PRF);
1385 u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
1386 /*u_var4=stv0367_readbits(state, F367TER_TSFIFO_LINEOK); */
1387 }
1388
1389 if (!u_var1)
1390 return FE_TER_NOLOCK;
1391
1392
1393 if (!u_var2)
1394 return FE_TER_NOPRFOUND;
1395
1396 if (!u_var3)
1397 return FE_TER_NOTPS;
1398
1399 guard = stv0367_readbits(state, F367TER_SYR_GUARD);
1400 stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
1401 switch (guard) {
1402 case 0:
1403 case 1:
1404 stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
1405 /*stv0367_writereg(state,R367TER_CHC_CTL, 0x1);*/
1406 stv0367_writebits(state, F367TER_SYR_FILTER, 0);
1407 break;
1408 case 2:
1409 case 3:
1410 stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
1411 /*stv0367_writereg(state,R367TER_CHC_CTL, 0x11);*/
1412 stv0367_writebits(state, F367TER_SYR_FILTER, 1);
1413 break;
1414
1415 default:
1416 return FE_TER_SWNOK;
1417 }
1418
1419 /* apply Sfec workaround if 8K 64QAM CR!=1/2*/
1420 if ((stv0367_readbits(state, F367TER_TPS_CONST) == 2) &&
1421 (mode == 1) &&
1422 (stv0367_readbits(state, F367TER_TPS_HPCODE) != 0)) {
1423 stv0367_writereg(state, R367TER_SFDLYSETH, 0xc0);
1424 stv0367_writereg(state, R367TER_SFDLYSETM, 0x60);
1425 stv0367_writereg(state, R367TER_SFDLYSETL, 0x0);
1426 } else
1427 stv0367_writereg(state, R367TER_SFDLYSETH, 0x0);
1428
1429 wd = stv0367ter_duration(mode, 125, 500, 250);
1430 u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
1431
1432 while ((!u_var4) && (wd >= 0)) {
1433 usleep_range(1000 * tempo, 1000 * (tempo + 1));
1434 wd -= tempo;
1435 u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
1436 }
1437
1438 if (!u_var4)
1439 return FE_TER_NOLOCK;
1440
1441 /* for 367 leave COM_N at 0x7 for IQ_mode*/
1442 /*if(ter_state->if_iq_mode!=FE_TER_NORMAL_IF_TUNER) {
1443 tempo=0;
1444 while ((stv0367_readbits(state,F367TER_COM_USEGAINTRK)!=1) &&
1445 (stv0367_readbits(state,F367TER_COM_AGCLOCK)!=1)&&(tempo<100)) {
1446 ChipWaitOrAbort(state,1);
1447 tempo+=1;
1448 }
1449
1450 stv0367_writebits(state,F367TER_COM_N,0x17);
1451 } */
1452
1453 stv0367_writebits(state, F367TER_SYR_TR_DIS, 1);
1454
1455 dprintk("FE_TER_LOCKOK !!!\n");
1456
1457 return FE_TER_LOCKOK;
1458
1459}
1460
1461static void stv0367ter_set_ts_mode(struct stv0367_state *state,
1462 enum stv0367_ts_mode PathTS)
1463{
1464
1465 dprintk("%s:\n", __func__);
1466
1467 if (state == NULL)
1468 return;
1469
1470 stv0367_writebits(state, F367TER_TS_DIS, 0);
1471 switch (PathTS) {
1472 default:
1473 /*for removing warning :default we can assume in parallel mode*/
1474 case STV0367_PARALLEL_PUNCT_CLOCK:
1475 stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 0);
1476 stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 0);
1477 break;
1478 case STV0367_SERIAL_PUNCT_CLOCK:
1479 stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 1);
1480 stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 1);
1481 break;
1482 }
1483}
1484
1485static void stv0367ter_set_clk_pol(struct stv0367_state *state,
1486 enum stv0367_clk_pol clock)
1487{
1488
1489 dprintk("%s:\n", __func__);
1490
1491 if (state == NULL)
1492 return;
1493
1494 switch (clock) {
1495 case STV0367_RISINGEDGE_CLOCK:
1496 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 1);
1497 break;
1498 case STV0367_FALLINGEDGE_CLOCK:
1499 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
1500 break;
1501 /*case FE_TER_CLOCK_POLARITY_DEFAULT:*/
1502 default:
1503 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
1504 break;
1505 }
1506}
1507
1508#if 0
1509static void stv0367ter_core_sw(struct stv0367_state *state)
1510{
1511
1512 dprintk("%s:\n", __func__);
1513
1514 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1515 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1516 msleep(350);
1517}
1518#endif
1519static int stv0367ter_standby(struct dvb_frontend *fe, u8 standby_on)
1520{
1521 struct stv0367_state *state = fe->demodulator_priv;
1522
1523 dprintk("%s:\n", __func__);
1524
1525 if (standby_on) {
1526 stv0367_writebits(state, F367TER_STDBY, 1);
1527 stv0367_writebits(state, F367TER_STDBY_FEC, 1);
1528 stv0367_writebits(state, F367TER_STDBY_CORE, 1);
1529 } else {
1530 stv0367_writebits(state, F367TER_STDBY, 0);
1531 stv0367_writebits(state, F367TER_STDBY_FEC, 0);
1532 stv0367_writebits(state, F367TER_STDBY_CORE, 0);
1533 }
1534
1535 return 0;
1536}
1537
1538static int stv0367ter_sleep(struct dvb_frontend *fe)
1539{
1540 return stv0367ter_standby(fe, 1);
1541}
1542
Mauro Carvalho Chehab8c8ca1c2012-10-27 11:26:42 -03001543static int stv0367ter_init(struct dvb_frontend *fe)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001544{
1545 struct stv0367_state *state = fe->demodulator_priv;
1546 struct stv0367ter_state *ter_state = state->ter_state;
1547 int i;
1548
1549 dprintk("%s:\n", __func__);
1550
1551 ter_state->pBER = 0;
1552
1553 for (i = 0; i < STV0367TER_NBREGS; i++)
1554 stv0367_writereg(state, def0367ter[i].addr,
1555 def0367ter[i].value);
1556
1557 switch (state->config->xtal) {
1558 /*set internal freq to 53.125MHz */
1559 case 25000000:
1560 stv0367_writereg(state, R367TER_PLLMDIV, 0xa);
1561 stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
1562 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1563 break;
1564 default:
1565 case 27000000:
1566 dprintk("FE_STV0367TER_SetCLKgen for 27Mhz\n");
1567 stv0367_writereg(state, R367TER_PLLMDIV, 0x1);
1568 stv0367_writereg(state, R367TER_PLLNDIV, 0x8);
1569 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1570 break;
1571 case 30000000:
1572 stv0367_writereg(state, R367TER_PLLMDIV, 0xc);
1573 stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
1574 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1575 break;
1576 }
1577
1578 stv0367_writereg(state, R367TER_I2CRPT, 0xa0);
1579 stv0367_writereg(state, R367TER_ANACTRL, 0x00);
1580
1581 /*Set TS1 and TS2 to serial or parallel mode */
1582 stv0367ter_set_ts_mode(state, state->config->ts_mode);
1583 stv0367ter_set_clk_pol(state, state->config->clk_pol);
1584
1585 state->chip_id = stv0367_readreg(state, R367TER_ID);
1586 ter_state->first_lock = 0;
1587 ter_state->unlock_counter = 2;
1588
1589 return 0;
1590}
1591
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001592static int stv0367ter_algo(struct dvb_frontend *fe)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001593{
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001594 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001595 struct stv0367_state *state = fe->demodulator_priv;
1596 struct stv0367ter_state *ter_state = state->ter_state;
1597 int offset = 0, tempo = 0;
1598 u8 u_var;
Peter Senna Tschudindf1ec022012-06-14 13:58:14 -03001599 u8 /*constell,*/ counter;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001600 s8 step;
1601 s32 timing_offset = 0;
1602 u32 trl_nomrate = 0, InternalFreq = 0, temp = 0;
1603
1604 dprintk("%s:\n", __func__);
1605
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001606 ter_state->frequency = p->frequency;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001607 ter_state->force = FE_TER_FORCENONE
1608 + stv0367_readbits(state, F367TER_FORCE) * 2;
1609 ter_state->if_iq_mode = state->config->if_iq_mode;
1610 switch (state->config->if_iq_mode) {
1611 case FE_TER_NORMAL_IF_TUNER: /* Normal IF mode */
1612 dprintk("ALGO: FE_TER_NORMAL_IF_TUNER selected\n");
1613 stv0367_writebits(state, F367TER_TUNER_BB, 0);
1614 stv0367_writebits(state, F367TER_LONGPATH_IF, 0);
1615 stv0367_writebits(state, F367TER_DEMUX_SWAP, 0);
1616 break;
1617 case FE_TER_LONGPATH_IF_TUNER: /* Long IF mode */
1618 dprintk("ALGO: FE_TER_LONGPATH_IF_TUNER selected\n");
1619 stv0367_writebits(state, F367TER_TUNER_BB, 0);
1620 stv0367_writebits(state, F367TER_LONGPATH_IF, 1);
1621 stv0367_writebits(state, F367TER_DEMUX_SWAP, 1);
1622 break;
1623 case FE_TER_IQ_TUNER: /* IQ mode */
1624 dprintk("ALGO: FE_TER_IQ_TUNER selected\n");
1625 stv0367_writebits(state, F367TER_TUNER_BB, 1);
1626 stv0367_writebits(state, F367TER_PPM_INVSEL, 0);
1627 break;
1628 default:
1629 printk(KERN_ERR "ALGO: wrong TUNER type selected\n");
1630 return -EINVAL;
1631 }
1632
1633 usleep_range(5000, 7000);
1634
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001635 switch (p->inversion) {
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001636 case INVERSION_AUTO:
1637 default:
1638 dprintk("%s: inversion AUTO\n", __func__);
1639 if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
1640 stv0367_writebits(state, F367TER_IQ_INVERT,
1641 ter_state->sense);
1642 else
1643 stv0367_writebits(state, F367TER_INV_SPECTR,
1644 ter_state->sense);
1645
1646 break;
1647 case INVERSION_ON:
1648 case INVERSION_OFF:
1649 if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
1650 stv0367_writebits(state, F367TER_IQ_INVERT,
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001651 p->inversion);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001652 else
1653 stv0367_writebits(state, F367TER_INV_SPECTR,
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001654 p->inversion);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001655
1656 break;
1657 }
1658
1659 if ((ter_state->if_iq_mode != FE_TER_NORMAL_IF_TUNER) &&
1660 (ter_state->pBW != ter_state->bw)) {
1661 stv0367ter_agc_iir_lock_detect_set(state);
1662
1663 /*set fine agc target to 180 for LPIF or IQ mode*/
1664 /* set Q_AGCTarget */
1665 stv0367_writebits(state, F367TER_SEL_IQNTAR, 1);
1666 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
1667 /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
1668
1669 /* set Q_AGCTarget */
1670 stv0367_writebits(state, F367TER_SEL_IQNTAR, 0);
1671 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
1672 /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
1673
1674 if (!stv0367_iir_filt_init(state, ter_state->bw,
1675 state->config->xtal))
1676 return -EINVAL;
1677 /*set IIR filter once for 6,7 or 8MHz BW*/
1678 ter_state->pBW = ter_state->bw;
1679
1680 stv0367ter_agc_iir_rst(state);
1681 }
1682
1683 if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
1684 stv0367_writebits(state, F367TER_BDI_LPSEL, 0x01);
1685 else
1686 stv0367_writebits(state, F367TER_BDI_LPSEL, 0x00);
1687
1688 InternalFreq = stv0367ter_get_mclk(state, state->config->xtal) / 1000;
1689 temp = (int)
1690 ((((ter_state->bw * 64 * (1 << 15) * 100)
1691 / (InternalFreq)) * 10) / 7);
1692
1693 stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB, temp % 2);
1694 temp = temp / 2;
1695 stv0367_writebits(state, F367TER_TRL_NOMRATE_HI, temp / 256);
1696 stv0367_writebits(state, F367TER_TRL_NOMRATE_LO, temp % 256);
1697
1698 temp = stv0367_readbits(state, F367TER_TRL_NOMRATE_HI) * 512 +
1699 stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2 +
1700 stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB);
1701 temp = (int)(((1 << 17) * ter_state->bw * 1000) / (7 * (InternalFreq)));
1702 stv0367_writebits(state, F367TER_GAIN_SRC_HI, temp / 256);
1703 stv0367_writebits(state, F367TER_GAIN_SRC_LO, temp % 256);
1704 temp = stv0367_readbits(state, F367TER_GAIN_SRC_HI) * 256 +
1705 stv0367_readbits(state, F367TER_GAIN_SRC_LO);
1706
1707 temp = (int)
1708 ((InternalFreq - state->config->if_khz) * (1 << 16)
1709 / (InternalFreq));
1710
1711 dprintk("DEROT temp=0x%x\n", temp);
1712 stv0367_writebits(state, F367TER_INC_DEROT_HI, temp / 256);
1713 stv0367_writebits(state, F367TER_INC_DEROT_LO, temp % 256);
1714
1715 ter_state->echo_pos = 0;
1716 ter_state->ucblocks = 0; /* liplianin */
1717 ter_state->pBER = 0; /* liplianin */
1718 stv0367_writebits(state, F367TER_LONG_ECHO, ter_state->echo_pos);
1719
1720 if (stv0367ter_lock_algo(state) != FE_TER_LOCKOK)
1721 return 0;
1722
1723 ter_state->state = FE_TER_LOCKOK;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001724
1725 ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE);
1726 ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD);
1727
1728 ter_state->first_lock = 1; /* we know sense now :) */
1729
1730 ter_state->agc_val =
1731 (stv0367_readbits(state, F367TER_AGC1_VAL_LO) << 16) +
1732 (stv0367_readbits(state, F367TER_AGC1_VAL_HI) << 24) +
1733 stv0367_readbits(state, F367TER_AGC2_VAL_LO) +
1734 (stv0367_readbits(state, F367TER_AGC2_VAL_HI) << 8);
1735
1736 /* Carrier offset calculation */
1737 stv0367_writebits(state, F367TER_FREEZE, 1);
1738 offset = (stv0367_readbits(state, F367TER_CRL_FOFFSET_VHI) << 16) ;
1739 offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_HI) << 8);
1740 offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_LO));
1741 stv0367_writebits(state, F367TER_FREEZE, 0);
1742 if (offset > 8388607)
1743 offset -= 16777216;
1744
1745 offset = offset * 2 / 16384;
1746
1747 if (ter_state->mode == FE_TER_MODE_2K)
1748 offset = (offset * 4464) / 1000;/*** 1 FFT BIN=4.464khz***/
1749 else if (ter_state->mode == FE_TER_MODE_4K)
1750 offset = (offset * 223) / 100;/*** 1 FFT BIN=2.23khz***/
1751 else if (ter_state->mode == FE_TER_MODE_8K)
1752 offset = (offset * 111) / 100;/*** 1 FFT BIN=1.1khz***/
1753
1754 if (stv0367_readbits(state, F367TER_PPM_INVSEL) == 1) {
1755 if ((stv0367_readbits(state, F367TER_INV_SPECTR) ==
1756 (stv0367_readbits(state,
1757 F367TER_STATUS_INV_SPECRUM) == 1)))
1758 offset = offset * -1;
1759 }
1760
1761 if (ter_state->bw == 6)
1762 offset = (offset * 6) / 8;
1763 else if (ter_state->bw == 7)
1764 offset = (offset * 7) / 8;
1765
1766 ter_state->frequency += offset;
1767
1768 tempo = 10; /* exit even if timing_offset stays null */
1769 while ((timing_offset == 0) && (tempo > 0)) {
1770 usleep_range(10000, 20000); /*was 20ms */
1771 /* fine tuning of timing offset if required */
1772 timing_offset = stv0367_readbits(state, F367TER_TRL_TOFFSET_LO)
1773 + 256 * stv0367_readbits(state,
1774 F367TER_TRL_TOFFSET_HI);
1775 if (timing_offset >= 32768)
1776 timing_offset -= 65536;
1777 trl_nomrate = (512 * stv0367_readbits(state,
1778 F367TER_TRL_NOMRATE_HI)
1779 + stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2
1780 + stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB));
1781
1782 timing_offset = ((signed)(1000000 / trl_nomrate) *
1783 timing_offset) / 2048;
1784 tempo--;
1785 }
1786
1787 if (timing_offset <= 0) {
1788 timing_offset = (timing_offset - 11) / 22;
1789 step = -1;
1790 } else {
1791 timing_offset = (timing_offset + 11) / 22;
1792 step = 1;
1793 }
1794
1795 for (counter = 0; counter < abs(timing_offset); counter++) {
1796 trl_nomrate += step;
1797 stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB,
1798 trl_nomrate % 2);
1799 stv0367_writebits(state, F367TER_TRL_NOMRATE_LO,
1800 trl_nomrate / 2);
1801 usleep_range(1000, 2000);
1802 }
1803
1804 usleep_range(5000, 6000);
1805 /* unlocks could happen in case of trl centring big step,
1806 then a core off/on restarts demod */
1807 u_var = stv0367_readbits(state, F367TER_LK);
1808
1809 if (!u_var) {
1810 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1811 msleep(20);
1812 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1813 }
1814
1815 return 0;
1816}
1817
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001818static int stv0367ter_set_frontend(struct dvb_frontend *fe)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001819{
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001820 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001821 struct stv0367_state *state = fe->demodulator_priv;
1822 struct stv0367ter_state *ter_state = state->ter_state;
1823
1824 /*u8 trials[2]; */
1825 s8 num_trials, index;
1826 u8 SenseTrials[] = { INVERSION_ON, INVERSION_OFF };
1827
1828 stv0367ter_init(fe);
1829
1830 if (fe->ops.tuner_ops.set_params) {
1831 if (fe->ops.i2c_gate_ctrl)
1832 fe->ops.i2c_gate_ctrl(fe, 1);
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03001833 fe->ops.tuner_ops.set_params(fe);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001834 if (fe->ops.i2c_gate_ctrl)
1835 fe->ops.i2c_gate_ctrl(fe, 0);
1836 }
1837
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001838 switch (p->transmission_mode) {
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001839 default:
1840 case TRANSMISSION_MODE_AUTO:
1841 case TRANSMISSION_MODE_2K:
1842 ter_state->mode = FE_TER_MODE_2K;
1843 break;
1844/* case TRANSMISSION_MODE_4K:
1845 pLook.mode = FE_TER_MODE_4K;
1846 break;*/
1847 case TRANSMISSION_MODE_8K:
1848 ter_state->mode = FE_TER_MODE_8K;
1849 break;
1850 }
1851
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001852 switch (p->guard_interval) {
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001853 default:
1854 case GUARD_INTERVAL_1_32:
1855 case GUARD_INTERVAL_1_16:
1856 case GUARD_INTERVAL_1_8:
1857 case GUARD_INTERVAL_1_4:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001858 ter_state->guard = p->guard_interval;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001859 break;
1860 case GUARD_INTERVAL_AUTO:
1861 ter_state->guard = GUARD_INTERVAL_1_32;
1862 break;
1863 }
1864
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001865 switch (p->bandwidth_hz) {
1866 case 6000000:
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001867 ter_state->bw = FE_TER_CHAN_BW_6M;
1868 break;
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001869 case 7000000:
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001870 ter_state->bw = FE_TER_CHAN_BW_7M;
1871 break;
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001872 case 8000000:
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001873 default:
1874 ter_state->bw = FE_TER_CHAN_BW_8M;
1875 }
1876
1877 ter_state->hierarchy = FE_TER_HIER_NONE;
1878
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001879 switch (p->inversion) {
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001880 case INVERSION_OFF:
1881 case INVERSION_ON:
1882 num_trials = 1;
1883 break;
1884 default:
1885 num_trials = 2;
1886 if (ter_state->first_lock)
1887 num_trials = 1;
1888 break;
1889 }
1890
1891 ter_state->state = FE_TER_NOLOCK;
1892 index = 0;
1893
1894 while (((index) < num_trials) && (ter_state->state != FE_TER_LOCKOK)) {
1895 if (!ter_state->first_lock) {
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001896 if (p->inversion == INVERSION_AUTO)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001897 ter_state->sense = SenseTrials[index];
1898
1899 }
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001900 stv0367ter_algo(fe);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001901
1902 if ((ter_state->state == FE_TER_LOCKOK) &&
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001903 (p->inversion == INVERSION_AUTO) &&
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001904 (index == 1)) {
1905 /* invert spectrum sense */
1906 SenseTrials[index] = SenseTrials[0];
1907 SenseTrials[(index + 1) % 2] = (SenseTrials[1] + 1) % 2;
1908 }
1909
1910 index++;
1911 }
1912
1913 return 0;
1914}
1915
1916static int stv0367ter_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1917{
1918 struct stv0367_state *state = fe->demodulator_priv;
1919 struct stv0367ter_state *ter_state = state->ter_state;
1920 u32 errs = 0;
1921
1922 /*wait for counting completion*/
1923 if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0) {
1924 errs =
1925 ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
1926 * (1 << 16))
1927 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
1928 * (1 << 8))
1929 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
1930 ter_state->ucblocks = errs;
1931 }
1932
1933 (*ucblocks) = ter_state->ucblocks;
1934
1935 return 0;
1936}
1937
Mauro Carvalho Chehab7c61d802011-12-30 11:30:21 -03001938static int stv0367ter_get_frontend(struct dvb_frontend *fe)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001939{
Mauro Carvalho Chehab7c61d802011-12-30 11:30:21 -03001940 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001941 struct stv0367_state *state = fe->demodulator_priv;
1942 struct stv0367ter_state *ter_state = state->ter_state;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001943
1944 int error = 0;
1945 enum stv0367_ter_mode mode;
1946 int constell = 0,/* snr = 0,*/ Data = 0;
1947
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001948 p->frequency = stv0367_get_tuner_freq(fe);
1949 if ((int)p->frequency < 0)
1950 p->frequency = -p->frequency;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001951
1952 constell = stv0367_readbits(state, F367TER_TPS_CONST);
1953 if (constell == 0)
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001954 p->modulation = QPSK;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001955 else if (constell == 1)
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001956 p->modulation = QAM_16;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001957 else
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001958 p->modulation = QAM_64;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001959
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001960 p->inversion = stv0367_readbits(state, F367TER_INV_SPECTR);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001961
1962 /* Get the Hierarchical mode */
1963 Data = stv0367_readbits(state, F367TER_TPS_HIERMODE);
1964
1965 switch (Data) {
1966 case 0:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001967 p->hierarchy = HIERARCHY_NONE;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001968 break;
1969 case 1:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001970 p->hierarchy = HIERARCHY_1;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001971 break;
1972 case 2:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001973 p->hierarchy = HIERARCHY_2;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001974 break;
1975 case 3:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001976 p->hierarchy = HIERARCHY_4;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001977 break;
1978 default:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001979 p->hierarchy = HIERARCHY_AUTO;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001980 break; /* error */
1981 }
1982
1983 /* Get the FEC Rate */
1984 if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
1985 Data = stv0367_readbits(state, F367TER_TPS_LPCODE);
1986 else
1987 Data = stv0367_readbits(state, F367TER_TPS_HPCODE);
1988
1989 switch (Data) {
1990 case 0:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001991 p->code_rate_HP = FEC_1_2;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001992 break;
1993 case 1:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001994 p->code_rate_HP = FEC_2_3;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001995 break;
1996 case 2:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03001997 p->code_rate_HP = FEC_3_4;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03001998 break;
1999 case 3:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002000 p->code_rate_HP = FEC_5_6;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002001 break;
2002 case 4:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002003 p->code_rate_HP = FEC_7_8;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002004 break;
2005 default:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002006 p->code_rate_HP = FEC_AUTO;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002007 break; /* error */
2008 }
2009
2010 mode = stv0367_readbits(state, F367TER_SYR_MODE);
2011
2012 switch (mode) {
2013 case FE_TER_MODE_2K:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002014 p->transmission_mode = TRANSMISSION_MODE_2K;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002015 break;
2016/* case FE_TER_MODE_4K:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002017 p->transmission_mode = TRANSMISSION_MODE_4K;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002018 break;*/
2019 case FE_TER_MODE_8K:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002020 p->transmission_mode = TRANSMISSION_MODE_8K;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002021 break;
2022 default:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002023 p->transmission_mode = TRANSMISSION_MODE_AUTO;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002024 }
2025
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002026 p->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002027
2028 return error;
2029}
2030
2031static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
2032{
2033 struct stv0367_state *state = fe->demodulator_priv;
2034 u32 snru32 = 0;
2035 int cpt = 0;
2036 u8 cut = stv0367_readbits(state, F367TER_IDENTIFICATIONREG);
2037
2038 while (cpt < 10) {
2039 usleep_range(2000, 3000);
2040 if (cut == 0x50) /*cut 1.0 cut 1.1*/
2041 snru32 += stv0367_readbits(state, F367TER_CHCSNR) / 4;
2042 else /*cu2.0*/
2043 snru32 += 125 * stv0367_readbits(state, F367TER_CHCSNR);
2044
2045 cpt++;
2046 }
2047
2048 snru32 /= 10;/*average on 10 values*/
2049
2050 *snr = snru32 / 1000;
2051
2052 return 0;
2053}
2054
2055#if 0
2056static int stv0367ter_status(struct dvb_frontend *fe)
2057{
2058
2059 struct stv0367_state *state = fe->demodulator_priv;
2060 struct stv0367ter_state *ter_state = state->ter_state;
2061 int locked = FALSE;
2062
2063 locked = (stv0367_readbits(state, F367TER_LK));
2064 if (!locked)
2065 ter_state->unlock_counter += 1;
2066 else
2067 ter_state->unlock_counter = 0;
2068
2069 if (ter_state->unlock_counter > 2) {
2070 if (!stv0367_readbits(state, F367TER_TPS_LOCK) ||
2071 (!stv0367_readbits(state, F367TER_LK))) {
2072 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
2073 usleep_range(2000, 3000);
2074 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
2075 msleep(350);
2076 locked = (stv0367_readbits(state, F367TER_TPS_LOCK)) &&
2077 (stv0367_readbits(state, F367TER_LK));
2078 }
2079
2080 }
2081
2082 return locked;
2083}
2084#endif
2085static int stv0367ter_read_status(struct dvb_frontend *fe, fe_status_t *status)
2086{
2087 struct stv0367_state *state = fe->demodulator_priv;
2088
2089 dprintk("%s:\n", __func__);
2090
2091 *status = 0;
2092
2093 if (stv0367_readbits(state, F367TER_LK)) {
2094 *status |= FE_HAS_LOCK;
2095 dprintk("%s: stv0367 has locked\n", __func__);
2096 }
2097
2098 return 0;
2099}
2100
2101static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber)
2102{
2103 struct stv0367_state *state = fe->demodulator_priv;
2104 struct stv0367ter_state *ter_state = state->ter_state;
2105 u32 Errors = 0, tber = 0, temporary = 0;
2106 int abc = 0, def = 0;
2107
2108
2109 /*wait for counting completion*/
2110 if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0)
2111 Errors = ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT)
2112 * (1 << 16))
2113 + ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT_HI)
2114 * (1 << 8))
2115 + ((u32)stv0367_readbits(state,
2116 F367TER_SFEC_ERR_CNT_LO));
2117 /*measurement not completed, load previous value*/
2118 else {
2119 tber = ter_state->pBER;
2120 return 0;
2121 }
2122
2123 abc = stv0367_readbits(state, F367TER_SFEC_ERR_SOURCE);
2124 def = stv0367_readbits(state, F367TER_SFEC_NUM_EVENT);
2125
2126 if (Errors == 0) {
2127 tber = 0;
2128 } else if (abc == 0x7) {
2129 if (Errors <= 4) {
2130 temporary = (Errors * 1000000000) / (8 * (1 << 14));
2131 temporary = temporary;
2132 } else if (Errors <= 42) {
2133 temporary = (Errors * 100000000) / (8 * (1 << 14));
2134 temporary = temporary * 10;
2135 } else if (Errors <= 429) {
2136 temporary = (Errors * 10000000) / (8 * (1 << 14));
2137 temporary = temporary * 100;
2138 } else if (Errors <= 4294) {
2139 temporary = (Errors * 1000000) / (8 * (1 << 14));
2140 temporary = temporary * 1000;
2141 } else if (Errors <= 42949) {
2142 temporary = (Errors * 100000) / (8 * (1 << 14));
2143 temporary = temporary * 10000;
2144 } else if (Errors <= 429496) {
2145 temporary = (Errors * 10000) / (8 * (1 << 14));
2146 temporary = temporary * 100000;
2147 } else { /*if (Errors<4294967) 2^22 max error*/
2148 temporary = (Errors * 1000) / (8 * (1 << 14));
2149 temporary = temporary * 100000; /* still to *10 */
2150 }
2151
2152 /* Byte error*/
2153 if (def == 2)
2154 /*tber=Errors/(8*(1 <<14));*/
2155 tber = temporary;
2156 else if (def == 3)
2157 /*tber=Errors/(8*(1 <<16));*/
2158 tber = temporary / 4;
2159 else if (def == 4)
2160 /*tber=Errors/(8*(1 <<18));*/
2161 tber = temporary / 16;
2162 else if (def == 5)
2163 /*tber=Errors/(8*(1 <<20));*/
2164 tber = temporary / 64;
2165 else if (def == 6)
2166 /*tber=Errors/(8*(1 <<22));*/
2167 tber = temporary / 256;
2168 else
2169 /* should not pass here*/
2170 tber = 0;
2171
2172 if ((Errors < 4294967) && (Errors > 429496))
2173 tber *= 10;
2174
2175 }
2176
2177 /* save actual value */
2178 ter_state->pBER = tber;
2179
2180 (*ber) = tber;
2181
2182 return 0;
2183}
2184#if 0
2185static u32 stv0367ter_get_per(struct stv0367_state *state)
2186{
2187 struct stv0367ter_state *ter_state = state->ter_state;
2188 u32 Errors = 0, Per = 0, temporary = 0;
2189 int abc = 0, def = 0, cpt = 0;
2190
2191 while (((stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 1) &&
2192 (cpt < 400)) || ((Errors == 0) && (cpt < 400))) {
2193 usleep_range(1000, 2000);
2194 Errors = ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
2195 * (1 << 16))
2196 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
2197 * (1 << 8))
2198 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
2199 cpt++;
2200 }
2201 abc = stv0367_readbits(state, F367TER_ERR_SRC1);
2202 def = stv0367_readbits(state, F367TER_NUM_EVT1);
2203
2204 if (Errors == 0)
2205 Per = 0;
2206 else if (abc == 0x9) {
2207 if (Errors <= 4) {
2208 temporary = (Errors * 1000000000) / (8 * (1 << 8));
2209 temporary = temporary;
2210 } else if (Errors <= 42) {
2211 temporary = (Errors * 100000000) / (8 * (1 << 8));
2212 temporary = temporary * 10;
2213 } else if (Errors <= 429) {
2214 temporary = (Errors * 10000000) / (8 * (1 << 8));
2215 temporary = temporary * 100;
2216 } else if (Errors <= 4294) {
2217 temporary = (Errors * 1000000) / (8 * (1 << 8));
2218 temporary = temporary * 1000;
2219 } else if (Errors <= 42949) {
2220 temporary = (Errors * 100000) / (8 * (1 << 8));
2221 temporary = temporary * 10000;
2222 } else { /*if(Errors<=429496) 2^16 errors max*/
2223 temporary = (Errors * 10000) / (8 * (1 << 8));
2224 temporary = temporary * 100000;
2225 }
2226
2227 /* pkt error*/
2228 if (def == 2)
2229 /*Per=Errors/(1 << 8);*/
2230 Per = temporary;
2231 else if (def == 3)
2232 /*Per=Errors/(1 << 10);*/
2233 Per = temporary / 4;
2234 else if (def == 4)
2235 /*Per=Errors/(1 << 12);*/
2236 Per = temporary / 16;
2237 else if (def == 5)
2238 /*Per=Errors/(1 << 14);*/
2239 Per = temporary / 64;
2240 else if (def == 6)
2241 /*Per=Errors/(1 << 16);*/
2242 Per = temporary / 256;
2243 else
2244 Per = 0;
2245
2246 }
2247 /* save actual value */
2248 ter_state->pPER = Per;
2249
2250 return Per;
2251}
2252#endif
2253static int stv0367_get_tune_settings(struct dvb_frontend *fe,
2254 struct dvb_frontend_tune_settings
2255 *fe_tune_settings)
2256{
2257 fe_tune_settings->min_delay_ms = 1000;
2258 fe_tune_settings->step_size = 0;
2259 fe_tune_settings->max_drift = 0;
2260
2261 return 0;
2262}
2263
2264static void stv0367_release(struct dvb_frontend *fe)
2265{
2266 struct stv0367_state *state = fe->demodulator_priv;
2267
2268 kfree(state->ter_state);
2269 kfree(state->cab_state);
2270 kfree(state);
2271}
2272
2273static struct dvb_frontend_ops stv0367ter_ops = {
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002274 .delsys = { SYS_DVBT },
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002275 .info = {
2276 .name = "ST STV0367 DVB-T",
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002277 .frequency_min = 47000000,
2278 .frequency_max = 862000000,
2279 .frequency_stepsize = 15625,
2280 .frequency_tolerance = 0,
2281 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
2282 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
2283 FE_CAN_FEC_AUTO |
2284 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
2285 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
2286 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
2287 FE_CAN_INVERSION_AUTO |
2288 FE_CAN_MUTE_TS
2289 },
2290 .release = stv0367_release,
2291 .init = stv0367ter_init,
2292 .sleep = stv0367ter_sleep,
2293 .i2c_gate_ctrl = stv0367ter_gate_ctrl,
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002294 .set_frontend = stv0367ter_set_frontend,
2295 .get_frontend = stv0367ter_get_frontend,
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002296 .get_tune_settings = stv0367_get_tune_settings,
2297 .read_status = stv0367ter_read_status,
2298 .read_ber = stv0367ter_read_ber,/* too slow */
2299/* .read_signal_strength = stv0367_read_signal_strength,*/
2300 .read_snr = stv0367ter_read_snr,
2301 .read_ucblocks = stv0367ter_read_ucblocks,
2302};
2303
2304struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
2305 struct i2c_adapter *i2c)
2306{
2307 struct stv0367_state *state = NULL;
2308 struct stv0367ter_state *ter_state = NULL;
2309
2310 /* allocate memory for the internal state */
2311 state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
2312 if (state == NULL)
2313 goto error;
2314 ter_state = kzalloc(sizeof(struct stv0367ter_state), GFP_KERNEL);
2315 if (ter_state == NULL)
2316 goto error;
2317
2318 /* setup the state */
2319 state->i2c = i2c;
2320 state->config = config;
2321 state->ter_state = ter_state;
2322 state->fe.ops = stv0367ter_ops;
2323 state->fe.demodulator_priv = state;
2324 state->chip_id = stv0367_readreg(state, 0xf000);
2325
2326 dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
2327
2328 /* check if the demod is there */
2329 if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
2330 goto error;
2331
2332 return &state->fe;
2333
2334error:
2335 kfree(ter_state);
2336 kfree(state);
2337 return NULL;
2338}
2339EXPORT_SYMBOL(stv0367ter_attach);
2340
2341static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
2342{
2343 struct stv0367_state *state = fe->demodulator_priv;
2344
2345 dprintk("%s:\n", __func__);
2346
2347 stv0367_writebits(state, F367CAB_I2CT_ON, (enable > 0) ? 1 : 0);
2348
2349 return 0;
2350}
2351
2352static u32 stv0367cab_get_mclk(struct dvb_frontend *fe, u32 ExtClk_Hz)
2353{
2354 struct stv0367_state *state = fe->demodulator_priv;
2355 u32 mclk_Hz = 0;/* master clock frequency (Hz) */
2356 u32 M, N, P;
2357
2358
2359 if (stv0367_readbits(state, F367CAB_BYPASS_PLLXN) == 0) {
2360 N = (u32)stv0367_readbits(state, F367CAB_PLL_NDIV);
2361 if (N == 0)
2362 N = N + 1;
2363
2364 M = (u32)stv0367_readbits(state, F367CAB_PLL_MDIV);
2365 if (M == 0)
2366 M = M + 1;
2367
2368 P = (u32)stv0367_readbits(state, F367CAB_PLL_PDIV);
2369
2370 if (P > 5)
2371 P = 5;
2372
2373 mclk_Hz = ((ExtClk_Hz / 2) * N) / (M * (1 << P));
2374 dprintk("stv0367cab_get_mclk BYPASS_PLLXN mclk_Hz=%d\n",
2375 mclk_Hz);
2376 } else
2377 mclk_Hz = ExtClk_Hz;
2378
2379 dprintk("stv0367cab_get_mclk final mclk_Hz=%d\n", mclk_Hz);
2380
2381 return mclk_Hz;
2382}
2383
2384static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz)
2385{
2386 u32 ADCClk_Hz = ExtClk_Hz;
2387
2388 ADCClk_Hz = stv0367cab_get_mclk(fe, ExtClk_Hz);
2389
2390 return ADCClk_Hz;
2391}
2392
Mauro Carvalho Chehab8c8ca1c2012-10-27 11:26:42 -03002393static enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
2394 u32 SymbolRate,
2395 enum stv0367cab_mod QAMSize)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002396{
2397 /* Set QAM size */
2398 stv0367_writebits(state, F367CAB_QAM_MODE, QAMSize);
2399
2400 /* Set Registers settings specific to the QAM size */
2401 switch (QAMSize) {
2402 case FE_CAB_MOD_QAM4:
2403 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2404 break;
2405 case FE_CAB_MOD_QAM16:
2406 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x64);
2407 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2408 stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
2409 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2410 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2411 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
2412 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2413 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x8a);
2414 break;
2415 case FE_CAB_MOD_QAM32:
2416 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2417 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x6e);
2418 stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
2419 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2420 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xb7);
2421 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x9d);
2422 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
2423 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2424 break;
2425 case FE_CAB_MOD_QAM64:
2426 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x82);
2427 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
2428 if (SymbolRate > 45000000) {
2429 stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
2430 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2431 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa5);
2432 } else if (SymbolRate > 25000000) {
2433 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2434 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2435 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
2436 } else {
2437 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2438 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
2439 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2440 }
2441 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
2442 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2443 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x99);
2444 break;
2445 case FE_CAB_MOD_QAM128:
2446 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2447 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x76);
2448 stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
2449 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xb1);
2450 if (SymbolRate > 45000000)
2451 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2452 else if (SymbolRate > 25000000)
2453 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
2454 else
2455 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0x97);
2456
2457 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x8e);
2458 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
2459 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2460 break;
2461 case FE_CAB_MOD_QAM256:
2462 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x94);
2463 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
2464 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2465 if (SymbolRate > 45000000)
2466 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2467 else if (SymbolRate > 25000000)
2468 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2469 else
2470 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
2471
2472 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2473 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x85);
2474 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2475 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2476 break;
2477 case FE_CAB_MOD_QAM512:
2478 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2479 break;
2480 case FE_CAB_MOD_QAM1024:
2481 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2482 break;
2483 default:
2484 break;
2485 }
2486
2487 return QAMSize;
2488}
2489
2490static u32 stv0367cab_set_derot_freq(struct stv0367_state *state,
2491 u32 adc_hz, s32 derot_hz)
2492{
2493 u32 sampled_if = 0;
2494 u32 adc_khz;
2495
2496 adc_khz = adc_hz / 1000;
2497
2498 dprintk("%s: adc_hz=%d derot_hz=%d\n", __func__, adc_hz, derot_hz);
2499
2500 if (adc_khz != 0) {
2501 if (derot_hz < 1000000)
2502 derot_hz = adc_hz / 4; /* ZIF operation */
2503 if (derot_hz > adc_hz)
2504 derot_hz = derot_hz - adc_hz;
2505 sampled_if = (u32)derot_hz / 1000;
2506 sampled_if *= 32768;
2507 sampled_if /= adc_khz;
2508 sampled_if *= 256;
2509 }
2510
2511 if (sampled_if > 8388607)
2512 sampled_if = 8388607;
2513
2514 dprintk("%s: sampled_if=0x%x\n", __func__, sampled_if);
2515
2516 stv0367_writereg(state, R367CAB_MIX_NCO_LL, sampled_if);
2517 stv0367_writereg(state, R367CAB_MIX_NCO_HL, (sampled_if >> 8));
2518 stv0367_writebits(state, F367CAB_MIX_NCO_INC_HH, (sampled_if >> 16));
2519
2520 return derot_hz;
2521}
2522
2523static u32 stv0367cab_get_derot_freq(struct stv0367_state *state, u32 adc_hz)
2524{
2525 u32 sampled_if;
2526
2527 sampled_if = stv0367_readbits(state, F367CAB_MIX_NCO_INC_LL) +
2528 (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HL) << 8) +
2529 (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HH) << 16);
2530
2531 sampled_if /= 256;
2532 sampled_if *= (adc_hz / 1000);
2533 sampled_if += 1;
2534 sampled_if /= 32768;
2535
2536 return sampled_if;
2537}
2538
2539static u32 stv0367cab_set_srate(struct stv0367_state *state, u32 adc_hz,
2540 u32 mclk_hz, u32 SymbolRate,
2541 enum stv0367cab_mod QAMSize)
2542{
2543 u32 QamSizeCorr = 0;
2544 u32 u32_tmp = 0, u32_tmp1 = 0;
2545 u32 adp_khz;
2546
2547 dprintk("%s:\n", __func__);
2548
2549 /* Set Correction factor of SRC gain */
2550 switch (QAMSize) {
2551 case FE_CAB_MOD_QAM4:
2552 QamSizeCorr = 1110;
2553 break;
2554 case FE_CAB_MOD_QAM16:
2555 QamSizeCorr = 1032;
2556 break;
2557 case FE_CAB_MOD_QAM32:
2558 QamSizeCorr = 954;
2559 break;
2560 case FE_CAB_MOD_QAM64:
2561 QamSizeCorr = 983;
2562 break;
2563 case FE_CAB_MOD_QAM128:
2564 QamSizeCorr = 957;
2565 break;
2566 case FE_CAB_MOD_QAM256:
2567 QamSizeCorr = 948;
2568 break;
2569 case FE_CAB_MOD_QAM512:
2570 QamSizeCorr = 0;
2571 break;
2572 case FE_CAB_MOD_QAM1024:
2573 QamSizeCorr = 944;
2574 break;
2575 default:
2576 break;
2577 }
2578
2579 /* Transfer ratio calculation */
2580 if (adc_hz != 0) {
2581 u32_tmp = 256 * SymbolRate;
2582 u32_tmp = u32_tmp / adc_hz;
2583 }
2584 stv0367_writereg(state, R367CAB_EQU_CRL_TFR, (u8)u32_tmp);
2585
2586 /* Symbol rate and SRC gain calculation */
2587 adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
2588 if (adp_khz != 0) {
2589 u32_tmp = SymbolRate;
2590 u32_tmp1 = SymbolRate;
2591
2592 if (u32_tmp < 2097152) { /* 2097152 = 2^21 */
2593 /* Symbol rate calculation */
2594 u32_tmp *= 2048; /* 2048 = 2^11 */
2595 u32_tmp = u32_tmp / adp_khz;
2596 u32_tmp = u32_tmp * 16384; /* 16384 = 2^14 */
2597 u32_tmp /= 125 ; /* 125 = 1000/2^3 */
2598 u32_tmp = u32_tmp * 8; /* 8 = 2^3 */
2599
2600 /* SRC Gain Calculation */
2601 u32_tmp1 *= 2048; /* *2*2^10 */
2602 u32_tmp1 /= 439; /* *2/878 */
2603 u32_tmp1 *= 256; /* *2^8 */
2604 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2605 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2606 u32_tmp1 = u32_tmp1 / 10000000;
2607
2608 } else if (u32_tmp < 4194304) { /* 4194304 = 2**22 */
2609 /* Symbol rate calculation */
2610 u32_tmp *= 1024 ; /* 1024 = 2**10 */
2611 u32_tmp = u32_tmp / adp_khz;
2612 u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
2613 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2614 u32_tmp = u32_tmp * 16; /* 16 = 2**4 */
2615
2616 /* SRC Gain Calculation */
2617 u32_tmp1 *= 1024; /* *2*2^9 */
2618 u32_tmp1 /= 439; /* *2/878 */
2619 u32_tmp1 *= 256; /* *2^8 */
2620 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz)*/
2621 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2622 u32_tmp1 = u32_tmp1 / 5000000;
2623 } else if (u32_tmp < 8388607) { /* 8388607 = 2**23 */
2624 /* Symbol rate calculation */
2625 u32_tmp *= 512 ; /* 512 = 2**9 */
2626 u32_tmp = u32_tmp / adp_khz;
2627 u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
2628 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2629 u32_tmp = u32_tmp * 32; /* 32 = 2**5 */
2630
2631 /* SRC Gain Calculation */
2632 u32_tmp1 *= 512; /* *2*2^8 */
2633 u32_tmp1 /= 439; /* *2/878 */
2634 u32_tmp1 *= 256; /* *2^8 */
2635 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2636 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2637 u32_tmp1 = u32_tmp1 / 2500000;
2638 } else {
2639 /* Symbol rate calculation */
2640 u32_tmp *= 256 ; /* 256 = 2**8 */
2641 u32_tmp = u32_tmp / adp_khz;
2642 u32_tmp = u32_tmp * 16384; /* 16384 = 2**13 */
2643 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2644 u32_tmp = u32_tmp * 64; /* 64 = 2**6 */
2645
2646 /* SRC Gain Calculation */
2647 u32_tmp1 *= 256; /* 2*2^7 */
2648 u32_tmp1 /= 439; /* *2/878 */
2649 u32_tmp1 *= 256; /* *2^8 */
2650 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2651 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2652 u32_tmp1 = u32_tmp1 / 1250000;
2653 }
2654 }
2655#if 0
2656 /* Filters' coefficients are calculated and written
2657 into registers only if the filters are enabled */
2658 if (stv0367_readbits(state, F367CAB_ADJ_EN)) {
2659 stv0367cab_SetIirAdjacentcoefficient(state, mclk_hz,
2660 SymbolRate);
2661 /* AllPass filter must be enabled
2662 when the adjacents filter is used */
2663 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 1);
2664 stv0367cab_SetAllPasscoefficient(state, mclk_hz, SymbolRate);
2665 } else
2666 /* AllPass filter must be disabled
2667 when the adjacents filter is not used */
2668#endif
2669 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
2670
2671 stv0367_writereg(state, R367CAB_SRC_NCO_LL, u32_tmp);
2672 stv0367_writereg(state, R367CAB_SRC_NCO_LH, (u32_tmp >> 8));
2673 stv0367_writereg(state, R367CAB_SRC_NCO_HL, (u32_tmp >> 16));
2674 stv0367_writereg(state, R367CAB_SRC_NCO_HH, (u32_tmp >> 24));
2675
2676 stv0367_writereg(state, R367CAB_IQDEM_GAIN_SRC_L, u32_tmp1 & 0x00ff);
2677 stv0367_writebits(state, F367CAB_GAIN_SRC_HI, (u32_tmp1 >> 8) & 0x00ff);
2678
2679 return SymbolRate ;
2680}
2681
2682static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz)
2683{
2684 u32 regsym;
2685 u32 adp_khz;
2686
2687 regsym = stv0367_readreg(state, R367CAB_SRC_NCO_LL) +
2688 (stv0367_readreg(state, R367CAB_SRC_NCO_LH) << 8) +
2689 (stv0367_readreg(state, R367CAB_SRC_NCO_HL) << 16) +
2690 (stv0367_readreg(state, R367CAB_SRC_NCO_HH) << 24);
2691
2692 adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
2693
2694 if (regsym < 134217728) { /* 134217728L = 2**27*/
2695 regsym = regsym * 32; /* 32 = 2**5 */
2696 regsym = regsym / 32768; /* 32768L = 2**15 */
2697 regsym = adp_khz * regsym; /* AdpClk in kHz */
2698 regsym = regsym / 128; /* 128 = 2**7 */
2699 regsym *= 125 ; /* 125 = 1000/2**3 */
2700 regsym /= 2048 ; /* 2048 = 2**11 */
2701 } else if (regsym < 268435456) { /* 268435456L = 2**28 */
2702 regsym = regsym * 16; /* 16 = 2**4 */
2703 regsym = regsym / 32768; /* 32768L = 2**15 */
2704 regsym = adp_khz * regsym; /* AdpClk in kHz */
2705 regsym = regsym / 128; /* 128 = 2**7 */
2706 regsym *= 125 ; /* 125 = 1000/2**3*/
2707 regsym /= 1024 ; /* 256 = 2**10*/
2708 } else if (regsym < 536870912) { /* 536870912L = 2**29*/
2709 regsym = regsym * 8; /* 8 = 2**3 */
2710 regsym = regsym / 32768; /* 32768L = 2**15 */
2711 regsym = adp_khz * regsym; /* AdpClk in kHz */
2712 regsym = regsym / 128; /* 128 = 2**7 */
2713 regsym *= 125 ; /* 125 = 1000/2**3 */
2714 regsym /= 512 ; /* 128 = 2**9 */
2715 } else {
2716 regsym = regsym * 4; /* 4 = 2**2 */
2717 regsym = regsym / 32768; /* 32768L = 2**15 */
2718 regsym = adp_khz * regsym; /* AdpClk in kHz */
2719 regsym = regsym / 128; /* 128 = 2**7 */
2720 regsym *= 125 ; /* 125 = 1000/2**3 */
2721 regsym /= 256 ; /* 64 = 2**8 */
2722 }
2723
2724 return regsym;
2725}
2726
2727static int stv0367cab_read_status(struct dvb_frontend *fe, fe_status_t *status)
2728{
2729 struct stv0367_state *state = fe->demodulator_priv;
2730
2731 dprintk("%s:\n", __func__);
2732
2733 *status = 0;
2734
2735 if (stv0367_readbits(state, F367CAB_QAMFEC_LOCK)) {
2736 *status |= FE_HAS_LOCK;
2737 dprintk("%s: stv0367 has locked\n", __func__);
2738 }
2739
2740 return 0;
2741}
2742
2743static int stv0367cab_standby(struct dvb_frontend *fe, u8 standby_on)
2744{
2745 struct stv0367_state *state = fe->demodulator_priv;
2746
2747 dprintk("%s:\n", __func__);
2748
2749 if (standby_on) {
2750 stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x03);
2751 stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x01);
2752 stv0367_writebits(state, F367CAB_STDBY, 1);
2753 stv0367_writebits(state, F367CAB_STDBY_CORE, 1);
2754 stv0367_writebits(state, F367CAB_EN_BUFFER_I, 0);
2755 stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 0);
2756 stv0367_writebits(state, F367CAB_POFFQ, 1);
2757 stv0367_writebits(state, F367CAB_POFFI, 1);
2758 } else {
2759 stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x00);
2760 stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x00);
2761 stv0367_writebits(state, F367CAB_STDBY, 0);
2762 stv0367_writebits(state, F367CAB_STDBY_CORE, 0);
2763 stv0367_writebits(state, F367CAB_EN_BUFFER_I, 1);
2764 stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 1);
2765 stv0367_writebits(state, F367CAB_POFFQ, 0);
2766 stv0367_writebits(state, F367CAB_POFFI, 0);
2767 }
2768
2769 return 0;
2770}
2771
2772static int stv0367cab_sleep(struct dvb_frontend *fe)
2773{
2774 return stv0367cab_standby(fe, 1);
2775}
2776
Mauro Carvalho Chehab8c8ca1c2012-10-27 11:26:42 -03002777static int stv0367cab_init(struct dvb_frontend *fe)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002778{
2779 struct stv0367_state *state = fe->demodulator_priv;
2780 struct stv0367cab_state *cab_state = state->cab_state;
2781 int i;
2782
2783 dprintk("%s:\n", __func__);
2784
2785 for (i = 0; i < STV0367CAB_NBREGS; i++)
2786 stv0367_writereg(state, def0367cab[i].addr,
2787 def0367cab[i].value);
2788
2789 switch (state->config->ts_mode) {
2790 case STV0367_DVBCI_CLOCK:
2791 dprintk("Setting TSMode = STV0367_DVBCI_CLOCK\n");
2792 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x03);
2793 break;
2794 case STV0367_SERIAL_PUNCT_CLOCK:
2795 case STV0367_SERIAL_CONT_CLOCK:
2796 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x01);
2797 break;
2798 case STV0367_PARALLEL_PUNCT_CLOCK:
2799 case STV0367_OUTPUTMODE_DEFAULT:
2800 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x00);
2801 break;
2802 }
2803
2804 switch (state->config->clk_pol) {
2805 case STV0367_RISINGEDGE_CLOCK:
2806 stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x00);
2807 break;
2808 case STV0367_FALLINGEDGE_CLOCK:
2809 case STV0367_CLOCKPOLARITY_DEFAULT:
2810 stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x01);
2811 break;
2812 }
2813
2814 stv0367_writebits(state, F367CAB_SYNC_STRIP, 0x00);
2815
2816 stv0367_writebits(state, F367CAB_CT_NBST, 0x01);
2817
2818 stv0367_writebits(state, F367CAB_TS_SWAP, 0x01);
2819
2820 stv0367_writebits(state, F367CAB_FIFO_BYPASS, 0x00);
2821
2822 stv0367_writereg(state, R367CAB_ANACTRL, 0x00);/*PLL enabled and used */
2823
2824 cab_state->mclk = stv0367cab_get_mclk(fe, state->config->xtal);
2825 cab_state->adc_clk = stv0367cab_get_adc_freq(fe, state->config->xtal);
2826
2827 return 0;
2828}
2829static
2830enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002831 struct dtv_frontend_properties *p)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002832{
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002833 struct stv0367cab_state *cab_state = state->cab_state;
2834 enum stv0367_cab_signal_type signalType = FE_CAB_NOAGC;
2835 u32 QAMFEC_Lock, QAM_Lock, u32_tmp,
2836 LockTime, TRLTimeOut, AGCTimeOut, CRLSymbols,
2837 CRLTimeOut, EQLTimeOut, DemodTimeOut, FECTimeOut;
2838 u8 TrackAGCAccum;
2839 s32 tmp;
2840
2841 dprintk("%s:\n", __func__);
2842
2843 /* Timeouts calculation */
2844 /* A max lock time of 25 ms is allowed for delayed AGC */
2845 AGCTimeOut = 25;
2846 /* 100000 symbols needed by the TRL as a maximum value */
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002847 TRLTimeOut = 100000000 / p->symbol_rate;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002848 /* CRLSymbols is the needed number of symbols to achieve a lock
2849 within [-4%, +4%] of the symbol rate.
2850 CRL timeout is calculated
2851 for a lock within [-search_range, +search_range].
2852 EQL timeout can be changed depending on
2853 the micro-reflections we want to handle.
2854 A characterization must be performed
2855 with these echoes to get new timeout values.
2856 */
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002857 switch (p->modulation) {
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002858 case QAM_16:
2859 CRLSymbols = 150000;
2860 EQLTimeOut = 100;
2861 break;
2862 case QAM_32:
2863 CRLSymbols = 250000;
2864 EQLTimeOut = 100;
2865 break;
2866 case QAM_64:
2867 CRLSymbols = 200000;
2868 EQLTimeOut = 100;
2869 break;
2870 case QAM_128:
2871 CRLSymbols = 250000;
2872 EQLTimeOut = 100;
2873 break;
2874 case QAM_256:
2875 CRLSymbols = 250000;
2876 EQLTimeOut = 100;
2877 break;
2878 default:
2879 CRLSymbols = 200000;
2880 EQLTimeOut = 100;
2881 break;
2882 }
2883#if 0
2884 if (pIntParams->search_range < 0) {
2885 CRLTimeOut = (25 * CRLSymbols *
2886 (-pIntParams->search_range / 1000)) /
2887 (pIntParams->symbol_rate / 1000);
2888 } else
2889#endif
2890 CRLTimeOut = (25 * CRLSymbols * (cab_state->search_range / 1000)) /
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002891 (p->symbol_rate / 1000);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002892
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002893 CRLTimeOut = (1000 * CRLTimeOut) / p->symbol_rate;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002894 /* Timeouts below 50ms are coerced */
2895 if (CRLTimeOut < 50)
2896 CRLTimeOut = 50;
2897 /* A maximum of 100 TS packets is needed to get FEC lock even in case
2898 the spectrum inversion needs to be changed.
2899 This is equal to 20 ms in case of the lowest symbol rate of 0.87Msps
2900 */
2901 FECTimeOut = 20;
2902 DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut;
2903
2904 dprintk("%s: DemodTimeOut=%d\n", __func__, DemodTimeOut);
2905
2906 /* Reset the TRL to ensure nothing starts until the
2907 AGC is stable which ensures a better lock time
2908 */
2909 stv0367_writereg(state, R367CAB_CTRL_1, 0x04);
2910 /* Set AGC accumulation time to minimum and lock threshold to maximum
2911 in order to speed up the AGC lock */
2912 TrackAGCAccum = stv0367_readbits(state, F367CAB_AGC_ACCUMRSTSEL);
2913 stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, 0x0);
2914 /* Modulus Mapper is disabled */
2915 stv0367_writebits(state, F367CAB_MODULUSMAP_EN, 0);
2916 /* Disable the sweep function */
2917 stv0367_writebits(state, F367CAB_SWEEP_EN, 0);
2918 /* The sweep function is never used, Sweep rate must be set to 0 */
2919 /* Set the derotator frequency in Hz */
2920 stv0367cab_set_derot_freq(state, cab_state->adc_clk,
2921 (1000 * (s32)state->config->if_khz + cab_state->derot_offset));
2922 /* Disable the Allpass Filter when the symbol rate is out of range */
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03002923 if ((p->symbol_rate > 10800000) | (p->symbol_rate < 1800000)) {
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002924 stv0367_writebits(state, F367CAB_ADJ_EN, 0);
2925 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
2926 }
2927#if 0
2928 /* Check if the tuner is locked */
2929 tuner_lock = stv0367cab_tuner_get_status(fe);
2930 if (tuner_lock == 0)
2931 return FE_367CAB_NOTUNER;
2932#endif
Geert Uytterhoeven83a35e32013-06-28 11:27:31 +02002933 /* Release the TRL to start demodulator acquisition */
Igor M. Liplianin17cce932011-01-25 17:02:00 -03002934 /* Wait for QAM lock */
2935 LockTime = 0;
2936 stv0367_writereg(state, R367CAB_CTRL_1, 0x00);
2937 do {
2938 QAM_Lock = stv0367_readbits(state, F367CAB_FSM_STATUS);
2939 if ((LockTime >= (DemodTimeOut - EQLTimeOut)) &&
2940 (QAM_Lock == 0x04))
2941 /*
2942 * We don't wait longer, the frequency/phase offset
2943 * must be too big
2944 */
2945 LockTime = DemodTimeOut;
2946 else if ((LockTime >= (AGCTimeOut + TRLTimeOut)) &&
2947 (QAM_Lock == 0x02))
2948 /*
2949 * We don't wait longer, either there is no signal or
2950 * it is not the right symbol rate or it is an analog
2951 * carrier
2952 */
2953 {
2954 LockTime = DemodTimeOut;
2955 u32_tmp = stv0367_readbits(state,
2956 F367CAB_AGC_PWR_WORD_LO) +
2957 (stv0367_readbits(state,
2958 F367CAB_AGC_PWR_WORD_ME) << 8) +
2959 (stv0367_readbits(state,
2960 F367CAB_AGC_PWR_WORD_HI) << 16);
2961 if (u32_tmp >= 131072)
2962 u32_tmp = 262144 - u32_tmp;
2963 u32_tmp = u32_tmp / (1 << (11 - stv0367_readbits(state,
2964 F367CAB_AGC_IF_BWSEL)));
2965
2966 if (u32_tmp < stv0367_readbits(state,
2967 F367CAB_AGC_PWRREF_LO) +
2968 256 * stv0367_readbits(state,
2969 F367CAB_AGC_PWRREF_HI) - 10)
2970 QAM_Lock = 0x0f;
2971 } else {
2972 usleep_range(10000, 20000);
2973 LockTime += 10;
2974 }
2975 dprintk("QAM_Lock=0x%x LockTime=%d\n", QAM_Lock, LockTime);
2976 tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
2977
2978 dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
2979
2980 } while (((QAM_Lock != 0x0c) && (QAM_Lock != 0x0b)) &&
2981 (LockTime < DemodTimeOut));
2982
2983 dprintk("QAM_Lock=0x%x\n", QAM_Lock);
2984
2985 tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
2986 dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
2987 tmp = stv0367_readreg(state, R367CAB_IT_STATUS2);
2988 dprintk("R367CAB_IT_STATUS2=0x%x\n", tmp);
2989
2990 tmp = stv0367cab_get_derot_freq(state, cab_state->adc_clk);
2991 dprintk("stv0367cab_get_derot_freq=0x%x\n", tmp);
2992
2993 if ((QAM_Lock == 0x0c) || (QAM_Lock == 0x0b)) {
2994 /* Wait for FEC lock */
2995 LockTime = 0;
2996 do {
2997 usleep_range(5000, 7000);
2998 LockTime += 5;
2999 QAMFEC_Lock = stv0367_readbits(state,
3000 F367CAB_QAMFEC_LOCK);
3001 } while (!QAMFEC_Lock && (LockTime < FECTimeOut));
3002 } else
3003 QAMFEC_Lock = 0;
3004
3005 if (QAMFEC_Lock) {
3006 signalType = FE_CAB_DATAOK;
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003007 cab_state->modulation = p->modulation;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003008 cab_state->spect_inv = stv0367_readbits(state,
3009 F367CAB_QUAD_INV);
3010#if 0
3011/* not clear for me */
3012 if (state->config->if_khz != 0) {
3013 if (state->config->if_khz > cab_state->adc_clk / 1000) {
3014 cab_state->freq_khz =
3015 FE_Cab_TunerGetFrequency(pIntParams->hTuner)
3016 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3017 - cab_state->adc_clk / 1000 + state->config->if_khz;
3018 } else {
3019 cab_state->freq_khz =
3020 FE_Cab_TunerGetFrequency(pIntParams->hTuner)
3021 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3022 + state->config->if_khz;
3023 }
3024 } else {
3025 cab_state->freq_khz =
3026 FE_Cab_TunerGetFrequency(pIntParams->hTuner) +
3027 stv0367cab_get_derot_freq(state,
3028 cab_state->adc_clk) -
3029 cab_state->adc_clk / 4000;
3030 }
3031#endif
3032 cab_state->symbol_rate = stv0367cab_GetSymbolRate(state,
3033 cab_state->mclk);
3034 cab_state->locked = 1;
3035
3036 /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/
3037 } else {
3038 switch (QAM_Lock) {
3039 case 1:
3040 signalType = FE_CAB_NOAGC;
3041 break;
3042 case 2:
3043 signalType = FE_CAB_NOTIMING;
3044 break;
3045 case 3:
3046 signalType = FE_CAB_TIMINGOK;
3047 break;
3048 case 4:
3049 signalType = FE_CAB_NOCARRIER;
3050 break;
3051 case 5:
3052 signalType = FE_CAB_CARRIEROK;
3053 break;
3054 case 7:
3055 signalType = FE_CAB_NOBLIND;
3056 break;
3057 case 8:
3058 signalType = FE_CAB_BLINDOK;
3059 break;
3060 case 10:
3061 signalType = FE_CAB_NODEMOD;
3062 break;
3063 case 11:
3064 signalType = FE_CAB_DEMODOK;
3065 break;
3066 case 12:
3067 signalType = FE_CAB_DEMODOK;
3068 break;
3069 case 13:
3070 signalType = FE_CAB_NODEMOD;
3071 break;
3072 case 14:
3073 signalType = FE_CAB_NOBLIND;
3074 break;
3075 case 15:
3076 signalType = FE_CAB_NOSIGNAL;
3077 break;
3078 default:
3079 break;
3080 }
3081
3082 }
3083
3084 /* Set the AGC control values to tracking values */
3085 stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum);
3086 return signalType;
3087}
3088
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003089static int stv0367cab_set_frontend(struct dvb_frontend *fe)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003090{
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003091 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003092 struct stv0367_state *state = fe->demodulator_priv;
3093 struct stv0367cab_state *cab_state = state->cab_state;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003094 enum stv0367cab_mod QAMSize = 0;
3095
3096 dprintk("%s: freq = %d, srate = %d\n", __func__,
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003097 p->frequency, p->symbol_rate);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003098
3099 cab_state->derot_offset = 0;
3100
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003101 switch (p->modulation) {
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003102 case QAM_16:
3103 QAMSize = FE_CAB_MOD_QAM16;
3104 break;
3105 case QAM_32:
3106 QAMSize = FE_CAB_MOD_QAM32;
3107 break;
3108 case QAM_64:
3109 QAMSize = FE_CAB_MOD_QAM64;
3110 break;
3111 case QAM_128:
3112 QAMSize = FE_CAB_MOD_QAM128;
3113 break;
3114 case QAM_256:
3115 QAMSize = FE_CAB_MOD_QAM256;
3116 break;
3117 default:
3118 break;
3119 }
3120
3121 stv0367cab_init(fe);
3122
3123 /* Tuner Frequency Setting */
3124 if (fe->ops.tuner_ops.set_params) {
3125 if (fe->ops.i2c_gate_ctrl)
3126 fe->ops.i2c_gate_ctrl(fe, 1);
Mauro Carvalho Chehab14d24d12011-12-24 12:24:33 -03003127 fe->ops.tuner_ops.set_params(fe);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003128 if (fe->ops.i2c_gate_ctrl)
3129 fe->ops.i2c_gate_ctrl(fe, 0);
3130 }
3131
3132 stv0367cab_SetQamSize(
3133 state,
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003134 p->symbol_rate,
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003135 QAMSize);
3136
3137 stv0367cab_set_srate(state,
3138 cab_state->adc_clk,
3139 cab_state->mclk,
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003140 p->symbol_rate,
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003141 QAMSize);
3142 /* Search algorithm launch, [-1.1*RangeOffset, +1.1*RangeOffset] scan */
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003143 cab_state->state = stv0367cab_algo(state, p);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003144 return 0;
3145}
3146
Mauro Carvalho Chehab7c61d802011-12-30 11:30:21 -03003147static int stv0367cab_get_frontend(struct dvb_frontend *fe)
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003148{
Mauro Carvalho Chehab7c61d802011-12-30 11:30:21 -03003149 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003150 struct stv0367_state *state = fe->demodulator_priv;
3151 struct stv0367cab_state *cab_state = state->cab_state;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003152
3153 enum stv0367cab_mod QAMSize;
3154
3155 dprintk("%s:\n", __func__);
3156
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003157 p->symbol_rate = stv0367cab_GetSymbolRate(state, cab_state->mclk);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003158
3159 QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
3160 switch (QAMSize) {
3161 case FE_CAB_MOD_QAM16:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003162 p->modulation = QAM_16;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003163 break;
3164 case FE_CAB_MOD_QAM32:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003165 p->modulation = QAM_32;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003166 break;
3167 case FE_CAB_MOD_QAM64:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003168 p->modulation = QAM_64;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003169 break;
3170 case FE_CAB_MOD_QAM128:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003171 p->modulation = QAM_128;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003172 break;
3173 case QAM_256:
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003174 p->modulation = QAM_256;
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003175 break;
3176 default:
3177 break;
3178 }
3179
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003180 p->frequency = stv0367_get_tuner_freq(fe);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003181
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003182 dprintk("%s: tuner frequency = %d\n", __func__, p->frequency);
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003183
3184 if (state->config->if_khz == 0) {
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003185 p->frequency +=
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003186 (stv0367cab_get_derot_freq(state, cab_state->adc_clk) -
3187 cab_state->adc_clk / 4000);
3188 return 0;
3189 }
3190
3191 if (state->config->if_khz > cab_state->adc_clk / 1000)
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003192 p->frequency += (state->config->if_khz
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003193 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3194 - cab_state->adc_clk / 1000);
3195 else
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003196 p->frequency += (state->config->if_khz
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003197 - stv0367cab_get_derot_freq(state, cab_state->adc_clk));
3198
3199 return 0;
3200}
3201
3202#if 0
3203void stv0367cab_GetErrorCount(state, enum stv0367cab_mod QAMSize,
3204 u32 symbol_rate, FE_367qam_Monitor *Monitor_results)
3205{
3206 stv0367cab_OptimiseNByteAndGetBER(state, QAMSize, symbol_rate, Monitor_results);
3207 stv0367cab_GetPacketsCount(state, Monitor_results);
3208
3209 return;
3210}
3211
3212static int stv0367cab_read_ber(struct dvb_frontend *fe, u32 *ber)
3213{
3214 struct stv0367_state *state = fe->demodulator_priv;
3215
3216 return 0;
3217}
3218#endif
3219static s32 stv0367cab_get_rf_lvl(struct stv0367_state *state)
3220{
3221 s32 rfLevel = 0;
3222 s32 RfAgcPwm = 0, IfAgcPwm = 0;
3223 u8 i;
3224
3225 stv0367_writebits(state, F367CAB_STDBY_ADCGP, 0x0);
3226
3227 RfAgcPwm =
3228 (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_LO) & 0x03) +
3229 (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_HI) << 2);
3230 RfAgcPwm = 100 * RfAgcPwm / 1023;
3231
3232 IfAgcPwm =
3233 stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_LO) +
3234 (stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_HI) << 8);
3235 if (IfAgcPwm >= 2048)
3236 IfAgcPwm -= 2048;
3237 else
3238 IfAgcPwm += 2048;
3239
3240 IfAgcPwm = 100 * IfAgcPwm / 4095;
3241
3242 /* For DTT75467 on NIM */
3243 if (RfAgcPwm < 90 && IfAgcPwm < 28) {
3244 for (i = 0; i < RF_LOOKUP_TABLE_SIZE; i++) {
3245 if (RfAgcPwm <= stv0367cab_RF_LookUp1[0][i]) {
3246 rfLevel = (-1) * stv0367cab_RF_LookUp1[1][i];
3247 break;
3248 }
3249 }
3250 if (i == RF_LOOKUP_TABLE_SIZE)
3251 rfLevel = -56;
3252 } else { /*if IF AGC>10*/
3253 for (i = 0; i < RF_LOOKUP_TABLE2_SIZE; i++) {
3254 if (IfAgcPwm <= stv0367cab_RF_LookUp2[0][i]) {
3255 rfLevel = (-1) * stv0367cab_RF_LookUp2[1][i];
3256 break;
3257 }
3258 }
3259 if (i == RF_LOOKUP_TABLE2_SIZE)
3260 rfLevel = -72;
3261 }
3262 return rfLevel;
3263}
3264
3265static int stv0367cab_read_strength(struct dvb_frontend *fe, u16 *strength)
3266{
3267 struct stv0367_state *state = fe->demodulator_priv;
3268
3269 s32 signal = stv0367cab_get_rf_lvl(state);
3270
3271 dprintk("%s: signal=%d dBm\n", __func__, signal);
3272
3273 if (signal <= -72)
3274 *strength = 65535;
3275 else
3276 *strength = (22 + signal) * (-1311);
3277
3278 dprintk("%s: strength=%d\n", __func__, (*strength));
3279
3280 return 0;
3281}
3282
3283static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr)
3284{
3285 struct stv0367_state *state = fe->demodulator_priv;
3286 u32 noisepercentage;
3287 enum stv0367cab_mod QAMSize;
3288 u32 regval = 0, temp = 0;
3289 int power, i;
3290
3291 QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
3292 switch (QAMSize) {
3293 case FE_CAB_MOD_QAM4:
3294 power = 21904;
3295 break;
3296 case FE_CAB_MOD_QAM16:
3297 power = 20480;
3298 break;
3299 case FE_CAB_MOD_QAM32:
3300 power = 23040;
3301 break;
3302 case FE_CAB_MOD_QAM64:
3303 power = 21504;
3304 break;
3305 case FE_CAB_MOD_QAM128:
3306 power = 23616;
3307 break;
3308 case FE_CAB_MOD_QAM256:
3309 power = 21760;
3310 break;
3311 case FE_CAB_MOD_QAM512:
3312 power = 1;
3313 break;
3314 case FE_CAB_MOD_QAM1024:
3315 power = 21280;
3316 break;
3317 default:
3318 power = 1;
3319 break;
3320 }
3321
3322 for (i = 0; i < 10; i++) {
3323 regval += (stv0367_readbits(state, F367CAB_SNR_LO)
3324 + 256 * stv0367_readbits(state, F367CAB_SNR_HI));
3325 }
3326
3327 regval /= 10; /*for average over 10 times in for loop above*/
3328 if (regval != 0) {
3329 temp = power
3330 * (1 << (3 + stv0367_readbits(state, F367CAB_SNR_PER)));
3331 temp /= regval;
3332 }
3333
3334 /* table values, not needed to calculate logarithms */
3335 if (temp >= 5012)
3336 noisepercentage = 100;
3337 else if (temp >= 3981)
3338 noisepercentage = 93;
3339 else if (temp >= 3162)
3340 noisepercentage = 86;
3341 else if (temp >= 2512)
3342 noisepercentage = 79;
3343 else if (temp >= 1995)
3344 noisepercentage = 72;
3345 else if (temp >= 1585)
3346 noisepercentage = 65;
3347 else if (temp >= 1259)
3348 noisepercentage = 58;
3349 else if (temp >= 1000)
3350 noisepercentage = 50;
3351 else if (temp >= 794)
3352 noisepercentage = 43;
3353 else if (temp >= 501)
3354 noisepercentage = 36;
3355 else if (temp >= 316)
3356 noisepercentage = 29;
3357 else if (temp >= 200)
3358 noisepercentage = 22;
3359 else if (temp >= 158)
3360 noisepercentage = 14;
3361 else if (temp >= 126)
3362 noisepercentage = 7;
3363 else
3364 noisepercentage = 0;
3365
3366 dprintk("%s: noisepercentage=%d\n", __func__, noisepercentage);
3367
3368 *snr = (noisepercentage * 65535) / 100;
3369
3370 return 0;
3371}
3372
Abylay Ospan78db66e2011-01-02 09:12:00 -03003373static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks)
3374{
3375 struct stv0367_state *state = fe->demodulator_priv;
3376 int corrected, tscount;
3377
3378 *ucblocks = (stv0367_readreg(state, R367CAB_RS_COUNTER_5) << 8)
3379 | stv0367_readreg(state, R367CAB_RS_COUNTER_4);
3380 corrected = (stv0367_readreg(state, R367CAB_RS_COUNTER_3) << 8)
3381 | stv0367_readreg(state, R367CAB_RS_COUNTER_2);
3382 tscount = (stv0367_readreg(state, R367CAB_RS_COUNTER_2) << 8)
3383 | stv0367_readreg(state, R367CAB_RS_COUNTER_1);
3384
3385 dprintk("%s: uncorrected blocks=%d corrected blocks=%d tscount=%d\n",
3386 __func__, *ucblocks, corrected, tscount);
3387
3388 return 0;
3389};
3390
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003391static struct dvb_frontend_ops stv0367cab_ops = {
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003392 .delsys = { SYS_DVBC_ANNEX_A },
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003393 .info = {
3394 .name = "ST STV0367 DVB-C",
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003395 .frequency_min = 47000000,
3396 .frequency_max = 862000000,
3397 .frequency_stepsize = 62500,
3398 .symbol_rate_min = 870000,
3399 .symbol_rate_max = 11700000,
3400 .caps = 0x400 |/* FE_CAN_QAM_4 */
3401 FE_CAN_QAM_16 | FE_CAN_QAM_32 |
3402 FE_CAN_QAM_64 | FE_CAN_QAM_128 |
3403 FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
3404 },
3405 .release = stv0367_release,
3406 .init = stv0367cab_init,
3407 .sleep = stv0367cab_sleep,
3408 .i2c_gate_ctrl = stv0367cab_gate_ctrl,
Mauro Carvalho Chehab285d55a2011-12-26 13:03:00 -03003409 .set_frontend = stv0367cab_set_frontend,
3410 .get_frontend = stv0367cab_get_frontend,
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003411 .read_status = stv0367cab_read_status,
3412/* .read_ber = stv0367cab_read_ber, */
3413 .read_signal_strength = stv0367cab_read_strength,
3414 .read_snr = stv0367cab_read_snr,
Abylay Ospan78db66e2011-01-02 09:12:00 -03003415 .read_ucblocks = stv0367cab_read_ucblcks,
Igor M. Liplianin17cce932011-01-25 17:02:00 -03003416 .get_tune_settings = stv0367_get_tune_settings,
3417};
3418
3419struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
3420 struct i2c_adapter *i2c)
3421{
3422 struct stv0367_state *state = NULL;
3423 struct stv0367cab_state *cab_state = NULL;
3424
3425 /* allocate memory for the internal state */
3426 state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
3427 if (state == NULL)
3428 goto error;
3429 cab_state = kzalloc(sizeof(struct stv0367cab_state), GFP_KERNEL);
3430 if (cab_state == NULL)
3431 goto error;
3432
3433 /* setup the state */
3434 state->i2c = i2c;
3435 state->config = config;
3436 cab_state->search_range = 280000;
3437 state->cab_state = cab_state;
3438 state->fe.ops = stv0367cab_ops;
3439 state->fe.demodulator_priv = state;
3440 state->chip_id = stv0367_readreg(state, 0xf000);
3441
3442 dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
3443
3444 /* check if the demod is there */
3445 if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
3446 goto error;
3447
3448 return &state->fe;
3449
3450error:
3451 kfree(cab_state);
3452 kfree(state);
3453 return NULL;
3454}
3455EXPORT_SYMBOL(stv0367cab_attach);
3456
3457MODULE_PARM_DESC(debug, "Set debug");
3458MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
3459
3460MODULE_AUTHOR("Igor M. Liplianin");
3461MODULE_DESCRIPTION("ST STV0367 DVB-C/T demodulator driver");
3462MODULE_LICENSE("GPL");