aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx23885/cx23885-dvb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx23885/cx23885-dvb.c')
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c307
1 files changed, 208 insertions, 99 deletions
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 022aa391937a..e1aac07b3158 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Conexant CX23885 PCIe bridge 2 * Driver for the Conexant CX23885 PCIe bridge
3 * 3 *
4 * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32 32
33#include "s5h1409.h" 33#include "s5h1409.h"
34#include "s5h1411.h"
34#include "mt2131.h" 35#include "mt2131.h"
35#include "tda8290.h" 36#include "tda8290.h"
36#include "tda18271.h" 37#include "tda18271.h"
@@ -41,6 +42,7 @@
41#include "tuner-simple.h" 42#include "tuner-simple.h"
42#include "dib7000p.h" 43#include "dib7000p.h"
43#include "dibx000_common.h" 44#include "dibx000_common.h"
45#include "zl10353.h"
44 46
45static unsigned int debug; 47static unsigned int debug;
46 48
@@ -76,19 +78,19 @@ static int dvb_buf_prepare(struct videobuf_queue *q,
76 struct videobuf_buffer *vb, enum v4l2_field field) 78 struct videobuf_buffer *vb, enum v4l2_field field)
77{ 79{
78 struct cx23885_tsport *port = q->priv_data; 80 struct cx23885_tsport *port = q->priv_data;
79 return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field); 81 return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field);
80} 82}
81 83
82static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 84static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
83{ 85{
84 struct cx23885_tsport *port = q->priv_data; 86 struct cx23885_tsport *port = q->priv_data;
85 cx23885_buf_queue(port, (struct cx23885_buffer*)vb); 87 cx23885_buf_queue(port, (struct cx23885_buffer *)vb);
86} 88}
87 89
88static void dvb_buf_release(struct videobuf_queue *q, 90static void dvb_buf_release(struct videobuf_queue *q,
89 struct videobuf_buffer *vb) 91 struct videobuf_buffer *vb)
90{ 92{
91 cx23885_free_buffer(q, (struct cx23885_buffer*)vb); 93 cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
92} 94}
93 95
94static struct videobuf_queue_ops dvb_qops = { 96static struct videobuf_queue_ops dvb_qops = {
@@ -164,10 +166,34 @@ static struct s5h1409_config hauppauge_hvr1500q_config = {
164 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, 166 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
165}; 167};
166 168
169static struct s5h1409_config dvico_s5h1409_config = {
170 .demod_address = 0x32 >> 1,
171 .output_mode = S5H1409_SERIAL_OUTPUT,
172 .gpio = S5H1409_GPIO_ON,
173 .qam_if = 44000,
174 .inversion = S5H1409_INVERSION_OFF,
175 .status_mode = S5H1409_DEMODLOCKING,
176 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
177};
178
179static struct s5h1411_config dvico_s5h1411_config = {
180 .output_mode = S5H1411_SERIAL_OUTPUT,
181 .gpio = S5H1411_GPIO_ON,
182 .qam_if = S5H1411_IF_44000,
183 .vsb_if = S5H1411_IF_44000,
184 .inversion = S5H1411_INVERSION_OFF,
185 .status_mode = S5H1411_DEMODLOCKING,
186 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
187};
188
167static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { 189static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
168 .i2c_address = 0x61, 190 .i2c_address = 0x61,
169 .if_khz = 5380, 191 .if_khz = 5380,
170 .tuner_callback = cx23885_tuner_callback 192};
193
194static struct xc5000_config dvico_xc5000_tunerconfig = {
195 .i2c_address = 0x64,
196 .if_khz = 5380,
171}; 197};
172 198
173static struct tda829x_config tda829x_no_probe = { 199static struct tda829x_config tda829x_no_probe = {
@@ -276,53 +302,35 @@ static struct dib7000p_config hauppauge_hvr1400_dib7000_config = {
276 .output_mode = OUTMODE_MPEG2_SERIAL, 302 .output_mode = OUTMODE_MPEG2_SERIAL,
277}; 303};
278 304
279static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) 305static struct zl10353_config dvico_fusionhdtv_xc3028 = {
280{ 306 .demod_address = 0x0f,
281 struct cx23885_tsport *port = ptr; 307 .if2 = 45600,
282 struct cx23885_dev *dev = port->dev; 308 .no_tuner = 1,
283 309};
284 switch (command) {
285 case XC2028_TUNER_RESET:
286 /* Send the tuner in then out of reset */
287 /* GPIO-2 xc3028 tuner */
288 dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg);
289
290 cx_set(GP0_IO, 0x00040000);
291 cx_clear(GP0_IO, 0x00000004);
292 msleep(5);
293
294 cx_set(GP0_IO, 0x00040004);
295 msleep(5);
296 break;
297 case XC2028_RESET_CLK:
298 dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg);
299 break;
300 default:
301 dprintk(1, "%s: unknown command %d, arg %d\n", __func__,
302 command, arg);
303 return -EINVAL;
304 }
305
306 return 0;
307}
308 310
309static int dvb_register(struct cx23885_tsport *port) 311static int dvb_register(struct cx23885_tsport *port)
310{ 312{
311 struct cx23885_dev *dev = port->dev; 313 struct cx23885_dev *dev = port->dev;
312 struct cx23885_i2c *i2c_bus = NULL; 314 struct cx23885_i2c *i2c_bus = NULL;
315 struct videobuf_dvb_frontend *fe0;
316
317 /* Get the first frontend */
318 fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
319 if (!fe0)
320 return -EINVAL;
313 321
314 /* init struct videobuf_dvb */ 322 /* init struct videobuf_dvb */
315 port->dvb.name = dev->name; 323 fe0->dvb.name = dev->name;
316 324
317 /* init frontend */ 325 /* init frontend */
318 switch (dev->board) { 326 switch (dev->board) {
319 case CX23885_BOARD_HAUPPAUGE_HVR1250: 327 case CX23885_BOARD_HAUPPAUGE_HVR1250:
320 i2c_bus = &dev->i2c_bus[0]; 328 i2c_bus = &dev->i2c_bus[0];
321 port->dvb.frontend = dvb_attach(s5h1409_attach, 329 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
322 &hauppauge_generic_config, 330 &hauppauge_generic_config,
323 &i2c_bus->i2c_adap); 331 &i2c_bus->i2c_adap);
324 if (port->dvb.frontend != NULL) { 332 if (fe0->dvb.frontend != NULL) {
325 dvb_attach(mt2131_attach, port->dvb.frontend, 333 dvb_attach(mt2131_attach, fe0->dvb.frontend,
326 &i2c_bus->i2c_adap, 334 &i2c_bus->i2c_adap,
327 &hauppauge_generic_tunerconfig, 0); 335 &hauppauge_generic_tunerconfig, 0);
328 } 336 }
@@ -331,27 +339,27 @@ static int dvb_register(struct cx23885_tsport *port)
331 i2c_bus = &dev->i2c_bus[0]; 339 i2c_bus = &dev->i2c_bus[0];
332 switch (alt_tuner) { 340 switch (alt_tuner) {
333 case 1: 341 case 1:
334 port->dvb.frontend = 342 fe0->dvb.frontend =
335 dvb_attach(s5h1409_attach, 343 dvb_attach(s5h1409_attach,
336 &hauppauge_ezqam_config, 344 &hauppauge_ezqam_config,
337 &i2c_bus->i2c_adap); 345 &i2c_bus->i2c_adap);
338 if (port->dvb.frontend != NULL) { 346 if (fe0->dvb.frontend != NULL) {
339 dvb_attach(tda829x_attach, port->dvb.frontend, 347 dvb_attach(tda829x_attach, fe0->dvb.frontend,
340 &dev->i2c_bus[1].i2c_adap, 0x42, 348 &dev->i2c_bus[1].i2c_adap, 0x42,
341 &tda829x_no_probe); 349 &tda829x_no_probe);
342 dvb_attach(tda18271_attach, port->dvb.frontend, 350 dvb_attach(tda18271_attach, fe0->dvb.frontend,
343 0x60, &dev->i2c_bus[1].i2c_adap, 351 0x60, &dev->i2c_bus[1].i2c_adap,
344 &hauppauge_tda18271_config); 352 &hauppauge_tda18271_config);
345 } 353 }
346 break; 354 break;
347 case 0: 355 case 0:
348 default: 356 default:
349 port->dvb.frontend = 357 fe0->dvb.frontend =
350 dvb_attach(s5h1409_attach, 358 dvb_attach(s5h1409_attach,
351 &hauppauge_generic_config, 359 &hauppauge_generic_config,
352 &i2c_bus->i2c_adap); 360 &i2c_bus->i2c_adap);
353 if (port->dvb.frontend != NULL) 361 if (fe0->dvb.frontend != NULL)
354 dvb_attach(mt2131_attach, port->dvb.frontend, 362 dvb_attach(mt2131_attach, fe0->dvb.frontend,
355 &i2c_bus->i2c_adap, 363 &i2c_bus->i2c_adap,
356 &hauppauge_generic_tunerconfig, 0); 364 &hauppauge_generic_tunerconfig, 0);
357 break; 365 break;
@@ -359,56 +367,55 @@ static int dvb_register(struct cx23885_tsport *port)
359 break; 367 break;
360 case CX23885_BOARD_HAUPPAUGE_HVR1800lp: 368 case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
361 i2c_bus = &dev->i2c_bus[0]; 369 i2c_bus = &dev->i2c_bus[0];
362 port->dvb.frontend = dvb_attach(s5h1409_attach, 370 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
363 &hauppauge_hvr1800lp_config, 371 &hauppauge_hvr1800lp_config,
364 &i2c_bus->i2c_adap); 372 &i2c_bus->i2c_adap);
365 if (port->dvb.frontend != NULL) { 373 if (fe0->dvb.frontend != NULL) {
366 dvb_attach(mt2131_attach, port->dvb.frontend, 374 dvb_attach(mt2131_attach, fe0->dvb.frontend,
367 &i2c_bus->i2c_adap, 375 &i2c_bus->i2c_adap,
368 &hauppauge_generic_tunerconfig, 0); 376 &hauppauge_generic_tunerconfig, 0);
369 } 377 }
370 break; 378 break;
371 case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: 379 case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
372 i2c_bus = &dev->i2c_bus[0]; 380 i2c_bus = &dev->i2c_bus[0];
373 port->dvb.frontend = dvb_attach(lgdt330x_attach, 381 fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
374 &fusionhdtv_5_express, 382 &fusionhdtv_5_express,
375 &i2c_bus->i2c_adap); 383 &i2c_bus->i2c_adap);
376 if (port->dvb.frontend != NULL) { 384 if (fe0->dvb.frontend != NULL) {
377 dvb_attach(simple_tuner_attach, port->dvb.frontend, 385 dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
378 &i2c_bus->i2c_adap, 0x61, 386 &i2c_bus->i2c_adap, 0x61,
379 TUNER_LG_TDVS_H06XF); 387 TUNER_LG_TDVS_H06XF);
380 } 388 }
381 break; 389 break;
382 case CX23885_BOARD_HAUPPAUGE_HVR1500Q: 390 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
383 i2c_bus = &dev->i2c_bus[1]; 391 i2c_bus = &dev->i2c_bus[1];
384 port->dvb.frontend = dvb_attach(s5h1409_attach, 392 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
385 &hauppauge_hvr1500q_config, 393 &hauppauge_hvr1500q_config,
386 &dev->i2c_bus[0].i2c_adap); 394 &dev->i2c_bus[0].i2c_adap);
387 if (port->dvb.frontend != NULL) 395 if (fe0->dvb.frontend != NULL)
388 dvb_attach(xc5000_attach, port->dvb.frontend, 396 dvb_attach(xc5000_attach, fe0->dvb.frontend,
389 &i2c_bus->i2c_adap, 397 &i2c_bus->i2c_adap,
390 &hauppauge_hvr1500q_tunerconfig, i2c_bus); 398 &hauppauge_hvr1500q_tunerconfig);
391 break; 399 break;
392 case CX23885_BOARD_HAUPPAUGE_HVR1500: 400 case CX23885_BOARD_HAUPPAUGE_HVR1500:
393 i2c_bus = &dev->i2c_bus[1]; 401 i2c_bus = &dev->i2c_bus[1];
394 port->dvb.frontend = dvb_attach(s5h1409_attach, 402 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
395 &hauppauge_hvr1500_config, 403 &hauppauge_hvr1500_config,
396 &dev->i2c_bus[0].i2c_adap); 404 &dev->i2c_bus[0].i2c_adap);
397 if (port->dvb.frontend != NULL) { 405 if (fe0->dvb.frontend != NULL) {
398 struct dvb_frontend *fe; 406 struct dvb_frontend *fe;
399 struct xc2028_config cfg = { 407 struct xc2028_config cfg = {
400 .i2c_adap = &i2c_bus->i2c_adap, 408 .i2c_adap = &i2c_bus->i2c_adap,
401 .i2c_addr = 0x61, 409 .i2c_addr = 0x61,
402 .callback = cx23885_hvr1500_xc3028_callback,
403 }; 410 };
404 static struct xc2028_ctrl ctl = { 411 static struct xc2028_ctrl ctl = {
405 .fname = "xc3028-v27.fw", 412 .fname = XC2028_DEFAULT_FIRMWARE,
406 .max_len = 64, 413 .max_len = 64,
407 .scode_table = XC3028_FE_OREN538, 414 .scode_table = XC3028_FE_OREN538,
408 }; 415 };
409 416
410 fe = dvb_attach(xc2028_attach, 417 fe = dvb_attach(xc2028_attach,
411 port->dvb.frontend, &cfg); 418 fe0->dvb.frontend, &cfg);
412 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) 419 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
413 fe->ops.tuner_ops.set_config(fe, &ctl); 420 fe->ops.tuner_ops.set_config(fe, &ctl);
414 } 421 }
@@ -416,102 +423,204 @@ static int dvb_register(struct cx23885_tsport *port)
416 case CX23885_BOARD_HAUPPAUGE_HVR1200: 423 case CX23885_BOARD_HAUPPAUGE_HVR1200:
417 case CX23885_BOARD_HAUPPAUGE_HVR1700: 424 case CX23885_BOARD_HAUPPAUGE_HVR1700:
418 i2c_bus = &dev->i2c_bus[0]; 425 i2c_bus = &dev->i2c_bus[0];
419 port->dvb.frontend = dvb_attach(tda10048_attach, 426 fe0->dvb.frontend = dvb_attach(tda10048_attach,
420 &hauppauge_hvr1200_config, 427 &hauppauge_hvr1200_config,
421 &i2c_bus->i2c_adap); 428 &i2c_bus->i2c_adap);
422 if (port->dvb.frontend != NULL) { 429 if (fe0->dvb.frontend != NULL) {
423 dvb_attach(tda829x_attach, port->dvb.frontend, 430 dvb_attach(tda829x_attach, fe0->dvb.frontend,
424 &dev->i2c_bus[1].i2c_adap, 0x42, 431 &dev->i2c_bus[1].i2c_adap, 0x42,
425 &tda829x_no_probe); 432 &tda829x_no_probe);
426 dvb_attach(tda18271_attach, port->dvb.frontend, 433 dvb_attach(tda18271_attach, fe0->dvb.frontend,
427 0x60, &dev->i2c_bus[1].i2c_adap, 434 0x60, &dev->i2c_bus[1].i2c_adap,
428 &hauppauge_hvr1200_tuner_config); 435 &hauppauge_hvr1200_tuner_config);
429 } 436 }
430 break; 437 break;
431 case CX23885_BOARD_HAUPPAUGE_HVR1400: 438 case CX23885_BOARD_HAUPPAUGE_HVR1400:
432 i2c_bus = &dev->i2c_bus[0]; 439 i2c_bus = &dev->i2c_bus[0];
433 port->dvb.frontend = dvb_attach(dib7000p_attach, 440 fe0->dvb.frontend = dvb_attach(dib7000p_attach,
434 &i2c_bus->i2c_adap, 441 &i2c_bus->i2c_adap,
435 0x12, &hauppauge_hvr1400_dib7000_config); 442 0x12, &hauppauge_hvr1400_dib7000_config);
436 if (port->dvb.frontend != NULL) { 443 if (fe0->dvb.frontend != NULL) {
437 struct dvb_frontend *fe; 444 struct dvb_frontend *fe;
438 struct xc2028_config cfg = { 445 struct xc2028_config cfg = {
439 .i2c_adap = &dev->i2c_bus[1].i2c_adap, 446 .i2c_adap = &dev->i2c_bus[1].i2c_adap,
440 .i2c_addr = 0x64, 447 .i2c_addr = 0x64,
441 .callback = cx23885_hvr1500_xc3028_callback,
442 }; 448 };
443 static struct xc2028_ctrl ctl = { 449 static struct xc2028_ctrl ctl = {
444 .fname = "xc3028L-v36.fw", 450 .fname = XC3028L_DEFAULT_FIRMWARE,
445 .max_len = 64, 451 .max_len = 64,
446 .demod = 5000, 452 .demod = 5000,
447 .d2633 = 1 453 /* This is true for all demods with
454 v36 firmware? */
455 .type = XC2028_D2633,
448 }; 456 };
449 457
450 fe = dvb_attach(xc2028_attach, 458 fe = dvb_attach(xc2028_attach,
451 port->dvb.frontend, &cfg); 459 fe0->dvb.frontend, &cfg);
460 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
461 fe->ops.tuner_ops.set_config(fe, &ctl);
462 }
463 break;
464 case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
465 i2c_bus = &dev->i2c_bus[port->nr - 1];
466
467 fe0->dvb.frontend = dvb_attach(s5h1409_attach,
468 &dvico_s5h1409_config,
469 &i2c_bus->i2c_adap);
470 if (fe0->dvb.frontend == NULL)
471 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
472 &dvico_s5h1411_config,
473 &i2c_bus->i2c_adap);
474 if (fe0->dvb.frontend != NULL)
475 dvb_attach(xc5000_attach, fe0->dvb.frontend,
476 &i2c_bus->i2c_adap,
477 &dvico_xc5000_tunerconfig);
478 break;
479 case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: {
480 i2c_bus = &dev->i2c_bus[port->nr - 1];
481
482 fe0->dvb.frontend = dvb_attach(zl10353_attach,
483 &dvico_fusionhdtv_xc3028,
484 &i2c_bus->i2c_adap);
485 if (fe0->dvb.frontend != NULL) {
486 struct dvb_frontend *fe;
487 struct xc2028_config cfg = {
488 .i2c_adap = &i2c_bus->i2c_adap,
489 .i2c_addr = 0x61,
490 };
491 static struct xc2028_ctrl ctl = {
492 .fname = XC2028_DEFAULT_FIRMWARE,
493 .max_len = 64,
494 .demod = XC3028_FE_ZARLINK456,
495 };
496
497 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
498 &cfg);
499 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
500 fe->ops.tuner_ops.set_config(fe, &ctl);
501 }
502 break;
503 }
504 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
505 i2c_bus = &dev->i2c_bus[0];
506
507 fe0->dvb.frontend = dvb_attach(zl10353_attach,
508 &dvico_fusionhdtv_xc3028,
509 &i2c_bus->i2c_adap);
510 if (fe0->dvb.frontend != NULL) {
511 struct dvb_frontend *fe;
512 struct xc2028_config cfg = {
513 .i2c_adap = &dev->i2c_bus[1].i2c_adap,
514 .i2c_addr = 0x61,
515 };
516 static struct xc2028_ctrl ctl = {
517 .fname = XC2028_DEFAULT_FIRMWARE,
518 .max_len = 64,
519 .demod = XC3028_FE_ZARLINK456,
520 };
521
522 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
523 &cfg);
452 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) 524 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
453 fe->ops.tuner_ops.set_config(fe, &ctl); 525 fe->ops.tuner_ops.set_config(fe, &ctl);
454 } 526 }
455 break; 527 break;
456 default: 528 default:
457 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 529 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
530 " isn't supported yet\n",
458 dev->name); 531 dev->name);
459 break; 532 break;
460 } 533 }
461 if (NULL == port->dvb.frontend) { 534 if (NULL == fe0->dvb.frontend) {
462 printk("%s: frontend initialization failed\n", dev->name); 535 printk(KERN_ERR "%s: frontend initialization failed\n",
536 dev->name);
463 return -1; 537 return -1;
464 } 538 }
539 /* define general-purpose callback pointer */
540 fe0->dvb.frontend->callback = cx23885_tuner_callback;
465 541
466 /* Put the analog decoder in standby to keep it quiet */ 542 /* Put the analog decoder in standby to keep it quiet */
467 cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); 543 cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
468 544
469 if (port->dvb.frontend->ops.analog_ops.standby) 545 if (fe0->dvb.frontend->ops.analog_ops.standby)
470 port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend); 546 fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
471 547
472 /* register everything */ 548 /* register everything */
473 return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, 549 return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
474 &dev->pci->dev, adapter_nr); 550 &dev->pci->dev, adapter_nr, 0);
551
475} 552}
476 553
477int cx23885_dvb_register(struct cx23885_tsport *port) 554int cx23885_dvb_register(struct cx23885_tsport *port)
478{ 555{
556
557 struct videobuf_dvb_frontend *fe0;
479 struct cx23885_dev *dev = port->dev; 558 struct cx23885_dev *dev = port->dev;
480 int err; 559 int err, i;
560
561 /* Here we need to allocate the correct number of frontends,
562 * as reflected in the cards struct. The reality is that currrently
563 * no cx23885 boards support this - yet. But, if we don't modify this
564 * code then the second frontend would never be allocated (later)
565 * and fail with error before the attach in dvb_register().
566 * Without these changes we risk an OOPS later. The changes here
567 * are for safety, and should provide a good foundation for the
568 * future addition of any multi-frontend cx23885 based boards.
569 */
570 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
571 port->num_frontends);
572
573 for (i = 1; i <= port->num_frontends; i++) {
574 if (videobuf_dvb_alloc_frontend(
575 &port->frontends, i) == NULL) {
576 printk(KERN_ERR "%s() failed to alloc\n", __func__);
577 return -ENOMEM;
578 }
481 579
482 dprintk(1, "%s\n", __func__); 580 fe0 = videobuf_dvb_get_frontend(&port->frontends, i);
483 dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", 581 if (!fe0)
484 dev->board, 582 err = -EINVAL;
485 dev->name,
486 dev->pci_bus,
487 dev->pci_slot);
488 583
489 err = -ENODEV; 584 dprintk(1, "%s\n", __func__);
585 dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n",
586 dev->board,
587 dev->name,
588 dev->pci_bus,
589 dev->pci_slot);
490 590
491 /* dvb stuff */ 591 err = -ENODEV;
492 printk("%s: cx23885 based dvb card\n", dev->name); 592
493 videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock, 593 /* dvb stuff */
594 /* We have to init the queue for each frontend on a port. */
595 printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name);
596 videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops,
597 &dev->pci->dev, &port->slock,
494 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, 598 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
495 sizeof(struct cx23885_buffer), port); 599 sizeof(struct cx23885_buffer), port);
600 }
496 err = dvb_register(port); 601 err = dvb_register(port);
497 if (err != 0) 602 if (err != 0)
498 printk("%s() dvb_register failed err = %d\n", __func__, err); 603 printk(KERN_ERR "%s() dvb_register failed err = %d\n",
604 __func__, err);
499 605
500 return err; 606 return err;
501} 607}
502 608
503int cx23885_dvb_unregister(struct cx23885_tsport *port) 609int cx23885_dvb_unregister(struct cx23885_tsport *port)
504{ 610{
505 /* dvb */ 611 struct videobuf_dvb_frontend *fe0;
506 if(port->dvb.frontend) 612
507 videobuf_dvb_unregister(&port->dvb); 613 /* FIXME: in an error condition where the we have
614 * an expected number of frontends (attach problem)
615 * then this might not clean up correctly, if 1
616 * is invalid.
617 * This comment only applies to future boards IF they
618 * implement MFE support.
619 */
620 fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
621 if (fe0->dvb.frontend)
622 videobuf_dvb_unregister_bus(&port->frontends);
508 623
509 return 0; 624 return 0;
510} 625}
511 626
512/*
513 * Local variables:
514 * c-basic-offset: 8
515 * End:
516 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
517*/