Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / media / video / cx88 / cx88-dvb.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 *
3 * device driver for Conexant 2388x based TV cards
4 * MPEG Transport Stream (DVB) routines
5 *
fc40b261 6 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
1da177e4
LT
7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/device.h>
27#include <linux/fs.h>
28#include <linux/kthread.h>
29#include <linux/file.h>
30#include <linux/suspend.h>
31
1da177e4
LT
32#include "cx88.h"
33#include "dvb-pll.h"
5e453dc7 34#include <media/v4l2-common.h>
41ef7c1e 35
1f10c7af
AQ
36#include "mt352.h"
37#include "mt352_priv.h"
ecf854df 38#include "cx88-vp3054-i2c.h"
1f10c7af
AQ
39#include "zl10353.h"
40#include "cx22702.h"
41#include "or51132.h"
42#include "lgdt330x.h"
60464da8
ST
43#include "s5h1409.h"
44#include "xc5000.h"
1f10c7af
AQ
45#include "nxt200x.h"
46#include "cx24123.h"
cd20ca9f 47#include "isl6421.h"
0df31f83 48#include "tuner-simple.h"
827855d3 49#include "tda9887.h"
d893d5dc 50#include "s5h1411.h"
e4aab64c
IL
51#include "stv0299.h"
52#include "z0194a.h"
53#include "stv0288.h"
54#include "stb6000.h"
5bd1b663 55#include "cx24116.h"
b699c271
IL
56#include "stv0900.h"
57#include "stb6100.h"
58#include "stb6100_proc.h"
111ac84a 59#include "mb86a16.h"
0cb73639 60#include "ds3000.h"
1da177e4
LT
61
62MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
63MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
64MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
65MODULE_LICENSE("GPL");
66
ff699e6b 67static unsigned int debug;
1da177e4
LT
68module_param(debug, int, 0644);
69MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
70
44c6e2a7
AWC
71static unsigned int dvb_buf_tscnt = 32;
72module_param(dvb_buf_tscnt, int, 0644);
73MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
74
78e92006
JG
75DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
76
1da177e4 77#define dprintk(level,fmt, arg...) if (debug >= level) \
6c5be74c 78 printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg)
1da177e4
LT
79
80/* ------------------------------------------------------------------ */
81
82static int dvb_buf_setup(struct videobuf_queue *q,
83 unsigned int *count, unsigned int *size)
84{
85 struct cx8802_dev *dev = q->priv_data;
86
87 dev->ts_packet_size = 188 * 4;
44c6e2a7 88 dev->ts_packet_count = dvb_buf_tscnt;
1da177e4
LT
89
90 *size = dev->ts_packet_size * dev->ts_packet_count;
44c6e2a7 91 *count = dvb_buf_tscnt;
1da177e4
LT
92 return 0;
93}
94
4a390558
MK
95static int dvb_buf_prepare(struct videobuf_queue *q,
96 struct videobuf_buffer *vb, enum v4l2_field field)
1da177e4
LT
97{
98 struct cx8802_dev *dev = q->priv_data;
c7b0ac05 99 return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
1da177e4
LT
100}
101
102static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
103{
104 struct cx8802_dev *dev = q->priv_data;
105 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
106}
107
4a390558
MK
108static void dvb_buf_release(struct videobuf_queue *q,
109 struct videobuf_buffer *vb)
1da177e4 110{
c7b0ac05 111 cx88_free_buffer(q, (struct cx88_buffer*)vb);
1da177e4
LT
112}
113
2e4e98e7 114static const struct videobuf_queue_ops dvb_qops = {
1da177e4
LT
115 .buf_setup = dvb_buf_setup,
116 .buf_prepare = dvb_buf_prepare,
117 .buf_queue = dvb_buf_queue,
118 .buf_release = dvb_buf_release,
119};
120
121/* ------------------------------------------------------------------ */
22f3f17d
MK
122
123static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
124{
125 struct cx8802_dev *dev= fe->dvb->priv;
126 struct cx8802_driver *drv = NULL;
127 int ret = 0;
363c35fc
ST
128 int fe_id;
129
130 fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
131 if (!fe_id) {
2af03eea 132 printk(KERN_ERR "%s() No frontend found\n", __func__);
363c35fc
ST
133 return -EINVAL;
134 }
135
8a317a87 136 mutex_lock(&dev->core->lock);
22f3f17d
MK
137 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
138 if (drv) {
363c35fc
ST
139 if (acquire){
140 dev->frontends.active_fe_id = fe_id;
22f3f17d 141 ret = drv->request_acquire(drv);
363c35fc 142 } else {
22f3f17d 143 ret = drv->request_release(drv);
363c35fc
ST
144 dev->frontends.active_fe_id = 0;
145 }
22f3f17d 146 }
1fe70e96 147 mutex_unlock(&dev->core->lock);
22f3f17d
MK
148
149 return ret;
150}
151
e32fadc4
MCC
152static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
153{
154 struct videobuf_dvb_frontends *f;
155 struct videobuf_dvb_frontend *fe;
156
157 if (!core->dvbdev)
158 return;
159
160 f = &core->dvbdev->frontends;
161
162 if (!f)
163 return;
164
165 if (f->gate <= 1) /* undefined or fe0 */
166 fe = videobuf_dvb_get_frontend(f, 1);
167 else
168 fe = videobuf_dvb_get_frontend(f, f->gate);
169
170 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
171 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
172}
173
22f3f17d
MK
174/* ------------------------------------------------------------------ */
175
3d7d027a 176static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
1da177e4 177{
2e4e98e7 178 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
179 static const u8 reset [] = { RESET, 0x80 };
180 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
181 static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
182 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
183 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
1da177e4
LT
184
185 mt352_write(fe, clock_config, sizeof(clock_config));
186 udelay(200);
187 mt352_write(fe, reset, sizeof(reset));
188 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
189
190 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
191 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
192 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
193 return 0;
194}
195
43eabb4e
CP
196static int dvico_dual_demod_init(struct dvb_frontend *fe)
197{
2e4e98e7 198 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 };
199 static const u8 reset [] = { RESET, 0x80 };
200 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
201 static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
202 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
203 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
43eabb4e
CP
204
205 mt352_write(fe, clock_config, sizeof(clock_config));
206 udelay(200);
207 mt352_write(fe, reset, sizeof(reset));
208 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
209
210 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
211 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
212 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
213
214 return 0;
215}
216
1da177e4
LT
217static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
218{
2e4e98e7 219 static const u8 clock_config [] = { 0x89, 0x38, 0x39 };
220 static const u8 reset [] = { 0x50, 0x80 };
221 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
222 static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
f2421ca3 223 0x00, 0xFF, 0x00, 0x40, 0x40 };
2e4e98e7 224 static const u8 dntv_extra[] = { 0xB5, 0x7A };
225 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
1da177e4
LT
226
227 mt352_write(fe, clock_config, sizeof(clock_config));
228 udelay(2000);
229 mt352_write(fe, reset, sizeof(reset));
230 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
231
232 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
233 udelay(2000);
234 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
235 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
236
237 return 0;
238}
239
2e4e98e7 240static const struct mt352_config dvico_fusionhdtv = {
f7b54b10 241 .demod_address = 0x0f,
3d7d027a 242 .demod_init = dvico_fusionhdtv_demod_init,
1da177e4
LT
243};
244
2e4e98e7 245static const struct mt352_config dntv_live_dvbt_config = {
1da177e4
LT
246 .demod_address = 0x0f,
247 .demod_init = dntv_live_dvbt_demod_init,
1da177e4 248};
fc40b261 249
2e4e98e7 250static const struct mt352_config dvico_fusionhdtv_dual = {
f7b54b10 251 .demod_address = 0x0f,
43eabb4e 252 .demod_init = dvico_dual_demod_init,
43eabb4e
CP
253};
254
2e4e98e7 255static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
70101a27
SW
256 .demod_address = (0x1e >> 1),
257 .no_tuner = 1,
258 .if2 = 45600,
259};
260
111ac84a
SI
261static struct mb86a16_config twinhan_vp1027 = {
262 .demod_address = 0x08,
263};
264
ecf854df 265#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
3d7d027a
CP
266static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
267{
2e4e98e7 268 static const u8 clock_config [] = { 0x89, 0x38, 0x38 };
269 static const u8 reset [] = { 0x50, 0x80 };
270 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
271 static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
3d7d027a 272 0x00, 0xFF, 0x00, 0x40, 0x40 };
2e4e98e7 273 static const u8 dntv_extra[] = { 0xB5, 0x7A };
274 static const u8 capt_range_cfg[] = { 0x75, 0x32 };
3d7d027a
CP
275
276 mt352_write(fe, clock_config, sizeof(clock_config));
277 udelay(2000);
278 mt352_write(fe, reset, sizeof(reset));
279 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
280
281 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
282 udelay(2000);
283 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
284 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
285
286 return 0;
287}
288
2e4e98e7 289static const struct mt352_config dntv_live_dvbt_pro_config = {
fc40b261
CP
290 .demod_address = 0x0f,
291 .no_tuner = 1,
3d7d027a 292 .demod_init = dntv_live_dvbt_pro_demod_init,
fc40b261
CP
293};
294#endif
1da177e4 295
2e4e98e7 296static const struct zl10353_config dvico_fusionhdtv_hybrid = {
f7b54b10 297 .demod_address = 0x0f,
f54376e2 298 .no_tuner = 1,
780dfef3
CP
299};
300
2e4e98e7 301static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
b3fb91d2
CP
302 .demod_address = 0x0f,
303 .if2 = 45600,
304 .no_tuner = 1,
305};
306
2e4e98e7 307static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
b3fb91d2
CP
308 .demod_address = 0x0f,
309 .if2 = 4560,
310 .no_tuner = 1,
311 .demod_init = dvico_fusionhdtv_demod_init,
312};
313
2e4e98e7 314static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
f7b54b10 315 .demod_address = 0x0f,
780dfef3 316};
780dfef3 317
2e4e98e7 318static const struct cx22702_config connexant_refboard_config = {
1da177e4 319 .demod_address = 0x43,
38d84c3b 320 .output_mode = CX22702_SERIAL_OUTPUT,
1da177e4
LT
321};
322
2e4e98e7 323static const struct cx22702_config hauppauge_hvr_config = {
aa481a65
ST
324 .demod_address = 0x63,
325 .output_mode = CX22702_SERIAL_OUTPUT,
326};
1da177e4 327
4a390558 328static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured)
1da177e4
LT
329{
330 struct cx8802_dev *dev= fe->dvb->priv;
331 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
332 return 0;
333}
334
2e4e98e7 335static const struct or51132_config pchdtv_hd3000 = {
f7b54b10
MK
336 .demod_address = 0x15,
337 .set_ts_params = or51132_set_ts_param,
1da177e4 338};
1da177e4 339
6ddcc919 340static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
0ccef6db
MK
341{
342 struct cx8802_dev *dev= fe->dvb->priv;
343 struct cx88_core *core = dev->core;
344
32d83efc 345 dprintk(1, "%s: index = %d\n", __func__, index);
0ccef6db
MK
346 if (index == 0)
347 cx_clear(MO_GP0_IO, 8);
348 else
349 cx_set(MO_GP0_IO, 8);
350 return 0;
351}
352
6ddcc919 353static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
f1798495
MK
354{
355 struct cx8802_dev *dev= fe->dvb->priv;
356 if (is_punctured)
357 dev->ts_gen_cntrl |= 0x04;
358 else
359 dev->ts_gen_cntrl &= ~0x04;
360 return 0;
361}
362
6ddcc919 363static struct lgdt330x_config fusionhdtv_3_gold = {
f7b54b10
MK
364 .demod_address = 0x0e,
365 .demod_chip = LGDT3302,
366 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
367 .set_ts_params = lgdt330x_set_ts_param,
0d723c09 368};
e52e98a7 369
2e4e98e7 370static const struct lgdt330x_config fusionhdtv_5_gold = {
f7b54b10
MK
371 .demod_address = 0x0e,
372 .demod_chip = LGDT3303,
373 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
374 .set_ts_params = lgdt330x_set_ts_param,
e52e98a7 375};
da215d22 376
2e4e98e7 377static const struct lgdt330x_config pchdtv_hd5500 = {
f7b54b10
MK
378 .demod_address = 0x59,
379 .demod_chip = LGDT3303,
380 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
381 .set_ts_params = lgdt330x_set_ts_param,
da215d22 382};
f1798495 383
4a390558 384static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
fde6d31e
KL
385{
386 struct cx8802_dev *dev= fe->dvb->priv;
387 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
388 return 0;
389}
390
2e4e98e7 391static const struct nxt200x_config ati_hdtvwonder = {
f7b54b10 392 .demod_address = 0x0a,
f7b54b10 393 .set_ts_params = nxt200x_set_ts_param,
fde6d31e 394};
fde6d31e 395
0fa14aa6
ST
396static int cx24123_set_ts_param(struct dvb_frontend* fe,
397 int is_punctured)
398{
399 struct cx8802_dev *dev= fe->dvb->priv;
f7b54b10 400 dev->ts_gen_cntrl = 0x02;
0fa14aa6
ST
401 return 0;
402}
403
f7b54b10
MK
404static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe,
405 fe_sec_voltage_t voltage)
0e0351e3
VC
406{
407 struct cx8802_dev *dev= fe->dvb->priv;
408 struct cx88_core *core = dev->core;
409
4a390558 410 if (voltage == SEC_VOLTAGE_OFF)
f7b54b10 411 cx_write(MO_GP0_IO, 0x000006fb);
4a390558 412 else
cd20ca9f 413 cx_write(MO_GP0_IO, 0x000006f9);
cd20ca9f
AQ
414
415 if (core->prev_set_voltage)
416 return core->prev_set_voltage(fe, voltage);
417 return 0;
0e0351e3
VC
418}
419
f7b54b10
MK
420static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
421 fe_sec_voltage_t voltage)
c02a34f4
SA
422{
423 struct cx8802_dev *dev= fe->dvb->priv;
424 struct cx88_core *core = dev->core;
425
426 if (voltage == SEC_VOLTAGE_OFF) {
427 dprintk(1,"LNB Voltage OFF\n");
428 cx_write(MO_GP0_IO, 0x0000efff);
429 }
430
431 if (core->prev_set_voltage)
432 return core->prev_set_voltage(fe, voltage);
433 return 0;
434}
435
af832623
IL
436static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
437 fe_sec_voltage_t voltage)
438{
439 struct cx8802_dev *dev= fe->dvb->priv;
440 struct cx88_core *core = dev->core;
441
ad5f74c0 442 cx_set(MO_GP0_IO, 0x6040);
af832623 443 switch (voltage) {
111ac84a
SI
444 case SEC_VOLTAGE_13:
445 cx_clear(MO_GP0_IO, 0x20);
446 break;
447 case SEC_VOLTAGE_18:
448 cx_set(MO_GP0_IO, 0x20);
449 break;
450 case SEC_VOLTAGE_OFF:
451 cx_clear(MO_GP0_IO, 0x20);
452 break;
453 }
454
455 if (core->prev_set_voltage)
456 return core->prev_set_voltage(fe, voltage);
457 return 0;
458}
459
460static int vp1027_set_voltage(struct dvb_frontend *fe,
461 fe_sec_voltage_t voltage)
462{
463 struct cx8802_dev *dev = fe->dvb->priv;
464 struct cx88_core *core = dev->core;
465
466 switch (voltage) {
467 case SEC_VOLTAGE_13:
468 dprintk(1, "LNB SEC Voltage=13\n");
469 cx_write(MO_GP0_IO, 0x00001220);
470 break;
471 case SEC_VOLTAGE_18:
472 dprintk(1, "LNB SEC Voltage=18\n");
473 cx_write(MO_GP0_IO, 0x00001222);
474 break;
475 case SEC_VOLTAGE_OFF:
476 dprintk(1, "LNB Voltage OFF\n");
477 cx_write(MO_GP0_IO, 0x00001230);
478 break;
af832623
IL
479 }
480
481 if (core->prev_set_voltage)
482 return core->prev_set_voltage(fe, voltage);
483 return 0;
484}
485
2e4e98e7 486static const struct cx24123_config geniatech_dvbs_config = {
f7b54b10
MK
487 .demod_address = 0x55,
488 .set_ts_params = cx24123_set_ts_param,
c02a34f4
SA
489};
490
2e4e98e7 491static const struct cx24123_config hauppauge_novas_config = {
f7b54b10
MK
492 .demod_address = 0x55,
493 .set_ts_params = cx24123_set_ts_param,
0e0351e3
VC
494};
495
2e4e98e7 496static const struct cx24123_config kworld_dvbs_100_config = {
f7b54b10
MK
497 .demod_address = 0x15,
498 .set_ts_params = cx24123_set_ts_param,
ef76856d 499 .lnb_polarity = 1,
0fa14aa6 500};
0fa14aa6 501
2e4e98e7 502static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
60464da8
ST
503 .demod_address = 0x32 >> 1,
504 .output_mode = S5H1409_PARALLEL_OUTPUT,
505 .gpio = S5H1409_GPIO_ON,
506 .qam_if = 44000,
507 .inversion = S5H1409_INVERSION_OFF,
508 .status_mode = S5H1409_DEMODLOCKING,
4917019d 509 .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
60464da8
ST
510};
511
2e4e98e7 512static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
5c00fac0
ST
513 .demod_address = 0x32 >> 1,
514 .output_mode = S5H1409_SERIAL_OUTPUT,
515 .gpio = S5H1409_GPIO_OFF,
516 .inversion = S5H1409_INVERSION_OFF,
517 .status_mode = S5H1409_DEMODLOCKING,
518 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
519};
520
2e4e98e7 521static const struct s5h1409_config kworld_atsc_120_config = {
99e09eac 522 .demod_address = 0x32 >> 1,
99e09eac
MCC
523 .output_mode = S5H1409_SERIAL_OUTPUT,
524 .gpio = S5H1409_GPIO_OFF,
525 .inversion = S5H1409_INVERSION_OFF,
526 .status_mode = S5H1409_DEMODLOCKING,
527 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
528};
529
2e4e98e7 530static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
60464da8
ST
531 .i2c_address = 0x64,
532 .if_khz = 5380,
60464da8
ST
533};
534
2e4e98e7 535static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
3f6014fc
SV
536 .demod_address = (0x1e >> 1),
537 .no_tuner = 1,
538 .if2 = 45600,
539};
540
2e4e98e7 541static const struct zl10353_config cx88_geniatech_x8000_mt = {
57069349
MCC
542 .demod_address = (0x1e >> 1),
543 .no_tuner = 1,
544 .disable_i2c_gate_ctrl = 1,
9507901e
MCC
545};
546
2e4e98e7 547static const struct s5h1411_config dvico_fusionhdtv7_config = {
d893d5dc
ST
548 .output_mode = S5H1411_SERIAL_OUTPUT,
549 .gpio = S5H1411_GPIO_ON,
550 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
551 .qam_if = S5H1411_IF_44000,
552 .vsb_if = S5H1411_IF_44000,
553 .inversion = S5H1411_INVERSION_OFF,
554 .status_mode = S5H1411_DEMODLOCKING
555};
556
2e4e98e7 557static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
d893d5dc
ST
558 .i2c_address = 0xc2 >> 1,
559 .if_khz = 5380,
d893d5dc
ST
560};
561
23fb348d
MCC
562static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
563{
564 struct dvb_frontend *fe;
363c35fc 565 struct videobuf_dvb_frontend *fe0 = NULL;
99e09eac 566 struct xc2028_ctrl ctl;
23fb348d
MCC
567 struct xc2028_config cfg = {
568 .i2c_adap = &dev->core->i2c_adap,
569 .i2c_addr = addr,
99e09eac 570 .ctrl = &ctl,
23fb348d
MCC
571 };
572
92abe9ee 573 /* Get the first frontend */
363c35fc
ST
574 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
575 if (!fe0)
576 return -EINVAL;
577
578 if (!fe0->dvb.frontend) {
ddd5441d
MCC
579 printk(KERN_ERR "%s/2: dvb frontend not attached. "
580 "Can't attach xc3028\n",
581 dev->core->name);
582 return -EINVAL;
583 }
584
99e09eac
MCC
585 /*
586 * Some xc3028 devices may be hidden by an I2C gate. This is known
587 * to happen with some s5h1409-based devices.
588 * Now that I2C gate is open, sets up xc3028 configuration
589 */
590 cx88_setup_xc3028(dev->core, &ctl);
591
363c35fc 592 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
23fb348d
MCC
593 if (!fe) {
594 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
595 dev->core->name);
363c35fc
ST
596 dvb_frontend_detach(fe0->dvb.frontend);
597 dvb_unregister_frontend(fe0->dvb.frontend);
598 fe0->dvb.frontend = NULL;
23fb348d
MCC
599 return -EINVAL;
600 }
601
602 printk(KERN_INFO "%s/2: xc3028 attached\n",
603 dev->core->name);
604
605 return 0;
606}
9507901e 607
5bd1b663
ST
608static int cx24116_set_ts_param(struct dvb_frontend *fe,
609 int is_punctured)
610{
611 struct cx8802_dev *dev = fe->dvb->priv;
612 dev->ts_gen_cntrl = 0x2;
613
614 return 0;
615}
616
b699c271
IL
617static int stv0900_set_ts_param(struct dvb_frontend *fe,
618 int is_punctured)
619{
620 struct cx8802_dev *dev = fe->dvb->priv;
621 dev->ts_gen_cntrl = 0;
622
623 return 0;
624}
625
5bd1b663
ST
626static int cx24116_reset_device(struct dvb_frontend *fe)
627{
628 struct cx8802_dev *dev = fe->dvb->priv;
629 struct cx88_core *core = dev->core;
630
631 /* Reset the part */
363c35fc 632 /* Put the cx24116 into reset */
5bd1b663
ST
633 cx_write(MO_SRST_IO, 0);
634 msleep(10);
363c35fc 635 /* Take the cx24116 out of reset */
5bd1b663
ST
636 cx_write(MO_SRST_IO, 1);
637 msleep(10);
638
639 return 0;
640}
641
2e4e98e7 642static const struct cx24116_config hauppauge_hvr4000_config = {
5bd1b663
ST
643 .demod_address = 0x05,
644 .set_ts_params = cx24116_set_ts_param,
645 .reset_device = cx24116_reset_device,
646};
647
2e4e98e7 648static const struct cx24116_config tevii_s460_config = {
af832623
IL
649 .demod_address = 0x55,
650 .set_ts_params = cx24116_set_ts_param,
651 .reset_device = cx24116_reset_device,
652};
653
0cb73639
IL
654static int ds3000_set_ts_param(struct dvb_frontend *fe,
655 int is_punctured)
656{
657 struct cx8802_dev *dev = fe->dvb->priv;
658 dev->ts_gen_cntrl = 4;
659
660 return 0;
661}
662
663static struct ds3000_config tevii_ds3000_config = {
664 .demod_address = 0x68,
665 .set_ts_params = ds3000_set_ts_param,
666};
667
2e4e98e7 668static const struct stv0900_config prof_7301_stv0900_config = {
b699c271
IL
669 .demod_address = 0x6a,
670/* demod_mode = 0,*/
671 .xtal = 27000000,
672 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
673 .diseqc_mode = 2,/* 2/3 PWM */
674 .tun1_maddress = 0,/* 0x60 */
675 .tun1_adc = 0,/* 2 Vpp */
676 .path1_mode = 3,
677 .set_ts_params = stv0900_set_ts_param,
678};
679
2e4e98e7 680static const struct stb6100_config prof_7301_stb6100_config = {
b699c271
IL
681 .tuner_address = 0x60,
682 .refclock = 27000000,
683};
684
2e4e98e7 685static const struct stv0299_config tevii_tuner_sharp_config = {
e4aab64c 686 .demod_address = 0x68,
d4305c68 687 .inittab = sharp_z0194a_inittab,
e4aab64c
IL
688 .mclk = 88000000UL,
689 .invert = 1,
690 .skip_reinit = 0,
691 .lock_output = 1,
692 .volt13_op0_op1 = STV0299_VOLT13_OP1,
693 .min_delay_ms = 100,
d4305c68 694 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
e4aab64c
IL
695 .set_ts_params = cx24116_set_ts_param,
696};
697
2e4e98e7 698static const struct stv0288_config tevii_tuner_earda_config = {
e4aab64c
IL
699 .demod_address = 0x68,
700 .min_delay_ms = 100,
701 .set_ts_params = cx24116_set_ts_param,
702};
703
6e0e12f1 704static int cx8802_alloc_frontends(struct cx8802_dev *dev)
1da177e4 705{
0590d91c 706 struct cx88_core *core = dev->core;
6e0e12f1 707 struct videobuf_dvb_frontend *fe = NULL;
e32fadc4 708 int i;
0590d91c 709
e32fadc4
MCC
710 mutex_init(&dev->frontends.lock);
711 INIT_LIST_HEAD(&dev->frontends.felist);
712
6e0e12f1
AW
713 if (!core->board.num_frontends)
714 return -ENODEV;
715
e32fadc4
MCC
716 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
717 core->board.num_frontends);
718 for (i = 1; i <= core->board.num_frontends; i++) {
6e0e12f1
AW
719 fe = videobuf_dvb_alloc_frontend(&dev->frontends, i);
720 if (!fe) {
e32fadc4
MCC
721 printk(KERN_ERR "%s() failed to alloc\n", __func__);
722 videobuf_dvb_dealloc_frontends(&dev->frontends);
6e0e12f1 723 return -ENOMEM;
e32fadc4
MCC
724 }
725 }
6e0e12f1
AW
726 return 0;
727}
728
4f3ca2f1
DH
729
730
2e4e98e7 731static const u8 samsung_smt_7020_inittab[] = {
4f3ca2f1
DH
732 0x01, 0x15,
733 0x02, 0x00,
734 0x03, 0x00,
735 0x04, 0x7D,
736 0x05, 0x0F,
737 0x06, 0x02,
738 0x07, 0x00,
739 0x08, 0x60,
740
741 0x0A, 0xC2,
742 0x0B, 0x00,
743 0x0C, 0x01,
744 0x0D, 0x81,
745 0x0E, 0x44,
746 0x0F, 0x09,
747 0x10, 0x3C,
748 0x11, 0x84,
749 0x12, 0xDA,
750 0x13, 0x99,
751 0x14, 0x8D,
752 0x15, 0xCE,
753 0x16, 0xE8,
754 0x17, 0x43,
755 0x18, 0x1C,
756 0x19, 0x1B,
757 0x1A, 0x1D,
758
759 0x1C, 0x12,
760 0x1D, 0x00,
761 0x1E, 0x00,
762 0x1F, 0x00,
763 0x20, 0x00,
764 0x21, 0x00,
765 0x22, 0x00,
766 0x23, 0x00,
767
768 0x28, 0x02,
769 0x29, 0x28,
770 0x2A, 0x14,
771 0x2B, 0x0F,
772 0x2C, 0x09,
773 0x2D, 0x05,
774
775 0x31, 0x1F,
776 0x32, 0x19,
777 0x33, 0xFC,
778 0x34, 0x13,
779 0xff, 0xff,
780};
781
782
783static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe,
784 struct dvb_frontend_parameters *params)
785{
786 struct cx8802_dev *dev = fe->dvb->priv;
787 u8 buf[4];
788 u32 div;
789 struct i2c_msg msg = {
790 .addr = 0x61,
791 .flags = 0,
792 .buf = buf,
793 .len = sizeof(buf) };
794
795 div = params->frequency / 125;
796
797 buf[0] = (div >> 8) & 0x7f;
798 buf[1] = div & 0xff;
799 buf[2] = 0x84; /* 0xC4 */
800 buf[3] = 0x00;
801
802 if (params->frequency < 1500000)
803 buf[3] |= 0x10;
804
805 if (fe->ops.i2c_gate_ctrl)
806 fe->ops.i2c_gate_ctrl(fe, 1);
807
808 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
809 return -EIO;
810
811 return 0;
812}
813
814static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
815 fe_sec_tone_mode_t tone)
816{
817 struct cx8802_dev *dev = fe->dvb->priv;
818 struct cx88_core *core = dev->core;
819
820 cx_set(MO_GP0_IO, 0x0800);
821
822 switch (tone) {
823 case SEC_TONE_ON:
824 cx_set(MO_GP0_IO, 0x08);
825 break;
826 case SEC_TONE_OFF:
827 cx_clear(MO_GP0_IO, 0x08);
828 break;
829 default:
830 return -EINVAL;
831 }
832
833 return 0;
834}
835
836static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
837 fe_sec_voltage_t voltage)
838{
839 struct cx8802_dev *dev = fe->dvb->priv;
840 struct cx88_core *core = dev->core;
841
842 u8 data;
843 struct i2c_msg msg = {
844 .addr = 8,
845 .flags = 0,
846 .buf = &data,
847 .len = sizeof(data) };
848
849 cx_set(MO_GP0_IO, 0x8000);
850
851 switch (voltage) {
852 case SEC_VOLTAGE_OFF:
853 break;
854 case SEC_VOLTAGE_13:
855 data = ISL6421_EN1 | ISL6421_LLC1;
856 cx_clear(MO_GP0_IO, 0x80);
857 break;
858 case SEC_VOLTAGE_18:
859 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
860 cx_clear(MO_GP0_IO, 0x80);
861 break;
862 default:
863 return -EINVAL;
864 };
865
866 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
867}
868
869static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
870 u32 srate, u32 ratio)
871{
872 u8 aclk = 0;
873 u8 bclk = 0;
874
875 if (srate < 1500000) {
876 aclk = 0xb7;
877 bclk = 0x47;
878 } else if (srate < 3000000) {
879 aclk = 0xb7;
880 bclk = 0x4b;
881 } else if (srate < 7000000) {
882 aclk = 0xb7;
883 bclk = 0x4f;
884 } else if (srate < 14000000) {
885 aclk = 0xb7;
886 bclk = 0x53;
887 } else if (srate < 30000000) {
888 aclk = 0xb6;
889 bclk = 0x53;
890 } else if (srate < 45000000) {
891 aclk = 0xb4;
892 bclk = 0x51;
893 }
894
895 stv0299_writereg(fe, 0x13, aclk);
896 stv0299_writereg(fe, 0x14, bclk);
897 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
898 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
899 stv0299_writereg(fe, 0x21, ratio & 0xf0);
900
901 return 0;
902}
903
904
2e4e98e7 905static const struct stv0299_config samsung_stv0299_config = {
4f3ca2f1
DH
906 .demod_address = 0x68,
907 .inittab = samsung_smt_7020_inittab,
908 .mclk = 88000000UL,
909 .invert = 0,
910 .skip_reinit = 0,
911 .lock_output = STV0299_LOCKOUTPUT_LK,
912 .volt13_op0_op1 = STV0299_VOLT13_OP1,
913 .min_delay_ms = 100,
914 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
915};
916
6e0e12f1
AW
917static int dvb_register(struct cx8802_dev *dev)
918{
919 struct cx88_core *core = dev->core;
920 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
921 int mfe_shared = 0; /* bus not shared by default */
922
923 if (0 != core->i2c_rc) {
924 printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name);
925 goto frontend_detach;
926 }
e32fadc4 927
363c35fc
ST
928 /* Get the first frontend */
929 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
930 if (!fe0)
60a5a927 931 goto frontend_detach;
1da177e4 932
8e739090
DB
933 /* multi-frontend gate control is undefined or defaults to fe0 */
934 dev->frontends.gate = 0;
935
e32fadc4
MCC
936 /* Sets the gate control callback to be used by i2c command calls */
937 core->gate_ctrl = cx88_dvb_gate_ctrl;
938
8e739090 939 /* init frontend(s) */
0590d91c 940 switch (core->boardnr) {
1da177e4 941 case CX88_BOARD_HAUPPAUGE_DVB_T1:
363c35fc 942 fe0->dvb.frontend = dvb_attach(cx22702_attach,
ed355260 943 &connexant_refboard_config,
0590d91c 944 &core->i2c_adap);
363c35fc
ST
945 if (fe0->dvb.frontend != NULL) {
946 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0590d91c
MCC
947 0x61, &core->i2c_adap,
948 DVB_PLL_THOMSON_DTT759X))
949 goto frontend_detach;
f54376e2 950 }
1da177e4 951 break;
e057ee11 952 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
1da177e4 953 case CX88_BOARD_CONEXANT_DVB_T1:
f39624fd 954 case CX88_BOARD_KWORLD_DVB_T_CX22702:
2b5200a7 955 case CX88_BOARD_WINFAST_DTV1000:
363c35fc 956 fe0->dvb.frontend = dvb_attach(cx22702_attach,
f7b54b10 957 &connexant_refboard_config,
0590d91c 958 &core->i2c_adap);
363c35fc
ST
959 if (fe0->dvb.frontend != NULL) {
960 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0590d91c
MCC
961 0x60, &core->i2c_adap,
962 DVB_PLL_THOMSON_DTT7579))
963 goto frontend_detach;
f54376e2 964 }
1da177e4 965 break;
4bd6e9d9 966 case CX88_BOARD_WINFAST_DTV2000H:
4d14c833 967 case CX88_BOARD_WINFAST_DTV2000H_J:
611900c1
ST
968 case CX88_BOARD_HAUPPAUGE_HVR1100:
969 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
a5a2ecfc 970 case CX88_BOARD_HAUPPAUGE_HVR1300:
363c35fc 971 fe0->dvb.frontend = dvb_attach(cx22702_attach,
ed355260 972 &hauppauge_hvr_config,
0590d91c 973 &core->i2c_adap);
363c35fc
ST
974 if (fe0->dvb.frontend != NULL) {
975 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
976 &core->i2c_adap, 0x61,
977 TUNER_PHILIPS_FMD1216ME_MK3))
978 goto frontend_detach;
f54376e2 979 }
611900c1 980 break;
363c35fc 981 case CX88_BOARD_HAUPPAUGE_HVR3000:
60a5a927
DB
982 /* MFE frontend 1 */
983 mfe_shared = 1;
984 dev->frontends.gate = 2;
363c35fc
ST
985 /* DVB-S init */
986 fe0->dvb.frontend = dvb_attach(cx24123_attach,
60a5a927
DB
987 &hauppauge_novas_config,
988 &dev->core->i2c_adap);
363c35fc 989 if (fe0->dvb.frontend) {
60a5a927
DB
990 if (!dvb_attach(isl6421_attach,
991 fe0->dvb.frontend,
992 &dev->core->i2c_adap,
993 0x08, ISL6421_DCL, 0x00))
994 goto frontend_detach;
363c35fc 995 }
60a5a927 996 /* MFE frontend 2 */
363c35fc 997 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
60a5a927
DB
998 if (!fe1)
999 goto frontend_detach;
1000 /* DVB-T init */
1001 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1002 &hauppauge_hvr_config,
1003 &dev->core->i2c_adap);
1004 if (fe1->dvb.frontend) {
1005 fe1->dvb.frontend->id = 1;
1006 if (!dvb_attach(simple_tuner_attach,
1007 fe1->dvb.frontend,
1008 &dev->core->i2c_adap,
1009 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1010 goto frontend_detach;
363c35fc
ST
1011 }
1012 break;
780dfef3 1013 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
363c35fc 1014 fe0->dvb.frontend = dvb_attach(mt352_attach,
f7b54b10 1015 &dvico_fusionhdtv,
0590d91c 1016 &core->i2c_adap);
363c35fc
ST
1017 if (fe0->dvb.frontend != NULL) {
1018 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0590d91c
MCC
1019 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1020 goto frontend_detach;
780dfef3 1021 break;
f54376e2 1022 }
780dfef3 1023 /* ZL10353 replaces MT352 on later cards */
363c35fc 1024 fe0->dvb.frontend = dvb_attach(zl10353_attach,
f7b54b10 1025 &dvico_fusionhdtv_plus_v1_1,
0590d91c 1026 &core->i2c_adap);
363c35fc
ST
1027 if (fe0->dvb.frontend != NULL) {
1028 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0590d91c
MCC
1029 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
1030 goto frontend_detach;
f54376e2 1031 }
c2af3cd6
MK
1032 break;
1033 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
c2af3cd6
MK
1034 /* The tin box says DEE1601, but it seems to be DTT7579
1035 * compatible, with a slightly different MT352 AGC gain. */
363c35fc 1036 fe0->dvb.frontend = dvb_attach(mt352_attach,
f7b54b10 1037 &dvico_fusionhdtv_dual,
0590d91c 1038 &core->i2c_adap);
363c35fc
ST
1039 if (fe0->dvb.frontend != NULL) {
1040 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0590d91c
MCC
1041 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1042 goto frontend_detach;
c2af3cd6
MK
1043 break;
1044 }
c2af3cd6 1045 /* ZL10353 replaces MT352 on later cards */
363c35fc 1046 fe0->dvb.frontend = dvb_attach(zl10353_attach,
f7b54b10 1047 &dvico_fusionhdtv_plus_v1_1,
0590d91c 1048 &core->i2c_adap);
363c35fc
ST
1049 if (fe0->dvb.frontend != NULL) {
1050 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0590d91c
MCC
1051 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
1052 goto frontend_detach;
c2af3cd6 1053 }
1da177e4 1054 break;
780dfef3 1055 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
363c35fc 1056 fe0->dvb.frontend = dvb_attach(mt352_attach,
f7b54b10 1057 &dvico_fusionhdtv,
0590d91c 1058 &core->i2c_adap);
363c35fc
ST
1059 if (fe0->dvb.frontend != NULL) {
1060 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0590d91c
MCC
1061 0x61, NULL, DVB_PLL_LG_Z201))
1062 goto frontend_detach;
f54376e2 1063 }
1da177e4
LT
1064 break;
1065 case CX88_BOARD_KWORLD_DVB_T:
1066 case CX88_BOARD_DNTV_LIVE_DVB_T:
a82decf6 1067 case CX88_BOARD_ADSTECH_DVB_T_PCI:
363c35fc 1068 fe0->dvb.frontend = dvb_attach(mt352_attach,
f7b54b10 1069 &dntv_live_dvbt_config,
0590d91c 1070 &core->i2c_adap);
363c35fc
ST
1071 if (fe0->dvb.frontend != NULL) {
1072 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0590d91c
MCC
1073 0x61, NULL, DVB_PLL_UNKNOWN_1))
1074 goto frontend_detach;
f54376e2 1075 }
1da177e4 1076 break;
fc40b261 1077 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
ecf854df 1078#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
f0ad9097 1079 /* MT352 is on a secondary I2C bus made from some GPIO lines */
363c35fc 1080 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
f0ad9097 1081 &dev->vp3054->adap);
363c35fc
ST
1082 if (fe0->dvb.frontend != NULL) {
1083 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
1084 &core->i2c_adap, 0x61,
1085 TUNER_PHILIPS_FMD1216ME_MK3))
1086 goto frontend_detach;
f54376e2 1087 }
fc40b261 1088#else
0590d91c
MCC
1089 printk(KERN_ERR "%s/2: built without vp3054 support\n",
1090 core->name);
fc40b261
CP
1091#endif
1092 break;
780dfef3 1093 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
363c35fc 1094 fe0->dvb.frontend = dvb_attach(zl10353_attach,
f7b54b10 1095 &dvico_fusionhdtv_hybrid,
0590d91c 1096 &core->i2c_adap);
363c35fc
ST
1097 if (fe0->dvb.frontend != NULL) {
1098 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
1099 &core->i2c_adap, 0x61,
1100 TUNER_THOMSON_FE6600))
1101 goto frontend_detach;
f54376e2 1102 }
780dfef3 1103 break;
b3fb91d2 1104 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
363c35fc 1105 fe0->dvb.frontend = dvb_attach(zl10353_attach,
b3fb91d2 1106 &dvico_fusionhdtv_xc3028,
0590d91c 1107 &core->i2c_adap);
363c35fc
ST
1108 if (fe0->dvb.frontend == NULL)
1109 fe0->dvb.frontend = dvb_attach(mt352_attach,
b3fb91d2 1110 &dvico_fusionhdtv_mt352_xc3028,
0590d91c 1111 &core->i2c_adap);
8765561f
CP
1112 /*
1113 * On this board, the demod provides the I2C bus pullup.
1114 * We must not permit gate_ctrl to be performed, or
1115 * the xc3028 cannot communicate on the bus.
1116 */
363c35fc
ST
1117 if (fe0->dvb.frontend)
1118 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
23fb348d 1119 if (attach_xc3028(0x61, dev) < 0)
becd4305 1120 goto frontend_detach;
b3fb91d2 1121 break;
1da177e4 1122 case CX88_BOARD_PCHDTV_HD3000:
363c35fc 1123 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
0590d91c 1124 &core->i2c_adap);
363c35fc
ST
1125 if (fe0->dvb.frontend != NULL) {
1126 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
1127 &core->i2c_adap, 0x61,
1128 TUNER_THOMSON_DTT761X))
1129 goto frontend_detach;
f54376e2 1130 }
1da177e4 1131 break;
f1798495
MK
1132 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
1133 dev->ts_gen_cntrl = 0x08;
f1798495 1134
0590d91c 1135 /* Do a hardware reset of chip before using it. */
f1798495
MK
1136 cx_clear(MO_GP0_IO, 1);
1137 mdelay(100);
0ccef6db 1138 cx_set(MO_GP0_IO, 1);
f1798495 1139 mdelay(200);
0ccef6db
MK
1140
1141 /* Select RF connector callback */
6ddcc919 1142 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
363c35fc 1143 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
f7b54b10 1144 &fusionhdtv_3_gold,
0590d91c 1145 &core->i2c_adap);
363c35fc
ST
1146 if (fe0->dvb.frontend != NULL) {
1147 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
1148 &core->i2c_adap, 0x61,
1149 TUNER_MICROTUNE_4042FI5))
1150 goto frontend_detach;
f1798495
MK
1151 }
1152 break;
0d723c09
MK
1153 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
1154 dev->ts_gen_cntrl = 0x08;
0d723c09 1155
0590d91c 1156 /* Do a hardware reset of chip before using it. */
0d723c09
MK
1157 cx_clear(MO_GP0_IO, 1);
1158 mdelay(100);
d975872c 1159 cx_set(MO_GP0_IO, 9);
0d723c09 1160 mdelay(200);
363c35fc 1161 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
f7b54b10 1162 &fusionhdtv_3_gold,
0590d91c 1163 &core->i2c_adap);
363c35fc
ST
1164 if (fe0->dvb.frontend != NULL) {
1165 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
1166 &core->i2c_adap, 0x61,
1167 TUNER_THOMSON_DTT761X))
1168 goto frontend_detach;
0d723c09
MK
1169 }
1170 break;
e52e98a7
MCC
1171 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
1172 dev->ts_gen_cntrl = 0x08;
e52e98a7 1173
0590d91c 1174 /* Do a hardware reset of chip before using it. */
e52e98a7
MCC
1175 cx_clear(MO_GP0_IO, 1);
1176 mdelay(100);
1177 cx_set(MO_GP0_IO, 1);
1178 mdelay(200);
363c35fc 1179 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
f7b54b10 1180 &fusionhdtv_5_gold,
0590d91c 1181 &core->i2c_adap);
363c35fc
ST
1182 if (fe0->dvb.frontend != NULL) {
1183 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
1184 &core->i2c_adap, 0x61,
1185 TUNER_LG_TDVS_H06XF))
1186 goto frontend_detach;
363c35fc 1187 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
0590d91c
MCC
1188 &core->i2c_adap, 0x43))
1189 goto frontend_detach;
e52e98a7
MCC
1190 }
1191 break;
da215d22
RS
1192 case CX88_BOARD_PCHDTV_HD5500:
1193 dev->ts_gen_cntrl = 0x08;
da215d22 1194
0590d91c 1195 /* Do a hardware reset of chip before using it. */
da215d22
RS
1196 cx_clear(MO_GP0_IO, 1);
1197 mdelay(100);
1198 cx_set(MO_GP0_IO, 1);
1199 mdelay(200);
363c35fc 1200 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
f7b54b10 1201 &pchdtv_hd5500,
0590d91c 1202 &core->i2c_adap);
363c35fc
ST
1203 if (fe0->dvb.frontend != NULL) {
1204 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
1205 &core->i2c_adap, 0x61,
1206 TUNER_LG_TDVS_H06XF))
1207 goto frontend_detach;
363c35fc 1208 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
0590d91c
MCC
1209 &core->i2c_adap, 0x43))
1210 goto frontend_detach;
da215d22
RS
1211 }
1212 break;
fde6d31e 1213 case CX88_BOARD_ATI_HDTVWONDER:
363c35fc 1214 fe0->dvb.frontend = dvb_attach(nxt200x_attach,
f7b54b10 1215 &ati_hdtvwonder,
0590d91c 1216 &core->i2c_adap);
363c35fc
ST
1217 if (fe0->dvb.frontend != NULL) {
1218 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
0590d91c
MCC
1219 &core->i2c_adap, 0x61,
1220 TUNER_PHILIPS_TUV1236D))
1221 goto frontend_detach;
f54376e2 1222 }
0fa14aa6 1223 break;
0fa14aa6
ST
1224 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
1225 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
363c35fc 1226 fe0->dvb.frontend = dvb_attach(cx24123_attach,
f7b54b10 1227 &hauppauge_novas_config,
0590d91c 1228 &core->i2c_adap);
363c35fc
ST
1229 if (fe0->dvb.frontend) {
1230 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
83fe92e7 1231 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
0590d91c 1232 goto frontend_detach;
cd20ca9f 1233 }
0e0351e3
VC
1234 break;
1235 case CX88_BOARD_KWORLD_DVBS_100:
363c35fc 1236 fe0->dvb.frontend = dvb_attach(cx24123_attach,
f7b54b10 1237 &kworld_dvbs_100_config,
0590d91c 1238 &core->i2c_adap);
363c35fc
ST
1239 if (fe0->dvb.frontend) {
1240 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1241 fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
cd20ca9f 1242 }
fde6d31e 1243 break;
c02a34f4 1244 case CX88_BOARD_GENIATECH_DVBS:
363c35fc 1245 fe0->dvb.frontend = dvb_attach(cx24123_attach,
f7b54b10 1246 &geniatech_dvbs_config,
0590d91c 1247 &core->i2c_adap);
363c35fc
ST
1248 if (fe0->dvb.frontend) {
1249 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1250 fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
c02a34f4
SA
1251 }
1252 break;
60464da8 1253 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
363c35fc 1254 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
60464da8 1255 &pinnacle_pctv_hd_800i_config,
0590d91c 1256 &core->i2c_adap);
363c35fc
ST
1257 if (fe0->dvb.frontend != NULL) {
1258 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
0590d91c 1259 &core->i2c_adap,
30650961 1260 &pinnacle_pctv_hd_800i_tuner_config))
0590d91c 1261 goto frontend_detach;
60464da8
ST
1262 }
1263 break;
5c00fac0 1264 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
363c35fc 1265 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
5c00fac0 1266 &dvico_hdtv5_pci_nano_config,
0590d91c 1267 &core->i2c_adap);
363c35fc 1268 if (fe0->dvb.frontend != NULL) {
5c00fac0
ST
1269 struct dvb_frontend *fe;
1270 struct xc2028_config cfg = {
0590d91c 1271 .i2c_adap = &core->i2c_adap,
5c00fac0 1272 .i2c_addr = 0x61,
5c00fac0
ST
1273 };
1274 static struct xc2028_ctrl ctl = {
ef80bfeb 1275 .fname = XC2028_DEFAULT_FIRMWARE,
5c00fac0 1276 .max_len = 64,
33e53161 1277 .scode_table = XC3028_FE_OREN538,
5c00fac0
ST
1278 };
1279
1280 fe = dvb_attach(xc2028_attach,
363c35fc 1281 fe0->dvb.frontend, &cfg);
5c00fac0
ST
1282 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
1283 fe->ops.tuner_ops.set_config(fe, &ctl);
1284 }
1285 break;
d49f7a24 1286 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
3047a176 1287 case CX88_BOARD_WINFAST_DTV1800H:
363c35fc 1288 fe0->dvb.frontend = dvb_attach(zl10353_attach,
3f6014fc 1289 &cx88_pinnacle_hybrid_pctv,
0590d91c 1290 &core->i2c_adap);
363c35fc
ST
1291 if (fe0->dvb.frontend) {
1292 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
3f6014fc
SV
1293 if (attach_xc3028(0x61, dev) < 0)
1294 goto frontend_detach;
1295 }
9507901e
MCC
1296 break;
1297 case CX88_BOARD_GENIATECH_X8000_MT:
99e09eac 1298 dev->ts_gen_cntrl = 0x00;
9507901e 1299
363c35fc 1300 fe0->dvb.frontend = dvb_attach(zl10353_attach,
9507901e 1301 &cx88_geniatech_x8000_mt,
0590d91c 1302 &core->i2c_adap);
23fb348d 1303 if (attach_xc3028(0x61, dev) < 0)
0590d91c 1304 goto frontend_detach;
9507901e 1305 break;
99e09eac 1306 case CX88_BOARD_KWORLD_ATSC_120:
363c35fc 1307 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
99e09eac 1308 &kworld_atsc_120_config,
0590d91c 1309 &core->i2c_adap);
99e09eac 1310 if (attach_xc3028(0x61, dev) < 0)
0590d91c 1311 goto frontend_detach;
99e09eac 1312 break;
d893d5dc 1313 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
363c35fc 1314 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
d893d5dc 1315 &dvico_fusionhdtv7_config,
0590d91c 1316 &core->i2c_adap);
363c35fc
ST
1317 if (fe0->dvb.frontend != NULL) {
1318 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
0590d91c 1319 &core->i2c_adap,
30650961 1320 &dvico_fusionhdtv7_tuner_config))
0590d91c 1321 goto frontend_detach;
d893d5dc
ST
1322 }
1323 break;
5bd1b663 1324 case CX88_BOARD_HAUPPAUGE_HVR4000:
60a5a927
DB
1325 /* MFE frontend 1 */
1326 mfe_shared = 1;
1327 dev->frontends.gate = 2;
363c35fc
ST
1328 /* DVB-S/S2 Init */
1329 fe0->dvb.frontend = dvb_attach(cx24116_attach,
60a5a927
DB
1330 &hauppauge_hvr4000_config,
1331 &dev->core->i2c_adap);
363c35fc 1332 if (fe0->dvb.frontend) {
60a5a927
DB
1333 if (!dvb_attach(isl6421_attach,
1334 fe0->dvb.frontend,
1335 &dev->core->i2c_adap,
1336 0x08, ISL6421_DCL, 0x00))
1337 goto frontend_detach;
363c35fc 1338 }
60a5a927 1339 /* MFE frontend 2 */
363c35fc 1340 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
60a5a927
DB
1341 if (!fe1)
1342 goto frontend_detach;
1343 /* DVB-T Init */
1344 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1345 &hauppauge_hvr_config,
1346 &dev->core->i2c_adap);
1347 if (fe1->dvb.frontend) {
1348 fe1->dvb.frontend->id = 1;
1349 if (!dvb_attach(simple_tuner_attach,
1350 fe1->dvb.frontend,
1351 &dev->core->i2c_adap,
1352 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
1353 goto frontend_detach;
363c35fc
ST
1354 }
1355 break;
5bd1b663 1356 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
363c35fc 1357 fe0->dvb.frontend = dvb_attach(cx24116_attach,
60a5a927
DB
1358 &hauppauge_hvr4000_config,
1359 &dev->core->i2c_adap);
363c35fc 1360 if (fe0->dvb.frontend) {
60a5a927
DB
1361 if (!dvb_attach(isl6421_attach,
1362 fe0->dvb.frontend,
1363 &dev->core->i2c_adap,
1364 0x08, ISL6421_DCL, 0x00))
1365 goto frontend_detach;
5bd1b663
ST
1366 }
1367 break;
cd3cde12 1368 case CX88_BOARD_PROF_6200:
4b29631d 1369 case CX88_BOARD_TBS_8910:
e4aab64c 1370 case CX88_BOARD_TEVII_S420:
363c35fc 1371 fe0->dvb.frontend = dvb_attach(stv0299_attach,
e4aab64c
IL
1372 &tevii_tuner_sharp_config,
1373 &core->i2c_adap);
363c35fc
ST
1374 if (fe0->dvb.frontend != NULL) {
1375 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
e4aab64c
IL
1376 &core->i2c_adap, DVB_PLL_OPERA1))
1377 goto frontend_detach;
363c35fc
ST
1378 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1379 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
e4aab64c
IL
1380
1381 } else {
363c35fc 1382 fe0->dvb.frontend = dvb_attach(stv0288_attach,
e4aab64c
IL
1383 &tevii_tuner_earda_config,
1384 &core->i2c_adap);
363c35fc
ST
1385 if (fe0->dvb.frontend != NULL) {
1386 if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
e4aab64c
IL
1387 &core->i2c_adap))
1388 goto frontend_detach;
363c35fc
ST
1389 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1390 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
e4aab64c
IL
1391 }
1392 }
1393 break;
af832623 1394 case CX88_BOARD_TEVII_S460:
363c35fc 1395 fe0->dvb.frontend = dvb_attach(cx24116_attach,
af832623
IL
1396 &tevii_s460_config,
1397 &core->i2c_adap);
93f26c14 1398 if (fe0->dvb.frontend != NULL)
363c35fc 1399 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
4cd7fb87 1400 break;
0cb73639
IL
1401 case CX88_BOARD_TEVII_S464:
1402 fe0->dvb.frontend = dvb_attach(ds3000_attach,
1403 &tevii_ds3000_config,
1404 &core->i2c_adap);
1405 if (fe0->dvb.frontend != NULL)
1406 fe0->dvb.frontend->ops.set_voltage =
1407 tevii_dvbs_set_voltage;
1408 break;
4cd7fb87 1409 case CX88_BOARD_OMICOM_SS4_PCI:
ee73042c 1410 case CX88_BOARD_TBS_8920:
57f51dbc 1411 case CX88_BOARD_PROF_7300:
4b29631d 1412 case CX88_BOARD_SATTRADE_ST4200:
363c35fc 1413 fe0->dvb.frontend = dvb_attach(cx24116_attach,
ee73042c
OR
1414 &hauppauge_hvr4000_config,
1415 &core->i2c_adap);
93f26c14 1416 if (fe0->dvb.frontend != NULL)
363c35fc 1417 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
af832623 1418 break;
70101a27
SW
1419 case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
1420 fe0->dvb.frontend = dvb_attach(zl10353_attach,
1421 &cx88_terratec_cinergy_ht_pci_mkii_config,
1422 &core->i2c_adap);
1423 if (fe0->dvb.frontend) {
1424 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1425 if (attach_xc3028(0x61, dev) < 0)
1426 goto frontend_detach;
1427 }
1428 break;
b699c271
IL
1429 case CX88_BOARD_PROF_7301:{
1430 struct dvb_tuner_ops *tuner_ops = NULL;
1431
1432 fe0->dvb.frontend = dvb_attach(stv0900_attach,
1433 &prof_7301_stv0900_config,
1434 &core->i2c_adap, 0);
1435 if (fe0->dvb.frontend != NULL) {
1436 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1437 &prof_7301_stb6100_config,
1438 &core->i2c_adap))
1439 goto frontend_detach;
1440
1441 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1442 tuner_ops->set_frequency = stb6100_set_freq;
1443 tuner_ops->get_frequency = stb6100_get_freq;
1444 tuner_ops->set_bandwidth = stb6100_set_bandw;
1445 tuner_ops->get_bandwidth = stb6100_get_bandw;
1446
1447 core->prev_set_voltage =
1448 fe0->dvb.frontend->ops.set_voltage;
1449 fe0->dvb.frontend->ops.set_voltage =
1450 tevii_dvbs_set_voltage;
1451 }
1452 break;
1453 }
4f3ca2f1
DH
1454 case CX88_BOARD_SAMSUNG_SMT_7020:
1455 dev->ts_gen_cntrl = 0x08;
1456
4f3ca2f1
DH
1457 cx_set(MO_GP0_IO, 0x0101);
1458
1459 cx_clear(MO_GP0_IO, 0x01);
1460 mdelay(100);
1461 cx_set(MO_GP0_IO, 0x01);
1462 mdelay(200);
1463
1464 fe0->dvb.frontend = dvb_attach(stv0299_attach,
1465 &samsung_stv0299_config,
1466 &dev->core->i2c_adap);
1467 if (fe0->dvb.frontend) {
1468 fe0->dvb.frontend->ops.tuner_ops.set_params =
1469 samsung_smt_7020_tuner_set_params;
1470 fe0->dvb.frontend->tuner_priv =
1471 &dev->core->i2c_adap;
1472 fe0->dvb.frontend->ops.set_voltage =
1473 samsung_smt_7020_set_voltage;
1474 fe0->dvb.frontend->ops.set_tone =
1475 samsung_smt_7020_set_tone;
1476 }
1477
1478 break;
111ac84a
SI
1479 case CX88_BOARD_TWINHAN_VP1027_DVBS:
1480 dev->ts_gen_cntrl = 0x00;
1481 fe0->dvb.frontend = dvb_attach(mb86a16_attach,
1482 &twinhan_vp1027,
1483 &core->i2c_adap);
1484 if (fe0->dvb.frontend) {
1485 core->prev_set_voltage =
1486 fe0->dvb.frontend->ops.set_voltage;
1487 fe0->dvb.frontend->ops.set_voltage =
1488 vp1027_set_voltage;
1489 }
1490 break;
4f3ca2f1 1491
1da177e4 1492 default:
5772f813 1493 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
0590d91c 1494 core->name);
1da177e4
LT
1495 break;
1496 }
363c35fc 1497
2c9bcea1 1498 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
9507901e
MCC
1499 printk(KERN_ERR
1500 "%s/2: frontend initialization failed\n",
0590d91c 1501 core->name);
60a5a927 1502 goto frontend_detach;
9507901e 1503 }
d7cba043 1504 /* define general-purpose callback pointer */
363c35fc 1505 fe0->dvb.frontend->callback = cx88_tuner_callback;
9507901e 1506
6c5be74c 1507 /* Ensure all frontends negotiate bus access */
363c35fc
ST
1508 fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1509 if (fe1)
1510 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1da177e4 1511
93352f5c 1512 /* Put the analog decoder in standby to keep it quiet */
622b828a 1513 call_all(core, core, s_power, 0);
93352f5c 1514
1da177e4 1515 /* register everything */
363c35fc 1516 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
9133aee0 1517 &dev->pci->dev, adapter_nr, mfe_shared, NULL);
0590d91c
MCC
1518
1519frontend_detach:
e32fadc4 1520 core->gate_ctrl = NULL;
becd4305 1521 videobuf_dvb_dealloc_frontends(&dev->frontends);
0590d91c 1522 return -EINVAL;
1da177e4
LT
1523}
1524
1525/* ----------------------------------------------------------- */
1526
6c5be74c
ST
1527/* CX8802 MPEG -> mini driver - We have been given the hardware */
1528static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1da177e4 1529{
6c5be74c
ST
1530 struct cx88_core *core = drv->core;
1531 int err = 0;
32d83efc 1532 dprintk( 1, "%s\n", __func__);
6c5be74c 1533
6a59d64c 1534 switch (core->boardnr) {
6c5be74c
ST
1535 case CX88_BOARD_HAUPPAUGE_HVR1300:
1536 /* We arrive here with either the cx23416 or the cx22702
1537 * on the bus. Take the bus from the cx23416 and enable the
1538 * cx22702 demod
1539 */
79392737
DB
1540 /* Toggle reset on cx22702 leaving i2c active */
1541 cx_set(MO_GP0_IO, 0x00000080);
1542 udelay(1000);
1543 cx_clear(MO_GP0_IO, 0x00000080);
1544 udelay(50);
1545 cx_set(MO_GP0_IO, 0x00000080);
1546 udelay(1000);
1547 /* enable the cx22702 pins */
6c5be74c
ST
1548 cx_clear(MO_GP0_IO, 0x00000004);
1549 udelay(1000);
1550 break;
363c35fc 1551
92abe9ee 1552 case CX88_BOARD_HAUPPAUGE_HVR3000:
363c35fc 1553 case CX88_BOARD_HAUPPAUGE_HVR4000:
79392737
DB
1554 /* Toggle reset on cx22702 leaving i2c active */
1555 cx_set(MO_GP0_IO, 0x00000080);
1556 udelay(1000);
1557 cx_clear(MO_GP0_IO, 0x00000080);
1558 udelay(50);
1559 cx_set(MO_GP0_IO, 0x00000080);
1560 udelay(1000);
1561 switch (core->dvbdev->frontends.active_fe_id) {
1562 case 1: /* DVB-S/S2 Enabled */
1563 /* tri-state the cx22702 pins */
1564 cx_set(MO_GP0_IO, 0x00000004);
1565 /* Take the cx24116/cx24123 out of reset */
1566 cx_write(MO_SRST_IO, 1);
363c35fc 1567 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
79392737
DB
1568 break;
1569 case 2: /* DVB-T Enabled */
363c35fc
ST
1570 /* Put the cx24116/cx24123 into reset */
1571 cx_write(MO_SRST_IO, 0);
79392737 1572 /* enable the cx22702 pins */
363c35fc
ST
1573 cx_clear(MO_GP0_IO, 0x00000004);
1574 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
79392737 1575 break;
363c35fc 1576 }
79392737 1577 udelay(1000);
363c35fc
ST
1578 break;
1579
6c5be74c
ST
1580 default:
1581 err = -ENODEV;
1582 }
1583 return err;
1584}
1585
1586/* CX8802 MPEG -> mini driver - We no longer have the hardware */
1587static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
1588{
1589 struct cx88_core *core = drv->core;
1590 int err = 0;
32d83efc 1591 dprintk( 1, "%s\n", __func__);
6c5be74c 1592
6a59d64c 1593 switch (core->boardnr) {
6c5be74c
ST
1594 case CX88_BOARD_HAUPPAUGE_HVR1300:
1595 /* Do Nothing, leave the cx22702 on the bus. */
1596 break;
363c35fc
ST
1597 case CX88_BOARD_HAUPPAUGE_HVR3000:
1598 case CX88_BOARD_HAUPPAUGE_HVR4000:
1599 break;
6c5be74c
ST
1600 default:
1601 err = -ENODEV;
1602 }
1603 return err;
1604}
1605
1606static int cx8802_dvb_probe(struct cx8802_driver *drv)
1607{
1608 struct cx88_core *core = drv->core;
1609 struct cx8802_dev *dev = drv->core->dvbdev;
cbd82441 1610 int err;
6e0e12f1
AW
1611 struct videobuf_dvb_frontend *fe;
1612 int i;
1da177e4 1613
32d83efc 1614 dprintk( 1, "%s\n", __func__);
6c5be74c 1615 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
6a59d64c 1616 core->boardnr,
6c5be74c
ST
1617 core->name,
1618 core->pci_bus,
1619 core->pci_slot);
1da177e4
LT
1620
1621 err = -ENODEV;
6a59d64c 1622 if (!(core->board.mpeg & CX88_MPEG_DVB))
1da177e4
LT
1623 goto fail_core;
1624
ecf854df 1625 /* If vp3054 isn't enabled, a stub will just return 0 */
fc40b261
CP
1626 err = vp3054_i2c_probe(dev);
1627 if (0 != err)
6e0e12f1 1628 goto fail_core;
fc40b261 1629
1da177e4 1630 /* dvb stuff */
5772f813 1631 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
363c35fc
ST
1632 dev->ts_gen_cntrl = 0x0c;
1633
6e0e12f1
AW
1634 err = cx8802_alloc_frontends(dev);
1635 if (err)
1636 goto fail_core;
1637
cbd82441 1638 err = -ENODEV;
6e0e12f1
AW
1639 for (i = 1; i <= core->board.num_frontends; i++) {
1640 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1641 if (fe == NULL) {
1642 printk(KERN_ERR "%s() failed to get frontend(%d)\n",
cbd82441 1643 __func__, i);
6e0e12f1
AW
1644 goto fail_probe;
1645 }
1646 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
cbd82441
DB
1647 &dev->pci->dev, &dev->slock,
1648 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1649 V4L2_FIELD_TOP,
1650 sizeof(struct cx88_buffer),
08bff03e 1651 dev, NULL);
6e0e12f1
AW
1652 /* init struct videobuf_dvb */
1653 fe->dvb.name = dev->core->name;
363c35fc 1654 }
6e0e12f1 1655
1da177e4 1656 err = dvb_register(dev);
cbd82441
DB
1657 if (err)
1658 /* frontends/adapter de-allocated in dvb_register */
5772f813
TP
1659 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
1660 core->name, err);
cbd82441
DB
1661 return err;
1662fail_probe:
1663 videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends);
92abe9ee 1664fail_core:
1da177e4
LT
1665 return err;
1666}
1667
6c5be74c 1668static int cx8802_dvb_remove(struct cx8802_driver *drv)
1da177e4 1669{
0fcd488d 1670 struct cx88_core *core = drv->core;
6c5be74c 1671 struct cx8802_dev *dev = drv->core->dvbdev;
611900c1 1672
0fcd488d
DB
1673 dprintk( 1, "%s\n", __func__);
1674
363c35fc 1675 videobuf_dvb_unregister_bus(&dev->frontends);
1da177e4 1676
fc40b261 1677 vp3054_i2c_remove(dev);
fc40b261 1678
e32fadc4
MCC
1679 core->gate_ctrl = NULL;
1680
6c5be74c 1681 return 0;
1da177e4
LT
1682}
1683
6c5be74c
ST
1684static struct cx8802_driver cx8802_dvb_driver = {
1685 .type_id = CX88_MPEG_DVB,
1686 .hw_access = CX8802_DRVCTL_SHARED,
1687 .probe = cx8802_dvb_probe,
1688 .remove = cx8802_dvb_remove,
1689 .advise_acquire = cx8802_dvb_advise_acquire,
1690 .advise_release = cx8802_dvb_advise_release,
1da177e4
LT
1691};
1692
31d0f845 1693static int __init dvb_init(void)
1da177e4 1694{
5772f813 1695 printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
1da177e4
LT
1696 (CX88_VERSION_CODE >> 16) & 0xff,
1697 (CX88_VERSION_CODE >> 8) & 0xff,
1698 CX88_VERSION_CODE & 0xff);
1699#ifdef SNAPSHOT
1700 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1701 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1702#endif
6c5be74c 1703 return cx8802_register_driver(&cx8802_dvb_driver);
1da177e4
LT
1704}
1705
31d0f845 1706static void __exit dvb_fini(void)
1da177e4 1707{
6c5be74c 1708 cx8802_unregister_driver(&cx8802_dvb_driver);
1da177e4
LT
1709}
1710
1711module_init(dvb_init);
1712module_exit(dvb_fini);
1713
1714/*
1715 * Local variables:
1716 * c-basic-offset: 8
1717 * compile-command: "make DVB=1"
1718 * End:
1719 */