aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSteven Toth <stoth@linuxtv.org>2008-10-11 10:05:50 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-17 16:23:10 -0400
commit363c35fc448943c3d6121332d28bcda2d2fbf87c (patch)
tree739864d237b7fa60bef51bc510fe55c888b606ca /drivers
parent548da7625c825eccc31b4b3865ae5389c3660486 (diff)
V4L/DVB (9222): S2API: Add Multiple-frontend on a single adapter support.
A detailed description from the original patches 2 years ago: "The WinTV-HVR3000 has a single transport bus which is shared between a DVB-T and DVB-S modulator. These patches build on the bus acquisition cx88 work from a few weeks ago to add support for this. So to applications the HVR3000 looks like this: /dev/dvb/adapter0/fe0 (cx24123 DVB-S demod) /dev/dvb/adapter0/fe1 (cx22702 DVB-T demod) Additional boards continue as before, eg: /dev/dvb/adapter1/fe0 (lgdt3302 ATSC demod) The basic change is removing the single instance of the videobuf_dvb in cx8802_dev and saa7134_dev(?) and replacing it with a list and some supporting functions. *NOTE* This branch was taken before v4l-dvb was closed for 2.6.19 so two or three current cx88 patches appear to be reversed by this tree, this will be cleaned up in the near future. The patches missing change the mutex handing to core->lock, fix an enumeration problem." It should be recognised that a number of people have been maintaining this patchset. Significant levels of Kudos to everyone one involved, including but not limited to: Darron Broad Fabio M. Di Nitto Carlo Scarfoglio Hans Werner Without the work of these people, and countless others, my two year old patches would of died on the Mercurial linuxtv.org vine a long time ago. TODO: Revise these patches a little further so that the need for demux1 and dvr0 is optional, not mandatory on the HVR3000. HISTORY (darron): This is the last update to MFE prepared by Hans which is based upon the `scratchpad' diff created by Carlo. All MFE work prior to that point must be attributed to Fabio who ported and maintained Steve's original patch up to that time. Signed-off-by: Steven Toth <stoth@linuxtv.org> Signed-off-by: Darron Broad <darron@kewl.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c24
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h1
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c115
-rw-r--r--drivers/media/video/cx23885/cx23885.h2
-rw-r--r--drivers/media/video/cx88/cx88-cards.c11
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c423
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c15
-rw-r--r--drivers/media/video/cx88/cx88-input.c1
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c22
-rw-r--r--drivers/media/video/cx88/cx88.h4
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c205
-rw-r--r--drivers/media/video/saa7134/saa7134.h2
-rw-r--r--drivers/media/video/videobuf-dvb.c171
13 files changed, 680 insertions, 316 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 72ce7935f253..26671757c70b 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -212,8 +212,9 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
212 212
213static void dvb_frontend_init(struct dvb_frontend *fe) 213static void dvb_frontend_init(struct dvb_frontend *fe)
214{ 214{
215 dprintk ("DVB: initialising frontend %i (%s)...\n", 215 dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n",
216 fe->dvb->num, 216 fe->dvb->num,
217 fe->id,
217 fe->ops.info.name); 218 fe->ops.info.name);
218 219
219 if (fe->ops.init) 220 if (fe->ops.init)
@@ -686,7 +687,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
686 mb(); 687 mb();
687 688
688 fe_thread = kthread_run(dvb_frontend_thread, fe, 689 fe_thread = kthread_run(dvb_frontend_thread, fe,
689 "kdvb-fe-%i", fe->dvb->num); 690 "kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id);
690 if (IS_ERR(fe_thread)) { 691 if (IS_ERR(fe_thread)) {
691 ret = PTR_ERR(fe_thread); 692 ret = PTR_ERR(fe_thread);
692 printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); 693 printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
@@ -710,8 +711,8 @@ static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe,
710 *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max); 711 *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
711 712
712 if (*freq_min == 0 || *freq_max == 0) 713 if (*freq_min == 0 || *freq_max == 0)
713 printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n", 714 printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
714 fe->dvb->num); 715 fe->dvb->num,fe->id);
715} 716}
716 717
717static int dvb_frontend_check_parameters(struct dvb_frontend *fe, 718static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
@@ -724,8 +725,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
724 dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max); 725 dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max);
725 if ((freq_min && parms->frequency < freq_min) || 726 if ((freq_min && parms->frequency < freq_min) ||
726 (freq_max && parms->frequency > freq_max)) { 727 (freq_max && parms->frequency > freq_max)) {
727 printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n", 728 printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
728 fe->dvb->num, parms->frequency, freq_min, freq_max); 729 fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max);
729 return -EINVAL; 730 return -EINVAL;
730 } 731 }
731 732
@@ -735,8 +736,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
735 parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || 736 parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
736 (fe->ops.info.symbol_rate_max && 737 (fe->ops.info.symbol_rate_max &&
737 parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) { 738 parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) {
738 printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", 739 printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
739 fe->dvb->num, parms->u.qpsk.symbol_rate, 740 fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate,
740 fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); 741 fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
741 return -EINVAL; 742 return -EINVAL;
742 } 743 }
@@ -746,8 +747,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
746 parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) || 747 parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
747 (fe->ops.info.symbol_rate_max && 748 (fe->ops.info.symbol_rate_max &&
748 parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) { 749 parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) {
749 printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n", 750 printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
750 fe->dvb->num, parms->u.qam.symbol_rate, 751 fe->dvb->num, fe->id, parms->u.qam.symbol_rate,
751 fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); 752 fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
752 return -EINVAL; 753 return -EINVAL;
753 } 754 }
@@ -1807,8 +1808,9 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
1807 fe->dvb = dvb; 1808 fe->dvb = dvb;
1808 fepriv->inversion = INVERSION_OFF; 1809 fepriv->inversion = INVERSION_OFF;
1809 1810
1810 printk ("DVB: registering frontend %i (%s)...\n", 1811 printk ("DVB: registering adapter %i frontend %i (%s)...\n",
1811 fe->dvb->num, 1812 fe->dvb->num,
1813 fe->id,
1812 fe->ops.info.name); 1814 fe->ops.info.name);
1813 1815
1814 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, 1816 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 3055301ff3ca..db4a63b0a32e 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -222,6 +222,7 @@ struct dvb_frontend {
222 struct dtv_frontend_properties dtv_property_cache; 222 struct dtv_frontend_properties dtv_property_cache;
223#define DVB_FRONTEND_COMPONENT_TUNER 0 223#define DVB_FRONTEND_COMPONENT_TUNER 0
224 int (*callback)(void *adapter_priv, int component, int cmd, int arg); 224 int (*callback)(void *adapter_priv, int component, int cmd, int arg);
225 int id;
225}; 226};
226 227
227extern int dvb_register_frontend(struct dvb_adapter *dvb, 228extern int dvb_register_frontend(struct dvb_adapter *dvb,
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 24bd18327aa0..fe1218fd44cb 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -312,48 +312,53 @@ static int dvb_register(struct cx23885_tsport *port)
312{ 312{
313 struct cx23885_dev *dev = port->dev; 313 struct cx23885_dev *dev = port->dev;
314 struct cx23885_i2c *i2c_bus = NULL; 314 struct cx23885_i2c *i2c_bus = NULL;
315 struct videobuf_dvb_frontend *fe0;
316
317 fe0 = videobuf_dvb_get_frontend(&port->frontends, 0);
318 if (!fe0)
319 return -EINVAL;
315 320
316 /* init struct videobuf_dvb */ 321 /* init struct videobuf_dvb */
317 port->dvb.name = dev->name; 322 fe0->dvb.name = dev->name;
318 323
319 /* init frontend */ 324 /* init frontend */
320 switch (dev->board) { 325 switch (dev->board) {
321 case CX23885_BOARD_HAUPPAUGE_HVR1250: 326 case CX23885_BOARD_HAUPPAUGE_HVR1250:
322 i2c_bus = &dev->i2c_bus[0]; 327 i2c_bus = &dev->i2c_bus[0];
323 port->dvb.frontend = dvb_attach(s5h1409_attach, 328 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
324 &hauppauge_generic_config, 329 &hauppauge_generic_config,
325 &i2c_bus->i2c_adap); 330 &i2c_bus->i2c_adap);
326 if (port->dvb.frontend != NULL) { 331 if (fe0->dvb.frontend != NULL) {
327 dvb_attach(mt2131_attach, port->dvb.frontend, 332 dvb_attach(mt2131_attach, fe0->dvb.frontend,
328 &i2c_bus->i2c_adap, 333 &i2c_bus->i2c_adap,
329 &hauppauge_generic_tunerconfig, 0); 334 &hauppauge_generic_tunerconfig, 0);
330 } 335 }
331 break; 336 break;
332 case CX23885_BOARD_HAUPPAUGE_HVR1800: 337 case CX23885_BOARD_HAUPPAUGE_HVR1800:
333 i2c_bus = &dev->i2c_bus[0]; 338 i2c_bus = &dev->i2c_bus[0];
334 switch (alt_tuner) { 339 switch (alt_tuner) { // XXXXXX multifrontend?
335 case 1: 340 case 1:
336 port->dvb.frontend = 341 fe0->dvb.frontend =
337 dvb_attach(s5h1409_attach, 342 dvb_attach(s5h1409_attach,
338 &hauppauge_ezqam_config, 343 &hauppauge_ezqam_config,
339 &i2c_bus->i2c_adap); 344 &i2c_bus->i2c_adap);
340 if (port->dvb.frontend != NULL) { 345 if (fe0->dvb.frontend != NULL) {
341 dvb_attach(tda829x_attach, port->dvb.frontend, 346 dvb_attach(tda829x_attach, fe0->dvb.frontend,
342 &dev->i2c_bus[1].i2c_adap, 0x42, 347 &dev->i2c_bus[1].i2c_adap, 0x42,
343 &tda829x_no_probe); 348 &tda829x_no_probe);
344 dvb_attach(tda18271_attach, port->dvb.frontend, 349 dvb_attach(tda18271_attach, fe0->dvb.frontend,
345 0x60, &dev->i2c_bus[1].i2c_adap, 350 0x60, &dev->i2c_bus[1].i2c_adap,
346 &hauppauge_tda18271_config); 351 &hauppauge_tda18271_config);
347 } 352 }
348 break; 353 break;
349 case 0: 354 case 0:
350 default: 355 default:
351 port->dvb.frontend = 356 fe0->dvb.frontend =
352 dvb_attach(s5h1409_attach, 357 dvb_attach(s5h1409_attach,
353 &hauppauge_generic_config, 358 &hauppauge_generic_config,
354 &i2c_bus->i2c_adap); 359 &i2c_bus->i2c_adap);
355 if (port->dvb.frontend != NULL) 360 if (fe0->dvb.frontend != NULL)
356 dvb_attach(mt2131_attach, port->dvb.frontend, 361 dvb_attach(mt2131_attach, fe0->dvb.frontend,
357 &i2c_bus->i2c_adap, 362 &i2c_bus->i2c_adap,
358 &hauppauge_generic_tunerconfig, 0); 363 &hauppauge_generic_tunerconfig, 0);
359 break; 364 break;
@@ -361,42 +366,42 @@ static int dvb_register(struct cx23885_tsport *port)
361 break; 366 break;
362 case CX23885_BOARD_HAUPPAUGE_HVR1800lp: 367 case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
363 i2c_bus = &dev->i2c_bus[0]; 368 i2c_bus = &dev->i2c_bus[0];
364 port->dvb.frontend = dvb_attach(s5h1409_attach, 369 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
365 &hauppauge_hvr1800lp_config, 370 &hauppauge_hvr1800lp_config,
366 &i2c_bus->i2c_adap); 371 &i2c_bus->i2c_adap);
367 if (port->dvb.frontend != NULL) { 372 if (fe0->dvb.frontend != NULL) {
368 dvb_attach(mt2131_attach, port->dvb.frontend, 373 dvb_attach(mt2131_attach, fe0->dvb.frontend,
369 &i2c_bus->i2c_adap, 374 &i2c_bus->i2c_adap,
370 &hauppauge_generic_tunerconfig, 0); 375 &hauppauge_generic_tunerconfig, 0);
371 } 376 }
372 break; 377 break;
373 case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: 378 case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
374 i2c_bus = &dev->i2c_bus[0]; 379 i2c_bus = &dev->i2c_bus[0];
375 port->dvb.frontend = dvb_attach(lgdt330x_attach, 380 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
376 &fusionhdtv_5_express, 381 &fusionhdtv_5_express,
377 &i2c_bus->i2c_adap); 382 &i2c_bus->i2c_adap);
378 if (port->dvb.frontend != NULL) { 383 if (fe0->dvb.frontend != NULL) {
379 dvb_attach(simple_tuner_attach, port->dvb.frontend, 384 dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
380 &i2c_bus->i2c_adap, 0x61, 385 &i2c_bus->i2c_adap, 0x61,
381 TUNER_LG_TDVS_H06XF); 386 TUNER_LG_TDVS_H06XF);
382 } 387 }
383 break; 388 break;
384 case CX23885_BOARD_HAUPPAUGE_HVR1500Q: 389 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
385 i2c_bus = &dev->i2c_bus[1]; 390 i2c_bus = &dev->i2c_bus[1];
386 port->dvb.frontend = dvb_attach(s5h1409_attach, 391 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
387 &hauppauge_hvr1500q_config, 392 &hauppauge_hvr1500q_config,
388 &dev->i2c_bus[0].i2c_adap); 393 &dev->i2c_bus[0].i2c_adap);
389 if (port->dvb.frontend != NULL) 394 if (fe0->dvb.frontend != NULL)
390 dvb_attach(xc5000_attach, port->dvb.frontend, 395 dvb_attach(xc5000_attach, fe0->dvb.frontend,
391 &i2c_bus->i2c_adap, 396 &i2c_bus->i2c_adap,
392 &hauppauge_hvr1500q_tunerconfig); 397 &hauppauge_hvr1500q_tunerconfig);
393 break; 398 break;
394 case CX23885_BOARD_HAUPPAUGE_HVR1500: 399 case CX23885_BOARD_HAUPPAUGE_HVR1500:
395 i2c_bus = &dev->i2c_bus[1]; 400 i2c_bus = &dev->i2c_bus[1];
396 port->dvb.frontend = dvb_attach(s5h1409_attach, 401 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
397 &hauppauge_hvr1500_config, 402 &hauppauge_hvr1500_config,
398 &dev->i2c_bus[0].i2c_adap); 403 &dev->i2c_bus[0].i2c_adap);
399 if (port->dvb.frontend != NULL) { 404 if (fe0->dvb.frontend != NULL) {
400 struct dvb_frontend *fe; 405 struct dvb_frontend *fe;
401 struct xc2028_config cfg = { 406 struct xc2028_config cfg = {
402 .i2c_adap = &i2c_bus->i2c_adap, 407 .i2c_adap = &i2c_bus->i2c_adap,
@@ -409,7 +414,7 @@ static int dvb_register(struct cx23885_tsport *port)
409 }; 414 };
410 415
411 fe = dvb_attach(xc2028_attach, 416 fe = dvb_attach(xc2028_attach,
412 port->dvb.frontend, &cfg); 417 fe0->dvb.frontend, &cfg);
413 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) 418 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
414 fe->ops.tuner_ops.set_config(fe, &ctl); 419 fe->ops.tuner_ops.set_config(fe, &ctl);
415 } 420 }
@@ -417,24 +422,24 @@ static int dvb_register(struct cx23885_tsport *port)
417 case CX23885_BOARD_HAUPPAUGE_HVR1200: 422 case CX23885_BOARD_HAUPPAUGE_HVR1200:
418 case CX23885_BOARD_HAUPPAUGE_HVR1700: 423 case CX23885_BOARD_HAUPPAUGE_HVR1700:
419 i2c_bus = &dev->i2c_bus[0]; 424 i2c_bus = &dev->i2c_bus[0];
420 port->dvb.frontend = dvb_attach(tda10048_attach, 425 fe0->dvb.frontend = dvb_attach(tda10048_attach,
421 &hauppauge_hvr1200_config, 426 &hauppauge_hvr1200_config,
422 &i2c_bus->i2c_adap); 427 &i2c_bus->i2c_adap);
423 if (port->dvb.frontend != NULL) { 428 if (fe0->dvb.frontend != NULL) {
424 dvb_attach(tda829x_attach, port->dvb.frontend, 429 dvb_attach(tda829x_attach, fe0->dvb.frontend,
425 &dev->i2c_bus[1].i2c_adap, 0x42, 430 &dev->i2c_bus[1].i2c_adap, 0x42,
426 &tda829x_no_probe); 431 &tda829x_no_probe);
427 dvb_attach(tda18271_attach, port->dvb.frontend, 432 dvb_attach(tda18271_attach, fe0->dvb.frontend,
428 0x60, &dev->i2c_bus[1].i2c_adap, 433 0x60, &dev->i2c_bus[1].i2c_adap,
429 &hauppauge_hvr1200_tuner_config); 434 &hauppauge_hvr1200_tuner_config);
430 } 435 }
431 break; 436 break;
432 case CX23885_BOARD_HAUPPAUGE_HVR1400: 437 case CX23885_BOARD_HAUPPAUGE_HVR1400:
433 i2c_bus = &dev->i2c_bus[0]; 438 i2c_bus = &dev->i2c_bus[0];
434 port->dvb.frontend = dvb_attach(dib7000p_attach, 439 fe0->dvb.frontend = dvb_attach(dib7000p_attach,
435 &i2c_bus->i2c_adap, 440 &i2c_bus->i2c_adap,
436 0x12, &hauppauge_hvr1400_dib7000_config); 441 0x12, &hauppauge_hvr1400_dib7000_config);
437 if (port->dvb.frontend != NULL) { 442 if (fe0->dvb.frontend != NULL) {
438 struct dvb_frontend *fe; 443 struct dvb_frontend *fe;
439 struct xc2028_config cfg = { 444 struct xc2028_config cfg = {
440 .i2c_adap = &dev->i2c_bus[1].i2c_adap, 445 .i2c_adap = &dev->i2c_bus[1].i2c_adap,
@@ -449,7 +454,7 @@ static int dvb_register(struct cx23885_tsport *port)
449 }; 454 };
450 455
451 fe = dvb_attach(xc2028_attach, 456 fe = dvb_attach(xc2028_attach,
452 port->dvb.frontend, &cfg); 457 fe0->dvb.frontend, &cfg);
453 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) 458 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
454 fe->ops.tuner_ops.set_config(fe, &ctl); 459 fe->ops.tuner_ops.set_config(fe, &ctl);
455 } 460 }
@@ -457,25 +462,25 @@ static int dvb_register(struct cx23885_tsport *port)
457 case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: 462 case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
458 i2c_bus = &dev->i2c_bus[port->nr - 1]; 463 i2c_bus = &dev->i2c_bus[port->nr - 1];
459 464
460 port->dvb.frontend = dvb_attach(s5h1409_attach, 465 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
461 &dvico_s5h1409_config, 466 &dvico_s5h1409_config,
462 &i2c_bus->i2c_adap); 467 &i2c_bus->i2c_adap);
463 if (port->dvb.frontend == NULL) 468 if (fe0->dvb.frontend == NULL)
464 port->dvb.frontend = dvb_attach(s5h1411_attach, 469 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
465 &dvico_s5h1411_config, 470 &dvico_s5h1411_config,
466 &i2c_bus->i2c_adap); 471 &i2c_bus->i2c_adap);
467 if (port->dvb.frontend != NULL) 472 if (fe0->dvb.frontend != NULL)
468 dvb_attach(xc5000_attach, port->dvb.frontend, 473 dvb_attach(xc5000_attach, fe0->dvb.frontend,
469 &i2c_bus->i2c_adap, 474 &i2c_bus->i2c_adap,
470 &dvico_xc5000_tunerconfig); 475 &dvico_xc5000_tunerconfig);
471 break; 476 break;
472 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { 477 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: {
473 i2c_bus = &dev->i2c_bus[port->nr - 1]; 478 i2c_bus = &dev->i2c_bus[port->nr - 1];
474 479
475 port->dvb.frontend = dvb_attach(zl10353_attach, 480 fe0->dvb.frontend = dvb_attach(zl10353_attach,
476 &dvico_fusionhdtv_xc3028, 481 &dvico_fusionhdtv_xc3028,
477 &i2c_bus->i2c_adap); 482 &i2c_bus->i2c_adap);
478 if (port->dvb.frontend != NULL) { 483 if (fe0->dvb.frontend != NULL) {
479 struct dvb_frontend *fe; 484 struct dvb_frontend *fe;
480 struct xc2028_config cfg = { 485 struct xc2028_config cfg = {
481 .i2c_adap = &i2c_bus->i2c_adap, 486 .i2c_adap = &i2c_bus->i2c_adap,
@@ -487,7 +492,7 @@ static int dvb_register(struct cx23885_tsport *port)
487 .demod = XC3028_FE_ZARLINK456, 492 .demod = XC3028_FE_ZARLINK456,
488 }; 493 };
489 494
490 fe = dvb_attach(xc2028_attach, port->dvb.frontend, 495 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
491 &cfg); 496 &cfg);
492 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) 497 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
493 fe->ops.tuner_ops.set_config(fe, &ctl); 498 fe->ops.tuner_ops.set_config(fe, &ctl);
@@ -497,10 +502,10 @@ static int dvb_register(struct cx23885_tsport *port)
497 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 502 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
498 i2c_bus = &dev->i2c_bus[0]; 503 i2c_bus = &dev->i2c_bus[0];
499 504
500 port->dvb.frontend = dvb_attach(zl10353_attach, 505 fe0->dvb.frontend = dvb_attach(zl10353_attach,
501 &dvico_fusionhdtv_xc3028, 506 &dvico_fusionhdtv_xc3028,
502 &i2c_bus->i2c_adap); 507 &i2c_bus->i2c_adap);
503 if (port->dvb.frontend != NULL) { 508 if (fe0->dvb.frontend != NULL) {
504 struct dvb_frontend *fe; 509 struct dvb_frontend *fe;
505 struct xc2028_config cfg = { 510 struct xc2028_config cfg = {
506 .i2c_adap = &dev->i2c_bus[1].i2c_adap, 511 .i2c_adap = &dev->i2c_bus[1].i2c_adap,
@@ -512,7 +517,7 @@ static int dvb_register(struct cx23885_tsport *port)
512 .demod = XC3028_FE_ZARLINK456, 517 .demod = XC3028_FE_ZARLINK456,
513 }; 518 };
514 519
515 fe = dvb_attach(xc2028_attach, port->dvb.frontend, 520 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
516 &cfg); 521 &cfg);
517 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) 522 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
518 fe->ops.tuner_ops.set_config(fe, &ctl); 523 fe->ops.tuner_ops.set_config(fe, &ctl);
@@ -523,29 +528,36 @@ static int dvb_register(struct cx23885_tsport *port)
523 dev->name); 528 dev->name);
524 break; 529 break;
525 } 530 }
526 if (NULL == port->dvb.frontend) { 531 if (NULL == fe0->dvb.frontend) {
527 printk("%s: frontend initialization failed\n", dev->name); 532 printk("%s: frontend initialization failed\n", dev->name);
528 return -1; 533 return -1;
529 } 534 }
530 /* define general-purpose callback pointer */ 535 /* define general-purpose callback pointer */
531 port->dvb.frontend->callback = cx23885_tuner_callback; 536 fe0->dvb.frontend->callback = cx23885_tuner_callback;
532 537
533 /* Put the analog decoder in standby to keep it quiet */ 538 /* Put the analog decoder in standby to keep it quiet */
534 cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); 539 cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
535 540
536 if (port->dvb.frontend->ops.analog_ops.standby) 541 if (fe0->dvb.frontend->ops.analog_ops.standby)
537 port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend); 542 fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
538 543
539 /* register everything */ 544 /* register everything */
540 return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, 545 return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
541 &dev->pci->dev, adapter_nr); 546 &dev->pci->dev, adapter_nr);
547
542} 548}
543 549
544int cx23885_dvb_register(struct cx23885_tsport *port) 550int cx23885_dvb_register(struct cx23885_tsport *port)
545{ 551{
552
553 struct videobuf_dvb_frontend *fe0;
546 struct cx23885_dev *dev = port->dev; 554 struct cx23885_dev *dev = port->dev;
547 int err; 555 int err;
548 556
557 fe0 = videobuf_dvb_get_frontend(&port->frontends, 0);
558 if (!fe0)
559 err = -EINVAL;
560
549 dprintk(1, "%s\n", __func__); 561 dprintk(1, "%s\n", __func__);
550 dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", 562 dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
551 dev->board, 563 dev->board,
@@ -557,7 +569,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
557 569
558 /* dvb stuff */ 570 /* dvb stuff */
559 printk("%s: cx23885 based dvb card\n", dev->name); 571 printk("%s: cx23885 based dvb card\n", dev->name);
560 videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, 572 videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock,
561 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, 573 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
562 sizeof(struct cx23885_buffer), port); 574 sizeof(struct cx23885_buffer), port);
563 err = dvb_register(port); 575 err = dvb_register(port);
@@ -569,9 +581,12 @@ int cx23885_dvb_register(struct cx23885_tsport *port)
569 581
570int cx23885_dvb_unregister(struct cx23885_tsport *port) 582int cx23885_dvb_unregister(struct cx23885_tsport *port)
571{ 583{
584 struct videobuf_dvb_frontend *fe0;
585
586 fe0 = videobuf_dvb_get_frontend(&port->frontends, 0);
572 /* dvb */ 587 /* dvb */
573 if(port->dvb.frontend) 588 if(fe0->dvb.frontend)
574 videobuf_dvb_unregister(&port->dvb); 589 videobuf_dvb_unregister_bus(&port->frontends);
575 590
576 return 0; 591 return 0;
577} 592}
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index ba4e0aaed463..aa34bf9ea4d9 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -225,7 +225,7 @@ struct cx23885_tsport {
225 int nr; 225 int nr;
226 int sram_chno; 226 int sram_chno;
227 227
228 struct videobuf_dvb dvb; 228 struct videobuf_dvb_frontends frontends;
229 229
230 /* dma queues */ 230 /* dma queues */
231 struct cx23885_dmaqueue mpegq; 231 struct cx23885_dmaqueue mpegq;
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 5da04e811ca2..638d9ec38d7f 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1291,6 +1291,7 @@ static const struct cx88_board cx88_boards[] = {
1291 .gpio0 = 0x84bf, 1291 .gpio0 = 0x84bf,
1292 }}, 1292 }},
1293 .mpeg = CX88_MPEG_DVB, 1293 .mpeg = CX88_MPEG_DVB,
1294 .num_frontends = 2,
1294 }, 1295 },
1295 [CX88_BOARD_NORWOOD_MICRO] = { 1296 [CX88_BOARD_NORWOOD_MICRO] = {
1296 .name = "Norwood Micro TV Tuner", 1297 .name = "Norwood Micro TV Tuner",
@@ -1761,6 +1762,7 @@ static const struct cx88_board cx88_boards[] = {
1761 } }, 1762 } },
1762 /* fixme: Add radio support */ 1763 /* fixme: Add radio support */
1763 .mpeg = CX88_MPEG_DVB, 1764 .mpeg = CX88_MPEG_DVB,
1765 .num_frontends = 2,
1764 }, 1766 },
1765 [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = { 1767 [CX88_BOARD_HAUPPAUGE_HVR4000LITE] = {
1766 .name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2", 1768 .name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2",
@@ -3002,12 +3004,17 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
3002 cx88_card_list(core, pci); 3004 cx88_card_list(core, pci);
3003 } 3005 }
3004 3006
3007 memset(&core->board, 0, sizeof(core->board));
3005 memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board)); 3008 memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
3006 3009
3007 info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s]\n", 3010 if (!core->board.num_frontends)
3011 core->board.num_frontends=1;
3012
3013 info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n",
3008 pci->subsystem_vendor, pci->subsystem_device, core->board.name, 3014 pci->subsystem_vendor, pci->subsystem_device, core->board.name,
3009 core->boardnr, card[core->nr] == core->boardnr ? 3015 core->boardnr, card[core->nr] == core->boardnr ?
3010 "insmod option" : "autodetected"); 3016 "insmod option" : "autodetected",
3017 core->board.num_frontends);
3011 3018
3012 if (tuner[core->nr] != UNSET) 3019 if (tuner[core->nr] != UNSET)
3013 core->board.tuner_type = tuner[core->nr]; 3020 core->board.tuner_type = tuner[core->nr];
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 344ed2626e59..099de66c72c4 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -116,13 +116,24 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
116 struct cx8802_dev *dev= fe->dvb->priv; 116 struct cx8802_dev *dev= fe->dvb->priv;
117 struct cx8802_driver *drv = NULL; 117 struct cx8802_driver *drv = NULL;
118 int ret = 0; 118 int ret = 0;
119 int fe_id;
120
121 fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
122 if (!fe_id) {
123 printk(KERN_ERR "%s() No frontend found\n", __FUNCTION__);
124 return -EINVAL;
125 }
126
119 127
120 drv = cx8802_get_driver(dev, CX88_MPEG_DVB); 128 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
121 if (drv) { 129 if (drv) {
122 if (acquire) 130 if (acquire){
131 dev->frontends.active_fe_id = fe_id;
123 ret = drv->request_acquire(drv); 132 ret = drv->request_acquire(drv);
124 else 133 } else {
125 ret = drv->request_release(drv); 134 ret = drv->request_release(drv);
135 dev->frontends.active_fe_id = 0;
136 }
126 } 137 }
127 138
128 return ret; 139 return ret;
@@ -396,7 +407,7 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
396 cx_write(MO_GP0_IO, 0x00006060); 407 cx_write(MO_GP0_IO, 0x00006060);
397 break; 408 break;
398 case SEC_VOLTAGE_OFF: 409 case SEC_VOLTAGE_OFF:
399 printk("LNB Voltage SEC_VOLTAGE_off\n"); 410 printk("LNB Voltage SEC_VOLTAGE_off\n");
400 break; 411 break;
401 } 412 }
402 413
@@ -483,6 +494,7 @@ static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
483static int attach_xc3028(u8 addr, struct cx8802_dev *dev) 494static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
484{ 495{
485 struct dvb_frontend *fe; 496 struct dvb_frontend *fe;
497 struct videobuf_dvb_frontend *fe0 = NULL;
486 struct xc2028_ctrl ctl; 498 struct xc2028_ctrl ctl;
487 struct xc2028_config cfg = { 499 struct xc2028_config cfg = {
488 .i2c_adap = &dev->core->i2c_adap, 500 .i2c_adap = &dev->core->i2c_adap,
@@ -490,7 +502,12 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
490 .ctrl = &ctl, 502 .ctrl = &ctl,
491 }; 503 };
492 504
493 if (!dev->dvb.frontend) { 505/* Get the first frontend */
506 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
507 if (!fe0)
508 return -EINVAL;
509
510 if (!fe0->dvb.frontend) {
494 printk(KERN_ERR "%s/2: dvb frontend not attached. " 511 printk(KERN_ERR "%s/2: dvb frontend not attached. "
495 "Can't attach xc3028\n", 512 "Can't attach xc3028\n",
496 dev->core->name); 513 dev->core->name);
@@ -504,10 +521,13 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
504 */ 521 */
505 cx88_setup_xc3028(dev->core, &ctl); 522 cx88_setup_xc3028(dev->core, &ctl);
506 523
507 fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); 524 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
508 if (!fe) { 525 if (!fe) {
509 printk(KERN_ERR "%s/2: xc3028 attach failed\n", 526 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
510 dev->core->name); 527 dev->core->name);
528 dvb_frontend_detach(fe0->dvb.frontend);
529 dvb_unregister_frontend(fe0->dvb.frontend);
530 fe0->dvb.frontend = NULL;
511 return -EINVAL; 531 return -EINVAL;
512 } 532 }
513 533
@@ -532,8 +552,10 @@ static int cx24116_reset_device(struct dvb_frontend *fe)
532 struct cx88_core *core = dev->core; 552 struct cx88_core *core = dev->core;
533 553
534 /* Reset the part */ 554 /* Reset the part */
555 /* Put the cx24116 into reset */
535 cx_write(MO_SRST_IO, 0); 556 cx_write(MO_SRST_IO, 0);
536 msleep(10); 557 msleep(10);
558 /* Take the cx24116 out of reset */
537 cx_write(MO_SRST_IO, 1); 559 cx_write(MO_SRST_IO, 1);
538 msleep(10); 560 msleep(10);
539 561
@@ -573,20 +595,28 @@ static struct stv0288_config tevii_tuner_earda_config = {
573 595
574static int dvb_register(struct cx8802_dev *dev) 596static int dvb_register(struct cx8802_dev *dev)
575{ 597{
598 //struct cx88_core *core = dev->core;
599
600 ///* init struct videobuf_dvb */
601 //fe->dvb.name = core->name;
602 //dev->ts_gen_cntrl = 0x0c;
603
576 struct cx88_core *core = dev->core; 604 struct cx88_core *core = dev->core;
605 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
577 606
578 /* init struct videobuf_dvb */ 607 /* Get the first frontend */
579 dev->dvb.name = core->name; 608 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
580 dev->ts_gen_cntrl = 0x0c; 609 if (!fe0)
610 return -EINVAL;
581 611
582 /* init frontend */ 612 /* init frontend */
583 switch (core->boardnr) { 613 switch (core->boardnr) {
584 case CX88_BOARD_HAUPPAUGE_DVB_T1: 614 case CX88_BOARD_HAUPPAUGE_DVB_T1:
585 dev->dvb.frontend = dvb_attach(cx22702_attach, 615 fe0->dvb.frontend = dvb_attach(cx22702_attach,
586 &connexant_refboard_config, 616 &connexant_refboard_config,
587 &core->i2c_adap); 617 &core->i2c_adap);
588 if (dev->dvb.frontend != NULL) { 618 if (fe0->dvb.frontend != NULL) {
589 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 619 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
590 0x61, &core->i2c_adap, 620 0x61, &core->i2c_adap,
591 DVB_PLL_THOMSON_DTT759X)) 621 DVB_PLL_THOMSON_DTT759X))
592 goto frontend_detach; 622 goto frontend_detach;
@@ -596,11 +626,11 @@ static int dvb_register(struct cx8802_dev *dev)
596 case CX88_BOARD_CONEXANT_DVB_T1: 626 case CX88_BOARD_CONEXANT_DVB_T1:
597 case CX88_BOARD_KWORLD_DVB_T_CX22702: 627 case CX88_BOARD_KWORLD_DVB_T_CX22702:
598 case CX88_BOARD_WINFAST_DTV1000: 628 case CX88_BOARD_WINFAST_DTV1000:
599 dev->dvb.frontend = dvb_attach(cx22702_attach, 629 fe0->dvb.frontend = dvb_attach(cx22702_attach,
600 &connexant_refboard_config, 630 &connexant_refboard_config,
601 &core->i2c_adap); 631 &core->i2c_adap);
602 if (dev->dvb.frontend != NULL) { 632 if (fe0->dvb.frontend != NULL) {
603 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 633 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
604 0x60, &core->i2c_adap, 634 0x60, &core->i2c_adap,
605 DVB_PLL_THOMSON_DTT7579)) 635 DVB_PLL_THOMSON_DTT7579))
606 goto frontend_detach; 636 goto frontend_detach;
@@ -610,33 +640,65 @@ static int dvb_register(struct cx8802_dev *dev)
610 case CX88_BOARD_HAUPPAUGE_HVR1100: 640 case CX88_BOARD_HAUPPAUGE_HVR1100:
611 case CX88_BOARD_HAUPPAUGE_HVR1100LP: 641 case CX88_BOARD_HAUPPAUGE_HVR1100LP:
612 case CX88_BOARD_HAUPPAUGE_HVR1300: 642 case CX88_BOARD_HAUPPAUGE_HVR1300:
613 case CX88_BOARD_HAUPPAUGE_HVR3000: 643 fe0->dvb.frontend = dvb_attach(cx22702_attach,
614 dev->dvb.frontend = dvb_attach(cx22702_attach,
615 &hauppauge_hvr_config, 644 &hauppauge_hvr_config,
616 &core->i2c_adap); 645 &core->i2c_adap);
617 if (dev->dvb.frontend != NULL) { 646 if (fe0->dvb.frontend != NULL) {
618 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 647 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
619 &core->i2c_adap, 0x61, 648 &core->i2c_adap, 0x61,
620 TUNER_PHILIPS_FMD1216ME_MK3)) 649 TUNER_PHILIPS_FMD1216ME_MK3))
621 goto frontend_detach; 650 goto frontend_detach;
622 } 651 }
623 break; 652 break;
653 case CX88_BOARD_HAUPPAUGE_HVR3000:
654 /* DVB-S init */
655 fe0->dvb.frontend = dvb_attach(cx24123_attach,
656 &hauppauge_novas_config,
657 &dev->core->i2c_adap);
658 if (fe0->dvb.frontend) {
659 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
660 &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
661 dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __FUNCTION__);
662 }
663 } else {
664 dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __FUNCTION__);
665 }
666 /* DVB-T init */
667 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
668 if (fe1) {
669 fe1->dvb.frontend = dvb_attach(cx22702_attach,
670 &hauppauge_hvr_config,
671 &dev->core->i2c_adap);
672 if (fe1->dvb.frontend) {
673 fe1->dvb.frontend->id = 1;
674 if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
675 &dev->core->i2c_adap, 0x61,
676 TUNER_PHILIPS_FMD1216ME_MK3)) {
677 dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __FUNCTION__);
678 }
679 } else {
680 dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __FUNCTION__);
681 }
682 } else {
683 dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__);
684 }
685 break;
624 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 686 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
625 dev->dvb.frontend = dvb_attach(mt352_attach, 687 fe0->dvb.frontend = dvb_attach(mt352_attach,
626 &dvico_fusionhdtv, 688 &dvico_fusionhdtv,
627 &core->i2c_adap); 689 &core->i2c_adap);
628 if (dev->dvb.frontend != NULL) { 690 if (fe0->dvb.frontend != NULL) {
629 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 691 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
630 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) 692 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
631 goto frontend_detach; 693 goto frontend_detach;
632 break; 694 break;
633 } 695 }
634 /* ZL10353 replaces MT352 on later cards */ 696 /* ZL10353 replaces MT352 on later cards */
635 dev->dvb.frontend = dvb_attach(zl10353_attach, 697 fe0->dvb.frontend = dvb_attach(zl10353_attach,
636 &dvico_fusionhdtv_plus_v1_1, 698 &dvico_fusionhdtv_plus_v1_1,
637 &core->i2c_adap); 699 &core->i2c_adap);
638 if (dev->dvb.frontend != NULL) { 700 if (fe0->dvb.frontend != NULL) {
639 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 701 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
640 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) 702 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
641 goto frontend_detach; 703 goto frontend_detach;
642 } 704 }
@@ -644,31 +706,31 @@ static int dvb_register(struct cx8802_dev *dev)
644 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: 706 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
645 /* The tin box says DEE1601, but it seems to be DTT7579 707 /* The tin box says DEE1601, but it seems to be DTT7579
646 * compatible, with a slightly different MT352 AGC gain. */ 708 * compatible, with a slightly different MT352 AGC gain. */
647 dev->dvb.frontend = dvb_attach(mt352_attach, 709 fe0->dvb.frontend = dvb_attach(mt352_attach,
648 &dvico_fusionhdtv_dual, 710 &dvico_fusionhdtv_dual,
649 &core->i2c_adap); 711 &core->i2c_adap);
650 if (dev->dvb.frontend != NULL) { 712 if (fe0->dvb.frontend != NULL) {
651 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 713 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
652 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) 714 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
653 goto frontend_detach; 715 goto frontend_detach;
654 break; 716 break;
655 } 717 }
656 /* ZL10353 replaces MT352 on later cards */ 718 /* ZL10353 replaces MT352 on later cards */
657 dev->dvb.frontend = dvb_attach(zl10353_attach, 719 fe0->dvb.frontend = dvb_attach(zl10353_attach,
658 &dvico_fusionhdtv_plus_v1_1, 720 &dvico_fusionhdtv_plus_v1_1,
659 &core->i2c_adap); 721 &core->i2c_adap);
660 if (dev->dvb.frontend != NULL) { 722 if (fe0->dvb.frontend != NULL) {
661 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 723 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
662 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) 724 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
663 goto frontend_detach; 725 goto frontend_detach;
664 } 726 }
665 break; 727 break;
666 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 728 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
667 dev->dvb.frontend = dvb_attach(mt352_attach, 729 fe0->dvb.frontend = dvb_attach(mt352_attach,
668 &dvico_fusionhdtv, 730 &dvico_fusionhdtv,
669 &core->i2c_adap); 731 &core->i2c_adap);
670 if (dev->dvb.frontend != NULL) { 732 if (fe0->dvb.frontend != NULL) {
671 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 733 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
672 0x61, NULL, DVB_PLL_LG_Z201)) 734 0x61, NULL, DVB_PLL_LG_Z201))
673 goto frontend_detach; 735 goto frontend_detach;
674 } 736 }
@@ -676,11 +738,11 @@ static int dvb_register(struct cx8802_dev *dev)
676 case CX88_BOARD_KWORLD_DVB_T: 738 case CX88_BOARD_KWORLD_DVB_T:
677 case CX88_BOARD_DNTV_LIVE_DVB_T: 739 case CX88_BOARD_DNTV_LIVE_DVB_T:
678 case CX88_BOARD_ADSTECH_DVB_T_PCI: 740 case CX88_BOARD_ADSTECH_DVB_T_PCI:
679 dev->dvb.frontend = dvb_attach(mt352_attach, 741 fe0->dvb.frontend = dvb_attach(mt352_attach,
680 &dntv_live_dvbt_config, 742 &dntv_live_dvbt_config,
681 &core->i2c_adap); 743 &core->i2c_adap);
682 if (dev->dvb.frontend != NULL) { 744 if (fe0->dvb.frontend != NULL) {
683 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 745 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
684 0x61, NULL, DVB_PLL_UNKNOWN_1)) 746 0x61, NULL, DVB_PLL_UNKNOWN_1))
685 goto frontend_detach; 747 goto frontend_detach;
686 } 748 }
@@ -688,10 +750,10 @@ static int dvb_register(struct cx8802_dev *dev)
688 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 750 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
689#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) 751#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
690 /* MT352 is on a secondary I2C bus made from some GPIO lines */ 752 /* MT352 is on a secondary I2C bus made from some GPIO lines */
691 dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, 753 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
692 &dev->vp3054->adap); 754 &dev->vp3054->adap);
693 if (dev->dvb.frontend != NULL) { 755 if (fe0->dvb.frontend != NULL) {
694 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 756 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
695 &core->i2c_adap, 0x61, 757 &core->i2c_adap, 0x61,
696 TUNER_PHILIPS_FMD1216ME_MK3)) 758 TUNER_PHILIPS_FMD1216ME_MK3))
697 goto frontend_detach; 759 goto frontend_detach;
@@ -702,22 +764,22 @@ static int dvb_register(struct cx8802_dev *dev)
702#endif 764#endif
703 break; 765 break;
704 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: 766 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
705 dev->dvb.frontend = dvb_attach(zl10353_attach, 767 fe0->dvb.frontend = dvb_attach(zl10353_attach,
706 &dvico_fusionhdtv_hybrid, 768 &dvico_fusionhdtv_hybrid,
707 &core->i2c_adap); 769 &core->i2c_adap);
708 if (dev->dvb.frontend != NULL) { 770 if (fe0->dvb.frontend != NULL) {
709 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 771 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
710 &core->i2c_adap, 0x61, 772 &core->i2c_adap, 0x61,
711 TUNER_THOMSON_FE6600)) 773 TUNER_THOMSON_FE6600))
712 goto frontend_detach; 774 goto frontend_detach;
713 } 775 }
714 break; 776 break;
715 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: 777 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
716 dev->dvb.frontend = dvb_attach(zl10353_attach, 778 fe0->dvb.frontend = dvb_attach(zl10353_attach,
717 &dvico_fusionhdtv_xc3028, 779 &dvico_fusionhdtv_xc3028,
718 &core->i2c_adap); 780 &core->i2c_adap);
719 if (dev->dvb.frontend == NULL) 781 if (fe0->dvb.frontend == NULL)
720 dev->dvb.frontend = dvb_attach(mt352_attach, 782 fe0->dvb.frontend = dvb_attach(mt352_attach,
721 &dvico_fusionhdtv_mt352_xc3028, 783 &dvico_fusionhdtv_mt352_xc3028,
722 &core->i2c_adap); 784 &core->i2c_adap);
723 /* 785 /*
@@ -725,16 +787,16 @@ static int dvb_register(struct cx8802_dev *dev)
725 * We must not permit gate_ctrl to be performed, or 787 * We must not permit gate_ctrl to be performed, or
726 * the xc3028 cannot communicate on the bus. 788 * the xc3028 cannot communicate on the bus.
727 */ 789 */
728 if (dev->dvb.frontend) 790 if (fe0->dvb.frontend)
729 dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; 791 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
730 if (attach_xc3028(0x61, dev) < 0) 792 if (attach_xc3028(0x61, dev) < 0)
731 return -EINVAL; 793 return -EINVAL;
732 break; 794 break;
733 case CX88_BOARD_PCHDTV_HD3000: 795 case CX88_BOARD_PCHDTV_HD3000:
734 dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, 796 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
735 &core->i2c_adap); 797 &core->i2c_adap);
736 if (dev->dvb.frontend != NULL) { 798 if (fe0->dvb.frontend != NULL) {
737 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 799 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
738 &core->i2c_adap, 0x61, 800 &core->i2c_adap, 0x61,
739 TUNER_THOMSON_DTT761X)) 801 TUNER_THOMSON_DTT761X))
740 goto frontend_detach; 802 goto frontend_detach;
@@ -751,11 +813,11 @@ static int dvb_register(struct cx8802_dev *dev)
751 813
752 /* Select RF connector callback */ 814 /* Select RF connector callback */
753 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; 815 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
754 dev->dvb.frontend = dvb_attach(lgdt330x_attach, 816 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
755 &fusionhdtv_3_gold, 817 &fusionhdtv_3_gold,
756 &core->i2c_adap); 818 &core->i2c_adap);
757 if (dev->dvb.frontend != NULL) { 819 if (fe0->dvb.frontend != NULL) {
758 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 820 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
759 &core->i2c_adap, 0x61, 821 &core->i2c_adap, 0x61,
760 TUNER_MICROTUNE_4042FI5)) 822 TUNER_MICROTUNE_4042FI5))
761 goto frontend_detach; 823 goto frontend_detach;
@@ -769,11 +831,11 @@ static int dvb_register(struct cx8802_dev *dev)
769 mdelay(100); 831 mdelay(100);
770 cx_set(MO_GP0_IO, 9); 832 cx_set(MO_GP0_IO, 9);
771 mdelay(200); 833 mdelay(200);
772 dev->dvb.frontend = dvb_attach(lgdt330x_attach, 834 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
773 &fusionhdtv_3_gold, 835 &fusionhdtv_3_gold,
774 &core->i2c_adap); 836 &core->i2c_adap);
775 if (dev->dvb.frontend != NULL) { 837 if (fe0->dvb.frontend != NULL) {
776 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 838 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
777 &core->i2c_adap, 0x61, 839 &core->i2c_adap, 0x61,
778 TUNER_THOMSON_DTT761X)) 840 TUNER_THOMSON_DTT761X))
779 goto frontend_detach; 841 goto frontend_detach;
@@ -787,15 +849,15 @@ static int dvb_register(struct cx8802_dev *dev)
787 mdelay(100); 849 mdelay(100);
788 cx_set(MO_GP0_IO, 1); 850 cx_set(MO_GP0_IO, 1);
789 mdelay(200); 851 mdelay(200);
790 dev->dvb.frontend = dvb_attach(lgdt330x_attach, 852 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
791 &fusionhdtv_5_gold, 853 &fusionhdtv_5_gold,
792 &core->i2c_adap); 854 &core->i2c_adap);
793 if (dev->dvb.frontend != NULL) { 855 if (fe0->dvb.frontend != NULL) {
794 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 856 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
795 &core->i2c_adap, 0x61, 857 &core->i2c_adap, 0x61,
796 TUNER_LG_TDVS_H06XF)) 858 TUNER_LG_TDVS_H06XF))
797 goto frontend_detach; 859 goto frontend_detach;
798 if (!dvb_attach(tda9887_attach, dev->dvb.frontend, 860 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
799 &core->i2c_adap, 0x43)) 861 &core->i2c_adap, 0x43))
800 goto frontend_detach; 862 goto frontend_detach;
801 } 863 }
@@ -808,25 +870,25 @@ static int dvb_register(struct cx8802_dev *dev)
808 mdelay(100); 870 mdelay(100);
809 cx_set(MO_GP0_IO, 1); 871 cx_set(MO_GP0_IO, 1);
810 mdelay(200); 872 mdelay(200);
811 dev->dvb.frontend = dvb_attach(lgdt330x_attach, 873 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
812 &pchdtv_hd5500, 874 &pchdtv_hd5500,
813 &core->i2c_adap); 875 &core->i2c_adap);
814 if (dev->dvb.frontend != NULL) { 876 if (fe0->dvb.frontend != NULL) {
815 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 877 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
816 &core->i2c_adap, 0x61, 878 &core->i2c_adap, 0x61,
817 TUNER_LG_TDVS_H06XF)) 879 TUNER_LG_TDVS_H06XF))
818 goto frontend_detach; 880 goto frontend_detach;
819 if (!dvb_attach(tda9887_attach, dev->dvb.frontend, 881 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
820 &core->i2c_adap, 0x43)) 882 &core->i2c_adap, 0x43))
821 goto frontend_detach; 883 goto frontend_detach;
822 } 884 }
823 break; 885 break;
824 case CX88_BOARD_ATI_HDTVWONDER: 886 case CX88_BOARD_ATI_HDTVWONDER:
825 dev->dvb.frontend = dvb_attach(nxt200x_attach, 887 fe0->dvb.frontend = dvb_attach(nxt200x_attach,
826 &ati_hdtvwonder, 888 &ati_hdtvwonder,
827 &core->i2c_adap); 889 &core->i2c_adap);
828 if (dev->dvb.frontend != NULL) { 890 if (fe0->dvb.frontend != NULL) {
829 if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend, 891 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
830 &core->i2c_adap, 0x61, 892 &core->i2c_adap, 0x61,
831 TUNER_PHILIPS_TUV1236D)) 893 TUNER_PHILIPS_TUV1236D))
832 goto frontend_detach; 894 goto frontend_detach;
@@ -834,49 +896,49 @@ static int dvb_register(struct cx8802_dev *dev)
834 break; 896 break;
835 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 897 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
836 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 898 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
837 dev->dvb.frontend = dvb_attach(cx24123_attach, 899 fe0->dvb.frontend = dvb_attach(cx24123_attach,
838 &hauppauge_novas_config, 900 &hauppauge_novas_config,
839 &core->i2c_adap); 901 &core->i2c_adap);
840 if (dev->dvb.frontend) { 902 if (fe0->dvb.frontend) {
841 if (!dvb_attach(isl6421_attach, dev->dvb.frontend, 903 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
842 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) 904 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
843 goto frontend_detach; 905 goto frontend_detach;
844 } 906 }
845 break; 907 break;
846 case CX88_BOARD_KWORLD_DVBS_100: 908 case CX88_BOARD_KWORLD_DVBS_100:
847 dev->dvb.frontend = dvb_attach(cx24123_attach, 909 fe0->dvb.frontend = dvb_attach(cx24123_attach,
848 &kworld_dvbs_100_config, 910 &kworld_dvbs_100_config,
849 &core->i2c_adap); 911 &core->i2c_adap);
850 if (dev->dvb.frontend) { 912 if (fe0->dvb.frontend) {
851 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; 913 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
852 dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; 914 fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
853 } 915 }
854 break; 916 break;
855 case CX88_BOARD_GENIATECH_DVBS: 917 case CX88_BOARD_GENIATECH_DVBS:
856 dev->dvb.frontend = dvb_attach(cx24123_attach, 918 fe0->dvb.frontend = dvb_attach(cx24123_attach,
857 &geniatech_dvbs_config, 919 &geniatech_dvbs_config,
858 &core->i2c_adap); 920 &core->i2c_adap);
859 if (dev->dvb.frontend) { 921 if (fe0->dvb.frontend) {
860 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; 922 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
861 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; 923 fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
862 } 924 }
863 break; 925 break;
864 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 926 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
865 dev->dvb.frontend = dvb_attach(s5h1409_attach, 927 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
866 &pinnacle_pctv_hd_800i_config, 928 &pinnacle_pctv_hd_800i_config,
867 &core->i2c_adap); 929 &core->i2c_adap);
868 if (dev->dvb.frontend != NULL) { 930 if (fe0->dvb.frontend != NULL) {
869 if (!dvb_attach(xc5000_attach, dev->dvb.frontend, 931 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
870 &core->i2c_adap, 932 &core->i2c_adap,
871 &pinnacle_pctv_hd_800i_tuner_config)) 933 &pinnacle_pctv_hd_800i_tuner_config))
872 goto frontend_detach; 934 goto frontend_detach;
873 } 935 }
874 break; 936 break;
875 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: 937 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
876 dev->dvb.frontend = dvb_attach(s5h1409_attach, 938 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
877 &dvico_hdtv5_pci_nano_config, 939 &dvico_hdtv5_pci_nano_config,
878 &core->i2c_adap); 940 &core->i2c_adap);
879 if (dev->dvb.frontend != NULL) { 941 if (fe0->dvb.frontend != NULL) {
880 struct dvb_frontend *fe; 942 struct dvb_frontend *fe;
881 struct xc2028_config cfg = { 943 struct xc2028_config cfg = {
882 .i2c_adap = &core->i2c_adap, 944 .i2c_adap = &core->i2c_adap,
@@ -889,17 +951,17 @@ static int dvb_register(struct cx8802_dev *dev)
889 }; 951 };
890 952
891 fe = dvb_attach(xc2028_attach, 953 fe = dvb_attach(xc2028_attach,
892 dev->dvb.frontend, &cfg); 954 fe0->dvb.frontend, &cfg);
893 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) 955 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
894 fe->ops.tuner_ops.set_config(fe, &ctl); 956 fe->ops.tuner_ops.set_config(fe, &ctl);
895 } 957 }
896 break; 958 break;
897 case CX88_BOARD_PINNACLE_HYBRID_PCTV: 959 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
898 dev->dvb.frontend = dvb_attach(zl10353_attach, 960 fe0->dvb.frontend = dvb_attach(zl10353_attach,
899 &cx88_pinnacle_hybrid_pctv, 961 &cx88_pinnacle_hybrid_pctv,
900 &core->i2c_adap); 962 &core->i2c_adap);
901 if (dev->dvb.frontend) { 963 if (fe0->dvb.frontend) {
902 dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; 964 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
903 if (attach_xc3028(0x61, dev) < 0) 965 if (attach_xc3028(0x61, dev) < 0)
904 goto frontend_detach; 966 goto frontend_detach;
905 } 967 }
@@ -907,85 +969,116 @@ static int dvb_register(struct cx8802_dev *dev)
907 case CX88_BOARD_GENIATECH_X8000_MT: 969 case CX88_BOARD_GENIATECH_X8000_MT:
908 dev->ts_gen_cntrl = 0x00; 970 dev->ts_gen_cntrl = 0x00;
909 971
910 dev->dvb.frontend = dvb_attach(zl10353_attach, 972 fe0->dvb.frontend = dvb_attach(zl10353_attach,
911 &cx88_geniatech_x8000_mt, 973 &cx88_geniatech_x8000_mt,
912 &core->i2c_adap); 974 &core->i2c_adap);
913 if (attach_xc3028(0x61, dev) < 0) 975 if (attach_xc3028(0x61, dev) < 0)
914 goto frontend_detach; 976 goto frontend_detach;
915 break; 977 break;
916 case CX88_BOARD_KWORLD_ATSC_120: 978 case CX88_BOARD_KWORLD_ATSC_120:
917 dev->dvb.frontend = dvb_attach(s5h1409_attach, 979 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
918 &kworld_atsc_120_config, 980 &kworld_atsc_120_config,
919 &core->i2c_adap); 981 &core->i2c_adap);
920 if (attach_xc3028(0x61, dev) < 0) 982 if (attach_xc3028(0x61, dev) < 0)
921 goto frontend_detach; 983 goto frontend_detach;
922 break; 984 break;
923 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: 985 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
924 dev->dvb.frontend = dvb_attach(s5h1411_attach, 986 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
925 &dvico_fusionhdtv7_config, 987 &dvico_fusionhdtv7_config,
926 &core->i2c_adap); 988 &core->i2c_adap);
927 if (dev->dvb.frontend != NULL) { 989 if (fe0->dvb.frontend != NULL) {
928 if (!dvb_attach(xc5000_attach, dev->dvb.frontend, 990 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
929 &core->i2c_adap, 991 &core->i2c_adap,
930 &dvico_fusionhdtv7_tuner_config)) 992 &dvico_fusionhdtv7_tuner_config))
931 goto frontend_detach; 993 goto frontend_detach;
932 } 994 }
933 break; 995 break;
934 case CX88_BOARD_HAUPPAUGE_HVR4000: 996 case CX88_BOARD_HAUPPAUGE_HVR4000:
997 /* DVB-S/S2 Init */
998 fe0->dvb.frontend = dvb_attach(cx24116_attach,
999 &hauppauge_hvr4000_config,
1000 &dev->core->i2c_adap);
1001 if (fe0->dvb.frontend) {
1002 if(!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1003 &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
1004 dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __FUNCTION__);
1005 }
1006 } else {
1007 dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __FUNCTION__);
1008 }
1009 /* DVB-T Init */
1010 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
1011 if (fe1) {
1012 fe1->dvb.frontend = dvb_attach(cx22702_attach,
1013 &hauppauge_hvr_config,
1014 &dev->core->i2c_adap);
1015 if (fe1->dvb.frontend) {
1016 fe1->dvb.frontend->id = 1;
1017 if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
1018 &dev->core->i2c_adap, 0x61,
1019 TUNER_PHILIPS_FMD1216ME_MK3)) {
1020 dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __FUNCTION__);
1021 }
1022 } else {
1023 dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __FUNCTION__);
1024 }
1025 } else {
1026 dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __FUNCTION__);
1027 }
1028 break;
935 case CX88_BOARD_HAUPPAUGE_HVR4000LITE: 1029 case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
936 /* Support for DVB-S only, not DVB-T support */ 1030 fe0->dvb.frontend = dvb_attach(cx24116_attach,
937 dev->dvb.frontend = dvb_attach(cx24116_attach,
938 &hauppauge_hvr4000_config, 1031 &hauppauge_hvr4000_config,
939 &dev->core->i2c_adap); 1032 &dev->core->i2c_adap);
940 if (dev->dvb.frontend) { 1033 if (fe0->dvb.frontend) {
941 dvb_attach(isl6421_attach, dev->dvb.frontend, 1034 dvb_attach(isl6421_attach, fe0->dvb.frontend,
942 &dev->core->i2c_adap, 1035 &dev->core->i2c_adap,
943 0x08, ISL6421_DCL, 0x00); 1036 0x08, ISL6421_DCL, 0x00);
944 } 1037 }
945 break; 1038 break;
946 case CX88_BOARD_TEVII_S420: 1039 case CX88_BOARD_TEVII_S420:
947 dev->dvb.frontend = dvb_attach(stv0299_attach, 1040 fe0->dvb.frontend = dvb_attach(stv0299_attach,
948 &tevii_tuner_sharp_config, 1041 &tevii_tuner_sharp_config,
949 &core->i2c_adap); 1042 &core->i2c_adap);
950 if (dev->dvb.frontend != NULL) { 1043 if (fe0->dvb.frontend != NULL) {
951 if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, 1044 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
952 &core->i2c_adap, DVB_PLL_OPERA1)) 1045 &core->i2c_adap, DVB_PLL_OPERA1))
953 goto frontend_detach; 1046 goto frontend_detach;
954 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; 1047 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
955 dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1048 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
956 1049
957 } else { 1050 } else {
958 dev->dvb.frontend = dvb_attach(stv0288_attach, 1051 fe0->dvb.frontend = dvb_attach(stv0288_attach,
959 &tevii_tuner_earda_config, 1052 &tevii_tuner_earda_config,
960 &core->i2c_adap); 1053 &core->i2c_adap);
961 if (dev->dvb.frontend != NULL) { 1054 if (fe0->dvb.frontend != NULL) {
962 if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61, 1055 if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
963 &core->i2c_adap)) 1056 &core->i2c_adap))
964 goto frontend_detach; 1057 goto frontend_detach;
965 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; 1058 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
966 dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1059 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
967 1060
968 } 1061 }
969 } 1062 }
970 break; 1063 break;
971 case CX88_BOARD_TEVII_S460: 1064 case CX88_BOARD_TEVII_S460:
972 dev->dvb.frontend = dvb_attach(cx24116_attach, 1065 fe0->dvb.frontend = dvb_attach(cx24116_attach,
973 &tevii_s460_config, 1066 &tevii_s460_config,
974 &core->i2c_adap); 1067 &core->i2c_adap);
975 if (dev->dvb.frontend != NULL) { 1068 if (fe0->dvb.frontend != NULL) {
976 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; 1069 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
977 dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1070 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
978 } 1071 }
979 break; 1072 break;
980 case CX88_BOARD_OMICOM_SS4_PCI: 1073 case CX88_BOARD_OMICOM_SS4_PCI:
981 case CX88_BOARD_TBS_8920: 1074 case CX88_BOARD_TBS_8920:
982 case CX88_BOARD_PROF_7300: 1075 case CX88_BOARD_PROF_7300:
983 dev->dvb.frontend = dvb_attach(cx24116_attach, 1076 fe0->dvb.frontend = dvb_attach(cx24116_attach,
984 &hauppauge_hvr4000_config, 1077 &hauppauge_hvr4000_config,
985 &core->i2c_adap); 1078 &core->i2c_adap);
986 if (dev->dvb.frontend != NULL) { 1079 if (fe0->dvb.frontend != NULL) {
987 core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; 1080 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
988 dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1081 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
989 } 1082 }
990 break; 1083 break;
991 default: 1084 default:
@@ -993,29 +1086,32 @@ static int dvb_register(struct cx8802_dev *dev)
993 core->name); 1086 core->name);
994 break; 1087 break;
995 } 1088 }
996 if (NULL == dev->dvb.frontend) { 1089
1090 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
997 printk(KERN_ERR 1091 printk(KERN_ERR
998 "%s/2: frontend initialization failed\n", 1092 "%s/2: frontend initialization failed\n",
999 core->name); 1093 core->name);
1000 return -EINVAL; 1094 return -EINVAL;
1001 } 1095 }
1002 /* define general-purpose callback pointer */ 1096 /* define general-purpose callback pointer */
1003 dev->dvb.frontend->callback = cx88_tuner_callback; 1097 fe0->dvb.frontend->callback = cx88_tuner_callback;
1004 1098
1005 /* Ensure all frontends negotiate bus access */ 1099 /* Ensure all frontends negotiate bus access */
1006 dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 1100 fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1101 if (fe1)
1102 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1007 1103
1008 /* Put the analog decoder in standby to keep it quiet */ 1104 /* Put the analog decoder in standby to keep it quiet */
1009 cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL); 1105 cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
1010 1106
1011 /* register everything */ 1107 /* register everything */
1012 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, 1108 return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1013 &dev->pci->dev, adapter_nr); 1109 &dev->pci->dev, adapter_nr);
1014 1110
1015frontend_detach: 1111frontend_detach:
1016 if (dev->dvb.frontend) { 1112 if (fe0->dvb.frontend) {
1017 dvb_frontend_detach(dev->dvb.frontend); 1113 dvb_frontend_detach(fe0->dvb.frontend);
1018 dev->dvb.frontend = NULL; 1114 fe0->dvb.frontend = NULL;
1019 } 1115 }
1020 return -EINVAL; 1116 return -EINVAL;
1021} 1117}
@@ -1039,6 +1135,66 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
1039 cx_clear(MO_GP0_IO, 0x00000004); 1135 cx_clear(MO_GP0_IO, 0x00000004);
1040 udelay(1000); 1136 udelay(1000);
1041 break; 1137 break;
1138
1139 case CX88_BOARD_HAUPPAUGE_HVR3000: /* ? */
1140 if(core->dvbdev->frontends.active_fe_id == 1) {
1141 /* DVB-S/S2 Enabled */
1142
1143 /* Toggle reset on cx22702 leaving i2c active */
1144 cx_write(MO_GP0_IO, core->board.input[0].gpio0);
1145 udelay(1000);
1146 cx_clear(MO_GP0_IO, 0x00000080);
1147 udelay(50);
1148 cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
1149 cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
1150 udelay(1000);
1151
1152 cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
1153 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1154 } else
1155 if (core->dvbdev->frontends.active_fe_id == 2) {
1156 /* DVB-T Enabled */
1157
1158 /* Put the cx24116/cx24123 into reset */
1159 cx_write(MO_SRST_IO, 0);
1160
1161 /* cx22702 out of reset and enable it */
1162 cx_set(MO_GP0_IO, 0x00000080);
1163 cx_clear(MO_GP0_IO, 0x00000004);
1164 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1165 udelay(1000);
1166 }
1167 break;
1168 case CX88_BOARD_HAUPPAUGE_HVR4000:
1169 if(core->dvbdev->frontends.active_fe_id == 1) {
1170 /* DVB-S/S2 Enabled */
1171
1172 /* Toggle reset on cx22702 leaving i2c active */
1173 cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080);
1174 udelay(1000);
1175 cx_clear(MO_GP0_IO, 0x00000080);
1176 udelay(50);
1177 cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
1178 cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
1179 udelay(1000);
1180
1181 cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
1182 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
1183 } else
1184 if (core->dvbdev->frontends.active_fe_id == 2) {
1185 /* DVB-T Enabled */
1186
1187 /* Put the cx24116/cx24123 into reset */
1188 cx_write(MO_SRST_IO, 0);
1189
1190 /* cx22702 out of reset and enable it */
1191 cx_set(MO_GP0_IO, 0x00000080);
1192 cx_clear(MO_GP0_IO, 0x00000004);
1193 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
1194 udelay(1000);
1195 }
1196 break;
1197
1042 default: 1198 default:
1043 err = -ENODEV; 1199 err = -ENODEV;
1044 } 1200 }
@@ -1056,6 +1212,9 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
1056 case CX88_BOARD_HAUPPAUGE_HVR1300: 1212 case CX88_BOARD_HAUPPAUGE_HVR1300:
1057 /* Do Nothing, leave the cx22702 on the bus. */ 1213 /* Do Nothing, leave the cx22702 on the bus. */
1058 break; 1214 break;
1215 case CX88_BOARD_HAUPPAUGE_HVR3000:
1216 case CX88_BOARD_HAUPPAUGE_HVR4000:
1217 break;
1059 default: 1218 default:
1060 err = -ENODEV; 1219 err = -ENODEV;
1061 } 1220 }
@@ -1066,7 +1225,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
1066{ 1225{
1067 struct cx88_core *core = drv->core; 1226 struct cx88_core *core = drv->core;
1068 struct cx8802_dev *dev = drv->core->dvbdev; 1227 struct cx8802_dev *dev = drv->core->dvbdev;
1069 int err; 1228 int err,i;
1229 struct videobuf_dvb_frontend *fe;
1070 1230
1071 dprintk( 1, "%s\n", __func__); 1231 dprintk( 1, "%s\n", __func__);
1072 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", 1232 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1086,12 +1246,23 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
1086 1246
1087 /* dvb stuff */ 1247 /* dvb stuff */
1088 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); 1248 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
1089 videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops, 1249 dev->ts_gen_cntrl = 0x0c;
1250
1251 for (i = 1; i <= core->board.num_frontends; i++) {
1252 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
1253 if (!fe) {
1254 printk(KERN_ERR "%s() failed to get frontend(%d)\n", __FUNCTION__, i);
1255 continue;
1256 }
1257 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
1090 &dev->pci->dev, &dev->slock, 1258 &dev->pci->dev, &dev->slock,
1091 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1259 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1092 V4L2_FIELD_TOP, 1260 V4L2_FIELD_TOP,
1093 sizeof(struct cx88_buffer), 1261 sizeof(struct cx88_buffer),
1094 dev); 1262 dev);
1263 /* init struct videobuf_dvb */
1264 fe->dvb.name = dev->core->name;
1265 }
1095 err = dvb_register(dev); 1266 err = dvb_register(dev);
1096 if (err != 0) 1267 if (err != 0)
1097 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", 1268 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
@@ -1105,9 +1276,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv)
1105{ 1276{
1106 struct cx8802_dev *dev = drv->core->dvbdev; 1277 struct cx8802_dev *dev = drv->core->dvbdev;
1107 1278
1108 /* dvb */ 1279 videobuf_dvb_unregister_bus(&dev->frontends);
1109 if (dev->dvb.frontend)
1110 videobuf_dvb_unregister(&dev->dvb);
1111 1280
1112 vp3054_i2c_remove(dev); 1281 vp3054_i2c_remove(dev);
1113 1282
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 8e74d64fdcd2..582769de26b5 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -116,18 +116,23 @@ static int detach_inform(struct i2c_client *client)
116 116
117void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) 117void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
118{ 118{
119 struct videobuf_dvb_frontend *fe0 = NULL;
119 if (0 != core->i2c_rc) 120 if (0 != core->i2c_rc)
120 return; 121 return;
121 122
122#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) 123#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
123 if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) { 124 if (core->dvbdev) {
124 if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) 125 /* Get the first frontend and assume that all I2C is routed through it */
125 core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); 126 /* TODO: Get _THIS_FE_ then find the right i2c_gate_ctrl for it */
127 fe0 = videobuf_dvb_get_frontend(&core->dvbdev->frontends, 1);
128
129 if (fe0 && fe0->dvb.frontend && fe0->dvb.frontend->ops.i2c_gate_ctrl)
130 fe0->dvb.frontend->ops.i2c_gate_ctrl(fe0->dvb.frontend, 1);
126 131
127 i2c_clients_command(&core->i2c_adap, cmd, arg); 132 i2c_clients_command(&core->i2c_adap, cmd, arg);
128 133
129 if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl) 134 if (fe0 && fe0->dvb.frontend && fe0->dvb.frontend->ops.i2c_gate_ctrl)
130 core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); 135 fe0->dvb.frontend->ops.i2c_gate_ctrl(fe0->dvb.frontend, 0);
131 } else 136 } else
132#endif 137#endif
133 i2c_clients_command(&core->i2c_adap, cmd, arg); 138 i2c_clients_command(&core->i2c_adap, cmd, arg);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 8683d104de72..17150cb88c80 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -495,6 +495,7 @@ void cx88_ir_irq(struct cx88_core *core)
495 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 495 case CX88_BOARD_PINNACLE_PCTV_HD_800i:
496 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); 496 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
497 ir_dprintk("biphase decoded: %x\n", ircode); 497 ir_dprintk("biphase decoded: %x\n", ircode);
498//TODO Darron has other code here
498 if ((ircode & 0xfffff000) != 0x3000) 499 if ((ircode & 0xfffff000) != 0x3000)
499 break; 500 break;
500 ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode); 501 ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode);
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index a6b061c2644a..22c2a88fbf1c 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -768,7 +768,8 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
768{ 768{
769 struct cx8802_dev *dev; 769 struct cx8802_dev *dev;
770 struct cx88_core *core; 770 struct cx88_core *core;
771 int err; 771 struct videobuf_dvb_frontend *demod;
772 int err,i;
772 773
773 /* general setup */ 774 /* general setup */
774 core = cx88_core_get(pci_dev); 775 core = cx88_core_get(pci_dev);
@@ -781,6 +782,11 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
781 if (!core->board.mpeg) 782 if (!core->board.mpeg)
782 goto fail_core; 783 goto fail_core;
783 784
785 if (!core->board.num_frontends) {
786 printk(KERN_ERR "%s() .num_frontends should be non-zero, err = %d\n", __FUNCTION__, err);
787 goto fail_core;
788 }
789
784 err = -ENOMEM; 790 err = -ENOMEM;
785 dev = kzalloc(sizeof(*dev),GFP_KERNEL); 791 dev = kzalloc(sizeof(*dev),GFP_KERNEL);
786 if (NULL == dev) 792 if (NULL == dev)
@@ -795,6 +801,20 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
795 INIT_LIST_HEAD(&dev->drvlist); 801 INIT_LIST_HEAD(&dev->drvlist);
796 list_add_tail(&dev->devlist,&cx8802_devlist); 802 list_add_tail(&dev->devlist,&cx8802_devlist);
797 803
804 mutex_init(&dev->frontends.lock);
805 INIT_LIST_HEAD(&dev->frontends.frontend.felist);
806
807 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __FUNCTION__, core->board.num_frontends);
808
809 for (i = 1; i <= core->board.num_frontends; i++) {
810 demod = videobuf_dvb_alloc_frontend(dev, &dev->frontends, i);
811 if(demod == NULL) {
812 printk(KERN_ERR "%s() failed to alloc\n", __FUNCTION__);
813 err = -ENOMEM;
814 goto fail_free;
815 }
816 }
817
798 /* Maintain a reference so cx88-video can query the 8802 device. */ 818 /* Maintain a reference so cx88-video can query the 8802 device. */
799 core->dvbdev = dev; 819 core->dvbdev = dev;
800 820
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index dbf01b8b57a5..063f7b57e42a 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -261,6 +261,7 @@ struct cx88_board {
261 struct cx88_input radio; 261 struct cx88_input radio;
262 enum cx88_board_type mpeg; 262 enum cx88_board_type mpeg;
263 unsigned int audio_chip; 263 unsigned int audio_chip;
264 int num_frontends;
264}; 265};
265 266
266struct cx88_subid { 267struct cx88_subid {
@@ -356,6 +357,7 @@ struct cx88_core {
356 struct cx8802_dev *dvbdev; 357 struct cx8802_dev *dvbdev;
357 enum cx88_board_type active_type_id; 358 enum cx88_board_type active_type_id;
358 int active_ref; 359 int active_ref;
360 int active_fe_id;
359}; 361};
360 362
361struct cx8800_dev; 363struct cx8800_dev;
@@ -490,7 +492,7 @@ struct cx8802_dev {
490 492
491#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) 493#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
492 /* for dvb only */ 494 /* for dvb only */
493 struct videobuf_dvb dvb; 495 struct videobuf_dvb_frontends frontends;
494#endif 496#endif
495 497
496#if defined(CONFIG_VIDEO_CX88_VP3054) || \ 498#if defined(CONFIG_VIDEO_CX88_VP3054) || \
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 87c10983266f..8ada0497fa03 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -535,11 +535,15 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,
535 struct tda1004x_config *cdec_conf, 535 struct tda1004x_config *cdec_conf,
536 struct tda827x_config *tuner_conf) 536 struct tda827x_config *tuner_conf)
537{ 537{
538 dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap); 538 struct videobuf_dvb_frontend *fe0;
539 if (dev->dvb.frontend) { 539
540 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 0);
541
542 fe0->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
543 if (fe0->dvb.frontend) {
540 if (cdec_conf->i2c_gate) 544 if (cdec_conf->i2c_gate)
541 dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; 545 fe0->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
542 if (dvb_attach(tda827x_attach, dev->dvb.frontend, 546 if (dvb_attach(tda827x_attach, fe0->dvb.frontend,
543 cdec_conf->tuner_address, 547 cdec_conf->tuner_address,
544 &dev->i2c_adap, tuner_conf)) 548 &dev->i2c_adap, tuner_conf))
545 return 0; 549 return 0;
@@ -944,12 +948,18 @@ static int dvb_init(struct saa7134_dev *dev)
944{ 948{
945 int ret; 949 int ret;
946 int attach_xc3028 = 0; 950 int attach_xc3028 = 0;
951 struct videobuf_dvb_frontend *fe0;
952
953 /* Get the first frontend */
954 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 0);
955 if (!fe0)
956 return -EINVAL;
947 957
948 /* init struct videobuf_dvb */ 958 /* init struct videobuf_dvb */
949 dev->ts.nr_bufs = 32; 959 dev->ts.nr_bufs = 32;
950 dev->ts.nr_packets = 32*4; 960 dev->ts.nr_packets = 32*4;
951 dev->dvb.name = dev->name; 961 fe0->dvb.name = dev->name;
952 videobuf_queue_sg_init(&dev->dvb.dvbq, &saa7134_ts_qops, 962 videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops,
953 &dev->pci->dev, &dev->slock, 963 &dev->pci->dev, &dev->slock,
954 V4L2_BUF_TYPE_VIDEO_CAPTURE, 964 V4L2_BUF_TYPE_VIDEO_CAPTURE,
955 V4L2_FIELD_ALTERNATE, 965 V4L2_FIELD_ALTERNATE,
@@ -959,47 +969,47 @@ static int dvb_init(struct saa7134_dev *dev)
959 switch (dev->board) { 969 switch (dev->board) {
960 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: 970 case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
961 dprintk("pinnacle 300i dvb setup\n"); 971 dprintk("pinnacle 300i dvb setup\n");
962 dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i, 972 fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
963 &dev->i2c_adap); 973 &dev->i2c_adap);
964 if (dev->dvb.frontend) { 974 if (fe0->dvb.frontend) {
965 dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params; 975 fe0->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
966 } 976 }
967 break; 977 break;
968 case SAA7134_BOARD_AVERMEDIA_777: 978 case SAA7134_BOARD_AVERMEDIA_777:
969 case SAA7134_BOARD_AVERMEDIA_A16AR: 979 case SAA7134_BOARD_AVERMEDIA_A16AR:
970 dprintk("avertv 777 dvb setup\n"); 980 dprintk("avertv 777 dvb setup\n");
971 dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, 981 fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
972 &dev->i2c_adap); 982 &dev->i2c_adap);
973 if (dev->dvb.frontend) { 983 if (fe0->dvb.frontend) {
974 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 984 dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
975 &dev->i2c_adap, 0x61, 985 &dev->i2c_adap, 0x61,
976 TUNER_PHILIPS_TD1316); 986 TUNER_PHILIPS_TD1316);
977 } 987 }
978 break; 988 break;
979 case SAA7134_BOARD_AVERMEDIA_A16D: 989 case SAA7134_BOARD_AVERMEDIA_A16D:
980 dprintk("AverMedia A16D dvb setup\n"); 990 dprintk("AverMedia A16D dvb setup\n");
981 dev->dvb.frontend = dvb_attach(mt352_attach, 991 fe0->dvb.frontend = dvb_attach(mt352_attach,
982 &avermedia_xc3028_mt352_dev, 992 &avermedia_xc3028_mt352_dev,
983 &dev->i2c_adap); 993 &dev->i2c_adap);
984 attach_xc3028 = 1; 994 attach_xc3028 = 1;
985 break; 995 break;
986 case SAA7134_BOARD_MD7134: 996 case SAA7134_BOARD_MD7134:
987 dev->dvb.frontend = dvb_attach(tda10046_attach, 997 fe0->dvb.frontend = dvb_attach(tda10046_attach,
988 &medion_cardbus, 998 &medion_cardbus,
989 &dev->i2c_adap); 999 &dev->i2c_adap);
990 if (dev->dvb.frontend) { 1000 if (fe0->dvb.frontend) {
991 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 1001 dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
992 &dev->i2c_adap, medion_cardbus.tuner_address, 1002 &dev->i2c_adap, medion_cardbus.tuner_address,
993 TUNER_PHILIPS_FMD1216ME_MK3); 1003 TUNER_PHILIPS_FMD1216ME_MK3);
994 } 1004 }
995 break; 1005 break;
996 case SAA7134_BOARD_PHILIPS_TOUGH: 1006 case SAA7134_BOARD_PHILIPS_TOUGH:
997 dev->dvb.frontend = dvb_attach(tda10046_attach, 1007 fe0->dvb.frontend = dvb_attach(tda10046_attach,
998 &philips_tu1216_60_config, 1008 &philips_tu1216_60_config,
999 &dev->i2c_adap); 1009 &dev->i2c_adap);
1000 if (dev->dvb.frontend) { 1010 if (fe0->dvb.frontend) {
1001 dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; 1011 fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
1002 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; 1012 fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
1003 } 1013 }
1004 break; 1014 break;
1005 case SAA7134_BOARD_FLYDVBTDUO: 1015 case SAA7134_BOARD_FLYDVBTDUO:
@@ -1010,24 +1020,24 @@ static int dvb_init(struct saa7134_dev *dev)
1010 break; 1020 break;
1011 case SAA7134_BOARD_PHILIPS_EUROPA: 1021 case SAA7134_BOARD_PHILIPS_EUROPA:
1012 case SAA7134_BOARD_VIDEOMATE_DVBT_300: 1022 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
1013 dev->dvb.frontend = dvb_attach(tda10046_attach, 1023 fe0->dvb.frontend = dvb_attach(tda10046_attach,
1014 &philips_europa_config, 1024 &philips_europa_config,
1015 &dev->i2c_adap); 1025 &dev->i2c_adap);
1016 if (dev->dvb.frontend) { 1026 if (fe0->dvb.frontend) {
1017 dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; 1027 dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
1018 dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; 1028 fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
1019 dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init; 1029 fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
1020 dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep; 1030 fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
1021 dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; 1031 fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
1022 } 1032 }
1023 break; 1033 break;
1024 case SAA7134_BOARD_VIDEOMATE_DVBT_200: 1034 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
1025 dev->dvb.frontend = dvb_attach(tda10046_attach, 1035 fe0->dvb.frontend = dvb_attach(tda10046_attach,
1026 &philips_tu1216_61_config, 1036 &philips_tu1216_61_config,
1027 &dev->i2c_adap); 1037 &dev->i2c_adap);
1028 if (dev->dvb.frontend) { 1038 if (fe0->dvb.frontend) {
1029 dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init; 1039 fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
1030 dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set; 1040 fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
1031 } 1041 }
1032 break; 1042 break;
1033 case SAA7134_BOARD_KWORLD_DVBT_210: 1043 case SAA7134_BOARD_KWORLD_DVBT_210:
@@ -1060,20 +1070,20 @@ static int dvb_init(struct saa7134_dev *dev)
1060 &tda827x_cfg_0) < 0) 1070 &tda827x_cfg_0) < 0)
1061 goto dettach_frontend; 1071 goto dettach_frontend;
1062 break; 1072 break;
1063 case SAA7134_BOARD_FLYDVB_TRIO: 1073 case SAA7134_BOARD_FLYDVB_TRIO: // XXXXXX multifrontend
1064 if (!use_frontend) { /* terrestrial */ 1074 if (!use_frontend) { /* terrestrial */
1065 if (configure_tda827x_fe(dev, &lifeview_trio_config, 1075 if (configure_tda827x_fe(dev, &lifeview_trio_config,
1066 &tda827x_cfg_0) < 0) 1076 &tda827x_cfg_0) < 0)
1067 goto dettach_frontend; 1077 goto dettach_frontend;
1068 } else { /* satellite */ 1078 } else { /* satellite */
1069 dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); 1079 fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
1070 if (dev->dvb.frontend) { 1080 if (fe0->dvb.frontend) {
1071 if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, 1081 if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
1072 &dev->i2c_adap, 0) == NULL) { 1082 &dev->i2c_adap, 0) == NULL) {
1073 wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__); 1083 wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
1074 goto dettach_frontend; 1084 goto dettach_frontend;
1075 } 1085 }
1076 if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 1086 if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap,
1077 0x08, 0, 0) == NULL) { 1087 0x08, 0, 0) == NULL) {
1078 wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__); 1088 wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
1079 goto dettach_frontend; 1089 goto dettach_frontend;
@@ -1083,11 +1093,11 @@ static int dvb_init(struct saa7134_dev *dev)
1083 break; 1093 break;
1084 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: 1094 case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
1085 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS: 1095 case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
1086 dev->dvb.frontend = dvb_attach(tda10046_attach, 1096 fe0->dvb.frontend = dvb_attach(tda10046_attach,
1087 &ads_tech_duo_config, 1097 &ads_tech_duo_config,
1088 &dev->i2c_adap); 1098 &dev->i2c_adap);
1089 if (dev->dvb.frontend) { 1099 if (fe0->dvb.frontend) {
1090 if (dvb_attach(tda827x_attach,dev->dvb.frontend, 1100 if (dvb_attach(tda827x_attach,fe0->dvb.frontend,
1091 ads_tech_duo_config.tuner_address, &dev->i2c_adap, 1101 ads_tech_duo_config.tuner_address, &dev->i2c_adap,
1092 &ads_duo_cfg) == NULL) { 1102 &ads_duo_cfg) == NULL) {
1093 wprintk("no tda827x tuner found at addr: %02x\n", 1103 wprintk("no tda827x tuner found at addr: %02x\n",
@@ -1108,15 +1118,15 @@ static int dvb_init(struct saa7134_dev *dev)
1108 &tda827x_cfg_0) < 0) 1118 &tda827x_cfg_0) < 0)
1109 goto dettach_frontend; 1119 goto dettach_frontend;
1110 } else { /* satellite */ 1120 } else { /* satellite */
1111 dev->dvb.frontend = dvb_attach(tda10086_attach, 1121 fe0->dvb.frontend = dvb_attach(tda10086_attach,
1112 &flydvbs, &dev->i2c_adap); 1122 &flydvbs, &dev->i2c_adap);
1113 if (dev->dvb.frontend) { 1123 if (fe0->dvb.frontend) {
1114 struct dvb_frontend *fe = dev->dvb.frontend; 1124 struct dvb_frontend *fe = fe0->dvb.frontend;
1115 u8 dev_id = dev->eedata[2]; 1125 u8 dev_id = dev->eedata[2];
1116 u8 data = 0xc4; 1126 u8 data = 0xc4;
1117 struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1}; 1127 struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
1118 1128
1119 if (dvb_attach(tda826x_attach, dev->dvb.frontend, 1129 if (dvb_attach(tda826x_attach, fe0->dvb.frontend,
1120 0x60, &dev->i2c_adap, 0) == NULL) { 1130 0x60, &dev->i2c_adap, 0) == NULL) {
1121 wprintk("%s: Medion Quadro, no tda826x " 1131 wprintk("%s: Medion Quadro, no tda826x "
1122 "found !\n", __func__); 1132 "found !\n", __func__);
@@ -1150,31 +1160,31 @@ static int dvb_init(struct saa7134_dev *dev)
1150 } 1160 }
1151 break; 1161 break;
1152 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: 1162 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
1153 dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180, 1163 fe0->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
1154 &dev->i2c_adap); 1164 &dev->i2c_adap);
1155 if (dev->dvb.frontend) 1165 if (fe0->dvb.frontend)
1156 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, 1166 dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61,
1157 NULL, DVB_PLL_TDHU2); 1167 NULL, DVB_PLL_TDHU2);
1158 break; 1168 break;
1159 case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI: 1169 case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
1160 case SAA7134_BOARD_KWORLD_ATSC110: 1170 case SAA7134_BOARD_KWORLD_ATSC110:
1161 dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110, 1171 fe0->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
1162 &dev->i2c_adap); 1172 &dev->i2c_adap);
1163 if (dev->dvb.frontend) 1173 if (fe0->dvb.frontend)
1164 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 1174 dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1165 &dev->i2c_adap, 0x61, 1175 &dev->i2c_adap, 0x61,
1166 TUNER_PHILIPS_TUV1236D); 1176 TUNER_PHILIPS_TUV1236D);
1167 break; 1177 break;
1168 case SAA7134_BOARD_FLYDVBS_LR300: 1178 case SAA7134_BOARD_FLYDVBS_LR300:
1169 dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, 1179 fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
1170 &dev->i2c_adap); 1180 &dev->i2c_adap);
1171 if (dev->dvb.frontend) { 1181 if (fe0->dvb.frontend) {
1172 if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, 1182 if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
1173 &dev->i2c_adap, 0) == NULL) { 1183 &dev->i2c_adap, 0) == NULL) {
1174 wprintk("%s: No tda826x found!\n", __func__); 1184 wprintk("%s: No tda826x found!\n", __func__);
1175 goto dettach_frontend; 1185 goto dettach_frontend;
1176 } 1186 }
1177 if (dvb_attach(isl6421_attach, dev->dvb.frontend, 1187 if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
1178 &dev->i2c_adap, 0x08, 0, 0) == NULL) { 1188 &dev->i2c_adap, 0x08, 0, 0) == NULL) {
1179 wprintk("%s: No ISL6421 found!\n", __func__); 1189 wprintk("%s: No ISL6421 found!\n", __func__);
1180 goto dettach_frontend; 1190 goto dettach_frontend;
@@ -1182,25 +1192,25 @@ static int dvb_init(struct saa7134_dev *dev)
1182 } 1192 }
1183 break; 1193 break;
1184 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID: 1194 case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
1185 dev->dvb.frontend = dvb_attach(tda10046_attach, 1195 fe0->dvb.frontend = dvb_attach(tda10046_attach,
1186 &medion_cardbus, 1196 &medion_cardbus,
1187 &dev->i2c_adap); 1197 &dev->i2c_adap);
1188 if (dev->dvb.frontend) { 1198 if (fe0->dvb.frontend) {
1189 dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; 1199 dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
1190 dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; 1200 fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
1191 1201
1192 dvb_attach(simple_tuner_attach, dev->dvb.frontend, 1202 dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
1193 &dev->i2c_adap, medion_cardbus.tuner_address, 1203 &dev->i2c_adap, medion_cardbus.tuner_address,
1194 TUNER_PHILIPS_FMD1216ME_MK3); 1204 TUNER_PHILIPS_FMD1216ME_MK3);
1195 } 1205 }
1196 break; 1206 break;
1197 case SAA7134_BOARD_VIDEOMATE_DVBT_200A: 1207 case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
1198 dev->dvb.frontend = dvb_attach(tda10046_attach, 1208 fe0->dvb.frontend = dvb_attach(tda10046_attach,
1199 &philips_europa_config, 1209 &philips_europa_config,
1200 &dev->i2c_adap); 1210 &dev->i2c_adap);
1201 if (dev->dvb.frontend) { 1211 if (fe0->dvb.frontend) {
1202 dev->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init; 1212 fe0->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
1203 dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; 1213 fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
1204 } 1214 }
1205 break; 1215 break;
1206 case SAA7134_BOARD_CINERGY_HT_PCMCIA: 1216 case SAA7134_BOARD_CINERGY_HT_PCMCIA:
@@ -1239,15 +1249,15 @@ static int dvb_init(struct saa7134_dev *dev)
1239 goto dettach_frontend; 1249 goto dettach_frontend;
1240 break; 1250 break;
1241 case SAA7134_BOARD_PHILIPS_SNAKE: 1251 case SAA7134_BOARD_PHILIPS_SNAKE:
1242 dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, 1252 fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
1243 &dev->i2c_adap); 1253 &dev->i2c_adap);
1244 if (dev->dvb.frontend) { 1254 if (fe0->dvb.frontend) {
1245 if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, 1255 if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
1246 &dev->i2c_adap, 0) == NULL) { 1256 &dev->i2c_adap, 0) == NULL) {
1247 wprintk("%s: No tda826x found!\n", __func__); 1257 wprintk("%s: No tda826x found!\n", __func__);
1248 goto dettach_frontend; 1258 goto dettach_frontend;
1249 } 1259 }
1250 if (dvb_attach(lnbp21_attach, dev->dvb.frontend, 1260 if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
1251 &dev->i2c_adap, 0, 0) == NULL) { 1261 &dev->i2c_adap, 0, 0) == NULL) {
1252 wprintk("%s: No lnbp21 found!\n", __func__); 1262 wprintk("%s: No lnbp21 found!\n", __func__);
1253 goto dettach_frontend; 1263 goto dettach_frontend;
@@ -1269,24 +1279,24 @@ static int dvb_init(struct saa7134_dev *dev)
1269 saa7134_set_gpio(dev, 25, 0); 1279 saa7134_set_gpio(dev, 25, 0);
1270 msleep(10); 1280 msleep(10);
1271 saa7134_set_gpio(dev, 25, 1); 1281 saa7134_set_gpio(dev, 25, 1);
1272 dev->dvb.frontend = dvb_attach(mt352_attach, 1282 fe0->dvb.frontend = dvb_attach(mt352_attach,
1273 &avermedia_xc3028_mt352_dev, 1283 &avermedia_xc3028_mt352_dev,
1274 &dev->i2c_adap); 1284 &dev->i2c_adap);
1275 attach_xc3028 = 1; 1285 attach_xc3028 = 1;
1276 break; 1286 break;
1277 case SAA7134_BOARD_MD7134_BRIDGE_2: 1287 case SAA7134_BOARD_MD7134_BRIDGE_2:
1278 dev->dvb.frontend = dvb_attach(tda10086_attach, 1288 fe0->dvb.frontend = dvb_attach(tda10086_attach,
1279 &sd1878_4m, &dev->i2c_adap); 1289 &sd1878_4m, &dev->i2c_adap);
1280 if (dev->dvb.frontend) { 1290 if (fe0->dvb.frontend) {
1281 struct dvb_frontend *fe; 1291 struct dvb_frontend *fe;
1282 if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, 1292 if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1283 &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) { 1293 &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
1284 wprintk("%s: MD7134 DVB-S, no SD1878 " 1294 wprintk("%s: MD7134 DVB-S, no SD1878 "
1285 "found !\n", __func__); 1295 "found !\n", __func__);
1286 goto dettach_frontend; 1296 goto dettach_frontend;
1287 } 1297 }
1288 /* we need to open the i2c gate (we know it exists) */ 1298 /* we need to open the i2c gate (we know it exists) */
1289 fe = dev->dvb.frontend; 1299 fe = fe0->dvb.frontend;
1290 fe->ops.i2c_gate_ctrl(fe, 1); 1300 fe->ops.i2c_gate_ctrl(fe, 1);
1291 if (dvb_attach(isl6405_attach, fe, 1301 if (dvb_attach(isl6405_attach, fe,
1292 &dev->i2c_adap, 0x08, 0, 0) == NULL) { 1302 &dev->i2c_adap, 0x08, 0, 0) == NULL) {
@@ -1305,7 +1315,7 @@ static int dvb_init(struct saa7134_dev *dev)
1305 saa7134_set_gpio(dev, 25, 0); 1315 saa7134_set_gpio(dev, 25, 0);
1306 msleep(10); 1316 msleep(10);
1307 saa7134_set_gpio(dev, 25, 1); 1317 saa7134_set_gpio(dev, 25, 1);
1308 dev->dvb.frontend = dvb_attach(mt352_attach, 1318 fe0->dvb.frontend = dvb_attach(mt352_attach,
1309 &avermedia_xc3028_mt352_dev, 1319 &avermedia_xc3028_mt352_dev,
1310 &dev->i2c_adap); 1320 &dev->i2c_adap);
1311 attach_xc3028 = 1; 1321 attach_xc3028 = 1;
@@ -1316,17 +1326,17 @@ static int dvb_init(struct saa7134_dev *dev)
1316 &tda827x_cfg_2) < 0) 1326 &tda827x_cfg_2) < 0)
1317 goto dettach_frontend; 1327 goto dettach_frontend;
1318 } else { /* satellite */ 1328 } else { /* satellite */
1319 dev->dvb.frontend = dvb_attach(tda10086_attach, 1329 fe0->dvb.frontend = dvb_attach(tda10086_attach,
1320 &flydvbs, &dev->i2c_adap); 1330 &flydvbs, &dev->i2c_adap);
1321 if (dev->dvb.frontend) { 1331 if (fe0->dvb.frontend) {
1322 if (dvb_attach(tda826x_attach, 1332 if (dvb_attach(tda826x_attach,
1323 dev->dvb.frontend, 0x60, 1333 fe0->dvb.frontend, 0x60,
1324 &dev->i2c_adap, 0) == NULL) { 1334 &dev->i2c_adap, 0) == NULL) {
1325 wprintk("%s: Asus Tiger 3in1, no " 1335 wprintk("%s: Asus Tiger 3in1, no "
1326 "tda826x found!\n", __func__); 1336 "tda826x found!\n", __func__);
1327 goto dettach_frontend; 1337 goto dettach_frontend;
1328 } 1338 }
1329 if (dvb_attach(lnbp21_attach, dev->dvb.frontend, 1339 if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
1330 &dev->i2c_adap, 0, 0) == NULL) { 1340 &dev->i2c_adap, 0, 0) == NULL) {
1331 wprintk("%s: Asus Tiger 3in1, no lnbp21" 1341 wprintk("%s: Asus Tiger 3in1, no lnbp21"
1332 " found!\n", __func__); 1342 " found!\n", __func__);
@@ -1352,10 +1362,10 @@ static int dvb_init(struct saa7134_dev *dev)
1352 .i2c_addr = 0x61, 1362 .i2c_addr = 0x61,
1353 }; 1363 };
1354 1364
1355 if (!dev->dvb.frontend) 1365 if (!fe0->dvb.frontend)
1356 return -1; 1366 return -1;
1357 1367
1358 fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); 1368 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
1359 if (!fe) { 1369 if (!fe) {
1360 printk(KERN_ERR "%s/2: xc3028 attach failed\n", 1370 printk(KERN_ERR "%s/2: xc3028 attach failed\n",
1361 dev->name); 1371 dev->name);
@@ -1363,40 +1373,47 @@ static int dvb_init(struct saa7134_dev *dev)
1363 } 1373 }
1364 } 1374 }
1365 1375
1366 if (NULL == dev->dvb.frontend) { 1376 if (NULL == fe0->dvb.frontend) {
1367 printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name); 1377 printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
1368 return -1; 1378 return -1;
1369 } 1379 }
1370 /* define general-purpose callback pointer */ 1380 /* define general-purpose callback pointer */
1371 dev->dvb.frontend->callback = saa7134_tuner_callback; 1381 fe0->dvb.frontend->callback = saa7134_tuner_callback;
1372 1382
1373 /* register everything else */ 1383 /* register everything else */
1374 ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, 1384 ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
1375 adapter_nr); 1385 &dev->pci->dev, adapter_nr);
1376 1386
1377 /* this sequence is necessary to make the tda1004x load its firmware 1387 /* this sequence is necessary to make the tda1004x load its firmware
1378 * and to enter analog mode of hybrid boards 1388 * and to enter analog mode of hybrid boards
1379 */ 1389 */
1380 if (!ret) { 1390 if (!ret) {
1381 if (dev->dvb.frontend->ops.init) 1391 if (fe0->dvb.frontend->ops.init)
1382 dev->dvb.frontend->ops.init(dev->dvb.frontend); 1392 fe0->dvb.frontend->ops.init(fe0->dvb.frontend);
1383 if (dev->dvb.frontend->ops.sleep) 1393 if (fe0->dvb.frontend->ops.sleep)
1384 dev->dvb.frontend->ops.sleep(dev->dvb.frontend); 1394 fe0->dvb.frontend->ops.sleep(fe0->dvb.frontend);
1385 if (dev->dvb.frontend->ops.tuner_ops.sleep) 1395 if (fe0->dvb.frontend->ops.tuner_ops.sleep)
1386 dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend); 1396 fe0->dvb.frontend->ops.tuner_ops.sleep(fe0->dvb.frontend);
1387 } 1397 }
1388 return ret; 1398 return ret;
1389 1399
1390dettach_frontend: 1400dettach_frontend:
1391 if (dev->dvb.frontend) 1401 if (fe0->dvb.frontend)
1392 dvb_frontend_detach(dev->dvb.frontend); 1402 dvb_frontend_detach(fe0->dvb.frontend);
1393 dev->dvb.frontend = NULL; 1403 fe0->dvb.frontend = NULL;
1394 1404
1395 return -1; 1405 return -1;
1396} 1406}
1397 1407
1398static int dvb_fini(struct saa7134_dev *dev) 1408static int dvb_fini(struct saa7134_dev *dev)
1399{ 1409{
1410 struct videobuf_dvb_frontend *fe0;
1411
1412 /* Get the first frontend */
1413 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
1414 if (!fe0)
1415 return -EINVAL;
1416
1400 /* FIXME: I suspect that this code is bogus, since the entry for 1417 /* FIXME: I suspect that this code is bogus, since the entry for
1401 Pinnacle 300I DVB-T PAL already defines the proper init to allow 1418 Pinnacle 300I DVB-T PAL already defines the proper init to allow
1402 the detection of mt2032 (TDA9887_PORT2_INACTIVE) 1419 the detection of mt2032 (TDA9887_PORT2_INACTIVE)
@@ -1416,7 +1433,7 @@ static int dvb_fini(struct saa7134_dev *dev)
1416 u8 data = 0x80; 1433 u8 data = 0x80;
1417 struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1}; 1434 struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1};
1418 struct dvb_frontend *fe; 1435 struct dvb_frontend *fe;
1419 fe = dev->dvb.frontend; 1436 fe = fe0->dvb.frontend;
1420 if (fe->ops.i2c_gate_ctrl) { 1437 if (fe->ops.i2c_gate_ctrl) {
1421 fe->ops.i2c_gate_ctrl(fe, 1); 1438 fe->ops.i2c_gate_ctrl(fe, 1);
1422 i2c_transfer(&dev->i2c_adap, &msg, 1); 1439 i2c_transfer(&dev->i2c_adap, &msg, 1);
@@ -1424,8 +1441,8 @@ static int dvb_fini(struct saa7134_dev *dev)
1424 } 1441 }
1425 } 1442 }
1426 } 1443 }
1427 if (dev->dvb.frontend) 1444 if (fe0->dvb.frontend)
1428 videobuf_dvb_unregister(&dev->dvb); 1445 videobuf_dvb_unregister_bus(&dev->frontends);
1429 return 0; 1446 return 0;
1430} 1447}
1431 1448
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 491ab1f8fdd3..24096d6e1ef8 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -581,7 +581,7 @@ struct saa7134_dev {
581 581
582#if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) 582#if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
583 /* SAA7134_MPEG_DVB only */ 583 /* SAA7134_MPEG_DVB only */
584 struct videobuf_dvb dvb; 584 struct videobuf_dvb_frontends frontends;
585 int (*original_demod_sleep)(struct dvb_frontend *fe); 585 int (*original_demod_sleep)(struct dvb_frontend *fe);
586 int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); 586 int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
587 int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); 587 int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index b56cffcbfd45..194fb765e58b 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -135,29 +135,75 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
135} 135}
136 136
137/* ------------------------------------------------------------------ */ 137/* ------------------------------------------------------------------ */
138/* Register a single adapter and one or more frontends */
139int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
140 struct module *module,
141 void *adapter_priv,
142 struct device *device,
143 short *adapter_nr) //NEW
144{
145 struct list_head *list, *q;
146 struct videobuf_dvb_frontend *fe;
147 int res = -EINVAL;
148
149 fe = videobuf_dvb_get_frontend(f, 1);
150 if (!fe) {
151 printk(KERN_WARNING "Unable to register the adapter which has no frontends\n");
152 goto err;
153 }
154
155 /* Bring up the adapter */
156 res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, fe->dvb.name, adapter_nr); //NEW
157 if (res < 0) {
158 printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
159 goto err;
160 }
138 161
139int videobuf_dvb_register(struct videobuf_dvb *dvb, 162 /* Attach all of the frontends to the adapter */
163 mutex_lock(&f->lock);
164 list_for_each_safe(list, q, &f->frontend.felist) {
165 fe = list_entry(list, struct videobuf_dvb_frontend, felist);
166
167 res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb);
168 if (res < 0) {
169 printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n",
170 fe->dvb.name, res);
171 }
172 }
173 mutex_unlock(&f->lock);
174
175err:
176 return res;
177}
178
179int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
140 struct module *module, 180 struct module *module,
141 void *adapter_priv, 181 void *adapter_priv,
142 struct device *device, 182 struct device *device,
143 short *adapter_nr) 183 char *adapter_name,
184 short *adapter_nr) //NEW
144{ 185{
145 int result; 186 int result;
146 187
147 mutex_init(&dvb->lock); 188 mutex_init(&fe->lock);
148 189
149 /* register adapter */ 190 /* register adapter */
150 result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device, 191 result = dvb_register_adapter(&fe->adapter, adapter_name, module, device, adapter_nr);
151 adapter_nr);
152 if (result < 0) { 192 if (result < 0) {
153 printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", 193 printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
154 dvb->name, result); 194 adapter_name, result);
155 goto fail_adapter;
156 } 195 }
157 dvb->adapter.priv = adapter_priv; 196 fe->adapter.priv = adapter_priv;
197
198 return result;
199}
200
201int videobuf_dvb_register_frontend(struct dvb_adapter *adapter, struct videobuf_dvb *dvb)
202{
203 int result;
158 204
159 /* register frontend */ 205 /* register frontend */
160 result = dvb_register_frontend(&dvb->adapter, dvb->frontend); 206 result = dvb_register_frontend(adapter, dvb->frontend);
161 if (result < 0) { 207 if (result < 0) {
162 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", 208 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
163 dvb->name, result); 209 dvb->name, result);
@@ -183,7 +229,9 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
183 dvb->dmxdev.filternum = 256; 229 dvb->dmxdev.filternum = 256;
184 dvb->dmxdev.demux = &dvb->demux.dmx; 230 dvb->dmxdev.demux = &dvb->demux.dmx;
185 dvb->dmxdev.capabilities = 0; 231 dvb->dmxdev.capabilities = 0;
186 result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); 232 //result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
233 result = dvb_dmxdev_init(&dvb->dmxdev, adapter);
234
187 if (result < 0) { 235 if (result < 0) {
188 printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", 236 printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
189 dvb->name, result); 237 dvb->name, result);
@@ -214,7 +262,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
214 } 262 }
215 263
216 /* register network adapter */ 264 /* register network adapter */
217 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); 265 dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx);
218 return 0; 266 return 0;
219 267
220fail_fe_conn: 268fail_fe_conn:
@@ -230,24 +278,101 @@ fail_dmx:
230fail_frontend: 278fail_frontend:
231 dvb_frontend_detach(dvb->frontend); 279 dvb_frontend_detach(dvb->frontend);
232 dvb_unregister_adapter(&dvb->adapter); 280 dvb_unregister_adapter(&dvb->adapter);
233fail_adapter: 281
234 return result; 282 return result;
235} 283}
236 284
237void videobuf_dvb_unregister(struct videobuf_dvb *dvb) 285void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f)
238{ 286{
239 dvb_net_release(&dvb->net); 287 struct list_head *list, *q;
240 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 288 struct videobuf_dvb_frontend *fe;
241 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 289
242 dvb_dmxdev_release(&dvb->dmxdev); 290 mutex_lock(&f->lock);
243 dvb_dmx_release(&dvb->demux); 291 list_for_each_safe(list, q, &f->frontend.felist) {
244 dvb_unregister_frontend(dvb->frontend); 292 fe = list_entry(list, struct videobuf_dvb_frontend, felist);
245 dvb_frontend_detach(dvb->frontend); 293
246 dvb_unregister_adapter(&dvb->adapter); 294 dvb_net_release(&fe->dvb.net);
295 fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, &fe->dvb.fe_mem);
296 fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, &fe->dvb.fe_hw);
297 dvb_dmxdev_release(&fe->dvb.dmxdev);
298 dvb_dmx_release(&fe->dvb.demux);
299 dvb_unregister_frontend(fe->dvb.frontend);
300 dvb_frontend_detach(fe->dvb.frontend);
301
302 list_del(list);
303 kfree(fe);
304 }
305 mutex_unlock(&f->lock);
306
307 dvb_unregister_adapter(&f->adapter);
308}
309
310struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id)
311{
312 struct list_head *list, *q;
313 struct videobuf_dvb_frontend *fe, *ret = NULL;
314
315 mutex_lock(&f->lock);
316
317 list_for_each_safe(list, q, &f->frontend.felist) {
318 fe = list_entry(list, struct videobuf_dvb_frontend, felist);
319 if (fe->id == id) {
320 ret = fe;
321 break;
322 }
323 }
324
325 mutex_unlock(&f->lock);
326
327 return ret;
328}
329
330int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p)
331{
332 struct list_head *list, *q;
333 struct videobuf_dvb_frontend *fe = NULL;
334 int ret = 0;
335
336 mutex_lock(&f->lock);
337
338 list_for_each_safe(list, q, &f->frontend.felist) {
339 fe = list_entry(list, struct videobuf_dvb_frontend, felist);
340 if (fe->dvb.frontend == p) {
341 ret = fe->id;
342 break;
343 }
344 }
345
346 mutex_unlock(&f->lock);
347
348 return ret;
349}
350
351struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(void *private, struct videobuf_dvb_frontends *f, int id)
352{
353 struct videobuf_dvb_frontend *fe;
354
355 fe = kzalloc(sizeof(struct videobuf_dvb_frontend),GFP_KERNEL);
356 if (fe == NULL)
357 goto fail_alloc;
358
359 fe->dev = private;
360 fe->id = id;
361 mutex_init(&fe->dvb.lock);
362
363 mutex_lock(&f->lock);
364 list_add_tail(&fe->felist,&f->frontend.felist);
365 mutex_unlock(&f->lock);
366
367fail_alloc:
368 return fe;
247} 369}
248 370
249EXPORT_SYMBOL(videobuf_dvb_register); 371EXPORT_SYMBOL(videobuf_dvb_register_bus);
250EXPORT_SYMBOL(videobuf_dvb_unregister); 372EXPORT_SYMBOL(videobuf_dvb_unregister_bus);
373EXPORT_SYMBOL(videobuf_dvb_alloc_frontend);
374EXPORT_SYMBOL(videobuf_dvb_get_frontend);
375EXPORT_SYMBOL(videobuf_dvb_find_frontend);
251 376
252/* ------------------------------------------------------------------ */ 377/* ------------------------------------------------------------------ */
253/* 378/*