blob: 7e02920f385a82ceafbde0205b39bfa726c9177d [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
1085static int generic_set_freq(struct dvb_frontend *fe,
1086 u32 freq /* in HZ */,
1087 unsigned bw,
1088 enum v4l2_tuner_type type,
1089 v4l2_std_id std, u32 delsys)
1090{
1091 struct r820t_priv *priv = fe->tuner_priv;
1092 int rc = -EINVAL;
1093 u32 lo_freq;
1094
1095 tuner_dbg("should set frequency to %d kHz, bw %d MHz\n",
1096 freq / 1000, bw);
1097
1098 mutex_lock(&priv->lock);
1099
1100 if ((type == V4L2_TUNER_ANALOG_TV) && (std == V4L2_STD_SECAM_LC))
1101 lo_freq = freq - priv->int_freq;
1102 else
1103 lo_freq = freq + priv->int_freq;
1104
1105 rc = r820t_set_tv_standard(priv, bw, type, std, delsys);
1106 if (rc < 0)
1107 goto err;
1108
1109 rc = r820t_set_mux(priv, lo_freq);
1110 if (rc < 0)
1111 goto err;
1112 rc = r820t_set_pll(priv, lo_freq);
1113 if (rc < 0 || !priv->has_lock)
1114 goto err;
1115
1116 rc = r820t_sysfreq_sel(priv, freq, type, std, delsys);
1117err:
1118 mutex_unlock(&priv->lock);
1119
1120 if (rc < 0)
1121 tuner_dbg("%s: failed=%d\n", __func__, rc);
1122 return rc;
1123}
1124
1125/*
1126 * r820t standby logic
1127 */
1128
1129static int r820t_standby(struct r820t_priv *priv)
1130{
1131 int rc;
1132
1133 rc = r820t_write_reg(priv, 0x06, 0xb1);
1134 if (rc < 0)
1135 return rc;
1136 rc = r820t_write_reg(priv, 0x05, 0x03);
1137 if (rc < 0)
1138 return rc;
1139 rc = r820t_write_reg(priv, 0x07, 0x3a);
1140 if (rc < 0)
1141 return rc;
1142 rc = r820t_write_reg(priv, 0x08, 0x40);
1143 if (rc < 0)
1144 return rc;
1145 rc = r820t_write_reg(priv, 0x09, 0xc0);
1146 if (rc < 0)
1147 return rc;
1148 rc = r820t_write_reg(priv, 0x0a, 0x36);
1149 if (rc < 0)
1150 return rc;
1151 rc = r820t_write_reg(priv, 0x0c, 0x35);
1152 if (rc < 0)
1153 return rc;
1154 rc = r820t_write_reg(priv, 0x0f, 0x68);
1155 if (rc < 0)
1156 return rc;
1157 rc = r820t_write_reg(priv, 0x11, 0x03);
1158 if (rc < 0)
1159 return rc;
1160 rc = r820t_write_reg(priv, 0x17, 0xf4);
1161 if (rc < 0)
1162 return rc;
1163 rc = r820t_write_reg(priv, 0x19, 0x0c);
1164
1165 /* Force initial calibration */
1166 priv->type = -1;
1167
1168 return rc;
1169}
1170
1171/*
1172 * r820t device init logic
1173 */
1174
1175static int r820t_xtal_check(struct r820t_priv *priv)
1176{
1177 int rc, i;
1178 u8 data[3], val;
1179
1180 /* Initialize the shadow registers */
1181 memcpy(priv->regs, r820t_init_array, sizeof(r820t_init_array));
1182
1183 /* cap 30pF & Drive Low */
1184 rc = r820t_write_reg_mask(priv, 0x10, 0x0b, 0x0b);
1185 if (rc < 0)
1186 return rc;
1187
1188 /* set pll autotune = 128kHz */
1189 rc = r820t_write_reg_mask(priv, 0x1a, 0x00, 0x0c);
1190 if (rc < 0)
1191 return rc;
1192
1193 /* set manual initial reg = 111111; */
1194 rc = r820t_write_reg_mask(priv, 0x13, 0x7f, 0x7f);
1195 if (rc < 0)
1196 return rc;
1197
1198 /* set auto */
1199 rc = r820t_write_reg_mask(priv, 0x13, 0x00, 0x40);
1200 if (rc < 0)
1201 return rc;
1202
1203 /* Try several xtal capacitor alternatives */
1204 for (i = 0; i < ARRAY_SIZE(r820t_xtal_capacitor); i++) {
1205 rc = r820t_write_reg_mask(priv, 0x10,
1206 r820t_xtal_capacitor[i][0], 0x1b);
1207 if (rc < 0)
1208 return rc;
1209
1210 msleep(5);
1211
1212 rc = r820_read(priv, 0x00, data, sizeof(data));
1213 if (rc < 0)
1214 return rc;
1215 if ((!data[2]) & 0x40)
1216 continue;
1217
1218 val = data[2] & 0x3f;
1219
1220 if (priv->cfg->xtal == 16000000 && (val > 29 || val < 23))
1221 break;
1222
1223 if (val != 0x3f)
1224 break;
1225 }
1226
1227 if (i == ARRAY_SIZE(r820t_xtal_capacitor))
1228 return -EINVAL;
1229
1230 return r820t_xtal_capacitor[i][1];
1231}
1232
1233/*
1234 * r820t frontend operations and tuner attach code
1235 */
1236
1237static int r820t_init(struct dvb_frontend *fe)
1238{
1239 struct r820t_priv *priv = fe->tuner_priv;
1240 int rc, i;
1241 int xtal_cap = 0;
1242
1243 tuner_dbg("%s:\n", __func__);
1244
1245 if (fe->ops.i2c_gate_ctrl)
1246 fe->ops.i2c_gate_ctrl(fe, 1);
1247
1248 mutex_lock(&priv->lock);
1249
1250 if ((priv->cfg->rafael_chip == CHIP_R820T) ||
1251 (priv->cfg->rafael_chip == CHIP_R828S) ||
1252 (priv->cfg->rafael_chip == CHIP_R820C)) {
1253 priv->xtal_cap_sel = XTAL_HIGH_CAP_0P;
1254 } else {
1255 for (i = 0; i < 3; i++) {
1256 rc = r820t_xtal_check(priv);
1257 if (rc < 0)
1258 goto err;
1259 if (!i || rc > xtal_cap)
1260 xtal_cap = rc;
1261 }
1262 priv->xtal_cap_sel = xtal_cap;
1263 }
1264
1265 /* Initialize registers */
1266 rc = r820t_write(priv, 0x05,
1267 r820t_init_array, sizeof(r820t_init_array));
1268
1269 mutex_unlock(&priv->lock);
1270
1271 if (fe->ops.i2c_gate_ctrl)
1272 fe->ops.i2c_gate_ctrl(fe, 0);
1273
1274 return rc;
1275err:
1276 if (fe->ops.i2c_gate_ctrl)
1277 fe->ops.i2c_gate_ctrl(fe, 0);
1278
1279 tuner_dbg("%s: failed=%d\n", __func__, rc);
1280 return rc;
1281}
1282
1283static int r820t_sleep(struct dvb_frontend *fe)
1284{
1285 struct r820t_priv *priv = fe->tuner_priv;
1286 int rc;
1287
1288 tuner_dbg("%s:\n", __func__);
1289
1290 if (fe->ops.i2c_gate_ctrl)
1291 fe->ops.i2c_gate_ctrl(fe, 1);
1292
1293 mutex_lock(&priv->lock);
1294 rc = r820t_standby(priv);
1295 mutex_unlock(&priv->lock);
1296
1297 if (fe->ops.i2c_gate_ctrl)
1298 fe->ops.i2c_gate_ctrl(fe, 0);
1299
1300 tuner_dbg("%s: failed=%d\n", __func__, rc);
1301 return rc;
1302}
1303
1304static int r820t_set_analog_freq(struct dvb_frontend *fe,
1305 struct analog_parameters *p)
1306{
1307 struct r820t_priv *priv = fe->tuner_priv;
1308 unsigned bw;
1309
1310 tuner_dbg("%s called\n", __func__);
1311
1312 /* if std is not defined, choose one */
1313 if (!p->std)
1314 p->std = V4L2_STD_MN;
1315
1316 if ((p->std == V4L2_STD_PAL_M) || (p->std == V4L2_STD_NTSC))
1317 bw = 6;
1318 else
1319 bw = 8;
1320
1321 return generic_set_freq(fe, 62500l * p->frequency, bw,
1322 V4L2_TUNER_ANALOG_TV, p->std, SYS_UNDEFINED);
1323}
1324
1325static int r820t_set_params(struct dvb_frontend *fe)
1326{
1327 struct r820t_priv *priv = fe->tuner_priv;
1328 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1329 int rc;
1330 unsigned bw;
1331
1332 tuner_dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
1333 __func__, c->delivery_system, c->frequency, c->bandwidth_hz);
1334
1335 if (fe->ops.i2c_gate_ctrl)
1336 fe->ops.i2c_gate_ctrl(fe, 1);
1337
1338 bw = (c->bandwidth_hz + 500000) / 1000000;
1339 if (!bw)
1340 bw = 8;
1341
1342 rc = generic_set_freq(fe, c->frequency, bw,
1343 V4L2_TUNER_DIGITAL_TV, 0, c->delivery_system);
1344
1345 if (fe->ops.i2c_gate_ctrl)
1346 fe->ops.i2c_gate_ctrl(fe, 0);
1347
1348 if (rc)
1349 tuner_dbg("%s: failed=%d\n", __func__, rc);
1350 return rc;
1351}
1352
1353static int r820t_signal(struct dvb_frontend *fe, u16 *strength)
1354{
1355 struct r820t_priv *priv = fe->tuner_priv;
1356
1357 if (priv->has_lock)
1358 *strength = 0xffff;
1359 else
1360 *strength = 0;
1361
1362 return 0;
1363}
1364
1365static int r820t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
1366{
1367 struct r820t_priv *priv = fe->tuner_priv;
1368
1369 tuner_dbg("%s:\n", __func__);
1370
1371 *frequency = priv->int_freq;
1372
1373 return 0;
1374}
1375
1376static int r820t_release(struct dvb_frontend *fe)
1377{
1378 struct r820t_priv *priv = fe->tuner_priv;
1379
1380 tuner_dbg("%s:\n", __func__);
1381
1382 mutex_lock(&r820t_list_mutex);
1383
1384 if (priv)
1385 hybrid_tuner_release_state(priv);
1386
1387 mutex_unlock(&r820t_list_mutex);
1388
1389 fe->tuner_priv = NULL;
1390
1391 kfree(fe->tuner_priv);
1392
1393 return 0;
1394}
1395
1396static const struct dvb_tuner_ops r820t_tuner_ops = {
1397 .info = {
1398 .name = "Rafael Micro R820T",
1399 .frequency_min = 42000000,
1400 .frequency_max = 1002000000,
1401 },
1402 .init = r820t_init,
1403 .release = r820t_release,
1404 .sleep = r820t_sleep,
1405 .set_params = r820t_set_params,
1406 .set_analog_params = r820t_set_analog_freq,
1407 .get_if_frequency = r820t_get_if_frequency,
1408 .get_rf_strength = r820t_signal,
1409};
1410
1411struct dvb_frontend *r820t_attach(struct dvb_frontend *fe,
1412 struct i2c_adapter *i2c,
1413 const struct r820t_config *cfg)
1414{
1415 struct r820t_priv *priv;
1416 int rc = -ENODEV;
1417 u8 data[5];
1418 int instance;
1419
1420 mutex_lock(&r820t_list_mutex);
1421
1422 instance = hybrid_tuner_request_state(struct r820t_priv, priv,
1423 hybrid_tuner_instance_list,
1424 i2c, cfg->i2c_addr,
1425 "r820t");
1426 switch (instance) {
1427 case 0:
1428 /* memory allocation failure */
1429 goto err_no_gate;
1430 break;
1431 case 1:
1432 /* new tuner instance */
1433 priv->cfg = cfg;
1434
1435 mutex_init(&priv->lock);
1436
1437 fe->tuner_priv = priv;
1438 break;
1439 case 2:
1440 /* existing tuner instance */
1441 fe->tuner_priv = priv;
1442 break;
1443 }
1444
1445 memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops, sizeof(r820t_tuner_ops));
1446
1447 if (fe->ops.i2c_gate_ctrl)
1448 fe->ops.i2c_gate_ctrl(fe, 1);
1449
1450 /* check if the tuner is there */
1451 rc = r820_read(priv, 0x00, data, sizeof(data));
1452 if (rc < 0)
1453 goto err;
1454
1455 rc = r820t_sleep(fe);
1456 if (rc < 0)
1457 goto err;
1458
1459 tuner_info("Rafael Micro r820t successfully identified\n");
1460
1461 fe->tuner_priv = priv;
1462 memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
1463 sizeof(struct dvb_tuner_ops));
1464
1465 if (fe->ops.i2c_gate_ctrl)
1466 fe->ops.i2c_gate_ctrl(fe, 0);
1467
1468 mutex_unlock(&r820t_list_mutex);
1469
1470 return fe;
1471err:
1472 if (fe->ops.i2c_gate_ctrl)
1473 fe->ops.i2c_gate_ctrl(fe, 0);
1474
1475err_no_gate:
1476 mutex_unlock(&r820t_list_mutex);
1477
1478 tuner_info("%s: failed=%d\n", __func__, rc);
1479 r820t_release(fe);
1480 return NULL;
1481}
1482EXPORT_SYMBOL_GPL(r820t_attach);
1483
1484MODULE_DESCRIPTION("Rafael Micro r820t silicon tuner driver");
1485MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1486MODULE_LICENSE("GPL");