r820t.c revision a7dd065f4976b54d0e75d58f8e94066501fede76
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
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
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	}
978	priv->int_freq = if_khz * 1000;
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
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
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
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
1196	rc = r820t_set_tv_standard(priv, bw, type, std, delsys);
1197	if (rc < 0)
1198		goto err;
1199
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
1205	rc = r820t_set_mux(priv, lo_freq);
1206	if (rc < 0)
1207		goto err;
1208
1209	rc = r820t_set_gain_mode(priv, true, 0);
1210	if (rc < 0)
1211		goto err;
1212
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);
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
1224err:
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
1341 *
1342 * All driver locks and i2c control are only in this part of the code
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
1353	mutex_lock(&priv->lock);
1354	if (fe->ops.i2c_gate_ctrl)
1355		fe->ops.i2c_gate_ctrl(fe, 1);
1356
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
1376err:
1377	if (fe->ops.i2c_gate_ctrl)
1378		fe->ops.i2c_gate_ctrl(fe, 0);
1379	mutex_unlock(&priv->lock);
1380
1381	if (rc < 0)
1382		tuner_dbg("%s: failed=%d\n", __func__, rc);
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
1393	mutex_lock(&priv->lock);
1394	if (fe->ops.i2c_gate_ctrl)
1395		fe->ops.i2c_gate_ctrl(fe, 1);
1396
1397	rc = r820t_standby(priv);
1398
1399	if (fe->ops.i2c_gate_ctrl)
1400		fe->ops.i2c_gate_ctrl(fe, 0);
1401	mutex_unlock(&priv->lock);
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;
1412	int rc;
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
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;
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
1449	mutex_lock(&priv->lock);
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);
1462	mutex_unlock(&priv->lock);
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;
1472	int rc = 0;
1473
1474	mutex_lock(&priv->lock);
1475	if (fe->ops.i2c_gate_ctrl)
1476		fe->ops.i2c_gate_ctrl(fe, 1);
1477
1478	if (priv->has_lock) {
1479		rc = r820t_read_gain(priv);
1480		if (rc < 0)
1481			goto err;
1482
1483		/* A higher gain at LNA means a lower signal strength */
1484		*strength = (45 - rc) << 4 | 0xff;
1485	} else {
1486		*strength = 0;
1487	}
1488
1489err:
1490	if (fe->ops.i2c_gate_ctrl)
1491		fe->ops.i2c_gate_ctrl(fe, 0);
1492	mutex_unlock(&priv->lock);
1493
1494	tuner_dbg("%s: %s, gain=%d strength=%d\n",
1495		  __func__,
1496		  priv->has_lock ? "PLL locked" : "no signal",
1497		  rc, *strength);
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");
1624