aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/tuners
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common/tuners')
-rw-r--r--drivers/media/common/tuners/Kconfig7
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/max2165.c442
-rw-r--r--drivers/media/common/tuners/max2165.h48
-rw-r--r--drivers/media/common/tuners/max2165_priv.h60
-rw-r--r--drivers/media/common/tuners/mxl5005s.c5
-rw-r--r--drivers/media/common/tuners/mxl5005s.h4
-rw-r--r--drivers/media/common/tuners/mxl5007t.c2
-rw-r--r--drivers/media/common/tuners/tda18271-common.c16
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c114
-rw-r--r--drivers/media/common/tuners/tda18271-maps.c1
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h47
-rw-r--r--drivers/media/common/tuners/tda18271.h12
-rw-r--r--drivers/media/common/tuners/tda8290.c1
-rw-r--r--drivers/media/common/tuners/tda9887.c2
-rw-r--r--drivers/media/common/tuners/xc5000.c97
-rw-r--r--drivers/media/common/tuners/xc5000.h6
17 files changed, 792 insertions, 73 deletions
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 607d319ce8ed..409a4261e5b5 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -172,4 +172,11 @@ config MEDIA_TUNER_MC44S803
172 help 172 help
173 Say Y here to support the Freescale MC44S803 based tuners 173 Say Y here to support the Freescale MC44S803 based tuners
174 174
175config MEDIA_TUNER_MAX2165
176 tristate "Maxim MAX2165 silicon tuner"
177 depends on VIDEO_MEDIA && I2C
178 default m if MEDIA_TUNER_CUSTOMISE
179 help
180 A driver for the silicon tuner MAX2165 from Maxim.
181
175endif # MEDIA_TUNER_CUSTOMISE 182endif # MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 4132b2be79e5..a5438523f30d 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
23obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o 23obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
24obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o 24obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
25obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o 25obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
26obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
26 27
27EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 28EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
28EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 29EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
new file mode 100644
index 000000000000..1b486cfb8ed9
--- /dev/null
+++ b/drivers/media/common/tuners/max2165.c
@@ -0,0 +1,442 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/videodev2.h>
25#include <linux/delay.h>
26#include <linux/dvb/frontend.h>
27#include <linux/i2c.h>
28
29#include "dvb_frontend.h"
30
31#include "max2165.h"
32#include "max2165_priv.h"
33#include "tuner-i2c.h"
34
35#define dprintk(args...) \
36 do { \
37 if (debug) \
38 printk(KERN_DEBUG "max2165: " args); \
39 } while (0)
40
41static int debug;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
44
45static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
46{
47 int ret;
48 u8 buf[] = { reg, data };
49 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
50
51 msg.addr = priv->config->i2c_address;
52
53 if (debug >= 2)
54 printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
55 __func__, reg, data);
56
57 ret = i2c_transfer(priv->i2c, &msg, 1);
58
59 if (ret != 1)
60 dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
61 __func__, reg, data, ret);
62
63 return (ret != 1) ? -EIO : 0;
64}
65
66static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
67{
68 int ret;
69 u8 dev_addr = priv->config->i2c_address;
70
71 u8 b0[] = { reg };
72 u8 b1[] = { 0 };
73 struct i2c_msg msg[] = {
74 { .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 },
75 { .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 },
76 };
77
78 ret = i2c_transfer(priv->i2c, msg, 2);
79 if (ret != 2) {
80 dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
81 __func__, reg, ret);
82 return -EIO;
83 }
84
85 *p_data = b1[0];
86 if (debug >= 2)
87 printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
88 __func__, reg, b1[0]);
89 return 0;
90}
91
92static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg,
93 u8 mask, u8 data)
94{
95 int ret;
96 u8 v;
97
98 data &= mask;
99 ret = max2165_read_reg(priv, reg, &v);
100 if (ret != 0)
101 return ret;
102 v &= ~mask;
103 v |= data;
104 ret = max2165_write_reg(priv, reg, v);
105
106 return ret;
107}
108
109static int max2165_read_rom_table(struct max2165_priv *priv)
110{
111 u8 dat[3];
112 int i;
113
114 for (i = 0; i < 3; i++) {
115 max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1);
116 max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]);
117 }
118
119 priv->tf_ntch_low_cfg = dat[0] >> 4;
120 priv->tf_ntch_hi_cfg = dat[0] & 0x0F;
121 priv->tf_balun_low_ref = dat[1] & 0x0F;
122 priv->tf_balun_hi_ref = dat[1] >> 4;
123 priv->bb_filter_7mhz_cfg = dat[2] & 0x0F;
124 priv->bb_filter_8mhz_cfg = dat[2] >> 4;
125
126 dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg);
127 dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg);
128 dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref);
129 dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref);
130 dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg);
131 dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg);
132
133 return 0;
134}
135
136static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/)
137{
138 u8 v;
139
140 v = (osc / 2);
141 if (v == 2)
142 v = 0x7;
143 else
144 v -= 8;
145
146 max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v);
147
148 return 0;
149}
150
151static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
152{
153 u8 val;
154
155 if (bw == BANDWIDTH_8_MHZ)
156 val = priv->bb_filter_8mhz_cfg;
157 else
158 val = priv->bb_filter_7mhz_cfg;
159
160 max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4);
161
162 return 0;
163}
164
165int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
166{
167 u32 remainder;
168 u32 q, f = 0;
169 int i;
170
171 if (0 == divisor)
172 return -1;
173
174 q = dividend / divisor;
175 remainder = dividend - q * divisor;
176
177 for (i = 0; i < 31; i++) {
178 remainder <<= 1;
179 if (remainder >= divisor) {
180 f += 1;
181 remainder -= divisor;
182 }
183 f <<= 1;
184 }
185
186 *quotient = q;
187 *fraction = f;
188
189 return 0;
190}
191
192static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
193{
194 u8 tf;
195 u8 tf_ntch;
196 double t;
197 u32 quotient, fraction;
198
199 /* Set PLL divider according to RF frequency */
200 fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
201 &quotient, &fraction);
202
203 /* 20-bit fraction */
204 fraction >>= 12;
205
206 max2165_write_reg(priv, REG_NDIV_INT, quotient);
207 max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16);
208 max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8);
209 max2165_write_reg(priv, REG_NDIV_FRAC0, fraction);
210
211 /* Norch Filter */
212 tf_ntch = (freq < 725000000) ?
213 priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg;
214
215 /* Tracking filter balun */
216 t = priv->tf_balun_low_ref;
217 t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref)
218 * (freq / 1000 - 470000) / (780000 - 470000);
219
220 tf = t;
221 dprintk("tf = %X\n", tf);
222 tf |= tf_ntch << 4;
223
224 max2165_write_reg(priv, REG_TRACK_FILTER, tf);
225
226 return 0;
227}
228
229static void max2165_debug_status(struct max2165_priv *priv)
230{
231 u8 status, autotune;
232 u8 auto_vco_success, auto_vco_active;
233 u8 pll_locked;
234 u8 dc_offset_low, dc_offset_hi;
235 u8 signal_lv_over_threshold;
236 u8 vco, vco_sub_band, adc;
237
238 max2165_read_reg(priv, REG_STATUS, &status);
239 max2165_read_reg(priv, REG_AUTOTUNE, &autotune);
240
241 auto_vco_success = (status >> 6) & 0x01;
242 auto_vco_active = (status >> 5) & 0x01;
243 pll_locked = (status >> 4) & 0x01;
244 dc_offset_low = (status >> 3) & 0x01;
245 dc_offset_hi = (status >> 2) & 0x01;
246 signal_lv_over_threshold = status & 0x01;
247
248 vco = autotune >> 6;
249 vco_sub_band = (autotune >> 3) & 0x7;
250 adc = autotune & 0x7;
251
252 dprintk("auto VCO active: %d, auto VCO success: %d\n",
253 auto_vco_active, auto_vco_success);
254 dprintk("PLL locked: %d\n", pll_locked);
255 dprintk("DC offset low: %d, DC offset high: %d\n",
256 dc_offset_low, dc_offset_hi);
257 dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold);
258 dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc);
259}
260
261static int max2165_set_params(struct dvb_frontend *fe,
262 struct dvb_frontend_parameters *params)
263{
264 struct max2165_priv *priv = fe->tuner_priv;
265 int ret;
266
267 dprintk("%s() frequency=%d (Hz)\n", __func__, params->frequency);
268 if (fe->ops.info.type == FE_ATSC) {
269 return -EINVAL;
270 } else if (fe->ops.info.type == FE_OFDM) {
271 dprintk("%s() OFDM\n", __func__);
272 switch (params->u.ofdm.bandwidth) {
273 case BANDWIDTH_6_MHZ:
274 return -EINVAL;
275 case BANDWIDTH_7_MHZ:
276 case BANDWIDTH_8_MHZ:
277 priv->frequency = params->frequency;
278 priv->bandwidth = params->u.ofdm.bandwidth;
279 break;
280 default:
281 printk(KERN_ERR "MAX2165 bandwidth not set!\n");
282 return -EINVAL;
283 }
284 } else {
285 printk(KERN_ERR "MAX2165 modulation type not supported!\n");
286 return -EINVAL;
287 }
288
289 dprintk("%s() frequency=%d\n", __func__, priv->frequency);
290
291 if (fe->ops.i2c_gate_ctrl)
292 fe->ops.i2c_gate_ctrl(fe, 1);
293 max2165_set_bandwidth(priv, priv->bandwidth);
294 ret = max2165_set_rf(priv, priv->frequency);
295 mdelay(50);
296 max2165_debug_status(priv);
297 if (fe->ops.i2c_gate_ctrl)
298 fe->ops.i2c_gate_ctrl(fe, 0);
299
300 if (ret != 0)
301 return -EREMOTEIO;
302
303 return 0;
304}
305
306static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq)
307{
308 struct max2165_priv *priv = fe->tuner_priv;
309 dprintk("%s()\n", __func__);
310 *freq = priv->frequency;
311 return 0;
312}
313
314static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
315{
316 struct max2165_priv *priv = fe->tuner_priv;
317 dprintk("%s()\n", __func__);
318
319 *bw = priv->bandwidth;
320 return 0;
321}
322
323static int max2165_get_status(struct dvb_frontend *fe, u32 *status)
324{
325 struct max2165_priv *priv = fe->tuner_priv;
326 u16 lock_status = 0;
327
328 dprintk("%s()\n", __func__);
329
330 if (fe->ops.i2c_gate_ctrl)
331 fe->ops.i2c_gate_ctrl(fe, 1);
332
333 max2165_debug_status(priv);
334 *status = lock_status;
335
336 if (fe->ops.i2c_gate_ctrl)
337 fe->ops.i2c_gate_ctrl(fe, 0);
338
339 return 0;
340}
341
342static int max2165_sleep(struct dvb_frontend *fe)
343{
344 dprintk("%s()\n", __func__);
345 return 0;
346}
347
348static int max2165_init(struct dvb_frontend *fe)
349{
350 struct max2165_priv *priv = fe->tuner_priv;
351 dprintk("%s()\n", __func__);
352
353 if (fe->ops.i2c_gate_ctrl)
354 fe->ops.i2c_gate_ctrl(fe, 1);
355
356 /* Setup initial values */
357 /* Fractional Mode on */
358 max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18);
359 /* LNA on */
360 max2165_write_reg(priv, REG_LNA, 0x01);
361 max2165_write_reg(priv, REG_PLL_CFG, 0x7A);
362 max2165_write_reg(priv, REG_TEST, 0x08);
363 max2165_write_reg(priv, REG_SHUTDOWN, 0x40);
364 max2165_write_reg(priv, REG_VCO_CTRL, 0x84);
365 max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3);
366 max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75);
367 max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00);
368 max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00);
369
370 max2165_set_osc(priv, priv->config->osc_clk);
371
372 max2165_read_rom_table(priv);
373
374 max2165_set_bandwidth(priv, BANDWIDTH_8_MHZ);
375
376 if (fe->ops.i2c_gate_ctrl)
377 fe->ops.i2c_gate_ctrl(fe, 0);
378
379 return 0;
380}
381
382static int max2165_release(struct dvb_frontend *fe)
383{
384 struct max2165_priv *priv = fe->tuner_priv;
385 dprintk("%s()\n", __func__);
386
387 kfree(priv);
388 fe->tuner_priv = NULL;
389
390 return 0;
391}
392
393static const struct dvb_tuner_ops max2165_tuner_ops = {
394 .info = {
395 .name = "Maxim MAX2165",
396 .frequency_min = 470000000,
397 .frequency_max = 780000000,
398 .frequency_step = 50000,
399 },
400
401 .release = max2165_release,
402 .init = max2165_init,
403 .sleep = max2165_sleep,
404
405 .set_params = max2165_set_params,
406 .set_analog_params = NULL,
407 .get_frequency = max2165_get_frequency,
408 .get_bandwidth = max2165_get_bandwidth,
409 .get_status = max2165_get_status
410};
411
412struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
413 struct i2c_adapter *i2c,
414 struct max2165_config *cfg)
415{
416 struct max2165_priv *priv = NULL;
417
418 dprintk("%s(%d-%04x)\n", __func__,
419 i2c ? i2c_adapter_id(i2c) : -1,
420 cfg ? cfg->i2c_address : -1);
421
422 priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL);
423 if (priv == NULL)
424 return NULL;
425
426 memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops,
427 sizeof(struct dvb_tuner_ops));
428
429 priv->config = cfg;
430 priv->i2c = i2c;
431 fe->tuner_priv = priv;
432
433 max2165_init(fe);
434 max2165_debug_status(priv);
435
436 return fe;
437}
438EXPORT_SYMBOL(max2165_attach);
439
440MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
441MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
442MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/max2165.h b/drivers/media/common/tuners/max2165.h
new file mode 100644
index 000000000000..c063c36a93d3
--- /dev/null
+++ b/drivers/media/common/tuners/max2165.h
@@ -0,0 +1,48 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MAX2165_H__
23#define __MAX2165_H__
24
25struct dvb_frontend;
26struct i2c_adapter;
27
28struct max2165_config {
29 u8 i2c_address;
30 u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */
31};
32
33#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \
34 (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE))
35extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
36 struct i2c_adapter *i2c,
37 struct max2165_config *cfg);
38#else
39static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
40 struct i2c_adapter *i2c,
41 struct max2165_config *cfg)
42{
43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
44 return NULL;
45}
46#endif
47
48#endif
diff --git a/drivers/media/common/tuners/max2165_priv.h b/drivers/media/common/tuners/max2165_priv.h
new file mode 100644
index 000000000000..91bbe021a08d
--- /dev/null
+++ b/drivers/media/common/tuners/max2165_priv.h
@@ -0,0 +1,60 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MAX2165_PRIV_H__
23#define __MAX2165_PRIV_H__
24
25#define REG_NDIV_INT 0x00
26#define REG_NDIV_FRAC2 0x01
27#define REG_NDIV_FRAC1 0x02
28#define REG_NDIV_FRAC0 0x03
29#define REG_TRACK_FILTER 0x04
30#define REG_LNA 0x05
31#define REG_PLL_CFG 0x06
32#define REG_TEST 0x07
33#define REG_SHUTDOWN 0x08
34#define REG_VCO_CTRL 0x09
35#define REG_BASEBAND_CTRL 0x0A
36#define REG_DC_OFFSET_CTRL 0x0B
37#define REG_DC_OFFSET_DAC 0x0C
38#define REG_ROM_TABLE_ADDR 0x0D
39
40/* Read Only Registers */
41#define REG_ROM_TABLE_DATA 0x10
42#define REG_STATUS 0x11
43#define REG_AUTOTUNE 0x12
44
45struct max2165_priv {
46 struct max2165_config *config;
47 struct i2c_adapter *i2c;
48
49 u32 frequency;
50 u32 bandwidth;
51
52 u8 tf_ntch_low_cfg;
53 u8 tf_ntch_hi_cfg;
54 u8 tf_balun_low_ref;
55 u8 tf_balun_hi_ref;
56 u8 bb_filter_7mhz_cfg;
57 u8 bb_filter_8mhz_cfg;
58};
59
60#endif
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 0803dab58fff..605e28b73263 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -2789,7 +2789,10 @@ static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
2789 2789
2790 /* add for 2.6.5 Special setting for QAM */ 2790 /* add for 2.6.5 Special setting for QAM */
2791 if (state->Mod_Type == MXL_QAM) { 2791 if (state->Mod_Type == MXL_QAM) {
2792 if (state->RF_IN < 680000000) 2792 if (state->config->qam_gain != 0)
2793 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN,
2794 state->config->qam_gain);
2795 else if (state->RF_IN < 680000000)
2793 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3); 2796 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
2794 else 2797 else
2795 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2); 2798 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
index 7ac6815b30aa..fc8a1ffc53b4 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -108,6 +108,10 @@ struct mxl5005s_config {
108#define MXL_LOW_IF 1 108#define MXL_LOW_IF 1
109 u8 if_mode; 109 u8 if_mode;
110 110
111 /* Some boards need to override the built-in logic for determining
112 the gain when in QAM mode (the HVR-1600 is one such case) */
113 u8 qam_gain;
114
111 /* Stuff I don't know what to do with */ 115 /* Stuff I don't know what to do with */
112 u8 AgcMasterByte; 116 u8 AgcMasterByte;
113}; 117};
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 2d02698d4f4f..7eb1bf75cd07 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -196,7 +196,7 @@ static void copy_reg_bits(struct reg_pair_t *reg_pair1,
196 i = j = 0; 196 i = j = 0;
197 197
198 while (reg_pair1[i].reg || reg_pair1[i].val) { 198 while (reg_pair1[i].reg || reg_pair1[i].val) {
199 while (reg_pair2[j].reg || reg_pair2[j].reg) { 199 while (reg_pair2[j].reg || reg_pair2[j].val) {
200 if (reg_pair1[i].reg != reg_pair2[j].reg) { 200 if (reg_pair1[i].reg != reg_pair2[j].reg) {
201 j++; 201 j++;
202 continue; 202 continue;
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index 155c93eb75da..e1f678281a58 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -326,12 +326,24 @@ int tda18271_init_regs(struct dvb_frontend *fe)
326 regs[R_EB22] = 0x48; 326 regs[R_EB22] = 0x48;
327 regs[R_EB23] = 0xb0; 327 regs[R_EB23] = 0xb0;
328 328
329 if (priv->small_i2c) { 329 switch (priv->small_i2c) {
330 case TDA18271_08_BYTE_CHUNK_INIT:
331 tda18271_write_regs(fe, 0x00, 0x08);
332 tda18271_write_regs(fe, 0x08, 0x08);
333 tda18271_write_regs(fe, 0x10, 0x08);
334 tda18271_write_regs(fe, 0x18, 0x08);
335 tda18271_write_regs(fe, 0x20, 0x07);
336 break;
337 case TDA18271_16_BYTE_CHUNK_INIT:
330 tda18271_write_regs(fe, 0x00, 0x10); 338 tda18271_write_regs(fe, 0x00, 0x10);
331 tda18271_write_regs(fe, 0x10, 0x10); 339 tda18271_write_regs(fe, 0x10, 0x10);
332 tda18271_write_regs(fe, 0x20, 0x07); 340 tda18271_write_regs(fe, 0x20, 0x07);
333 } else 341 break;
342 case TDA18271_39_BYTE_CHUNK_INIT:
343 default:
334 tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); 344 tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
345 break;
346 }
335 347
336 /* setup agc1 gain */ 348 /* setup agc1 gain */
337 regs[R_EB17] = 0x00; 349 regs[R_EB17] = 0x00;
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 3a50ce96fcb9..b2e15456d5f3 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -256,8 +256,9 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
256 struct tda18271_priv *priv = fe->tuner_priv; 256 struct tda18271_priv *priv = fe->tuner_priv;
257 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; 257 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
258 unsigned char *regs = priv->tda18271_regs; 258 unsigned char *regs = priv->tda18271_regs;
259 int tm_current, rfcal_comp, approx, i, ret; 259 int i, ret;
260 u8 dc_over_dt, rf_tab; 260 u8 tm_current, dc_over_dt, rf_tab;
261 s32 rfcal_comp, approx;
261 262
262 /* power up */ 263 /* power up */
263 ret = tda18271_set_standby_mode(fe, 0, 0, 0); 264 ret = tda18271_set_standby_mode(fe, 0, 0, 0);
@@ -277,11 +278,11 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
277 return i; 278 return i;
278 279
279 if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) { 280 if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
280 approx = map[i].rf_a1 * 281 approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +
281 (freq / 1000 - map[i].rf1) + map[i].rf_b1 + rf_tab; 282 map[i].rf_b1 + rf_tab;
282 } else { 283 } else {
283 approx = map[i].rf_a2 * 284 approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +
284 (freq / 1000 - map[i].rf2) + map[i].rf_b2 + rf_tab; 285 map[i].rf_b2 + rf_tab;
285 } 286 }
286 287
287 if (approx < 0) 288 if (approx < 0)
@@ -292,9 +293,9 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
292 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt); 293 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
293 294
294 /* calculate temperature compensation */ 295 /* calculate temperature compensation */
295 rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000; 296 rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;
296 297
297 regs[R_EB14] = approx + rfcal_comp; 298 regs[R_EB14] = (unsigned char)(approx + rfcal_comp);
298 ret = tda18271_write_regs(fe, R_EB14, 1); 299 ret = tda18271_write_regs(fe, R_EB14, 1);
299fail: 300fail:
300 return ret; 301 return ret;
@@ -572,6 +573,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
572 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; 573 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
573 unsigned char *regs = priv->tda18271_regs; 574 unsigned char *regs = priv->tda18271_regs;
574 int bcal, rf, i; 575 int bcal, rf, i;
576 s32 divisor, dividend;
575#define RF1 0 577#define RF1 0
576#define RF2 1 578#define RF2 1
577#define RF3 2 579#define RF3 2
@@ -610,20 +612,22 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
610 switch (rf) { 612 switch (rf) {
611 case RF1: 613 case RF1:
612 map[i].rf_a1 = 0; 614 map[i].rf_a1 = 0;
613 map[i].rf_b1 = prog_cal[RF1] - prog_tab[RF1]; 615 map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]);
614 map[i].rf1 = rf_freq[RF1] / 1000; 616 map[i].rf1 = rf_freq[RF1] / 1000;
615 break; 617 break;
616 case RF2: 618 case RF2:
617 map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] - 619 dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) -
618 prog_cal[RF1] + prog_tab[RF1]) / 620 (s32)(prog_cal[RF1] + prog_tab[RF1]);
619 (s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000); 621 divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
622 map[i].rf_a1 = (dividend / divisor);
620 map[i].rf2 = rf_freq[RF2] / 1000; 623 map[i].rf2 = rf_freq[RF2] / 1000;
621 break; 624 break;
622 case RF3: 625 case RF3:
623 map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] - 626 dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) -
624 prog_cal[RF2] + prog_tab[RF2]) / 627 (s32)(prog_cal[RF2] + prog_tab[RF2]);
625 (s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000); 628 divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
626 map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2]; 629 map[i].rf_a2 = (dividend / divisor);
630 map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]);
627 map[i].rf3 = rf_freq[RF3] / 1000; 631 map[i].rf3 = rf_freq[RF3] / 1000;
628 break; 632 break;
629 default: 633 default:
@@ -1181,6 +1185,48 @@ static int tda18271_get_id(struct dvb_frontend *fe)
1181 return ret; 1185 return ret;
1182} 1186}
1183 1187
1188static int tda18271_setup_configuration(struct dvb_frontend *fe,
1189 struct tda18271_config *cfg)
1190{
1191 struct tda18271_priv *priv = fe->tuner_priv;
1192
1193 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1194 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1195 priv->config = (cfg) ? cfg->config : 0;
1196 priv->small_i2c = (cfg) ?
1197 cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;
1198 priv->output_opt = (cfg) ?
1199 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1200
1201 return 0;
1202}
1203
1204static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)
1205{
1206 /* tda18271_cal_on_startup == -1 when cal module option is unset */
1207 return ((tda18271_cal_on_startup == -1) ?
1208 /* honor configuration setting */
1209 ((cfg) && (cfg->rf_cal_on_startup)) :
1210 /* module option overrides configuration setting */
1211 (tda18271_cal_on_startup)) ? 1 : 0;
1212}
1213
1214static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
1215{
1216 struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;
1217
1218 tda18271_setup_configuration(fe, cfg);
1219
1220 if (tda18271_need_cal_on_startup(cfg))
1221 tda18271_init(fe);
1222
1223 /* override default std map with values in config struct */
1224 if ((cfg) && (cfg->std_map))
1225 tda18271_update_std_map(fe, cfg->std_map);
1226
1227 return 0;
1228}
1229
1184static struct dvb_tuner_ops tda18271_tuner_ops = { 1230static struct dvb_tuner_ops tda18271_tuner_ops = {
1185 .info = { 1231 .info = {
1186 .name = "NXP TDA18271HD", 1232 .name = "NXP TDA18271HD",
@@ -1193,6 +1239,7 @@ static struct dvb_tuner_ops tda18271_tuner_ops = {
1193 .set_params = tda18271_set_params, 1239 .set_params = tda18271_set_params,
1194 .set_analog_params = tda18271_set_analog_params, 1240 .set_analog_params = tda18271_set_analog_params,
1195 .release = tda18271_release, 1241 .release = tda18271_release,
1242 .set_config = tda18271_set_config,
1196 .get_frequency = tda18271_get_frequency, 1243 .get_frequency = tda18271_get_frequency,
1197 .get_bandwidth = tda18271_get_bandwidth, 1244 .get_bandwidth = tda18271_get_bandwidth,
1198}; 1245};
@@ -1213,33 +1260,14 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1213 case 0: 1260 case 0:
1214 goto fail; 1261 goto fail;
1215 case 1: 1262 case 1:
1216 {
1217 /* new tuner instance */ 1263 /* new tuner instance */
1218 int rf_cal_on_startup; 1264 fe->tuner_priv = priv;
1219 1265
1220 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; 1266 tda18271_setup_configuration(fe, cfg);
1221 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1222 priv->config = (cfg) ? cfg->config : 0;
1223 priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
1224 priv->output_opt = (cfg) ?
1225 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1226
1227 /* tda18271_cal_on_startup == -1 when cal
1228 * module option is unset */
1229 if (tda18271_cal_on_startup == -1) {
1230 /* honor attach-time configuration */
1231 rf_cal_on_startup =
1232 ((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
1233 } else {
1234 /* module option overrides attach configuration */
1235 rf_cal_on_startup = tda18271_cal_on_startup;
1236 }
1237 1267
1238 priv->cal_initialized = false; 1268 priv->cal_initialized = false;
1239 mutex_init(&priv->lock); 1269 mutex_init(&priv->lock);
1240 1270
1241 fe->tuner_priv = priv;
1242
1243 if (tda_fail(tda18271_get_id(fe))) 1271 if (tda_fail(tda18271_get_id(fe)))
1244 goto fail; 1272 goto fail;
1245 1273
@@ -1249,12 +1277,12 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1249 mutex_lock(&priv->lock); 1277 mutex_lock(&priv->lock);
1250 tda18271_init_regs(fe); 1278 tda18271_init_regs(fe);
1251 1279
1252 if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2)) 1280 if ((tda18271_need_cal_on_startup(cfg)) &&
1281 (priv->id == TDA18271HDC2))
1253 tda18271c2_rf_cal_init(fe); 1282 tda18271c2_rf_cal_init(fe);
1254 1283
1255 mutex_unlock(&priv->lock); 1284 mutex_unlock(&priv->lock);
1256 break; 1285 break;
1257 }
1258 default: 1286 default:
1259 /* existing tuner instance */ 1287 /* existing tuner instance */
1260 fe->tuner_priv = priv; 1288 fe->tuner_priv = priv;
@@ -1271,7 +1299,11 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1271 priv->small_i2c = cfg->small_i2c; 1299 priv->small_i2c = cfg->small_i2c;
1272 if (cfg->output_opt) 1300 if (cfg->output_opt)
1273 priv->output_opt = cfg->output_opt; 1301 priv->output_opt = cfg->output_opt;
1302 if (cfg->std_map)
1303 tda18271_update_std_map(fe, cfg->std_map);
1274 } 1304 }
1305 if (tda18271_need_cal_on_startup(cfg))
1306 tda18271_init(fe);
1275 break; 1307 break;
1276 } 1308 }
1277 1309
@@ -1298,7 +1330,7 @@ EXPORT_SYMBOL_GPL(tda18271_attach);
1298MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver"); 1330MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
1299MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); 1331MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1300MODULE_LICENSE("GPL"); 1332MODULE_LICENSE("GPL");
1301MODULE_VERSION("0.3"); 1333MODULE_VERSION("0.4");
1302 1334
1303/* 1335/*
1304 * Overrides for Emacs so that we follow Linus's tabbing style. 1336 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
index e21fdeff3ddf..e7f84c705da8 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
@@ -978,6 +978,7 @@ static struct tda18271_cid_target_map tda18271_cid_target[] = {
978int tda18271_lookup_cid_target(struct dvb_frontend *fe, 978int tda18271_lookup_cid_target(struct dvb_frontend *fe,
979 u32 *freq, u8 *cid_target, u16 *count_limit) 979 u32 *freq, u8 *cid_target, u16 *count_limit)
980{ 980{
981 struct tda18271_priv *priv = fe->tuner_priv;
981 int i = 0; 982 int i = 0;
982 983
983 while ((tda18271_cid_target[i].rfmax * 1000) < *freq) { 984 while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 2bee229acd91..9589ab0576d2 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -80,10 +80,10 @@ struct tda18271_rf_tracking_filter_cal {
80 u32 rf1; 80 u32 rf1;
81 u32 rf2; 81 u32 rf2;
82 u32 rf3; 82 u32 rf3;
83 int rf_a1; 83 s32 rf_a1;
84 int rf_b1; 84 s32 rf_b1;
85 int rf_a2; 85 s32 rf_a2;
86 int rf_b2; 86 s32 rf_b2;
87}; 87};
88 88
89enum tda18271_pll { 89enum tda18271_pll {
@@ -109,11 +109,12 @@ struct tda18271_priv {
109 enum tda18271_i2c_gate gate; 109 enum tda18271_i2c_gate gate;
110 enum tda18271_ver id; 110 enum tda18271_ver id;
111 enum tda18271_output_options output_opt; 111 enum tda18271_output_options output_opt;
112 enum tda18271_small_i2c small_i2c;
112 113
113 unsigned int config; /* interface to saa713x / tda829x */ 114 unsigned int config; /* interface to saa713x / tda829x */
114 unsigned int tm_rfcal;
115 unsigned int cal_initialized:1; 115 unsigned int cal_initialized:1;
116 unsigned int small_i2c:1; 116
117 u8 tm_rfcal;
117 118
118 struct tda18271_map_layout *maps; 119 struct tda18271_map_layout *maps;
119 struct tda18271_std_map std; 120 struct tda18271_std_map std;
@@ -135,27 +136,37 @@ extern int tda18271_debug;
135#define DBG_ADV 8 136#define DBG_ADV 8
136#define DBG_CAL 16 137#define DBG_CAL 16
137 138
138#define tda_printk(kern, fmt, arg...) \ 139#define tda_printk(st, kern, fmt, arg...) do {\
139 printk(kern "%s: " fmt, __func__, ##arg) 140 if (st) { \
140 141 struct tda18271_priv *state = st; \
141#define tda_dprintk(lvl, fmt, arg...) do {\ 142 printk(kern "%s: [%d-%04x|%s] " fmt, __func__, \
143 i2c_adapter_id(state->i2c_props.adap), \
144 state->i2c_props.addr, \
145 (state->role == TDA18271_MASTER) \
146 ? "M" : "S", ##arg); \
147 } else \
148 printk(kern "%s: " fmt, __func__, ##arg); \
149} while (0)
150
151#define tda_dprintk(st, lvl, fmt, arg...) do {\
142 if (tda18271_debug & lvl) \ 152 if (tda18271_debug & lvl) \
143 tda_printk(KERN_DEBUG, fmt, ##arg); } while (0) 153 tda_printk(st, KERN_DEBUG, fmt, ##arg); } while (0)
144 154
145#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) 155#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
146#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg) 156#define tda_warn(fmt, arg...) tda_printk(priv, KERN_WARNING, fmt, ##arg)
147#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg) 157#define tda_err(fmt, arg...) tda_printk(priv, KERN_ERR, fmt, ##arg)
148#define tda_dbg(fmt, arg...) tda_dprintk(DBG_INFO, fmt, ##arg) 158#define tda_dbg(fmt, arg...) tda_dprintk(priv, DBG_INFO, fmt, ##arg)
149#define tda_map(fmt, arg...) tda_dprintk(DBG_MAP, fmt, ##arg) 159#define tda_map(fmt, arg...) tda_dprintk(priv, DBG_MAP, fmt, ##arg)
150#define tda_reg(fmt, arg...) tda_dprintk(DBG_REG, fmt, ##arg) 160#define tda_reg(fmt, arg...) tda_dprintk(priv, DBG_REG, fmt, ##arg)
151#define tda_cal(fmt, arg...) tda_dprintk(DBG_CAL, fmt, ##arg) 161#define tda_cal(fmt, arg...) tda_dprintk(priv, DBG_CAL, fmt, ##arg)
152 162
153#define tda_fail(ret) \ 163#define tda_fail(ret) \
154({ \ 164({ \
155 int __ret; \ 165 int __ret; \
156 __ret = (ret < 0); \ 166 __ret = (ret < 0); \
157 if (__ret) \ 167 if (__ret) \
158 tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\ 168 tda_printk(priv, KERN_ERR, \
169 "error %d on line %d\n", ret, __LINE__); \
159 __ret; \ 170 __ret; \
160}) 171})
161 172
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 323f2912128d..d7fcc36dc6e6 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -78,6 +78,12 @@ enum tda18271_output_options {
78 TDA18271_OUTPUT_XT_OFF = 2, 78 TDA18271_OUTPUT_XT_OFF = 2,
79}; 79};
80 80
81enum tda18271_small_i2c {
82 TDA18271_39_BYTE_CHUNK_INIT = 0,
83 TDA18271_16_BYTE_CHUNK_INIT = 1,
84 TDA18271_08_BYTE_CHUNK_INIT = 2,
85};
86
81struct tda18271_config { 87struct tda18271_config {
82 /* override default if freq / std settings (optional) */ 88 /* override default if freq / std settings (optional) */
83 struct tda18271_std_map *std_map; 89 struct tda18271_std_map *std_map;
@@ -91,12 +97,12 @@ struct tda18271_config {
91 /* output options that can be disabled */ 97 /* output options that can be disabled */
92 enum tda18271_output_options output_opt; 98 enum tda18271_output_options output_opt;
93 99
100 /* some i2c providers cant write all 39 registers at once */
101 enum tda18271_small_i2c small_i2c;
102
94 /* force rf tracking filter calibration on startup */ 103 /* force rf tracking filter calibration on startup */
95 unsigned int rf_cal_on_startup:1; 104 unsigned int rf_cal_on_startup:1;
96 105
97 /* some i2c providers cant write all 39 registers at once */
98 unsigned int small_i2c:1;
99
100 /* interface to saa713x / tda829x */ 106 /* interface to saa713x / tda829x */
101 unsigned int config; 107 unsigned int config;
102}; 108};
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 064d14c8d7b2..c190b0dedee4 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -33,6 +33,7 @@ module_param(debug, int, 0644);
33MODULE_PARM_DESC(debug, "enable verbose debug messages"); 33MODULE_PARM_DESC(debug, "enable verbose debug messages");
34 34
35static int deemphasis_50; 35static int deemphasis_50;
36module_param(deemphasis_50, int, 0644);
36MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis"); 37MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
37 38
38/* ---------------------------------------------------------------------- */ 39/* ---------------------------------------------------------------------- */
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index 544cdbe88a6c..a71c100c95df 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -463,7 +463,7 @@ static int tda9887_set_insmod(struct dvb_frontend *fe)
463 buf[1] &= ~cQSS; 463 buf[1] &= ~cQSS;
464 } 464 }
465 465
466 if (adjust >= 0x00 && adjust < 0x20) { 466 if (adjust < 0x20) {
467 buf[2] &= ~cTopMask; 467 buf[2] &= ~cTopMask;
468 buf[2] |= adjust; 468 buf[2] |= adjust;
469 } 469 }
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index f4ffcdc9b848..432003dded7c 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -61,6 +61,7 @@ struct xc5000_priv {
61 u32 bandwidth; 61 u32 bandwidth;
62 u8 video_standard; 62 u8 video_standard;
63 u8 rf_mode; 63 u8 rf_mode;
64 u8 radio_input;
64}; 65};
65 66
66/* Misc Defines */ 67/* Misc Defines */
@@ -632,8 +633,12 @@ static int xc5000_set_params(struct dvb_frontend *fe,
632 struct xc5000_priv *priv = fe->tuner_priv; 633 struct xc5000_priv *priv = fe->tuner_priv;
633 int ret; 634 int ret;
634 635
635 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) 636 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
636 xc_load_fw_and_init_tuner(fe); 637 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
638 dprintk(1, "Unable to load firmware and init tuner\n");
639 return -EINVAL;
640 }
641 }
637 642
638 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); 643 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
639 644
@@ -739,15 +744,12 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
739 return ret; 744 return ret;
740} 745}
741 746
742static int xc5000_set_analog_params(struct dvb_frontend *fe, 747static int xc5000_set_tv_freq(struct dvb_frontend *fe,
743 struct analog_parameters *params) 748 struct analog_parameters *params)
744{ 749{
745 struct xc5000_priv *priv = fe->tuner_priv; 750 struct xc5000_priv *priv = fe->tuner_priv;
746 int ret; 751 int ret;
747 752
748 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
749 xc_load_fw_and_init_tuner(fe);
750
751 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", 753 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
752 __func__, params->frequency); 754 __func__, params->frequency);
753 755
@@ -827,6 +829,86 @@ tune_channel:
827 return 0; 829 return 0;
828} 830}
829 831
832static int xc5000_set_radio_freq(struct dvb_frontend *fe,
833 struct analog_parameters *params)
834{
835 struct xc5000_priv *priv = fe->tuner_priv;
836 int ret = -EINVAL;
837 u8 radio_input;
838
839 dprintk(1, "%s() frequency=%d (in units of khz)\n",
840 __func__, params->frequency);
841
842 if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
843 dprintk(1, "%s() radio input not configured\n", __func__);
844 return -EINVAL;
845 }
846
847 if (priv->radio_input == XC5000_RADIO_FM1)
848 radio_input = FM_Radio_INPUT1;
849 else if (priv->radio_input == XC5000_RADIO_FM2)
850 radio_input = FM_Radio_INPUT2;
851 else {
852 dprintk(1, "%s() unknown radio input %d\n", __func__,
853 priv->radio_input);
854 return -EINVAL;
855 }
856
857 priv->freq_hz = params->frequency * 125 / 2;
858
859 priv->rf_mode = XC_RF_MODE_AIR;
860
861 ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
862 XC5000_Standard[radio_input].AudioMode);
863
864 if (ret != XC_RESULT_SUCCESS) {
865 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
866 return -EREMOTEIO;
867 }
868
869 ret = xc_SetSignalSource(priv, priv->rf_mode);
870 if (ret != XC_RESULT_SUCCESS) {
871 printk(KERN_ERR
872 "xc5000: xc_SetSignalSource(%d) failed\n",
873 priv->rf_mode);
874 return -EREMOTEIO;
875 }
876
877 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
878
879 return 0;
880}
881
882static int xc5000_set_analog_params(struct dvb_frontend *fe,
883 struct analog_parameters *params)
884{
885 struct xc5000_priv *priv = fe->tuner_priv;
886 int ret = -EINVAL;
887
888 if (priv->i2c_props.adap == NULL)
889 return -EINVAL;
890
891 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
892 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
893 dprintk(1, "Unable to load firmware and init tuner\n");
894 return -EINVAL;
895 }
896 }
897
898 switch (params->mode) {
899 case V4L2_TUNER_RADIO:
900 ret = xc5000_set_radio_freq(fe, params);
901 break;
902 case V4L2_TUNER_ANALOG_TV:
903 case V4L2_TUNER_DIGITAL_TV:
904 ret = xc5000_set_tv_freq(fe, params);
905 break;
906 }
907
908 return ret;
909}
910
911
830static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) 912static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
831{ 913{
832 struct xc5000_priv *priv = fe->tuner_priv; 914 struct xc5000_priv *priv = fe->tuner_priv;
@@ -1000,6 +1082,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
1000 priv->if_khz = cfg->if_khz; 1082 priv->if_khz = cfg->if_khz;
1001 } 1083 }
1002 1084
1085 if (priv->radio_input == 0)
1086 priv->radio_input = cfg->radio_input;
1087
1003 /* Check if firmware has been loaded. It is possible that another 1088 /* Check if firmware has been loaded. It is possible that another
1004 instance of the driver has loaded the firmware. 1089 instance of the driver has loaded the firmware.
1005 */ 1090 */
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index f4c146698a00..e6d7236c9ea1 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -30,11 +30,17 @@ struct i2c_adapter;
30struct xc5000_config { 30struct xc5000_config {
31 u8 i2c_address; 31 u8 i2c_address;
32 u32 if_khz; 32 u32 if_khz;
33 u8 radio_input;
33}; 34};
34 35
35/* xc5000 callback command */ 36/* xc5000 callback command */
36#define XC5000_TUNER_RESET 0 37#define XC5000_TUNER_RESET 0
37 38
39/* Possible Radio inputs */
40#define XC5000_RADIO_NOT_CONFIGURED 0
41#define XC5000_RADIO_FM1 1
42#define XC5000_RADIO_FM2 2
43
38/* For each bridge framework, when it attaches either analog or digital, 44/* For each bridge framework, when it attaches either analog or digital,
39 * it has to store a reference back to its _core equivalent structure, 45 * it has to store a reference back to its _core equivalent structure,
40 * so that it can service the hardware by steering gpio's etc. 46 * so that it can service the hardware by steering gpio's etc.