[media] r820t: use the right IF for the selected TV standard
[deliverable/linux.git] / drivers / media / tuners / r820t.c
CommitLineData
a80abc58
MCC
1/*
2 * Rafael Micro R820T driver
3 *
4 * Copyright (C) 2013 Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
6 * This driver was written from scratch, based on an existing driver
7 * that it is part of rtl-sdr git tree, released under GPLv2:
8 * https://groups.google.com/forum/#!topic/ultra-cheap-sdr/Y3rBEOFtHug
9 * https://github.com/n1gp/gr-baz
10 *
11 * From what I understood from the threads, the original driver was converted
12 * to userspace from a Realtek tree. I couldn't find the original tree.
13 * However, the original driver look awkward on my eyes. So, I decided to
14 * write a new version from it from the scratch, while trying to reproduce
15 * everything found there.
16 *
17 * TODO:
18 * After locking, the original driver seems to have some routines to
19 * improve reception. This was not implemented here yet.
20 *
21 * RF Gain set/get is not implemented.
22 *
23 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation; either version 2 of the License, or
26 * (at your option) any later version.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 */
34
35#include <linux/videodev2.h>
36#include <linux/mutex.h>
37#include <linux/slab.h>
38#include "tuner-i2c.h"
39#include <asm/div64.h>
40#include "r820t.h"
41
42/*
43 * FIXME: I think that there are only 32 registers, but better safe than
44 * sorry. After finishing the driver, we may review it.
45 */
46#define REG_SHADOW_START 5
47#define NUM_REGS 27
48
49#define VER_NUM 49
50
51static int debug;
52module_param(debug, int, 0644);
53MODULE_PARM_DESC(debug, "enable verbose debug messages");
54
55/*
56 * enums and structures
57 */
58
59enum xtal_cap_value {
60 XTAL_LOW_CAP_30P = 0,
61 XTAL_LOW_CAP_20P,
62 XTAL_LOW_CAP_10P,
63 XTAL_LOW_CAP_0P,
64 XTAL_HIGH_CAP_0P
65};
66
67struct r820t_priv {
68 struct list_head hybrid_tuner_instance_list;
69 const struct r820t_config *cfg;
70 struct tuner_i2c_props i2c_props;
71 struct mutex lock;
72
73 u8 regs[NUM_REGS];
74 u8 buf[NUM_REGS + 1];
75 enum xtal_cap_value xtal_cap_sel;
76 u16 pll; /* kHz */
77 u32 int_freq;
78 u8 fil_cal_code;
79 bool imr_done;
80
81 /* Store current mode */
82 u32 delsys;
83 enum v4l2_tuner_type type;
84 v4l2_std_id std;
85 u32 bw; /* in MHz */
86
87 bool has_lock;
88};
89
90struct r820t_freq_range {
91 u32 freq;
92 u8 open_d;
93 u8 rf_mux_ploy;
94 u8 tf_c;
95 u8 xtal_cap20p;
96 u8 xtal_cap10p;
97 u8 xtal_cap0p;
98 u8 imr_mem; /* Not used, currently */
99};
100
101#define VCO_POWER_REF 0x02
102
103/*
104 * Static constants
105 */
106
107static LIST_HEAD(hybrid_tuner_instance_list);
108static DEFINE_MUTEX(r820t_list_mutex);
109
110/* Those initial values start from REG_SHADOW_START */
111static const u8 r820t_init_array[NUM_REGS] = {
112 0x83, 0x32, 0x75, /* 05 to 07 */
113 0xc0, 0x40, 0xd6, 0x6c, /* 08 to 0b */
114 0xf5, 0x63, 0x75, 0x68, /* 0c to 0f */
115 0x6c, 0x83, 0x80, 0x00, /* 10 to 13 */
116 0x0f, 0x00, 0xc0, 0x30, /* 14 to 17 */
117 0x48, 0xcc, 0x60, 0x00, /* 18 to 1b */
118 0x54, 0xae, 0x4a, 0xc0 /* 1c to 1f */
119};
120
121/* Tuner frequency ranges */
122static const struct r820t_freq_range freq_ranges[] = {
123 {
124 .freq = 0,
125 .open_d = 0x08, /* low */
126 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
127 .tf_c = 0xdf, /* R27[7:0] band2,band0 */
128 .xtal_cap20p = 0x02, /* R16[1:0] 20pF (10) */
129 .xtal_cap10p = 0x01,
130 .xtal_cap0p = 0x00,
131 .imr_mem = 0,
132 }, {
133 .freq = 50, /* Start freq, in MHz */
134 .open_d = 0x08, /* low */
135 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
136 .tf_c = 0xbe, /* R27[7:0] band4,band1 */
137 .xtal_cap20p = 0x02, /* R16[1:0] 20pF (10) */
138 .xtal_cap10p = 0x01,
139 .xtal_cap0p = 0x00,
140 .imr_mem = 0,
141 }, {
142 .freq = 55, /* Start freq, in MHz */
143 .open_d = 0x08, /* low */
144 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
145 .tf_c = 0x8b, /* R27[7:0] band7,band4 */
146 .xtal_cap20p = 0x02, /* R16[1:0] 20pF (10) */
147 .xtal_cap10p = 0x01,
148 .xtal_cap0p = 0x00,
149 .imr_mem = 0,
150 }, {
151 .freq = 60, /* Start freq, in MHz */
152 .open_d = 0x08, /* low */
153 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
154 .tf_c = 0x7b, /* R27[7:0] band8,band4 */
155 .xtal_cap20p = 0x02, /* R16[1:0] 20pF (10) */
156 .xtal_cap10p = 0x01,
157 .xtal_cap0p = 0x00,
158 .imr_mem = 0,
159 }, {
160 .freq = 65, /* Start freq, in MHz */
161 .open_d = 0x08, /* low */
162 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
163 .tf_c = 0x69, /* R27[7:0] band9,band6 */
164 .xtal_cap20p = 0x02, /* R16[1:0] 20pF (10) */
165 .xtal_cap10p = 0x01,
166 .xtal_cap0p = 0x00,
167 .imr_mem = 0,
168 }, {
169 .freq = 70, /* Start freq, in MHz */
170 .open_d = 0x08, /* low */
171 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
172 .tf_c = 0x58, /* R27[7:0] band10,band7 */
173 .xtal_cap20p = 0x02, /* R16[1:0] 20pF (10) */
174 .xtal_cap10p = 0x01,
175 .xtal_cap0p = 0x00,
176 .imr_mem = 0,
177 }, {
178 .freq = 75, /* Start freq, in MHz */
179 .open_d = 0x00, /* high */
180 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
181 .tf_c = 0x44, /* R27[7:0] band11,band11 */
182 .xtal_cap20p = 0x02, /* R16[1:0] 20pF (10) */
183 .xtal_cap10p = 0x01,
184 .xtal_cap0p = 0x00,
185 .imr_mem = 0,
186 }, {
187 .freq = 80, /* Start freq, in MHz */
188 .open_d = 0x00, /* high */
189 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
190 .tf_c = 0x44, /* R27[7:0] band11,band11 */
191 .xtal_cap20p = 0x02, /* R16[1:0] 20pF (10) */
192 .xtal_cap10p = 0x01,
193 .xtal_cap0p = 0x00,
194 .imr_mem = 0,
195 }, {
196 .freq = 90, /* Start freq, in MHz */
197 .open_d = 0x00, /* high */
198 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
199 .tf_c = 0x34, /* R27[7:0] band12,band11 */
200 .xtal_cap20p = 0x01, /* R16[1:0] 10pF (01) */
201 .xtal_cap10p = 0x01,
202 .xtal_cap0p = 0x00,
203 .imr_mem = 0,
204 }, {
205 .freq = 100, /* Start freq, in MHz */
206 .open_d = 0x00, /* high */
207 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
208 .tf_c = 0x34, /* R27[7:0] band12,band11 */
209 .xtal_cap20p = 0x01, /* R16[1:0] 10pF (01) */
210 .xtal_cap10p = 0x01,
211 .xtal_cap0p = 0x00,
212 .imr_mem = 0,
213 }, {
214 .freq = 110, /* Start freq, in MHz */
215 .open_d = 0x00, /* high */
216 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
217 .tf_c = 0x24, /* R27[7:0] band13,band11 */
218 .xtal_cap20p = 0x01, /* R16[1:0] 10pF (01) */
219 .xtal_cap10p = 0x01,
220 .xtal_cap0p = 0x00,
221 .imr_mem = 1,
222 }, {
223 .freq = 120, /* Start freq, in MHz */
224 .open_d = 0x00, /* high */
225 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
226 .tf_c = 0x24, /* R27[7:0] band13,band11 */
227 .xtal_cap20p = 0x01, /* R16[1:0] 10pF (01) */
228 .xtal_cap10p = 0x01,
229 .xtal_cap0p = 0x00,
230 .imr_mem = 1,
231 }, {
232 .freq = 140, /* Start freq, in MHz */
233 .open_d = 0x00, /* high */
234 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
235 .tf_c = 0x14, /* R27[7:0] band14,band11 */
236 .xtal_cap20p = 0x01, /* R16[1:0] 10pF (01) */
237 .xtal_cap10p = 0x01,
238 .xtal_cap0p = 0x00,
239 .imr_mem = 1,
240 }, {
241 .freq = 180, /* Start freq, in MHz */
242 .open_d = 0x00, /* high */
243 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
244 .tf_c = 0x13, /* R27[7:0] band14,band12 */
245 .xtal_cap20p = 0x00, /* R16[1:0] 0pF (00) */
246 .xtal_cap10p = 0x00,
247 .xtal_cap0p = 0x00,
248 .imr_mem = 1,
249 }, {
250 .freq = 220, /* Start freq, in MHz */
251 .open_d = 0x00, /* high */
252 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
253 .tf_c = 0x13, /* R27[7:0] band14,band12 */
254 .xtal_cap20p = 0x00, /* R16[1:0] 0pF (00) */
255 .xtal_cap10p = 0x00,
256 .xtal_cap0p = 0x00,
257 .imr_mem = 2,
258 }, {
259 .freq = 250, /* Start freq, in MHz */
260 .open_d = 0x00, /* high */
261 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
262 .tf_c = 0x11, /* R27[7:0] highest,highest */
263 .xtal_cap20p = 0x00, /* R16[1:0] 0pF (00) */
264 .xtal_cap10p = 0x00,
265 .xtal_cap0p = 0x00,
266 .imr_mem = 2,
267 }, {
268 .freq = 280, /* Start freq, in MHz */
269 .open_d = 0x00, /* high */
270 .rf_mux_ploy = 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
271 .tf_c = 0x00, /* R27[7:0] highest,highest */
272 .xtal_cap20p = 0x00, /* R16[1:0] 0pF (00) */
273 .xtal_cap10p = 0x00,
274 .xtal_cap0p = 0x00,
275 .imr_mem = 2,
276 }, {
277 .freq = 310, /* Start freq, in MHz */
278 .open_d = 0x00, /* high */
279 .rf_mux_ploy = 0x41, /* R26[7:6]=1 (bypass) R26[1:0]=1 (middle) */
280 .tf_c = 0x00, /* R27[7:0] highest,highest */
281 .xtal_cap20p = 0x00, /* R16[1:0] 0pF (00) */
282 .xtal_cap10p = 0x00,
283 .xtal_cap0p = 0x00,
284 .imr_mem = 2,
285 }, {
286 .freq = 450, /* Start freq, in MHz */
287 .open_d = 0x00, /* high */
288 .rf_mux_ploy = 0x41, /* R26[7:6]=1 (bypass) R26[1:0]=1 (middle) */
289 .tf_c = 0x00, /* R27[7:0] highest,highest */
290 .xtal_cap20p = 0x00, /* R16[1:0] 0pF (00) */
291 .xtal_cap10p = 0x00,
292 .xtal_cap0p = 0x00,
293 .imr_mem = 3,
294 }, {
295 .freq = 588, /* Start freq, in MHz */
296 .open_d = 0x00, /* high */
297 .rf_mux_ploy = 0x40, /* R26[7:6]=1 (bypass) R26[1:0]=0 (highest) */
298 .tf_c = 0x00, /* R27[7:0] highest,highest */
299 .xtal_cap20p = 0x00, /* R16[1:0] 0pF (00) */
300 .xtal_cap10p = 0x00,
301 .xtal_cap0p = 0x00,
302 .imr_mem = 3,
303 }, {
304 .freq = 650, /* Start freq, in MHz */
305 .open_d = 0x00, /* high */
306 .rf_mux_ploy = 0x40, /* R26[7:6]=1 (bypass) R26[1:0]=0 (highest) */
307 .tf_c = 0x00, /* R27[7:0] highest,highest */
308 .xtal_cap20p = 0x00, /* R16[1:0] 0pF (00) */
309 .xtal_cap10p = 0x00,
310 .xtal_cap0p = 0x00,
311 .imr_mem = 4,
312 }
313};
314
315static int r820t_xtal_capacitor[][2] = {
316 { 0x0b, XTAL_LOW_CAP_30P },
317 { 0x02, XTAL_LOW_CAP_20P },
318 { 0x01, XTAL_LOW_CAP_10P },
319 { 0x00, XTAL_LOW_CAP_0P },
320 { 0x10, XTAL_HIGH_CAP_0P },
321};
322
50786ddf
MCC
323/*
324 * measured with a Racal 6103E GSM test set at 928 MHz with -60 dBm
325 * input power, for raw results see:
326 * http://steve-m.de/projects/rtl-sdr/gain_measurement/r820t/
327 */
328
329static const int r820t_lna_gain_steps[] = {
330 0, 9, 13, 40, 38, 13, 31, 22, 26, 31, 26, 14, 19, 5, 35, 13
331};
332
333static const int r820t_mixer_gain_steps[] = {
334 0, 5, 10, 10, 19, 9, 10, 25, 17, 10, 8, 16, 13, 6, 3, -8
335};
336
a80abc58
MCC
337/*
338 * I2C read/write code and shadow registers logic
339 */
340static void shadow_store(struct r820t_priv *priv, u8 reg, const u8 *val,
341 int len)
342{
343 int r = reg - REG_SHADOW_START;
344
345 if (r < 0) {
346 len += r;
347 r = 0;
348 }
349 if (len <= 0)
350 return;
351 if (len > NUM_REGS)
352 len = NUM_REGS;
353
354 tuner_dbg("%s: prev reg=%02x len=%d: %*ph\n",
355 __func__, r + REG_SHADOW_START, len, len, val);
356
357 memcpy(&priv->regs[r], val, len);
358}
359
360static int r820t_write(struct r820t_priv *priv, u8 reg, const u8 *val,
361 int len)
362{
363 int rc, size, pos = 0;
364
365 /* Store the shadow registers */
366 shadow_store(priv, reg, val, len);
367
368 do {
369 if (len > priv->cfg->max_i2c_msg_len - 1)
370 size = priv->cfg->max_i2c_msg_len - 1;
371 else
372 size = len;
373
374 /* Fill I2C buffer */
375 priv->buf[0] = reg;
376 memcpy(&priv->buf[1], &val[pos], size);
377
378 rc = tuner_i2c_xfer_send(&priv->i2c_props, priv->buf, size + 1);
379 if (rc != size + 1) {
380 tuner_info("%s: i2c wr failed=%d reg=%02x len=%d: %*ph\n",
381 __func__, rc, reg, size, size, &priv->buf[1]);
382 if (rc < 0)
383 return rc;
384 return -EREMOTEIO;
385 }
386 tuner_dbg("%s: i2c wr reg=%02x len=%d: %*ph\n",
387 __func__, reg, size, size, &priv->buf[1]);
388
389 reg += size;
390 len -= size;
391 pos += size;
392 } while (len > 0);
393
394 return 0;
395}
396
397static int r820t_write_reg(struct r820t_priv *priv, u8 reg, u8 val)
398{
399 return r820t_write(priv, reg, &val, 1);
400}
401
402static int r820t_write_reg_mask(struct r820t_priv *priv, u8 reg, u8 val,
403 u8 bit_mask)
404{
405 int r = reg - REG_SHADOW_START;
406
407 if (r >= 0 && r < NUM_REGS)
408 val = (priv->regs[r] & ~bit_mask) | (val & bit_mask);
409 else
410 return -EINVAL;
411
412 return r820t_write(priv, reg, &val, 1);
413}
414
415static int r820_read(struct r820t_priv *priv, u8 reg, u8 *val, int len)
416{
417 int rc;
418 u8 *p = &priv->buf[1];
419
420 priv->buf[0] = reg;
421
422 rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, priv->buf, 1, p, len);
423 if (rc != len) {
424 tuner_info("%s: i2c rd failed=%d reg=%02x len=%d: %*ph\n",
425 __func__, rc, reg, len, len, p);
426 if (rc < 0)
427 return rc;
428 return -EREMOTEIO;
429 }
430 tuner_dbg("%s: i2c rd reg=%02x len=%d: %*ph\n",
431 __func__, reg, len, len, p);
432
433 /* Copy data to the output buffer */
434 memcpy(val, p, len);
435
436 return 0;
437}
438
439/*
440 * r820t tuning logic
441 */
442
443static int r820t_set_mux(struct r820t_priv *priv, u32 freq)
444{
445 const struct r820t_freq_range *range;
446 int i, rc;
447 u8 val;
448
449 /* Get the proper frequency range */
450 freq = freq / 1000000;
451 for (i = 0; i < ARRAY_SIZE(freq_ranges) - 1; i++) {
452 if (freq < freq_ranges[i + 1].freq)
453 break;
454 }
455 range = &freq_ranges[i];
456
457 tuner_dbg("set r820t range#%d for frequency %d MHz\n", i, freq);
458
459 /* Open Drain */
460 rc = r820t_write_reg_mask(priv, 0x17, range->open_d, 0x08);
461 if (rc < 0)
462 return rc;
463
464 /* RF_MUX,Polymux */
465 rc = r820t_write_reg_mask(priv, 0x1a, range->rf_mux_ploy, 0xc3);
466 if (rc < 0)
467 return rc;
468
469 /* TF BAND */
470 rc = r820t_write_reg(priv, 0x1b, range->tf_c);
471 if (rc < 0)
472 return rc;
473
474 /* XTAL CAP & Drive */
475 switch (priv->xtal_cap_sel) {
476 case XTAL_LOW_CAP_30P:
477 case XTAL_LOW_CAP_20P:
478 val = range->xtal_cap20p | 0x08;
479 break;
480 case XTAL_LOW_CAP_10P:
481 val = range->xtal_cap10p | 0x08;
482 break;
483 case XTAL_HIGH_CAP_0P:
484 val = range->xtal_cap0p | 0x00;
485 break;
486 default:
487 case XTAL_LOW_CAP_0P:
488 val = range->xtal_cap0p | 0x08;
489 break;
490 }
491 rc = r820t_write_reg_mask(priv, 0x10, val, 0x0b);
492 if (rc < 0)
493 return rc;
494
495 /*
496 * FIXME: the original driver has a logic there with preserves
497 * gain/phase from registers 8 and 9 reading the data from the
498 * registers before writing, if "IMF done". That code was sort of
499 * commented there, as the flag is always false.
500 */
501 rc = r820t_write_reg_mask(priv, 0x08, 0, 0x3f);
502 if (rc < 0)
503 return rc;
504
505 rc = r820t_write_reg_mask(priv, 0x09, 0, 0x3f);
506
507 return rc;
508}
509
510static int r820t_set_pll(struct r820t_priv *priv, u32 freq)
511{
512 u64 tmp64, vco_freq;
513 int rc, i;
514 u32 vco_fra; /* VCO contribution by SDM (kHz) */
515 u32 vco_min = 1770000;
516 u32 vco_max = vco_min * 2;
517 u32 pll_ref;
518 u16 n_sdm = 2;
519 u16 sdm = 0;
520 u8 mix_div = 2;
521 u8 div_buf = 0;
522 u8 div_num = 0;
523 u8 ni, si, nint, vco_fine_tune, val;
524 u8 data[5];
525
526 freq = freq / 1000; /* Frequency in kHz */
527
528 pll_ref = priv->cfg->xtal / 1000;
529
530 tuner_dbg("set r820t pll for frequency %d kHz = %d\n", freq, pll_ref);
531
532 /* FIXME: this seems to be a hack - probably it can be removed */
533 rc = r820t_write_reg_mask(priv, 0x10, 0x00, 0x00);
534 if (rc < 0)
535 return rc;
536
537 /* set pll autotune = 128kHz */
538 rc = r820t_write_reg_mask(priv, 0x1a, 0x00, 0x0c);
539 if (rc < 0)
540 return rc;
541
542 /* set VCO current = 100 */
543 rc = r820t_write_reg_mask(priv, 0x12, 0x80, 0xe0);
544 if (rc < 0)
545 return rc;
546
547 /* Calculate divider */
548 while (mix_div <= 64) {
549 if (((freq * mix_div) >= vco_min) &&
550 ((freq * mix_div) < vco_max)) {
551 div_buf = mix_div;
552 while (div_buf > 2) {
553 div_buf = div_buf >> 1;
554 div_num++;
555 }
556 break;
557 }
558 mix_div = mix_div << 1;
559 }
560
561 rc = r820_read(priv, 0x00, data, sizeof(data));
562 if (rc < 0)
563 return rc;
564
565 vco_fine_tune = (data[4] & 0x30) >> 4;
566
567 if (vco_fine_tune > VCO_POWER_REF)
568 div_num = div_num - 1;
569 else if (vco_fine_tune < VCO_POWER_REF)
570 div_num = div_num + 1;
571
572 rc = r820t_write_reg_mask(priv, 0x10, div_num << 5, 0xe0);
573 if (rc < 0)
574 return rc;
575
576 vco_freq = (u64)(freq * (u64)mix_div);
577
578 tmp64 = vco_freq;
579 do_div(tmp64, 2 * pll_ref);
580 nint = (u8)tmp64;
581
582 tmp64 = vco_freq - ((u64)2) * pll_ref * nint;
583 do_div(tmp64, 1000);
584 vco_fra = (u16)(tmp64);
585
586 pll_ref /= 1000;
587
588 /* boundary spur prevention */
589 if (vco_fra < pll_ref / 64) {
590 vco_fra = 0;
591 } else if (vco_fra > pll_ref * 127 / 64) {
592 vco_fra = 0;
593 nint++;
594 } else if ((vco_fra > pll_ref * 127 / 128) && (vco_fra < pll_ref)) {
595 vco_fra = pll_ref * 127 / 128;
596 } else if ((vco_fra > pll_ref) && (vco_fra < pll_ref * 129 / 128)) {
597 vco_fra = pll_ref * 129 / 128;
598 }
599
600 if (nint > 63) {
601 tuner_info("No valid PLL values for %u kHz!\n", freq);
602 return -EINVAL;
603 }
604
605 ni = (nint - 13) / 4;
606 si = nint - 4 * ni - 13;
607
608 rc = r820t_write_reg(priv, 0x14, ni + (si << 6));
609 if (rc < 0)
610 return rc;
611
612 /* pw_sdm */
613 if (!vco_fra)
614 val = 0x08;
615 else
616 val = 0x00;
617
618 rc = r820t_write_reg_mask(priv, 0x12, val, 0x08);
619 if (rc < 0)
620 return rc;
621
622 /* sdm calculator */
623 while (vco_fra > 1) {
624 if (vco_fra > (2 * pll_ref / n_sdm)) {
625 sdm = sdm + 32768 / (n_sdm / 2);
626 vco_fra = vco_fra - 2 * pll_ref / n_sdm;
627 if (n_sdm >= 0x8000)
628 break;
629 }
630 n_sdm = n_sdm << 1;
631 }
632
633 rc = r820t_write_reg_mask(priv, 0x16, sdm >> 8, 0x08);
634 if (rc < 0)
635 return rc;
636 rc = r820t_write_reg_mask(priv, 0x15, sdm & 0xff, 0x08);
637 if (rc < 0)
638 return rc;
639
640 for (i = 0; i < 2; i++) {
641 /*
642 * FIXME: Rafael chips R620D, R828D and R828 seems to
643 * need 20 ms for analog TV
644 */
645 msleep(10);
646
647 /* Check if PLL has locked */
648 rc = r820_read(priv, 0x00, data, 3);
649 if (rc < 0)
650 return rc;
651 if (data[2] & 0x40)
652 break;
653
654 if (!i) {
655 /* Didn't lock. Increase VCO current */
656 rc = r820t_write_reg_mask(priv, 0x12, 0x60, 0xe0);
657 if (rc < 0)
658 return rc;
659 }
660 }
661
662 if (!(data[2] & 0x40)) {
663 priv->has_lock = false;
664 return 0;
665 }
666
667 priv->has_lock = true;
668 tuner_dbg("tuner has lock at frequency %d kHz\n", freq);
669
670 /* set pll autotune = 8kHz */
671 rc = r820t_write_reg_mask(priv, 0x1a, 0x08, 0x08);
672
673 return rc;
674}
675
676static int r820t_sysfreq_sel(struct r820t_priv *priv, u32 freq,
677 enum v4l2_tuner_type type,
678 v4l2_std_id std,
679 u32 delsys)
680{
681 int rc;
682 u8 mixer_top, lna_top, cp_cur, div_buf_cur, lna_vth_l, mixer_vth_l;
683 u8 air_cable1_in, cable2_in, pre_dect, lna_discharge, filter_cur;
684
685 tuner_dbg("adjusting tuner parameters for the standard\n");
686
687 switch (delsys) {
688 case SYS_DVBT:
689 if ((freq == 506000000) || (freq == 666000000) ||
690 (freq == 818000000)) {
691 mixer_top = 0x14; /* mixer top:14 , top-1, low-discharge */
692 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
693 cp_cur = 0x28; /* 101, 0.2 */
694 div_buf_cur = 0x20; /* 10, 200u */
695 } else {
696 mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
697 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
698 cp_cur = 0x38; /* 111, auto */
699 div_buf_cur = 0x30; /* 11, 150u */
700 }
701 lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
702 mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
703 air_cable1_in = 0x00;
704 cable2_in = 0x00;
705 pre_dect = 0x40;
706 lna_discharge = 14;
707 filter_cur = 0x40; /* 10, low */
708 break;
709 case SYS_DVBT2:
710 mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
711 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
712 lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
713 mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
714 air_cable1_in = 0x00;
715 cable2_in = 0x00;
716 pre_dect = 0x40;
717 lna_discharge = 14;
718 cp_cur = 0x38; /* 111, auto */
719 div_buf_cur = 0x30; /* 11, 150u */
720 filter_cur = 0x40; /* 10, low */
721 break;
722 case SYS_ISDBT:
723 mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
724 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
725 lna_vth_l = 0x75; /* lna vth 1.04 , vtl 0.84 */
726 mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
727 air_cable1_in = 0x00;
728 cable2_in = 0x00;
729 pre_dect = 0x40;
730 lna_discharge = 14;
731 cp_cur = 0x38; /* 111, auto */
732 div_buf_cur = 0x30; /* 11, 150u */
733 filter_cur = 0x40; /* 10, low */
734 break;
735 default: /* DVB-T 8M */
736 mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
737 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
738 lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
739 mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
740 air_cable1_in = 0x00;
741 cable2_in = 0x00;
742 pre_dect = 0x40;
743 lna_discharge = 14;
744 cp_cur = 0x38; /* 111, auto */
745 div_buf_cur = 0x30; /* 11, 150u */
746 filter_cur = 0x40; /* 10, low */
747 break;
748 }
749
750 rc = r820t_write_reg_mask(priv, 0x1d, lna_top, 0xc7);
751 if (rc < 0)
752 return rc;
753 rc = r820t_write_reg_mask(priv, 0x1c, mixer_top, 0xf8);
754 if (rc < 0)
755 return rc;
756 rc = r820t_write_reg(priv, 0x0d, lna_vth_l);
757 if (rc < 0)
758 return rc;
759 rc = r820t_write_reg(priv, 0x0e, mixer_vth_l);
760 if (rc < 0)
761 return rc;
762
763 /* Air-IN only for Astrometa */
764 rc = r820t_write_reg_mask(priv, 0x05, air_cable1_in, 0x60);
765 if (rc < 0)
766 return rc;
767 rc = r820t_write_reg_mask(priv, 0x06, cable2_in, 0x08);
768 if (rc < 0)
769 return rc;
770
771 rc = r820t_write_reg_mask(priv, 0x11, cp_cur, 0x38);
772 if (rc < 0)
773 return rc;
774 rc = r820t_write_reg_mask(priv, 0x17, div_buf_cur, 0x30);
775 if (rc < 0)
776 return rc;
777 rc = r820t_write_reg_mask(priv, 0x0a, filter_cur, 0x60);
778 if (rc < 0)
779 return rc;
780 /*
781 * Original driver initializes regs 0x05 and 0x06 with the
782 * same value again on this point. Probably, it is just an
783 * error there
784 */
785
786 /*
787 * Set LNA
788 */
789
790 tuner_dbg("adjusting LNA parameters\n");
791 if (type != V4L2_TUNER_ANALOG_TV) {
792 /* LNA TOP: lowest */
793 rc = r820t_write_reg_mask(priv, 0x1d, 0, 0x38);
794 if (rc < 0)
795 return rc;
796
797 /* 0: normal mode */
798 rc = r820t_write_reg_mask(priv, 0x1c, 0, 0x04);
799 if (rc < 0)
800 return rc;
801
802 /* 0: PRE_DECT off */
803 rc = r820t_write_reg_mask(priv, 0x06, 0, 0x40);
804 if (rc < 0)
805 return rc;
806
807 /* agc clk 250hz */
808 rc = r820t_write_reg_mask(priv, 0x1a, 0x30, 0x30);
809 if (rc < 0)
810 return rc;
811
812 msleep(250);
813
814 /* write LNA TOP = 3 */
815 rc = r820t_write_reg_mask(priv, 0x1d, 0x18, 0x38);
816 if (rc < 0)
817 return rc;
818
819 /*
820 * write discharge mode
821 * FIXME: IMHO, the mask here is wrong, but it matches
822 * what's there at the original driver
823 */
824 rc = r820t_write_reg_mask(priv, 0x1c, mixer_top, 0x04);
825 if (rc < 0)
826 return rc;
827
828 /* LNA discharge current */
829 rc = r820t_write_reg_mask(priv, 0x1e, lna_discharge, 0x1f);
830 if (rc < 0)
831 return rc;
832
833 /* agc clk 60hz */
834 rc = r820t_write_reg_mask(priv, 0x1a, 0x20, 0x30);
835 if (rc < 0)
836 return rc;
837 } else {
838 /* PRE_DECT off */
839 rc = r820t_write_reg_mask(priv, 0x06, 0, 0x40);
840 if (rc < 0)
841 return rc;
842
843 /* write LNA TOP */
844 rc = r820t_write_reg_mask(priv, 0x1d, lna_top, 0x38);
845 if (rc < 0)
846 return rc;
847
848 /*
849 * write discharge mode
850 * FIXME: IMHO, the mask here is wrong, but it matches
851 * what's there at the original driver
852 */
853 rc = r820t_write_reg_mask(priv, 0x1c, mixer_top, 0x04);
854 if (rc < 0)
855 return rc;
856
857 /* LNA discharge current */
858 rc = r820t_write_reg_mask(priv, 0x1e, lna_discharge, 0x1f);
859 if (rc < 0)
860 return rc;
861
862 /* agc clk 1Khz, external det1 cap 1u */
863 rc = r820t_write_reg_mask(priv, 0x1a, 0x00, 0x30);
864 if (rc < 0)
865 return rc;
866
867 rc = r820t_write_reg_mask(priv, 0x10, 0x00, 0x04);
868 if (rc < 0)
869 return rc;
870 }
871 return 0;
872}
873
874static int r820t_set_tv_standard(struct r820t_priv *priv,
875 unsigned bw,
876 enum v4l2_tuner_type type,
877 v4l2_std_id std, u32 delsys)
878
879{
880 int rc, i;
881 u32 if_khz, filt_cal_lo;
882 u8 data[5], val;
883 u8 filt_gain, img_r, filt_q, hp_cor, ext_enable, loop_through;
884 u8 lt_att, flt_ext_widest, polyfil_cur;
885 bool need_calibration;
886
887 tuner_dbg("selecting the delivery system\n");
888
889 if (delsys == SYS_ISDBT) {
890 if_khz = 4063;
891 filt_cal_lo = 59000;
892 filt_gain = 0x10; /* +3db, 6mhz on */
893 img_r = 0x00; /* image negative */
894 filt_q = 0x10; /* r10[4]:low q(1'b1) */
895 hp_cor = 0x6a; /* 1.7m disable, +2cap, 1.25mhz */
896 ext_enable = 0x40; /* r30[6], ext enable; r30[5]:0 ext at lna max */
897 loop_through = 0x00; /* r5[7], lt on */
898 lt_att = 0x00; /* r31[7], lt att enable */
899 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
900 polyfil_cur = 0x60; /* r25[6:5]:min */
901 } else {
902 if (bw <= 6) {
903 if_khz = 3570;
904 filt_cal_lo = 56000; /* 52000->56000 */
905 filt_gain = 0x10; /* +3db, 6mhz on */
906 img_r = 0x00; /* image negative */
907 filt_q = 0x10; /* r10[4]:low q(1'b1) */
908 hp_cor = 0x6b; /* 1.7m disable, +2cap, 1.0mhz */
909 ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
910 loop_through = 0x00; /* r5[7], lt on */
911 lt_att = 0x00; /* r31[7], lt att enable */
912 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
913 polyfil_cur = 0x60; /* r25[6:5]:min */
914 } else if (bw == 7) {
915 if_khz = 4070;
916 filt_cal_lo = 60000;
917 filt_gain = 0x10; /* +3db, 6mhz on */
918 img_r = 0x00; /* image negative */
919 filt_q = 0x10; /* r10[4]:low q(1'b1) */
920 hp_cor = 0x2b; /* 1.7m disable, +1cap, 1.0mhz */
921 ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
922 loop_through = 0x00; /* r5[7], lt on */
923 lt_att = 0x00; /* r31[7], lt att enable */
924 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
925 polyfil_cur = 0x60; /* r25[6:5]:min */
926#if 0 /* 7 MHz type 2 - nor sure why/where this is used - Perhaps Australia? */
927 if_khz = 4570;
928 filt_cal_lo = 63000;
929 filt_gain = 0x10; /* +3db, 6mhz on */
930 img_r = 0x00; /* image negative */
931 filt_q = 0x10; /* r10[4]:low q(1'b1) */
932 hp_cor = 0x2a; /* 1.7m disable, +1cap, 1.25mhz */
933 ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
934 loop_through = 0x00; /* r5[7], lt on */
935 lt_att = 0x00; /* r31[7], lt att enable */
936 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
937 polyfil_cur = 0x60; /* r25[6:5]:min */
938#endif
939 } else {
940 if_khz = 4570;
941 filt_cal_lo = 68500;
942 filt_gain = 0x10; /* +3db, 6mhz on */
943 img_r = 0x00; /* image negative */
944 filt_q = 0x10; /* r10[4]:low q(1'b1) */
945 hp_cor = 0x0b; /* 1.7m disable, +0cap, 1.0mhz */
946 ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
947 loop_through = 0x00; /* r5[7], lt on */
948 lt_att = 0x00; /* r31[7], lt att enable */
949 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
950 polyfil_cur = 0x60; /* r25[6:5]:min */
951 }
952 }
953
954 /* Initialize the shadow registers */
955 memcpy(priv->regs, r820t_init_array, sizeof(r820t_init_array));
956
957 /* Init Flag & Xtal_check Result */
958 if (priv->imr_done)
959 val = 1 | priv->xtal_cap_sel << 1;
960 else
961 val = 0;
962 rc = r820t_write_reg_mask(priv, 0x0c, val, 0x0f);
963 if (rc < 0)
964 return rc;
965
966 /* version */
967 rc = r820t_write_reg_mask(priv, 0x13, VER_NUM, 0x3f);
968 if (rc < 0)
969 return rc;
970
971 /* for LT Gain test */
972 if (type != V4L2_TUNER_ANALOG_TV) {
973 rc = r820t_write_reg_mask(priv, 0x1d, 0x00, 0x38);
974 if (rc < 0)
975 return rc;
976 msleep(1);
977 }
f60f5bcb 978 priv->int_freq = if_khz * 1000;
a80abc58
MCC
979
980 /* Check if standard changed. If so, filter calibration is needed */
981 if (type != priv->type)
982 need_calibration = true;
983 else if ((type == V4L2_TUNER_ANALOG_TV) && (std != priv->std))
984 need_calibration = true;
985 else if ((type == V4L2_TUNER_DIGITAL_TV) &&
986 ((delsys != priv->delsys) || bw != priv->bw))
987 need_calibration = true;
988 else
989 need_calibration = false;
990
991 if (need_calibration) {
992 tuner_dbg("calibrating the tuner\n");
993 for (i = 0; i < 2; i++) {
994 /* Set filt_cap */
995 rc = r820t_write_reg_mask(priv, 0x0b, hp_cor, 0x60);
996 if (rc < 0)
997 return rc;
998
999 /* set cali clk =on */
1000 rc = r820t_write_reg_mask(priv, 0x0f, 0x04, 0x04);
1001 if (rc < 0)
1002 return rc;
1003
1004 /* X'tal cap 0pF for PLL */
1005 rc = r820t_write_reg_mask(priv, 0x10, 0x00, 0x03);
1006 if (rc < 0)
1007 return rc;
1008
1009 rc = r820t_set_pll(priv, filt_cal_lo);
1010 if (rc < 0 || !priv->has_lock)
1011 return rc;
1012
1013 /* Start Trigger */
1014 rc = r820t_write_reg_mask(priv, 0x0b, 0x10, 0x10);
1015 if (rc < 0)
1016 return rc;
1017
1018 msleep(1);
1019
1020 /* Stop Trigger */
1021 rc = r820t_write_reg_mask(priv, 0x0b, 0x00, 0x10);
1022 if (rc < 0)
1023 return rc;
1024
1025 /* set cali clk =off */
1026 rc = r820t_write_reg_mask(priv, 0x0f, 0x00, 0x04);
1027 if (rc < 0)
1028 return rc;
1029
1030 /* Check if calibration worked */
1031 rc = r820_read(priv, 0x00, data, sizeof(data));
1032 if (rc < 0)
1033 return rc;
1034
1035 priv->fil_cal_code = data[4] & 0x0f;
1036 if (priv->fil_cal_code && priv->fil_cal_code != 0x0f)
1037 break;
1038 }
1039 /* narrowest */
1040 if (priv->fil_cal_code == 0x0f)
1041 priv->fil_cal_code = 0;
1042 }
1043
1044 rc = r820t_write_reg_mask(priv, 0x0a,
1045 filt_q | priv->fil_cal_code, 0x1f);
1046 if (rc < 0)
1047 return rc;
1048
1049 /* Set BW, Filter_gain, & HP corner */
1050 rc = r820t_write_reg_mask(priv, 0x0b, hp_cor, 0x10);
1051 if (rc < 0)
1052 return rc;
1053
1054
1055 /* Set Img_R */
1056 rc = r820t_write_reg_mask(priv, 0x07, img_r, 0x80);
1057 if (rc < 0)
1058 return rc;
1059
1060 /* Set filt_3dB, V6MHz */
1061 rc = r820t_write_reg_mask(priv, 0x06, filt_gain, 0x30);
1062 if (rc < 0)
1063 return rc;
1064
1065 /* channel filter extension */
1066 rc = r820t_write_reg_mask(priv, 0x1e, ext_enable, 0x60);
1067 if (rc < 0)
1068 return rc;
1069
1070 /* Loop through */
1071 rc = r820t_write_reg_mask(priv, 0x05, loop_through, 0x80);
1072 if (rc < 0)
1073 return rc;
1074
1075 /* Loop through attenuation */
1076 rc = r820t_write_reg_mask(priv, 0x1f, lt_att, 0x80);
1077 if (rc < 0)
1078 return rc;
1079
1080 /* filter extension widest */
1081 rc = r820t_write_reg_mask(priv, 0x0f, flt_ext_widest, 0x80);
1082 if (rc < 0)
1083 return rc;
1084
1085 /* RF poly filter current */
1086 rc = r820t_write_reg_mask(priv, 0x19, polyfil_cur, 0x60);
1087 if (rc < 0)
1088 return rc;
1089
1090 /* Store current standard. If it changes, re-calibrate the tuner */
1091 priv->delsys = delsys;
1092 priv->type = type;
1093 priv->std = std;
1094 priv->bw = bw;
1095
1096 return 0;
1097}
1098
f8fde0e0
MCC
1099static int r820t_read_gain(struct r820t_priv *priv)
1100{
1101 u8 data[4];
1102 int rc;
1103
1104 rc = r820_read(priv, 0x00, data, sizeof(data));
1105 if (rc < 0)
1106 return rc;
1107
1108 return ((data[3] & 0x0f) << 1) + ((data[3] & 0xf0) >> 4);
1109}
1110
50786ddf
MCC
1111static int r820t_set_gain_mode(struct r820t_priv *priv,
1112 bool set_manual_gain,
1113 int gain)
1114{
1115 int rc;
1116
1117 if (set_manual_gain) {
1118 int i, total_gain = 0;
1119 uint8_t mix_index = 0, lna_index = 0;
1120 u8 data[4];
1121
1122 /* LNA auto off */
1123 rc = r820t_write_reg_mask(priv, 0x05, 0x10, 0x10);
1124 if (rc < 0)
1125 return rc;
1126
1127 /* Mixer auto off */
1128 rc = r820t_write_reg_mask(priv, 0x07, 0, 0x10);
1129 if (rc < 0)
1130 return rc;
1131
1132 rc = r820_read(priv, 0x00, data, sizeof(data));
1133 if (rc < 0)
1134 return rc;
1135
1136 /* set fixed VGA gain for now (16.3 dB) */
1137 rc = r820t_write_reg_mask(priv, 0x0c, 0x08, 0x9f);
1138 if (rc < 0)
1139 return rc;
1140
1141 for (i = 0; i < 15; i++) {
1142 if (total_gain >= gain)
1143 break;
1144
1145 total_gain += r820t_lna_gain_steps[++lna_index];
1146
1147 if (total_gain >= gain)
1148 break;
1149
1150 total_gain += r820t_mixer_gain_steps[++mix_index];
1151 }
1152
1153 /* set LNA gain */
1154 rc = r820t_write_reg_mask(priv, 0x05, lna_index, 0x0f);
1155 if (rc < 0)
1156 return rc;
1157
1158 /* set Mixer gain */
1159 rc = r820t_write_reg_mask(priv, 0x07, mix_index, 0x0f);
1160 if (rc < 0)
1161 return rc;
1162 } else {
1163 /* LNA */
1164 rc = r820t_write_reg_mask(priv, 0x05, 0, 0xef);
1165 if (rc < 0)
1166 return rc;
1167
1168 /* Mixer */
1169 rc = r820t_write_reg_mask(priv, 0x07, 0x10, 0xef);
1170 if (rc < 0)
1171 return rc;
1172
1173 /* set fixed VGA gain for now (26.5 dB) */
1174 rc = r820t_write_reg_mask(priv, 0x0c, 0x0b, 0x9f);
1175 if (rc < 0)
1176 return rc;
1177 }
1178
1179 return 0;
1180}
1181
1182
a80abc58
MCC
1183static int generic_set_freq(struct dvb_frontend *fe,
1184 u32 freq /* in HZ */,
1185 unsigned bw,
1186 enum v4l2_tuner_type type,
1187 v4l2_std_id std, u32 delsys)
1188{
1189 struct r820t_priv *priv = fe->tuner_priv;
1190 int rc = -EINVAL;
1191 u32 lo_freq;
1192
1193 tuner_dbg("should set frequency to %d kHz, bw %d MHz\n",
1194 freq / 1000, bw);
1195
a7dd065f
MCC
1196 rc = r820t_set_tv_standard(priv, bw, type, std, delsys);
1197 if (rc < 0)
1198 goto err;
1199
a80abc58
MCC
1200 if ((type == V4L2_TUNER_ANALOG_TV) && (std == V4L2_STD_SECAM_LC))
1201 lo_freq = freq - priv->int_freq;
1202 else
1203 lo_freq = freq + priv->int_freq;
1204
a80abc58
MCC
1205 rc = r820t_set_mux(priv, lo_freq);
1206 if (rc < 0)
1207 goto err;
50786ddf
MCC
1208
1209 rc = r820t_set_gain_mode(priv, true, 0);
1210 if (rc < 0)
1211 goto err;
1212
a80abc58
MCC
1213 rc = r820t_set_pll(priv, lo_freq);
1214 if (rc < 0 || !priv->has_lock)
1215 goto err;
1216
1217 rc = r820t_sysfreq_sel(priv, freq, type, std, delsys);
da31934f
MCC
1218 if (rc < 0)
1219 goto err;
1220
1221 tuner_dbg("%s: PLL locked on frequency %d Hz, gain=%d\n",
1222 __func__, freq, r820t_read_gain(priv));
1223
a80abc58 1224err:
a80abc58
MCC
1225
1226 if (rc < 0)
1227 tuner_dbg("%s: failed=%d\n", __func__, rc);
1228 return rc;
1229}
1230
1231/*
1232 * r820t standby logic
1233 */
1234
1235static int r820t_standby(struct r820t_priv *priv)
1236{
1237 int rc;
1238
1239 rc = r820t_write_reg(priv, 0x06, 0xb1);
1240 if (rc < 0)
1241 return rc;
1242 rc = r820t_write_reg(priv, 0x05, 0x03);
1243 if (rc < 0)
1244 return rc;
1245 rc = r820t_write_reg(priv, 0x07, 0x3a);
1246 if (rc < 0)
1247 return rc;
1248 rc = r820t_write_reg(priv, 0x08, 0x40);
1249 if (rc < 0)
1250 return rc;
1251 rc = r820t_write_reg(priv, 0x09, 0xc0);
1252 if (rc < 0)
1253 return rc;
1254 rc = r820t_write_reg(priv, 0x0a, 0x36);
1255 if (rc < 0)
1256 return rc;
1257 rc = r820t_write_reg(priv, 0x0c, 0x35);
1258 if (rc < 0)
1259 return rc;
1260 rc = r820t_write_reg(priv, 0x0f, 0x68);
1261 if (rc < 0)
1262 return rc;
1263 rc = r820t_write_reg(priv, 0x11, 0x03);
1264 if (rc < 0)
1265 return rc;
1266 rc = r820t_write_reg(priv, 0x17, 0xf4);
1267 if (rc < 0)
1268 return rc;
1269 rc = r820t_write_reg(priv, 0x19, 0x0c);
1270
1271 /* Force initial calibration */
1272 priv->type = -1;
1273
1274 return rc;
1275}
1276
1277/*
1278 * r820t device init logic
1279 */
1280
1281static int r820t_xtal_check(struct r820t_priv *priv)
1282{
1283 int rc, i;
1284 u8 data[3], val;
1285
1286 /* Initialize the shadow registers */
1287 memcpy(priv->regs, r820t_init_array, sizeof(r820t_init_array));
1288
1289 /* cap 30pF & Drive Low */
1290 rc = r820t_write_reg_mask(priv, 0x10, 0x0b, 0x0b);
1291 if (rc < 0)
1292 return rc;
1293
1294 /* set pll autotune = 128kHz */
1295 rc = r820t_write_reg_mask(priv, 0x1a, 0x00, 0x0c);
1296 if (rc < 0)
1297 return rc;
1298
1299 /* set manual initial reg = 111111; */
1300 rc = r820t_write_reg_mask(priv, 0x13, 0x7f, 0x7f);
1301 if (rc < 0)
1302 return rc;
1303
1304 /* set auto */
1305 rc = r820t_write_reg_mask(priv, 0x13, 0x00, 0x40);
1306 if (rc < 0)
1307 return rc;
1308
1309 /* Try several xtal capacitor alternatives */
1310 for (i = 0; i < ARRAY_SIZE(r820t_xtal_capacitor); i++) {
1311 rc = r820t_write_reg_mask(priv, 0x10,
1312 r820t_xtal_capacitor[i][0], 0x1b);
1313 if (rc < 0)
1314 return rc;
1315
1316 msleep(5);
1317
1318 rc = r820_read(priv, 0x00, data, sizeof(data));
1319 if (rc < 0)
1320 return rc;
1321 if ((!data[2]) & 0x40)
1322 continue;
1323
1324 val = data[2] & 0x3f;
1325
1326 if (priv->cfg->xtal == 16000000 && (val > 29 || val < 23))
1327 break;
1328
1329 if (val != 0x3f)
1330 break;
1331 }
1332
1333 if (i == ARRAY_SIZE(r820t_xtal_capacitor))
1334 return -EINVAL;
1335
1336 return r820t_xtal_capacitor[i][1];
1337}
1338
1339/*
1340 * r820t frontend operations and tuner attach code
7a5ef30d
MCC
1341 *
1342 * All driver locks and i2c control are only in this part of the code
a80abc58
MCC
1343 */
1344
1345static int r820t_init(struct dvb_frontend *fe)
1346{
1347 struct r820t_priv *priv = fe->tuner_priv;
1348 int rc, i;
1349 int xtal_cap = 0;
1350
1351 tuner_dbg("%s:\n", __func__);
1352
7a5ef30d 1353 mutex_lock(&priv->lock);
a80abc58
MCC
1354 if (fe->ops.i2c_gate_ctrl)
1355 fe->ops.i2c_gate_ctrl(fe, 1);
1356
a80abc58
MCC
1357 if ((priv->cfg->rafael_chip == CHIP_R820T) ||
1358 (priv->cfg->rafael_chip == CHIP_R828S) ||
1359 (priv->cfg->rafael_chip == CHIP_R820C)) {
1360 priv->xtal_cap_sel = XTAL_HIGH_CAP_0P;
1361 } else {
1362 for (i = 0; i < 3; i++) {
1363 rc = r820t_xtal_check(priv);
1364 if (rc < 0)
1365 goto err;
1366 if (!i || rc > xtal_cap)
1367 xtal_cap = rc;
1368 }
1369 priv->xtal_cap_sel = xtal_cap;
1370 }
1371
1372 /* Initialize registers */
1373 rc = r820t_write(priv, 0x05,
1374 r820t_init_array, sizeof(r820t_init_array));
1375
a80abc58
MCC
1376err:
1377 if (fe->ops.i2c_gate_ctrl)
1378 fe->ops.i2c_gate_ctrl(fe, 0);
7a5ef30d 1379 mutex_unlock(&priv->lock);
a80abc58 1380
7a5ef30d
MCC
1381 if (rc < 0)
1382 tuner_dbg("%s: failed=%d\n", __func__, rc);
a80abc58
MCC
1383 return rc;
1384}
1385
1386static int r820t_sleep(struct dvb_frontend *fe)
1387{
1388 struct r820t_priv *priv = fe->tuner_priv;
1389 int rc;
1390
1391 tuner_dbg("%s:\n", __func__);
1392
7a5ef30d 1393 mutex_lock(&priv->lock);
a80abc58
MCC
1394 if (fe->ops.i2c_gate_ctrl)
1395 fe->ops.i2c_gate_ctrl(fe, 1);
1396
a80abc58 1397 rc = r820t_standby(priv);
a80abc58
MCC
1398
1399 if (fe->ops.i2c_gate_ctrl)
1400 fe->ops.i2c_gate_ctrl(fe, 0);
7a5ef30d 1401 mutex_unlock(&priv->lock);
a80abc58
MCC
1402
1403 tuner_dbg("%s: failed=%d\n", __func__, rc);
1404 return rc;
1405}
1406
1407static int r820t_set_analog_freq(struct dvb_frontend *fe,
1408 struct analog_parameters *p)
1409{
1410 struct r820t_priv *priv = fe->tuner_priv;
1411 unsigned bw;
7a5ef30d 1412 int rc;
a80abc58
MCC
1413
1414 tuner_dbg("%s called\n", __func__);
1415
1416 /* if std is not defined, choose one */
1417 if (!p->std)
1418 p->std = V4L2_STD_MN;
1419
1420 if ((p->std == V4L2_STD_PAL_M) || (p->std == V4L2_STD_NTSC))
1421 bw = 6;
1422 else
1423 bw = 8;
1424
7a5ef30d
MCC
1425 mutex_lock(&priv->lock);
1426 if (fe->ops.i2c_gate_ctrl)
1427 fe->ops.i2c_gate_ctrl(fe, 1);
1428
1429 rc = generic_set_freq(fe, 62500l * p->frequency, bw,
1430 V4L2_TUNER_ANALOG_TV, p->std, SYS_UNDEFINED);
1431
1432 if (fe->ops.i2c_gate_ctrl)
1433 fe->ops.i2c_gate_ctrl(fe, 0);
1434 mutex_unlock(&priv->lock);
1435
1436 return rc;
a80abc58
MCC
1437}
1438
1439static int r820t_set_params(struct dvb_frontend *fe)
1440{
1441 struct r820t_priv *priv = fe->tuner_priv;
1442 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1443 int rc;
1444 unsigned bw;
1445
1446 tuner_dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
1447 __func__, c->delivery_system, c->frequency, c->bandwidth_hz);
1448
7a5ef30d 1449 mutex_lock(&priv->lock);
a80abc58
MCC
1450 if (fe->ops.i2c_gate_ctrl)
1451 fe->ops.i2c_gate_ctrl(fe, 1);
1452
1453 bw = (c->bandwidth_hz + 500000) / 1000000;
1454 if (!bw)
1455 bw = 8;
1456
1457 rc = generic_set_freq(fe, c->frequency, bw,
1458 V4L2_TUNER_DIGITAL_TV, 0, c->delivery_system);
1459
1460 if (fe->ops.i2c_gate_ctrl)
1461 fe->ops.i2c_gate_ctrl(fe, 0);
7a5ef30d 1462 mutex_unlock(&priv->lock);
a80abc58
MCC
1463
1464 if (rc)
1465 tuner_dbg("%s: failed=%d\n", __func__, rc);
1466 return rc;
1467}
1468
1469static int r820t_signal(struct dvb_frontend *fe, u16 *strength)
1470{
1471 struct r820t_priv *priv = fe->tuner_priv;
f8fde0e0 1472 int rc = 0;
a80abc58 1473
7a5ef30d
MCC
1474 mutex_lock(&priv->lock);
1475 if (fe->ops.i2c_gate_ctrl)
1476 fe->ops.i2c_gate_ctrl(fe, 1);
1477
f8fde0e0
MCC
1478 if (priv->has_lock) {
1479 rc = r820t_read_gain(priv);
1480 if (rc < 0)
7a5ef30d 1481 goto err;
f8fde0e0
MCC
1482
1483 /* A higher gain at LNA means a lower signal strength */
1484 *strength = (45 - rc) << 4 | 0xff;
1485 } else {
a80abc58 1486 *strength = 0;
f8fde0e0
MCC
1487 }
1488
7a5ef30d
MCC
1489err:
1490 if (fe->ops.i2c_gate_ctrl)
1491 fe->ops.i2c_gate_ctrl(fe, 0);
1492 mutex_unlock(&priv->lock);
1493
f8fde0e0
MCC
1494 tuner_dbg("%s: %s, gain=%d strength=%d\n",
1495 __func__,
1496 priv->has_lock ? "PLL locked" : "no signal",
1497 rc, *strength);
a80abc58
MCC
1498
1499 return 0;
1500}
1501
1502static int r820t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
1503{
1504 struct r820t_priv *priv = fe->tuner_priv;
1505
1506 tuner_dbg("%s:\n", __func__);
1507
1508 *frequency = priv->int_freq;
1509
1510 return 0;
1511}
1512
1513static int r820t_release(struct dvb_frontend *fe)
1514{
1515 struct r820t_priv *priv = fe->tuner_priv;
1516
1517 tuner_dbg("%s:\n", __func__);
1518
1519 mutex_lock(&r820t_list_mutex);
1520
1521 if (priv)
1522 hybrid_tuner_release_state(priv);
1523
1524 mutex_unlock(&r820t_list_mutex);
1525
1526 fe->tuner_priv = NULL;
1527
1528 kfree(fe->tuner_priv);
1529
1530 return 0;
1531}
1532
1533static const struct dvb_tuner_ops r820t_tuner_ops = {
1534 .info = {
1535 .name = "Rafael Micro R820T",
1536 .frequency_min = 42000000,
1537 .frequency_max = 1002000000,
1538 },
1539 .init = r820t_init,
1540 .release = r820t_release,
1541 .sleep = r820t_sleep,
1542 .set_params = r820t_set_params,
1543 .set_analog_params = r820t_set_analog_freq,
1544 .get_if_frequency = r820t_get_if_frequency,
1545 .get_rf_strength = r820t_signal,
1546};
1547
1548struct dvb_frontend *r820t_attach(struct dvb_frontend *fe,
1549 struct i2c_adapter *i2c,
1550 const struct r820t_config *cfg)
1551{
1552 struct r820t_priv *priv;
1553 int rc = -ENODEV;
1554 u8 data[5];
1555 int instance;
1556
1557 mutex_lock(&r820t_list_mutex);
1558
1559 instance = hybrid_tuner_request_state(struct r820t_priv, priv,
1560 hybrid_tuner_instance_list,
1561 i2c, cfg->i2c_addr,
1562 "r820t");
1563 switch (instance) {
1564 case 0:
1565 /* memory allocation failure */
1566 goto err_no_gate;
1567 break;
1568 case 1:
1569 /* new tuner instance */
1570 priv->cfg = cfg;
1571
1572 mutex_init(&priv->lock);
1573
1574 fe->tuner_priv = priv;
1575 break;
1576 case 2:
1577 /* existing tuner instance */
1578 fe->tuner_priv = priv;
1579 break;
1580 }
1581
1582 memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops, sizeof(r820t_tuner_ops));
1583
1584 if (fe->ops.i2c_gate_ctrl)
1585 fe->ops.i2c_gate_ctrl(fe, 1);
1586
1587 /* check if the tuner is there */
1588 rc = r820_read(priv, 0x00, data, sizeof(data));
1589 if (rc < 0)
1590 goto err;
1591
1592 rc = r820t_sleep(fe);
1593 if (rc < 0)
1594 goto err;
1595
1596 tuner_info("Rafael Micro r820t successfully identified\n");
1597
1598 fe->tuner_priv = priv;
1599 memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
1600 sizeof(struct dvb_tuner_ops));
1601
1602 if (fe->ops.i2c_gate_ctrl)
1603 fe->ops.i2c_gate_ctrl(fe, 0);
1604
1605 mutex_unlock(&r820t_list_mutex);
1606
1607 return fe;
1608err:
1609 if (fe->ops.i2c_gate_ctrl)
1610 fe->ops.i2c_gate_ctrl(fe, 0);
1611
1612err_no_gate:
1613 mutex_unlock(&r820t_list_mutex);
1614
1615 tuner_info("%s: failed=%d\n", __func__, rc);
1616 r820t_release(fe);
1617 return NULL;
1618}
1619EXPORT_SYMBOL_GPL(r820t_attach);
1620
1621MODULE_DESCRIPTION("Rafael Micro r820t silicon tuner driver");
1622MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1623MODULE_LICENSE("GPL");
This page took 0.089594 seconds and 5 git commands to generate.