blob: ed9cd65695487ae08fd95225c54565094cd789fc [file] [log] [blame]
Mauro Carvalho Chehaba80abc52013-04-05 14:35:18 -03001/*
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
323/*
324 * I2C read/write code and shadow registers logic
325 */
326static void shadow_store(struct r820t_priv *priv, u8 reg, const u8 *val,
327 int len)
328{
329 int r = reg - REG_SHADOW_START;
330
331 if (r < 0) {
332 len += r;
333 r = 0;
334 }
335 if (len <= 0)
336 return;
337 if (len > NUM_REGS)
338 len = NUM_REGS;
339
340 tuner_dbg("%s: prev reg=%02x len=%d: %*ph\n",
341 __func__, r + REG_SHADOW_START, len, len, val);
342
343 memcpy(&priv->regs[r], val, len);
344}
345
346static int r820t_write(struct r820t_priv *priv, u8 reg, const u8 *val,
347 int len)
348{
349 int rc, size, pos = 0;
350
351 /* Store the shadow registers */
352 shadow_store(priv, reg, val, len);
353
354 do {
355 if (len > priv->cfg->max_i2c_msg_len - 1)
356 size = priv->cfg->max_i2c_msg_len - 1;
357 else
358 size = len;
359
360 /* Fill I2C buffer */
361 priv->buf[0] = reg;
362 memcpy(&priv->buf[1], &val[pos], size);
363
364 rc = tuner_i2c_xfer_send(&priv->i2c_props, priv->buf, size + 1);
365 if (rc != size + 1) {
366 tuner_info("%s: i2c wr failed=%d reg=%02x len=%d: %*ph\n",
367 __func__, rc, reg, size, size, &priv->buf[1]);
368 if (rc < 0)
369 return rc;
370 return -EREMOTEIO;
371 }
372 tuner_dbg("%s: i2c wr reg=%02x len=%d: %*ph\n",
373 __func__, reg, size, size, &priv->buf[1]);
374
375 reg += size;
376 len -= size;
377 pos += size;
378 } while (len > 0);
379
380 return 0;
381}
382
383static int r820t_write_reg(struct r820t_priv *priv, u8 reg, u8 val)
384{
385 return r820t_write(priv, reg, &val, 1);
386}
387
388static int r820t_write_reg_mask(struct r820t_priv *priv, u8 reg, u8 val,
389 u8 bit_mask)
390{
391 int r = reg - REG_SHADOW_START;
392
393 if (r >= 0 && r < NUM_REGS)
394 val = (priv->regs[r] & ~bit_mask) | (val & bit_mask);
395 else
396 return -EINVAL;
397
398 return r820t_write(priv, reg, &val, 1);
399}
400
401static int r820_read(struct r820t_priv *priv, u8 reg, u8 *val, int len)
402{
403 int rc;
404 u8 *p = &priv->buf[1];
405
406 priv->buf[0] = reg;
407
408 rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, priv->buf, 1, p, len);
409 if (rc != len) {
410 tuner_info("%s: i2c rd failed=%d reg=%02x len=%d: %*ph\n",
411 __func__, rc, reg, len, len, p);
412 if (rc < 0)
413 return rc;
414 return -EREMOTEIO;
415 }
416 tuner_dbg("%s: i2c rd reg=%02x len=%d: %*ph\n",
417 __func__, reg, len, len, p);
418
419 /* Copy data to the output buffer */
420 memcpy(val, p, len);
421
422 return 0;
423}
424
425/*
426 * r820t tuning logic
427 */
428
429static int r820t_set_mux(struct r820t_priv *priv, u32 freq)
430{
431 const struct r820t_freq_range *range;
432 int i, rc;
433 u8 val;
434
435 /* Get the proper frequency range */
436 freq = freq / 1000000;
437 for (i = 0; i < ARRAY_SIZE(freq_ranges) - 1; i++) {
438 if (freq < freq_ranges[i + 1].freq)
439 break;
440 }
441 range = &freq_ranges[i];
442
443 tuner_dbg("set r820t range#%d for frequency %d MHz\n", i, freq);
444
445 /* Open Drain */
446 rc = r820t_write_reg_mask(priv, 0x17, range->open_d, 0x08);
447 if (rc < 0)
448 return rc;
449
450 /* RF_MUX,Polymux */
451 rc = r820t_write_reg_mask(priv, 0x1a, range->rf_mux_ploy, 0xc3);
452 if (rc < 0)
453 return rc;
454
455 /* TF BAND */
456 rc = r820t_write_reg(priv, 0x1b, range->tf_c);
457 if (rc < 0)
458 return rc;
459
460 /* XTAL CAP & Drive */
461 switch (priv->xtal_cap_sel) {
462 case XTAL_LOW_CAP_30P:
463 case XTAL_LOW_CAP_20P:
464 val = range->xtal_cap20p | 0x08;
465 break;
466 case XTAL_LOW_CAP_10P:
467 val = range->xtal_cap10p | 0x08;
468 break;
469 case XTAL_HIGH_CAP_0P:
470 val = range->xtal_cap0p | 0x00;
471 break;
472 default:
473 case XTAL_LOW_CAP_0P:
474 val = range->xtal_cap0p | 0x08;
475 break;
476 }
477 rc = r820t_write_reg_mask(priv, 0x10, val, 0x0b);
478 if (rc < 0)
479 return rc;
480
481 /*
482 * FIXME: the original driver has a logic there with preserves
483 * gain/phase from registers 8 and 9 reading the data from the
484 * registers before writing, if "IMF done". That code was sort of
485 * commented there, as the flag is always false.
486 */
487 rc = r820t_write_reg_mask(priv, 0x08, 0, 0x3f);
488 if (rc < 0)
489 return rc;
490
491 rc = r820t_write_reg_mask(priv, 0x09, 0, 0x3f);
492
493 return rc;
494}
495
496static int r820t_set_pll(struct r820t_priv *priv, u32 freq)
497{
498 u64 tmp64, vco_freq;
499 int rc, i;
500 u32 vco_fra; /* VCO contribution by SDM (kHz) */
501 u32 vco_min = 1770000;
502 u32 vco_max = vco_min * 2;
503 u32 pll_ref;
504 u16 n_sdm = 2;
505 u16 sdm = 0;
506 u8 mix_div = 2;
507 u8 div_buf = 0;
508 u8 div_num = 0;
509 u8 ni, si, nint, vco_fine_tune, val;
510 u8 data[5];
511
512 freq = freq / 1000; /* Frequency in kHz */
513
514 pll_ref = priv->cfg->xtal / 1000;
515
516 tuner_dbg("set r820t pll for frequency %d kHz = %d\n", freq, pll_ref);
517
518 /* FIXME: this seems to be a hack - probably it can be removed */
519 rc = r820t_write_reg_mask(priv, 0x10, 0x00, 0x00);
520 if (rc < 0)
521 return rc;
522
523 /* set pll autotune = 128kHz */
524 rc = r820t_write_reg_mask(priv, 0x1a, 0x00, 0x0c);
525 if (rc < 0)
526 return rc;
527
528 /* set VCO current = 100 */
529 rc = r820t_write_reg_mask(priv, 0x12, 0x80, 0xe0);
530 if (rc < 0)
531 return rc;
532
533 /* Calculate divider */
534 while (mix_div <= 64) {
535 if (((freq * mix_div) >= vco_min) &&
536 ((freq * mix_div) < vco_max)) {
537 div_buf = mix_div;
538 while (div_buf > 2) {
539 div_buf = div_buf >> 1;
540 div_num++;
541 }
542 break;
543 }
544 mix_div = mix_div << 1;
545 }
546
547 rc = r820_read(priv, 0x00, data, sizeof(data));
548 if (rc < 0)
549 return rc;
550
551 vco_fine_tune = (data[4] & 0x30) >> 4;
552
553 if (vco_fine_tune > VCO_POWER_REF)
554 div_num = div_num - 1;
555 else if (vco_fine_tune < VCO_POWER_REF)
556 div_num = div_num + 1;
557
558 rc = r820t_write_reg_mask(priv, 0x10, div_num << 5, 0xe0);
559 if (rc < 0)
560 return rc;
561
562 vco_freq = (u64)(freq * (u64)mix_div);
563
564 tmp64 = vco_freq;
565 do_div(tmp64, 2 * pll_ref);
566 nint = (u8)tmp64;
567
568 tmp64 = vco_freq - ((u64)2) * pll_ref * nint;
569 do_div(tmp64, 1000);
570 vco_fra = (u16)(tmp64);
571
572 pll_ref /= 1000;
573
574 /* boundary spur prevention */
575 if (vco_fra < pll_ref / 64) {
576 vco_fra = 0;
577 } else if (vco_fra > pll_ref * 127 / 64) {
578 vco_fra = 0;
579 nint++;
580 } else if ((vco_fra > pll_ref * 127 / 128) && (vco_fra < pll_ref)) {
581 vco_fra = pll_ref * 127 / 128;
582 } else if ((vco_fra > pll_ref) && (vco_fra < pll_ref * 129 / 128)) {
583 vco_fra = pll_ref * 129 / 128;
584 }
585
586 if (nint > 63) {
587 tuner_info("No valid PLL values for %u kHz!\n", freq);
588 return -EINVAL;
589 }
590
591 ni = (nint - 13) / 4;
592 si = nint - 4 * ni - 13;
593
594 rc = r820t_write_reg(priv, 0x14, ni + (si << 6));
595 if (rc < 0)
596 return rc;
597
598 /* pw_sdm */
599 if (!vco_fra)
600 val = 0x08;
601 else
602 val = 0x00;
603
604 rc = r820t_write_reg_mask(priv, 0x12, val, 0x08);
605 if (rc < 0)
606 return rc;
607
608 /* sdm calculator */
609 while (vco_fra > 1) {
610 if (vco_fra > (2 * pll_ref / n_sdm)) {
611 sdm = sdm + 32768 / (n_sdm / 2);
612 vco_fra = vco_fra - 2 * pll_ref / n_sdm;
613 if (n_sdm >= 0x8000)
614 break;
615 }
616 n_sdm = n_sdm << 1;
617 }
618
619 rc = r820t_write_reg_mask(priv, 0x16, sdm >> 8, 0x08);
620 if (rc < 0)
621 return rc;
622 rc = r820t_write_reg_mask(priv, 0x15, sdm & 0xff, 0x08);
623 if (rc < 0)
624 return rc;
625
626 for (i = 0; i < 2; i++) {
627 /*
628 * FIXME: Rafael chips R620D, R828D and R828 seems to
629 * need 20 ms for analog TV
630 */
631 msleep(10);
632
633 /* Check if PLL has locked */
634 rc = r820_read(priv, 0x00, data, 3);
635 if (rc < 0)
636 return rc;
637 if (data[2] & 0x40)
638 break;
639
640 if (!i) {
641 /* Didn't lock. Increase VCO current */
642 rc = r820t_write_reg_mask(priv, 0x12, 0x60, 0xe0);
643 if (rc < 0)
644 return rc;
645 }
646 }
647
648 if (!(data[2] & 0x40)) {
649 priv->has_lock = false;
650 return 0;
651 }
652
653 priv->has_lock = true;
654 tuner_dbg("tuner has lock at frequency %d kHz\n", freq);
655
656 /* set pll autotune = 8kHz */
657 rc = r820t_write_reg_mask(priv, 0x1a, 0x08, 0x08);
658
659 return rc;
660}
661
662static int r820t_sysfreq_sel(struct r820t_priv *priv, u32 freq,
663 enum v4l2_tuner_type type,
664 v4l2_std_id std,
665 u32 delsys)
666{
667 int rc;
668 u8 mixer_top, lna_top, cp_cur, div_buf_cur, lna_vth_l, mixer_vth_l;
669 u8 air_cable1_in, cable2_in, pre_dect, lna_discharge, filter_cur;
670
671 tuner_dbg("adjusting tuner parameters for the standard\n");
672
673 switch (delsys) {
674 case SYS_DVBT:
675 if ((freq == 506000000) || (freq == 666000000) ||
676 (freq == 818000000)) {
677 mixer_top = 0x14; /* mixer top:14 , top-1, low-discharge */
678 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
679 cp_cur = 0x28; /* 101, 0.2 */
680 div_buf_cur = 0x20; /* 10, 200u */
681 } else {
682 mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
683 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
684 cp_cur = 0x38; /* 111, auto */
685 div_buf_cur = 0x30; /* 11, 150u */
686 }
687 lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
688 mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
689 air_cable1_in = 0x00;
690 cable2_in = 0x00;
691 pre_dect = 0x40;
692 lna_discharge = 14;
693 filter_cur = 0x40; /* 10, low */
694 break;
695 case SYS_DVBT2:
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 lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
699 mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
700 air_cable1_in = 0x00;
701 cable2_in = 0x00;
702 pre_dect = 0x40;
703 lna_discharge = 14;
704 cp_cur = 0x38; /* 111, auto */
705 div_buf_cur = 0x30; /* 11, 150u */
706 filter_cur = 0x40; /* 10, low */
707 break;
708 case SYS_ISDBT:
709 mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
710 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
711 lna_vth_l = 0x75; /* lna vth 1.04 , vtl 0.84 */
712 mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
713 air_cable1_in = 0x00;
714 cable2_in = 0x00;
715 pre_dect = 0x40;
716 lna_discharge = 14;
717 cp_cur = 0x38; /* 111, auto */
718 div_buf_cur = 0x30; /* 11, 150u */
719 filter_cur = 0x40; /* 10, low */
720 break;
721 default: /* DVB-T 8M */
722 mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
723 lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
724 lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
725 mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
726 air_cable1_in = 0x00;
727 cable2_in = 0x00;
728 pre_dect = 0x40;
729 lna_discharge = 14;
730 cp_cur = 0x38; /* 111, auto */
731 div_buf_cur = 0x30; /* 11, 150u */
732 filter_cur = 0x40; /* 10, low */
733 break;
734 }
735
736 rc = r820t_write_reg_mask(priv, 0x1d, lna_top, 0xc7);
737 if (rc < 0)
738 return rc;
739 rc = r820t_write_reg_mask(priv, 0x1c, mixer_top, 0xf8);
740 if (rc < 0)
741 return rc;
742 rc = r820t_write_reg(priv, 0x0d, lna_vth_l);
743 if (rc < 0)
744 return rc;
745 rc = r820t_write_reg(priv, 0x0e, mixer_vth_l);
746 if (rc < 0)
747 return rc;
748
749 /* Air-IN only for Astrometa */
750 rc = r820t_write_reg_mask(priv, 0x05, air_cable1_in, 0x60);
751 if (rc < 0)
752 return rc;
753 rc = r820t_write_reg_mask(priv, 0x06, cable2_in, 0x08);
754 if (rc < 0)
755 return rc;
756
757 rc = r820t_write_reg_mask(priv, 0x11, cp_cur, 0x38);
758 if (rc < 0)
759 return rc;
760 rc = r820t_write_reg_mask(priv, 0x17, div_buf_cur, 0x30);
761 if (rc < 0)
762 return rc;
763 rc = r820t_write_reg_mask(priv, 0x0a, filter_cur, 0x60);
764 if (rc < 0)
765 return rc;
766 /*
767 * Original driver initializes regs 0x05 and 0x06 with the
768 * same value again on this point. Probably, it is just an
769 * error there
770 */
771
772 /*
773 * Set LNA
774 */
775
776 tuner_dbg("adjusting LNA parameters\n");
777 if (type != V4L2_TUNER_ANALOG_TV) {
778 /* LNA TOP: lowest */
779 rc = r820t_write_reg_mask(priv, 0x1d, 0, 0x38);
780 if (rc < 0)
781 return rc;
782
783 /* 0: normal mode */
784 rc = r820t_write_reg_mask(priv, 0x1c, 0, 0x04);
785 if (rc < 0)
786 return rc;
787
788 /* 0: PRE_DECT off */
789 rc = r820t_write_reg_mask(priv, 0x06, 0, 0x40);
790 if (rc < 0)
791 return rc;
792
793 /* agc clk 250hz */
794 rc = r820t_write_reg_mask(priv, 0x1a, 0x30, 0x30);
795 if (rc < 0)
796 return rc;
797
798 msleep(250);
799
800 /* write LNA TOP = 3 */
801 rc = r820t_write_reg_mask(priv, 0x1d, 0x18, 0x38);
802 if (rc < 0)
803 return rc;
804
805 /*
806 * write discharge mode
807 * FIXME: IMHO, the mask here is wrong, but it matches
808 * what's there at the original driver
809 */
810 rc = r820t_write_reg_mask(priv, 0x1c, mixer_top, 0x04);
811 if (rc < 0)
812 return rc;
813
814 /* LNA discharge current */
815 rc = r820t_write_reg_mask(priv, 0x1e, lna_discharge, 0x1f);
816 if (rc < 0)
817 return rc;
818
819 /* agc clk 60hz */
820 rc = r820t_write_reg_mask(priv, 0x1a, 0x20, 0x30);
821 if (rc < 0)
822 return rc;
823 } else {
824 /* PRE_DECT off */
825 rc = r820t_write_reg_mask(priv, 0x06, 0, 0x40);
826 if (rc < 0)
827 return rc;
828
829 /* write LNA TOP */
830 rc = r820t_write_reg_mask(priv, 0x1d, lna_top, 0x38);
831 if (rc < 0)
832 return rc;
833
834 /*
835 * write discharge mode
836 * FIXME: IMHO, the mask here is wrong, but it matches
837 * what's there at the original driver
838 */
839 rc = r820t_write_reg_mask(priv, 0x1c, mixer_top, 0x04);
840 if (rc < 0)
841 return rc;
842
843 /* LNA discharge current */
844 rc = r820t_write_reg_mask(priv, 0x1e, lna_discharge, 0x1f);
845 if (rc < 0)
846 return rc;
847
848 /* agc clk 1Khz, external det1 cap 1u */
849 rc = r820t_write_reg_mask(priv, 0x1a, 0x00, 0x30);
850 if (rc < 0)
851 return rc;
852
853 rc = r820t_write_reg_mask(priv, 0x10, 0x00, 0x04);
854 if (rc < 0)
855 return rc;
856 }
857 return 0;
858}
859
860static int r820t_set_tv_standard(struct r820t_priv *priv,
861 unsigned bw,
862 enum v4l2_tuner_type type,
863 v4l2_std_id std, u32 delsys)
864
865{
866 int rc, i;
867 u32 if_khz, filt_cal_lo;
868 u8 data[5], val;
869 u8 filt_gain, img_r, filt_q, hp_cor, ext_enable, loop_through;
870 u8 lt_att, flt_ext_widest, polyfil_cur;
871 bool need_calibration;
872
873 tuner_dbg("selecting the delivery system\n");
874
875 if (delsys == SYS_ISDBT) {
876 if_khz = 4063;
877 filt_cal_lo = 59000;
878 filt_gain = 0x10; /* +3db, 6mhz on */
879 img_r = 0x00; /* image negative */
880 filt_q = 0x10; /* r10[4]:low q(1'b1) */
881 hp_cor = 0x6a; /* 1.7m disable, +2cap, 1.25mhz */
882 ext_enable = 0x40; /* r30[6], ext enable; r30[5]:0 ext at lna max */
883 loop_through = 0x00; /* r5[7], lt on */
884 lt_att = 0x00; /* r31[7], lt att enable */
885 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
886 polyfil_cur = 0x60; /* r25[6:5]:min */
887 } else {
888 if (bw <= 6) {
889 if_khz = 3570;
890 filt_cal_lo = 56000; /* 52000->56000 */
891 filt_gain = 0x10; /* +3db, 6mhz on */
892 img_r = 0x00; /* image negative */
893 filt_q = 0x10; /* r10[4]:low q(1'b1) */
894 hp_cor = 0x6b; /* 1.7m disable, +2cap, 1.0mhz */
895 ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
896 loop_through = 0x00; /* r5[7], lt on */
897 lt_att = 0x00; /* r31[7], lt att enable */
898 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
899 polyfil_cur = 0x60; /* r25[6:5]:min */
900 } else if (bw == 7) {
901 if_khz = 4070;
902 filt_cal_lo = 60000;
903 filt_gain = 0x10; /* +3db, 6mhz on */
904 img_r = 0x00; /* image negative */
905 filt_q = 0x10; /* r10[4]:low q(1'b1) */
906 hp_cor = 0x2b; /* 1.7m disable, +1cap, 1.0mhz */
907 ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
908 loop_through = 0x00; /* r5[7], lt on */
909 lt_att = 0x00; /* r31[7], lt att enable */
910 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
911 polyfil_cur = 0x60; /* r25[6:5]:min */
912#if 0 /* 7 MHz type 2 - nor sure why/where this is used - Perhaps Australia? */
913 if_khz = 4570;
914 filt_cal_lo = 63000;
915 filt_gain = 0x10; /* +3db, 6mhz on */
916 img_r = 0x00; /* image negative */
917 filt_q = 0x10; /* r10[4]:low q(1'b1) */
918 hp_cor = 0x2a; /* 1.7m disable, +1cap, 1.25mhz */
919 ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
920 loop_through = 0x00; /* r5[7], lt on */
921 lt_att = 0x00; /* r31[7], lt att enable */
922 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
923 polyfil_cur = 0x60; /* r25[6:5]:min */
924#endif
925 } else {
926 if_khz = 4570;
927 filt_cal_lo = 68500;
928 filt_gain = 0x10; /* +3db, 6mhz on */
929 img_r = 0x00; /* image negative */
930 filt_q = 0x10; /* r10[4]:low q(1'b1) */
931 hp_cor = 0x0b; /* 1.7m disable, +0cap, 1.0mhz */
932 ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
933 loop_through = 0x00; /* r5[7], lt on */
934 lt_att = 0x00; /* r31[7], lt att enable */
935 flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
936 polyfil_cur = 0x60; /* r25[6:5]:min */
937 }
938 }
939
940 /* Initialize the shadow registers */
941 memcpy(priv->regs, r820t_init_array, sizeof(r820t_init_array));
942
943 /* Init Flag & Xtal_check Result */
944 if (priv->imr_done)
945 val = 1 | priv->xtal_cap_sel << 1;
946 else
947 val = 0;
948 rc = r820t_write_reg_mask(priv, 0x0c, val, 0x0f);
949 if (rc < 0)
950 return rc;
951
952 /* version */
953 rc = r820t_write_reg_mask(priv, 0x13, VER_NUM, 0x3f);
954 if (rc < 0)
955 return rc;
956
957 /* for LT Gain test */
958 if (type != V4L2_TUNER_ANALOG_TV) {
959 rc = r820t_write_reg_mask(priv, 0x1d, 0x00, 0x38);
960 if (rc < 0)
961 return rc;
962 msleep(1);
963 }
964 priv->int_freq = if_khz;
965
966 /* Check if standard changed. If so, filter calibration is needed */
967 if (type != priv->type)
968 need_calibration = true;
969 else if ((type == V4L2_TUNER_ANALOG_TV) && (std != priv->std))
970 need_calibration = true;
971 else if ((type == V4L2_TUNER_DIGITAL_TV) &&
972 ((delsys != priv->delsys) || bw != priv->bw))
973 need_calibration = true;
974 else
975 need_calibration = false;
976
977 if (need_calibration) {
978 tuner_dbg("calibrating the tuner\n");
979 for (i = 0; i < 2; i++) {
980 /* Set filt_cap */
981 rc = r820t_write_reg_mask(priv, 0x0b, hp_cor, 0x60);
982 if (rc < 0)
983 return rc;
984
985 /* set cali clk =on */
986 rc = r820t_write_reg_mask(priv, 0x0f, 0x04, 0x04);
987 if (rc < 0)
988 return rc;
989
990 /* X'tal cap 0pF for PLL */
991 rc = r820t_write_reg_mask(priv, 0x10, 0x00, 0x03);
992 if (rc < 0)
993 return rc;
994
995 rc = r820t_set_pll(priv, filt_cal_lo);
996 if (rc < 0 || !priv->has_lock)
997 return rc;
998
999 /* Start Trigger */
1000 rc = r820t_write_reg_mask(priv, 0x0b, 0x10, 0x10);
1001 if (rc < 0)
1002 return rc;
1003
1004 msleep(1);
1005
1006 /* Stop Trigger */
1007 rc = r820t_write_reg_mask(priv, 0x0b, 0x00, 0x10);
1008 if (rc < 0)
1009 return rc;
1010
1011 /* set cali clk =off */
1012 rc = r820t_write_reg_mask(priv, 0x0f, 0x00, 0x04);
1013 if (rc < 0)
1014 return rc;
1015
1016 /* Check if calibration worked */
1017 rc = r820_read(priv, 0x00, data, sizeof(data));
1018 if (rc < 0)
1019 return rc;
1020
1021 priv->fil_cal_code = data[4] & 0x0f;
1022 if (priv->fil_cal_code && priv->fil_cal_code != 0x0f)
1023 break;
1024 }
1025 /* narrowest */
1026 if (priv->fil_cal_code == 0x0f)
1027 priv->fil_cal_code = 0;
1028 }
1029
1030 rc = r820t_write_reg_mask(priv, 0x0a,
1031 filt_q | priv->fil_cal_code, 0x1f);
1032 if (rc < 0)
1033 return rc;
1034
1035 /* Set BW, Filter_gain, & HP corner */
1036 rc = r820t_write_reg_mask(priv, 0x0b, hp_cor, 0x10);
1037 if (rc < 0)
1038 return rc;
1039
1040
1041 /* Set Img_R */
1042 rc = r820t_write_reg_mask(priv, 0x07, img_r, 0x80);
1043 if (rc < 0)
1044 return rc;
1045
1046 /* Set filt_3dB, V6MHz */
1047 rc = r820t_write_reg_mask(priv, 0x06, filt_gain, 0x30);
1048 if (rc < 0)
1049 return rc;
1050
1051 /* channel filter extension */
1052 rc = r820t_write_reg_mask(priv, 0x1e, ext_enable, 0x60);
1053 if (rc < 0)
1054 return rc;
1055
1056 /* Loop through */
1057 rc = r820t_write_reg_mask(priv, 0x05, loop_through, 0x80);
1058 if (rc < 0)
1059 return rc;
1060
1061 /* Loop through attenuation */
1062 rc = r820t_write_reg_mask(priv, 0x1f, lt_att, 0x80);
1063 if (rc < 0)
1064 return rc;
1065
1066 /* filter extension widest */
1067 rc = r820t_write_reg_mask(priv, 0x0f, flt_ext_widest, 0x80);
1068 if (rc < 0)
1069 return rc;
1070
1071 /* RF poly filter current */
1072 rc = r820t_write_reg_mask(priv, 0x19, polyfil_cur, 0x60);
1073 if (rc < 0)
1074 return rc;
1075
1076 /* Store current standard. If it changes, re-calibrate the tuner */
1077 priv->delsys = delsys;
1078 priv->type = type;
1079 priv->std = std;
1080 priv->bw = bw;
1081
1082 return 0;
1083}
1084
Mauro Carvalho Chehabf8fde0e2013-04-07 18:12:56 -03001085static int r820t_read_gain(struct r820t_priv *priv)
1086{
1087 u8 data[4];
1088 int rc;
1089
1090 rc = r820_read(priv, 0x00, data, sizeof(data));
1091 if (rc < 0)
1092 return rc;
1093
1094 return ((data[3] & 0x0f) << 1) + ((data[3] & 0xf0) >> 4);
1095}
1096
Mauro Carvalho Chehaba80abc52013-04-05 14:35:18 -03001097static int generic_set_freq(struct dvb_frontend *fe,
1098 u32 freq /* in HZ */,
1099 unsigned bw,
1100 enum v4l2_tuner_type type,
1101 v4l2_std_id std, u32 delsys)
1102{
1103 struct r820t_priv *priv = fe->tuner_priv;
1104 int rc = -EINVAL;
1105 u32 lo_freq;
1106
1107 tuner_dbg("should set frequency to %d kHz, bw %d MHz\n",
1108 freq / 1000, bw);
1109
1110 mutex_lock(&priv->lock);
1111
1112 if ((type == V4L2_TUNER_ANALOG_TV) && (std == V4L2_STD_SECAM_LC))
1113 lo_freq = freq - priv->int_freq;
1114 else
1115 lo_freq = freq + priv->int_freq;
1116
1117 rc = r820t_set_tv_standard(priv, bw, type, std, delsys);
1118 if (rc < 0)
1119 goto err;
1120
1121 rc = r820t_set_mux(priv, lo_freq);
1122 if (rc < 0)
1123 goto err;
1124 rc = r820t_set_pll(priv, lo_freq);
1125 if (rc < 0 || !priv->has_lock)
1126 goto err;
1127
1128 rc = r820t_sysfreq_sel(priv, freq, type, std, delsys);
1129err:
1130 mutex_unlock(&priv->lock);
1131
1132 if (rc < 0)
1133 tuner_dbg("%s: failed=%d\n", __func__, rc);
1134 return rc;
1135}
1136
1137/*
1138 * r820t standby logic
1139 */
1140
1141static int r820t_standby(struct r820t_priv *priv)
1142{
1143 int rc;
1144
1145 rc = r820t_write_reg(priv, 0x06, 0xb1);
1146 if (rc < 0)
1147 return rc;
1148 rc = r820t_write_reg(priv, 0x05, 0x03);
1149 if (rc < 0)
1150 return rc;
1151 rc = r820t_write_reg(priv, 0x07, 0x3a);
1152 if (rc < 0)
1153 return rc;
1154 rc = r820t_write_reg(priv, 0x08, 0x40);
1155 if (rc < 0)
1156 return rc;
1157 rc = r820t_write_reg(priv, 0x09, 0xc0);
1158 if (rc < 0)
1159 return rc;
1160 rc = r820t_write_reg(priv, 0x0a, 0x36);
1161 if (rc < 0)
1162 return rc;
1163 rc = r820t_write_reg(priv, 0x0c, 0x35);
1164 if (rc < 0)
1165 return rc;
1166 rc = r820t_write_reg(priv, 0x0f, 0x68);
1167 if (rc < 0)
1168 return rc;
1169 rc = r820t_write_reg(priv, 0x11, 0x03);
1170 if (rc < 0)
1171 return rc;
1172 rc = r820t_write_reg(priv, 0x17, 0xf4);
1173 if (rc < 0)
1174 return rc;
1175 rc = r820t_write_reg(priv, 0x19, 0x0c);
1176
1177 /* Force initial calibration */
1178 priv->type = -1;
1179
1180 return rc;
1181}
1182
1183/*
1184 * r820t device init logic
1185 */
1186
1187static int r820t_xtal_check(struct r820t_priv *priv)
1188{
1189 int rc, i;
1190 u8 data[3], val;
1191
1192 /* Initialize the shadow registers */
1193 memcpy(priv->regs, r820t_init_array, sizeof(r820t_init_array));
1194
1195 /* cap 30pF & Drive Low */
1196 rc = r820t_write_reg_mask(priv, 0x10, 0x0b, 0x0b);
1197 if (rc < 0)
1198 return rc;
1199
1200 /* set pll autotune = 128kHz */
1201 rc = r820t_write_reg_mask(priv, 0x1a, 0x00, 0x0c);
1202 if (rc < 0)
1203 return rc;
1204
1205 /* set manual initial reg = 111111; */
1206 rc = r820t_write_reg_mask(priv, 0x13, 0x7f, 0x7f);
1207 if (rc < 0)
1208 return rc;
1209
1210 /* set auto */
1211 rc = r820t_write_reg_mask(priv, 0x13, 0x00, 0x40);
1212 if (rc < 0)
1213 return rc;
1214
1215 /* Try several xtal capacitor alternatives */
1216 for (i = 0; i < ARRAY_SIZE(r820t_xtal_capacitor); i++) {
1217 rc = r820t_write_reg_mask(priv, 0x10,
1218 r820t_xtal_capacitor[i][0], 0x1b);
1219 if (rc < 0)
1220 return rc;
1221
1222 msleep(5);
1223
1224 rc = r820_read(priv, 0x00, data, sizeof(data));
1225 if (rc < 0)
1226 return rc;
1227 if ((!data[2]) & 0x40)
1228 continue;
1229
1230 val = data[2] & 0x3f;
1231
1232 if (priv->cfg->xtal == 16000000 && (val > 29 || val < 23))
1233 break;
1234
1235 if (val != 0x3f)
1236 break;
1237 }
1238
1239 if (i == ARRAY_SIZE(r820t_xtal_capacitor))
1240 return -EINVAL;
1241
1242 return r820t_xtal_capacitor[i][1];
1243}
1244
1245/*
1246 * r820t frontend operations and tuner attach code
1247 */
1248
1249static int r820t_init(struct dvb_frontend *fe)
1250{
1251 struct r820t_priv *priv = fe->tuner_priv;
1252 int rc, i;
1253 int xtal_cap = 0;
1254
1255 tuner_dbg("%s:\n", __func__);
1256
1257 if (fe->ops.i2c_gate_ctrl)
1258 fe->ops.i2c_gate_ctrl(fe, 1);
1259
1260 mutex_lock(&priv->lock);
1261
1262 if ((priv->cfg->rafael_chip == CHIP_R820T) ||
1263 (priv->cfg->rafael_chip == CHIP_R828S) ||
1264 (priv->cfg->rafael_chip == CHIP_R820C)) {
1265 priv->xtal_cap_sel = XTAL_HIGH_CAP_0P;
1266 } else {
1267 for (i = 0; i < 3; i++) {
1268 rc = r820t_xtal_check(priv);
1269 if (rc < 0)
1270 goto err;
1271 if (!i || rc > xtal_cap)
1272 xtal_cap = rc;
1273 }
1274 priv->xtal_cap_sel = xtal_cap;
1275 }
1276
1277 /* Initialize registers */
1278 rc = r820t_write(priv, 0x05,
1279 r820t_init_array, sizeof(r820t_init_array));
1280
1281 mutex_unlock(&priv->lock);
1282
1283 if (fe->ops.i2c_gate_ctrl)
1284 fe->ops.i2c_gate_ctrl(fe, 0);
1285
1286 return rc;
1287err:
1288 if (fe->ops.i2c_gate_ctrl)
1289 fe->ops.i2c_gate_ctrl(fe, 0);
1290
1291 tuner_dbg("%s: failed=%d\n", __func__, rc);
1292 return rc;
1293}
1294
1295static int r820t_sleep(struct dvb_frontend *fe)
1296{
1297 struct r820t_priv *priv = fe->tuner_priv;
1298 int rc;
1299
1300 tuner_dbg("%s:\n", __func__);
1301
1302 if (fe->ops.i2c_gate_ctrl)
1303 fe->ops.i2c_gate_ctrl(fe, 1);
1304
1305 mutex_lock(&priv->lock);
1306 rc = r820t_standby(priv);
1307 mutex_unlock(&priv->lock);
1308
1309 if (fe->ops.i2c_gate_ctrl)
1310 fe->ops.i2c_gate_ctrl(fe, 0);
1311
1312 tuner_dbg("%s: failed=%d\n", __func__, rc);
1313 return rc;
1314}
1315
1316static int r820t_set_analog_freq(struct dvb_frontend *fe,
1317 struct analog_parameters *p)
1318{
1319 struct r820t_priv *priv = fe->tuner_priv;
1320 unsigned bw;
1321
1322 tuner_dbg("%s called\n", __func__);
1323
1324 /* if std is not defined, choose one */
1325 if (!p->std)
1326 p->std = V4L2_STD_MN;
1327
1328 if ((p->std == V4L2_STD_PAL_M) || (p->std == V4L2_STD_NTSC))
1329 bw = 6;
1330 else
1331 bw = 8;
1332
1333 return generic_set_freq(fe, 62500l * p->frequency, bw,
1334 V4L2_TUNER_ANALOG_TV, p->std, SYS_UNDEFINED);
1335}
1336
1337static int r820t_set_params(struct dvb_frontend *fe)
1338{
1339 struct r820t_priv *priv = fe->tuner_priv;
1340 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1341 int rc;
1342 unsigned bw;
1343
1344 tuner_dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
1345 __func__, c->delivery_system, c->frequency, c->bandwidth_hz);
1346
1347 if (fe->ops.i2c_gate_ctrl)
1348 fe->ops.i2c_gate_ctrl(fe, 1);
1349
1350 bw = (c->bandwidth_hz + 500000) / 1000000;
1351 if (!bw)
1352 bw = 8;
1353
1354 rc = generic_set_freq(fe, c->frequency, bw,
1355 V4L2_TUNER_DIGITAL_TV, 0, c->delivery_system);
1356
1357 if (fe->ops.i2c_gate_ctrl)
1358 fe->ops.i2c_gate_ctrl(fe, 0);
1359
1360 if (rc)
1361 tuner_dbg("%s: failed=%d\n", __func__, rc);
1362 return rc;
1363}
1364
1365static int r820t_signal(struct dvb_frontend *fe, u16 *strength)
1366{
1367 struct r820t_priv *priv = fe->tuner_priv;
Mauro Carvalho Chehabf8fde0e2013-04-07 18:12:56 -03001368 int rc = 0;
Mauro Carvalho Chehaba80abc52013-04-05 14:35:18 -03001369
Mauro Carvalho Chehabf8fde0e2013-04-07 18:12:56 -03001370 if (priv->has_lock) {
1371 rc = r820t_read_gain(priv);
1372 if (rc < 0)
1373 return rc;
1374
1375 /* A higher gain at LNA means a lower signal strength */
1376 *strength = (45 - rc) << 4 | 0xff;
1377 } else {
Mauro Carvalho Chehaba80abc52013-04-05 14:35:18 -03001378 *strength = 0;
Mauro Carvalho Chehabf8fde0e2013-04-07 18:12:56 -03001379 }
1380
1381 tuner_dbg("%s: %s, gain=%d strength=%d\n",
1382 __func__,
1383 priv->has_lock ? "PLL locked" : "no signal",
1384 rc, *strength);
Mauro Carvalho Chehaba80abc52013-04-05 14:35:18 -03001385
1386 return 0;
1387}
1388
1389static int r820t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
1390{
1391 struct r820t_priv *priv = fe->tuner_priv;
1392
1393 tuner_dbg("%s:\n", __func__);
1394
1395 *frequency = priv->int_freq;
1396
1397 return 0;
1398}
1399
1400static int r820t_release(struct dvb_frontend *fe)
1401{
1402 struct r820t_priv *priv = fe->tuner_priv;
1403
1404 tuner_dbg("%s:\n", __func__);
1405
1406 mutex_lock(&r820t_list_mutex);
1407
1408 if (priv)
1409 hybrid_tuner_release_state(priv);
1410
1411 mutex_unlock(&r820t_list_mutex);
1412
1413 fe->tuner_priv = NULL;
1414
1415 kfree(fe->tuner_priv);
1416
1417 return 0;
1418}
1419
1420static const struct dvb_tuner_ops r820t_tuner_ops = {
1421 .info = {
1422 .name = "Rafael Micro R820T",
1423 .frequency_min = 42000000,
1424 .frequency_max = 1002000000,
1425 },
1426 .init = r820t_init,
1427 .release = r820t_release,
1428 .sleep = r820t_sleep,
1429 .set_params = r820t_set_params,
1430 .set_analog_params = r820t_set_analog_freq,
1431 .get_if_frequency = r820t_get_if_frequency,
1432 .get_rf_strength = r820t_signal,
1433};
1434
1435struct dvb_frontend *r820t_attach(struct dvb_frontend *fe,
1436 struct i2c_adapter *i2c,
1437 const struct r820t_config *cfg)
1438{
1439 struct r820t_priv *priv;
1440 int rc = -ENODEV;
1441 u8 data[5];
1442 int instance;
1443
1444 mutex_lock(&r820t_list_mutex);
1445
1446 instance = hybrid_tuner_request_state(struct r820t_priv, priv,
1447 hybrid_tuner_instance_list,
1448 i2c, cfg->i2c_addr,
1449 "r820t");
1450 switch (instance) {
1451 case 0:
1452 /* memory allocation failure */
1453 goto err_no_gate;
1454 break;
1455 case 1:
1456 /* new tuner instance */
1457 priv->cfg = cfg;
1458
1459 mutex_init(&priv->lock);
1460
1461 fe->tuner_priv = priv;
1462 break;
1463 case 2:
1464 /* existing tuner instance */
1465 fe->tuner_priv = priv;
1466 break;
1467 }
1468
1469 memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops, sizeof(r820t_tuner_ops));
1470
1471 if (fe->ops.i2c_gate_ctrl)
1472 fe->ops.i2c_gate_ctrl(fe, 1);
1473
1474 /* check if the tuner is there */
1475 rc = r820_read(priv, 0x00, data, sizeof(data));
1476 if (rc < 0)
1477 goto err;
1478
1479 rc = r820t_sleep(fe);
1480 if (rc < 0)
1481 goto err;
1482
1483 tuner_info("Rafael Micro r820t successfully identified\n");
1484
1485 fe->tuner_priv = priv;
1486 memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
1487 sizeof(struct dvb_tuner_ops));
1488
1489 if (fe->ops.i2c_gate_ctrl)
1490 fe->ops.i2c_gate_ctrl(fe, 0);
1491
1492 mutex_unlock(&r820t_list_mutex);
1493
1494 return fe;
1495err:
1496 if (fe->ops.i2c_gate_ctrl)
1497 fe->ops.i2c_gate_ctrl(fe, 0);
1498
1499err_no_gate:
1500 mutex_unlock(&r820t_list_mutex);
1501
1502 tuner_info("%s: failed=%d\n", __func__, rc);
1503 r820t_release(fe);
1504 return NULL;
1505}
1506EXPORT_SYMBOL_GPL(r820t_attach);
1507
1508MODULE_DESCRIPTION("Rafael Micro r820t silicon tuner driver");
1509MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1510MODULE_LICENSE("GPL");