diff options
Diffstat (limited to 'drivers/media/video/cx23885/cx23885-dvb.c')
-rw-r--r-- | drivers/media/video/cx23885/cx23885-dvb.c | 307 |
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 | ||
45 | static unsigned int debug; | 47 | static 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 | ||
82 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | 84 | static 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 | ||
88 | static void dvb_buf_release(struct videobuf_queue *q, | 90 | static 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 | ||
94 | static struct videobuf_queue_ops dvb_qops = { | 96 | static 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 | ||
169 | static 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 | |||
179 | static 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 | |||
167 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { | 189 | static 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 | |||
194 | static struct xc5000_config dvico_xc5000_tunerconfig = { | ||
195 | .i2c_address = 0x64, | ||
196 | .if_khz = 5380, | ||
171 | }; | 197 | }; |
172 | 198 | ||
173 | static struct tda829x_config tda829x_no_probe = { | 199 | static 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 | ||
279 | static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) | 305 | static 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 | ||
309 | static int dvb_register(struct cx23885_tsport *port) | 311 | static 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 | ||
477 | int cx23885_dvb_register(struct cx23885_tsport *port) | 554 | int 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 | ||
503 | int cx23885_dvb_unregister(struct cx23885_tsport *port) | 609 | int 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 | */ | ||