1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 DVB device driver for cx231xx
4
5 Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
6 Based on em28xx driver
7
8 */
9
10#include "cx231xx.h"
11#include <linux/kernel.h>
12#include <linux/slab.h>
13
14#include <media/dvbdev.h>
15#include <media/dmxdev.h>
16#include <media/dvb_demux.h>
17#include <media/dvb_net.h>
18#include <media/dvb_frontend.h>
19#include <media/v4l2-common.h>
20#include <media/tuner.h>
21
22#include "xc5000.h"
23#include "s5h1432.h"
24#include "tda18271.h"
25#include "s5h1411.h"
26#include "lgdt3305.h"
27#include "si2165.h"
28#include "si2168.h"
29#include "mb86a20s.h"
30#include "si2157.h"
31#include "lgdt3306a.h"
32#include "r820t.h"
33#include "mn88473.h"
34
35MODULE_DESCRIPTION("driver for cx231xx based DVB cards");
36MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
37MODULE_LICENSE("GPL");
38
39static unsigned int debug;
40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "enable debug messages [dvb]");
42
43DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
44
45#define CX231XX_DVB_NUM_BUFS 5
46#define CX231XX_DVB_MAX_PACKETSIZE 564
47#define CX231XX_DVB_MAX_PACKETS 64
48#define CX231XX_DVB_MAX_FRONTENDS 2
49
50struct cx231xx_dvb {
51 struct dvb_frontend *frontend[CX231XX_DVB_MAX_FRONTENDS];
52
53 /* feed count management */
54 struct mutex lock;
55 int nfeeds;
56
57 /* general boilerplate stuff */
58 struct dvb_adapter adapter;
59 struct dvb_demux demux;
60 struct dmxdev dmxdev;
61 struct dmx_frontend fe_hw;
62 struct dmx_frontend fe_mem;
63 struct dvb_net net;
64 struct i2c_client *i2c_client_demod[2];
65 struct i2c_client *i2c_client_tuner;
66};
67
68static struct s5h1432_config dvico_s5h1432_config = {
69 .output_mode = S5H1432_SERIAL_OUTPUT,
70 .gpio = S5H1432_GPIO_ON,
71 .qam_if = S5H1432_IF_4000,
72 .vsb_if = S5H1432_IF_4000,
73 .inversion = S5H1432_INVERSION_OFF,
74 .status_mode = S5H1432_DEMODLOCKING,
75 .mpeg_timing = S5H1432_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
76};
77
78static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = {
79 .dvbt_6 = { .if_freq = 4000, .agc_mode = 3, .std = 4,
80 .if_lvl = 1, .rfagc_top = 0x37, },
81 .dvbt_7 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
82 .if_lvl = 1, .rfagc_top = 0x37, },
83 .dvbt_8 = { .if_freq = 4000, .agc_mode = 3, .std = 6,
84 .if_lvl = 1, .rfagc_top = 0x37, },
85};
86
87static struct tda18271_std_map mb86a20s_tda18271_config = {
88 .dvbt_6 = { .if_freq = 4000, .agc_mode = 3, .std = 4,
89 .if_lvl = 0, .rfagc_top = 0x37, },
90};
91
92static struct tda18271_config cnxt_rde253s_tunerconfig = {
93 .std_map = &cnxt_rde253s_tda18271_std_map,
94 .gate = TDA18271_GATE_ANALOG,
95};
96
97static struct s5h1411_config tda18271_s5h1411_config = {
98 .output_mode = S5H1411_SERIAL_OUTPUT,
99 .gpio = S5H1411_GPIO_OFF,
100 .vsb_if = S5H1411_IF_3250,
101 .qam_if = S5H1411_IF_4000,
102 .inversion = S5H1411_INVERSION_ON,
103 .status_mode = S5H1411_DEMODLOCKING,
104 .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
105};
106static struct s5h1411_config xc5000_s5h1411_config = {
107 .output_mode = S5H1411_SERIAL_OUTPUT,
108 .gpio = S5H1411_GPIO_OFF,
109 .vsb_if = S5H1411_IF_3250,
110 .qam_if = S5H1411_IF_3250,
111 .inversion = S5H1411_INVERSION_OFF,
112 .status_mode = S5H1411_DEMODLOCKING,
113 .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
114};
115
116static struct lgdt3305_config hcw_lgdt3305_config = {
117 .i2c_addr = 0x0e,
118 .mpeg_mode = LGDT3305_MPEG_SERIAL,
119 .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
120 .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
121 .deny_i2c_rptr = 1,
122 .spectral_inversion = 1,
123 .qam_if_khz = 4000,
124 .vsb_if_khz = 3250,
125};
126
127static struct tda18271_std_map hauppauge_tda18271_std_map = {
128 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
129 .if_lvl = 1, .rfagc_top = 0x58, },
130 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
131 .if_lvl = 1, .rfagc_top = 0x58, },
132};
133
134static struct tda18271_config hcw_tda18271_config = {
135 .std_map = &hauppauge_tda18271_std_map,
136 .gate = TDA18271_GATE_DIGITAL,
137};
138
139static const struct mb86a20s_config pv_mb86a20s_config = {
140 .demod_address = 0x10,
141 .is_serial = true,
142};
143
144static struct tda18271_config pv_tda18271_config = {
145 .std_map = &mb86a20s_tda18271_config,
146 .gate = TDA18271_GATE_DIGITAL,
147 .small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
148};
149
150static const struct lgdt3306a_config hauppauge_955q_lgdt3306a_config = {
151 .qam_if_khz = 4000,
152 .vsb_if_khz = 3250,
153 .spectral_inversion = 1,
154 .mpeg_mode = LGDT3306A_MPEG_SERIAL,
155 .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE,
156 .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH,
157 .xtalMHz = 25,
158};
159
160static struct r820t_config astrometa_t2hybrid_r820t_config = {
161 .i2c_addr = 0x3a, /* 0x74 >> 1 */
162 .xtal = 16000000,
163 .rafael_chip = CHIP_R828D,
164 .max_i2c_msg_len = 2,
165};
166
167static inline void print_err_status(struct cx231xx *dev, int packet, int status)
168{
169 char *errmsg = "Unknown";
170
171 switch (status) {
172 case -ENOENT:
173 errmsg = "unlinked synchronously";
174 break;
175 case -ECONNRESET:
176 errmsg = "unlinked asynchronously";
177 break;
178 case -ENOSR:
179 errmsg = "Buffer error (overrun)";
180 break;
181 case -EPIPE:
182 errmsg = "Stalled (device not responding)";
183 break;
184 case -EOVERFLOW:
185 errmsg = "Babble (bad cable?)";
186 break;
187 case -EPROTO:
188 errmsg = "Bit-stuff error (bad cable?)";
189 break;
190 case -EILSEQ:
191 errmsg = "CRC/Timeout (could be anything)";
192 break;
193 case -ETIME:
194 errmsg = "Device does not respond";
195 break;
196 }
197 if (packet < 0) {
198 dev_dbg(dev->dev,
199 "URB status %d [%s].\n", status, errmsg);
200 } else {
201 dev_dbg(dev->dev,
202 "URB packet %d, status %d [%s].\n",
203 packet, status, errmsg);
204 }
205}
206
207static inline int dvb_isoc_copy(struct cx231xx *dev, struct urb *urb)
208{
209 int i;
210
211 if (!dev)
212 return 0;
213
214 if (dev->state & DEV_DISCONNECTED)
215 return 0;
216
217 if (urb->status < 0) {
218 print_err_status(dev, packet: -1, status: urb->status);
219 if (urb->status == -ENOENT)
220 return 0;
221 }
222
223 for (i = 0; i < urb->number_of_packets; i++) {
224 int status = urb->iso_frame_desc[i].status;
225
226 if (status < 0) {
227 print_err_status(dev, packet: i, status);
228 if (urb->iso_frame_desc[i].status != -EPROTO)
229 continue;
230 }
231
232 dvb_dmx_swfilter(demux: &dev->dvb->demux,
233 buf: urb->transfer_buffer +
234 urb->iso_frame_desc[i].offset,
235 count: urb->iso_frame_desc[i].actual_length);
236 }
237
238 return 0;
239}
240
241static inline int dvb_bulk_copy(struct cx231xx *dev, struct urb *urb)
242{
243 if (!dev)
244 return 0;
245
246 if (dev->state & DEV_DISCONNECTED)
247 return 0;
248
249 if (urb->status < 0) {
250 print_err_status(dev, packet: -1, status: urb->status);
251 if (urb->status == -ENOENT)
252 return 0;
253 }
254
255 /* Feed the transport payload into the kernel demux */
256 dvb_dmx_swfilter(demux: &dev->dvb->demux,
257 buf: urb->transfer_buffer, count: urb->actual_length);
258
259 return 0;
260}
261
262static int start_streaming(struct cx231xx_dvb *dvb)
263{
264 int rc;
265 struct cx231xx *dev = dvb->adapter.priv;
266
267 if (dev->USE_ISO) {
268 dev_dbg(dev->dev, "DVB transfer mode is ISO.\n");
269 cx231xx_set_alt_setting(dev, index: INDEX_TS1, alt: 5);
270 rc = cx231xx_set_mode(dev, set_mode: CX231XX_DIGITAL_MODE);
271 if (rc < 0)
272 return rc;
273 dev->mode_tv = 1;
274 return cx231xx_init_isoc(dev, CX231XX_DVB_MAX_PACKETS,
275 CX231XX_DVB_NUM_BUFS,
276 max_pkt_size: dev->ts1_mode.max_pkt_size,
277 isoc_copy: dvb_isoc_copy);
278 } else {
279 dev_dbg(dev->dev, "DVB transfer mode is BULK.\n");
280 cx231xx_set_alt_setting(dev, index: INDEX_TS1, alt: 0);
281 rc = cx231xx_set_mode(dev, set_mode: CX231XX_DIGITAL_MODE);
282 if (rc < 0)
283 return rc;
284 dev->mode_tv = 1;
285 return cx231xx_init_bulk(dev, CX231XX_DVB_MAX_PACKETS,
286 CX231XX_DVB_NUM_BUFS,
287 max_pkt_size: dev->ts1_mode.max_pkt_size,
288 bulk_copy: dvb_bulk_copy);
289 }
290
291}
292
293static int stop_streaming(struct cx231xx_dvb *dvb)
294{
295 struct cx231xx *dev = dvb->adapter.priv;
296
297 if (dev->USE_ISO)
298 cx231xx_uninit_isoc(dev);
299 else
300 cx231xx_uninit_bulk(dev);
301
302 cx231xx_set_mode(dev, set_mode: CX231XX_SUSPEND);
303
304 return 0;
305}
306
307static int start_feed(struct dvb_demux_feed *feed)
308{
309 struct dvb_demux *demux = feed->demux;
310 struct cx231xx_dvb *dvb = demux->priv;
311 int rc, ret;
312
313 if (!demux->dmx.frontend)
314 return -EINVAL;
315
316 mutex_lock(&dvb->lock);
317 dvb->nfeeds++;
318 rc = dvb->nfeeds;
319
320 if (dvb->nfeeds == 1) {
321 ret = start_streaming(dvb);
322 if (ret < 0)
323 rc = ret;
324 }
325
326 mutex_unlock(lock: &dvb->lock);
327 return rc;
328}
329
330static int stop_feed(struct dvb_demux_feed *feed)
331{
332 struct dvb_demux *demux = feed->demux;
333 struct cx231xx_dvb *dvb = demux->priv;
334 int err = 0;
335
336 mutex_lock(&dvb->lock);
337 dvb->nfeeds--;
338
339 if (0 == dvb->nfeeds)
340 err = stop_streaming(dvb);
341
342 mutex_unlock(lock: &dvb->lock);
343 return err;
344}
345
346/* ------------------------------------------------------------------ */
347static int cx231xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
348{
349 struct cx231xx *dev = fe->dvb->priv;
350
351 if (acquire)
352 return cx231xx_set_mode(dev, set_mode: CX231XX_DIGITAL_MODE);
353 else
354 return cx231xx_set_mode(dev, set_mode: CX231XX_SUSPEND);
355}
356
357/* ------------------------------------------------------------------ */
358
359static struct xc5000_config cnxt_rde250_tunerconfig = {
360 .i2c_address = 0x61,
361 .if_khz = 4000,
362};
363static struct xc5000_config cnxt_rdu250_tunerconfig = {
364 .i2c_address = 0x61,
365 .if_khz = 3250,
366};
367
368/* ------------------------------------------------------------------ */
369#if 0
370static int attach_xc5000(u8 addr, struct cx231xx *dev)
371{
372
373 struct dvb_frontend *fe;
374 struct xc5000_config cfg;
375
376 memset(&cfg, 0, sizeof(cfg));
377 cfg.i2c_adap = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master);
378 cfg.i2c_addr = addr;
379
380 if (!dev->dvb->frontend[0]) {
381 dev_err(dev->dev, "%s/2: dvb frontend not attached. Can't attach xc5000\n",
382 dev->name);
383 return -EINVAL;
384 }
385
386 fe = dvb_attach(xc5000_attach, dev->dvb->frontend[0], &cfg);
387 if (!fe) {
388 dev_err(dev->dev, "%s/2: xc5000 attach failed\n", dev->name);
389 dvb_frontend_detach(dev->dvb->frontend[0]);
390 dev->dvb->frontend[0] = NULL;
391 return -EINVAL;
392 }
393
394 dev_info(dev->dev, "%s/2: xc5000 attached\n", dev->name);
395
396 return 0;
397}
398#endif
399
400int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq)
401{
402 if (dev->dvb && dev->dvb->frontend[0]) {
403
404 struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops;
405
406 if (dops->set_analog_params != NULL) {
407 struct analog_parameters params;
408
409 params.frequency = freq;
410 params.std = dev->norm;
411 params.mode = 0; /* 0- Air; 1 - cable */
412 /*params.audmode = ; */
413
414 /* Set the analog parameters to set the frequency */
415 dops->set_analog_params(dev->dvb->frontend[0], &params);
416 }
417
418 }
419
420 return 0;
421}
422
423int cx231xx_reset_analog_tuner(struct cx231xx *dev)
424{
425 int status = 0;
426
427 if (dev->dvb && dev->dvb->frontend[0]) {
428
429 struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops;
430
431 if (dops->init != NULL && !dev->xc_fw_load_done) {
432
433 dev_dbg(dev->dev,
434 "Reloading firmware for XC5000\n");
435 status = dops->init(dev->dvb->frontend[0]);
436 if (status == 0) {
437 dev->xc_fw_load_done = 1;
438 dev_dbg(dev->dev,
439 "XC5000 firmware download completed\n");
440 } else {
441 dev->xc_fw_load_done = 0;
442 dev_dbg(dev->dev,
443 "XC5000 firmware download failed !!!\n");
444 }
445 }
446
447 }
448
449 return status;
450}
451
452/* ------------------------------------------------------------------ */
453
454static int register_dvb(struct cx231xx_dvb *dvb,
455 struct module *module,
456 struct cx231xx *dev, struct device *device)
457{
458 int result;
459
460 mutex_init(&dvb->lock);
461
462
463 /* register adapter */
464 result = dvb_register_adapter(adap: &dvb->adapter, name: dev->name, module, device,
465 adapter_nums: adapter_nr);
466 if (result < 0) {
467 dev_warn(dev->dev,
468 "%s: dvb_register_adapter failed (errno = %d)\n",
469 dev->name, result);
470 goto fail_adapter;
471 }
472 dvb_register_media_controller(adap: &dvb->adapter, mdev: dev->media_dev);
473
474 /* Ensure all frontends negotiate bus access */
475 dvb->frontend[0]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
476 if (dvb->frontend[1])
477 dvb->frontend[1]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl;
478
479 dvb->adapter.priv = dev;
480
481 /* register frontend */
482 result = dvb_register_frontend(dvb: &dvb->adapter, fe: dvb->frontend[0]);
483 if (result < 0) {
484 dev_warn(dev->dev,
485 "%s: dvb_register_frontend failed (errno = %d)\n",
486 dev->name, result);
487 goto fail_frontend0;
488 }
489
490 if (dvb->frontend[1]) {
491 result = dvb_register_frontend(dvb: &dvb->adapter, fe: dvb->frontend[1]);
492 if (result < 0) {
493 dev_warn(dev->dev,
494 "%s: 2nd dvb_register_frontend failed (errno = %d)\n",
495 dev->name, result);
496 goto fail_frontend1;
497 }
498
499 /* MFE lock */
500 dvb->adapter.mfe_shared = 1;
501 }
502
503 /* register demux stuff */
504 dvb->demux.dmx.capabilities =
505 DMX_TS_FILTERING | DMX_SECTION_FILTERING |
506 DMX_MEMORY_BASED_FILTERING;
507 dvb->demux.priv = dvb;
508 dvb->demux.filternum = 256;
509 dvb->demux.feednum = 256;
510 dvb->demux.start_feed = start_feed;
511 dvb->demux.stop_feed = stop_feed;
512
513 result = dvb_dmx_init(demux: &dvb->demux);
514 if (result < 0) {
515 dev_warn(dev->dev,
516 "%s: dvb_dmx_init failed (errno = %d)\n",
517 dev->name, result);
518 goto fail_dmx;
519 }
520
521 dvb->dmxdev.filternum = 256;
522 dvb->dmxdev.demux = &dvb->demux.dmx;
523 dvb->dmxdev.capabilities = 0;
524 result = dvb_dmxdev_init(dmxdev: &dvb->dmxdev, adap: &dvb->adapter);
525 if (result < 0) {
526 dev_warn(dev->dev,
527 "%s: dvb_dmxdev_init failed (errno = %d)\n",
528 dev->name, result);
529 goto fail_dmxdev;
530 }
531
532 dvb->fe_hw.source = DMX_FRONTEND_0;
533 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
534 if (result < 0) {
535 dev_warn(dev->dev,
536 "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
537 dev->name, result);
538 goto fail_fe_hw;
539 }
540
541 dvb->fe_mem.source = DMX_MEMORY_FE;
542 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
543 if (result < 0) {
544 dev_warn(dev->dev,
545 "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
546 dev->name, result);
547 goto fail_fe_mem;
548 }
549
550 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
551 if (result < 0) {
552 dev_warn(dev->dev,
553 "%s: connect_frontend failed (errno = %d)\n",
554 dev->name, result);
555 goto fail_fe_conn;
556 }
557
558 /* register network adapter */
559 dvb_net_init(adap: &dvb->adapter, dvbnet: &dvb->net, dmxdemux: &dvb->demux.dmx);
560 result = dvb_create_media_graph(adap: &dvb->adapter,
561 create_rf_connector: dev->tuner_type == TUNER_ABSENT);
562 if (result < 0)
563 goto fail_create_graph;
564
565 return 0;
566
567fail_create_graph:
568 dvb_net_release(dvbnet: &dvb->net);
569fail_fe_conn:
570 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
571fail_fe_mem:
572 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
573fail_fe_hw:
574 dvb_dmxdev_release(dmxdev: &dvb->dmxdev);
575fail_dmxdev:
576 dvb_dmx_release(demux: &dvb->demux);
577fail_dmx:
578 if (dvb->frontend[1])
579 dvb_unregister_frontend(fe: dvb->frontend[1]);
580 dvb_unregister_frontend(fe: dvb->frontend[0]);
581fail_frontend1:
582 if (dvb->frontend[1])
583 dvb_frontend_detach(fe: dvb->frontend[1]);
584fail_frontend0:
585 dvb_frontend_detach(fe: dvb->frontend[0]);
586 dvb_unregister_adapter(adap: &dvb->adapter);
587fail_adapter:
588 return result;
589}
590
591static void unregister_dvb(struct cx231xx_dvb *dvb)
592{
593 dvb_net_release(dvbnet: &dvb->net);
594 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
595 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
596 dvb_dmxdev_release(dmxdev: &dvb->dmxdev);
597 dvb_dmx_release(demux: &dvb->demux);
598 if (dvb->frontend[1])
599 dvb_unregister_frontend(fe: dvb->frontend[1]);
600 dvb_unregister_frontend(fe: dvb->frontend[0]);
601 if (dvb->frontend[1])
602 dvb_frontend_detach(fe: dvb->frontend[1]);
603 dvb_frontend_detach(fe: dvb->frontend[0]);
604 dvb_unregister_adapter(adap: &dvb->adapter);
605
606 /* remove I2C tuner */
607 dvb_module_release(client: dvb->i2c_client_tuner);
608 dvb->i2c_client_tuner = NULL;
609 /* remove I2C demod(s) */
610 dvb_module_release(client: dvb->i2c_client_demod[1]);
611 dvb->i2c_client_demod[1] = NULL;
612 dvb_module_release(client: dvb->i2c_client_demod[0]);
613 dvb->i2c_client_demod[0] = NULL;
614}
615
616static int dvb_init(struct cx231xx *dev)
617{
618 int result;
619 struct cx231xx_dvb *dvb;
620 struct i2c_adapter *tuner_i2c;
621 struct i2c_adapter *demod_i2c;
622 struct i2c_client *client;
623 struct i2c_adapter *adapter;
624
625 if (!dev->board.has_dvb) {
626 /* This device does not support the extension */
627 return 0;
628 }
629
630 dvb = kzalloc(size: sizeof(struct cx231xx_dvb), GFP_KERNEL);
631
632 if (dvb == NULL) {
633 dev_info(dev->dev,
634 "cx231xx_dvb: memory allocation failed\n");
635 return -ENOMEM;
636 }
637 dev->dvb = dvb;
638 dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
639 dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
640
641 tuner_i2c = cx231xx_get_i2c_adap(dev, i2c_port: dev->board.tuner_i2c_master);
642 demod_i2c = cx231xx_get_i2c_adap(dev, i2c_port: dev->board.demod_i2c_master);
643 mutex_lock(&dev->lock);
644 cx231xx_set_mode(dev, set_mode: CX231XX_DIGITAL_MODE);
645 cx231xx_demod_reset(dev);
646 /* init frontend */
647 switch (dev->model) {
648 case CX231XX_BOARD_CNXT_CARRAERA:
649 case CX231XX_BOARD_CNXT_RDE_250:
650
651 dev->dvb->frontend[0] = dvb_attach(s5h1432_attach,
652 &dvico_s5h1432_config,
653 demod_i2c);
654
655 if (!dev->dvb->frontend[0]) {
656 dev_err(dev->dev,
657 "Failed to attach s5h1432 front end\n");
658 result = -EINVAL;
659 goto out_free;
660 }
661
662 /* define general-purpose callback pointer */
663 dvb->frontend[0]->callback = cx231xx_tuner_callback;
664
665 if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0],
666 tuner_i2c,
667 &cnxt_rde250_tunerconfig)) {
668 result = -EINVAL;
669 goto out_free;
670 }
671
672 break;
673 case CX231XX_BOARD_CNXT_SHELBY:
674 case CX231XX_BOARD_CNXT_RDU_250:
675
676 dev->dvb->frontend[0] = dvb_attach(s5h1411_attach,
677 &xc5000_s5h1411_config,
678 demod_i2c);
679
680 if (!dev->dvb->frontend[0]) {
681 dev_err(dev->dev,
682 "Failed to attach s5h1411 front end\n");
683 result = -EINVAL;
684 goto out_free;
685 }
686
687 /* define general-purpose callback pointer */
688 dvb->frontend[0]->callback = cx231xx_tuner_callback;
689
690 if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0],
691 tuner_i2c,
692 &cnxt_rdu250_tunerconfig)) {
693 result = -EINVAL;
694 goto out_free;
695 }
696 break;
697 case CX231XX_BOARD_CNXT_RDE_253S:
698
699 dev->dvb->frontend[0] = dvb_attach(s5h1432_attach,
700 &dvico_s5h1432_config,
701 demod_i2c);
702
703 if (!dev->dvb->frontend[0]) {
704 dev_err(dev->dev,
705 "Failed to attach s5h1432 front end\n");
706 result = -EINVAL;
707 goto out_free;
708 }
709
710 /* define general-purpose callback pointer */
711 dvb->frontend[0]->callback = cx231xx_tuner_callback;
712
713 if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0],
714 dev->board.tuner_addr, tuner_i2c,
715 &cnxt_rde253s_tunerconfig)) {
716 result = -EINVAL;
717 goto out_free;
718 }
719 break;
720 case CX231XX_BOARD_CNXT_RDU_253S:
721 case CX231XX_BOARD_KWORLD_UB445_USB_HYBRID:
722
723 dev->dvb->frontend[0] = dvb_attach(s5h1411_attach,
724 &tda18271_s5h1411_config,
725 demod_i2c);
726
727 if (!dev->dvb->frontend[0]) {
728 dev_err(dev->dev,
729 "Failed to attach s5h1411 front end\n");
730 result = -EINVAL;
731 goto out_free;
732 }
733
734 /* define general-purpose callback pointer */
735 dvb->frontend[0]->callback = cx231xx_tuner_callback;
736
737 if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0],
738 dev->board.tuner_addr, tuner_i2c,
739 &cnxt_rde253s_tunerconfig)) {
740 result = -EINVAL;
741 goto out_free;
742 }
743 break;
744 case CX231XX_BOARD_HAUPPAUGE_EXETER:
745
746 dev_info(dev->dev,
747 "%s: looking for tuner / demod on i2c bus: %d\n",
748 __func__, i2c_adapter_id(tuner_i2c));
749
750 dev->dvb->frontend[0] = dvb_attach(lgdt3305_attach,
751 &hcw_lgdt3305_config,
752 demod_i2c);
753
754 if (!dev->dvb->frontend[0]) {
755 dev_err(dev->dev,
756 "Failed to attach LG3305 front end\n");
757 result = -EINVAL;
758 goto out_free;
759 }
760
761 /* define general-purpose callback pointer */
762 dvb->frontend[0]->callback = cx231xx_tuner_callback;
763
764 dvb_attach(tda18271_attach, dev->dvb->frontend[0],
765 dev->board.tuner_addr, tuner_i2c,
766 &hcw_tda18271_config);
767 break;
768
769 case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx:
770 {
771 struct si2165_platform_data si2165_pdata = {};
772
773 /* attach demod */
774 si2165_pdata.fe = &dev->dvb->frontend[0];
775 si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
776 si2165_pdata.ref_freq_hz = 16000000;
777
778 /* perform probe/init/attach */
779 client = dvb_module_probe(module_name: "si2165", NULL, adap: demod_i2c,
780 addr: dev->board.demod_addr,
781 platform_data: &si2165_pdata);
782 if (!client) {
783 result = -ENODEV;
784 goto out_free;
785 }
786 dvb->i2c_client_demod[0] = client;
787
788 dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
789
790 /* define general-purpose callback pointer */
791 dvb->frontend[0]->callback = cx231xx_tuner_callback;
792
793 dvb_attach(tda18271_attach, dev->dvb->frontend[0],
794 dev->board.tuner_addr, tuner_i2c,
795 &hcw_tda18271_config);
796
797 dev->cx231xx_reset_analog_tuner = NULL;
798 break;
799 }
800 case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx:
801 {
802 struct si2165_platform_data si2165_pdata = {};
803 struct si2157_config si2157_config = {};
804
805 /* attach demod */
806 si2165_pdata.fe = &dev->dvb->frontend[0];
807 si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT;
808 si2165_pdata.ref_freq_hz = 24000000;
809
810 /* perform probe/init/attach */
811 client = dvb_module_probe(module_name: "si2165", NULL, adap: demod_i2c,
812 addr: dev->board.demod_addr,
813 platform_data: &si2165_pdata);
814 if (!client) {
815 result = -ENODEV;
816 goto out_free;
817 }
818 dvb->i2c_client_demod[0] = client;
819
820 dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
821
822 /* define general-purpose callback pointer */
823 dvb->frontend[0]->callback = cx231xx_tuner_callback;
824
825 /* attach tuner */
826 si2157_config.fe = dev->dvb->frontend[0];
827#ifdef CONFIG_MEDIA_CONTROLLER_DVB
828 si2157_config.mdev = dev->media_dev;
829#endif
830 si2157_config.if_port = 1;
831 si2157_config.inversion = true;
832
833 /* perform probe/init/attach */
834 client = dvb_module_probe(module_name: "si2157", NULL, adap: tuner_i2c,
835 addr: dev->board.tuner_addr,
836 platform_data: &si2157_config);
837 if (!client) {
838 result = -ENODEV;
839 goto out_free;
840 }
841 dev->cx231xx_reset_analog_tuner = NULL;
842
843 dev->dvb->i2c_client_tuner = client;
844 break;
845 }
846 case CX231XX_BOARD_HAUPPAUGE_955Q:
847 {
848 struct si2157_config si2157_config = {};
849 struct lgdt3306a_config lgdt3306a_config = {};
850
851 lgdt3306a_config = hauppauge_955q_lgdt3306a_config;
852 lgdt3306a_config.fe = &dev->dvb->frontend[0];
853 lgdt3306a_config.i2c_adapter = &adapter;
854
855 /* perform probe/init/attach */
856 client = dvb_module_probe(module_name: "lgdt3306a", NULL, adap: demod_i2c,
857 addr: dev->board.demod_addr,
858 platform_data: &lgdt3306a_config);
859 if (!client) {
860 result = -ENODEV;
861 goto out_free;
862 }
863 dvb->i2c_client_demod[0] = client;
864
865 dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
866
867 /* define general-purpose callback pointer */
868 dvb->frontend[0]->callback = cx231xx_tuner_callback;
869
870 /* attach tuner */
871 si2157_config.fe = dev->dvb->frontend[0];
872#ifdef CONFIG_MEDIA_CONTROLLER_DVB
873 si2157_config.mdev = dev->media_dev;
874#endif
875 si2157_config.if_port = 1;
876 si2157_config.inversion = true;
877
878 /* perform probe/init/attach */
879 client = dvb_module_probe(module_name: "si2157", NULL, adap: tuner_i2c,
880 addr: dev->board.tuner_addr,
881 platform_data: &si2157_config);
882 if (!client) {
883 result = -ENODEV;
884 goto out_free;
885 }
886 dev->cx231xx_reset_analog_tuner = NULL;
887
888 dev->dvb->i2c_client_tuner = client;
889 break;
890 }
891 case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
892 case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID:
893
894 dev_info(dev->dev,
895 "%s: looking for demod on i2c bus: %d\n",
896 __func__, i2c_adapter_id(tuner_i2c));
897
898 dev->dvb->frontend[0] = dvb_attach(mb86a20s_attach,
899 &pv_mb86a20s_config,
900 demod_i2c);
901
902 if (!dev->dvb->frontend[0]) {
903 dev_err(dev->dev,
904 "Failed to attach mb86a20s demod\n");
905 result = -EINVAL;
906 goto out_free;
907 }
908
909 /* define general-purpose callback pointer */
910 dvb->frontend[0]->callback = cx231xx_tuner_callback;
911
912 dvb_attach(tda18271_attach, dev->dvb->frontend[0],
913 dev->board.tuner_addr, tuner_i2c,
914 &pv_tda18271_config);
915 break;
916
917 case CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD:
918 {
919 struct si2157_config si2157_config = {};
920 struct si2168_config si2168_config = {};
921
922 /* attach demodulator chip */
923 si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */
924 si2168_config.fe = &dev->dvb->frontend[0];
925 si2168_config.i2c_adapter = &adapter;
926 si2168_config.ts_clock_inv = true;
927
928 /* perform probe/init/attach */
929 client = dvb_module_probe(module_name: "si2168", NULL, adap: demod_i2c,
930 addr: dev->board.demod_addr,
931 platform_data: &si2168_config);
932 if (!client) {
933 result = -ENODEV;
934 goto out_free;
935 }
936 dvb->i2c_client_demod[0] = client;
937
938 /* attach tuner chip */
939 si2157_config.fe = dev->dvb->frontend[0];
940#ifdef CONFIG_MEDIA_CONTROLLER_DVB
941 si2157_config.mdev = dev->media_dev;
942#endif
943 si2157_config.if_port = 1;
944 si2157_config.inversion = false;
945
946 /* perform probe/init/attach */
947 client = dvb_module_probe(module_name: "si2157", NULL, adap: tuner_i2c,
948 addr: dev->board.tuner_addr,
949 platform_data: &si2157_config);
950 if (!client) {
951 result = -ENODEV;
952 goto out_free;
953 }
954 dev->cx231xx_reset_analog_tuner = NULL;
955 dev->dvb->i2c_client_tuner = client;
956 break;
957 }
958 case CX231XX_BOARD_ASTROMETA_T2HYBRID:
959 {
960 struct mn88473_config mn88473_config = {};
961
962 /* attach demodulator chip */
963 mn88473_config.i2c_wr_max = 16;
964 mn88473_config.xtal = 25000000;
965 mn88473_config.fe = &dev->dvb->frontend[0];
966
967 /* perform probe/init/attach */
968 client = dvb_module_probe(module_name: "mn88473", NULL, adap: demod_i2c,
969 addr: dev->board.demod_addr,
970 platform_data: &mn88473_config);
971 if (!client) {
972 result = -ENODEV;
973 goto out_free;
974 }
975 dvb->i2c_client_demod[0] = client;
976
977 /* define general-purpose callback pointer */
978 dvb->frontend[0]->callback = cx231xx_tuner_callback;
979
980 /* attach tuner chip */
981 dvb_attach(r820t_attach, dev->dvb->frontend[0],
982 tuner_i2c,
983 &astrometa_t2hybrid_r820t_config);
984 break;
985 }
986 case CX231XX_BOARD_HAUPPAUGE_935C:
987 {
988 struct si2157_config si2157_config = {};
989 struct si2168_config si2168_config = {};
990
991 /* attach demodulator chip */
992 si2168_config.ts_mode = SI2168_TS_SERIAL;
993 si2168_config.fe = &dev->dvb->frontend[0];
994 si2168_config.i2c_adapter = &adapter;
995 si2168_config.ts_clock_inv = true;
996
997 /* perform probe/init/attach */
998 client = dvb_module_probe(module_name: "si2168", NULL, adap: demod_i2c,
999 addr: dev->board.demod_addr,
1000 platform_data: &si2168_config);
1001 if (!client) {
1002 result = -ENODEV;
1003 goto out_free;
1004 }
1005 dvb->i2c_client_demod[0] = client;
1006 dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL;
1007
1008 /* define general-purpose callback pointer */
1009 dvb->frontend[0]->callback = cx231xx_tuner_callback;
1010
1011 /* attach tuner */
1012 si2157_config.fe = dev->dvb->frontend[0];
1013#ifdef CONFIG_MEDIA_CONTROLLER_DVB
1014 si2157_config.mdev = dev->media_dev;
1015#endif
1016 si2157_config.if_port = 1;
1017 si2157_config.inversion = true;
1018
1019 /* perform probe/init/attach */
1020 client = dvb_module_probe(module_name: "si2157", NULL, adap: tuner_i2c,
1021 addr: dev->board.tuner_addr,
1022 platform_data: &si2157_config);
1023 if (!client) {
1024 result = -ENODEV;
1025 goto out_free;
1026 }
1027 dev->cx231xx_reset_analog_tuner = NULL;
1028 dev->dvb->i2c_client_tuner = client;
1029 break;
1030 }
1031 case CX231XX_BOARD_HAUPPAUGE_975:
1032 {
1033 struct i2c_adapter *adapter2;
1034 struct si2157_config si2157_config = {};
1035 struct lgdt3306a_config lgdt3306a_config = {};
1036 struct si2168_config si2168_config = {};
1037
1038 /* attach first demodulator chip */
1039 lgdt3306a_config = hauppauge_955q_lgdt3306a_config;
1040 lgdt3306a_config.fe = &dev->dvb->frontend[0];
1041 lgdt3306a_config.i2c_adapter = &adapter;
1042
1043 /* perform probe/init/attach */
1044 client = dvb_module_probe(module_name: "lgdt3306a", NULL, adap: demod_i2c,
1045 addr: dev->board.demod_addr,
1046 platform_data: &lgdt3306a_config);
1047 if (!client) {
1048 result = -ENODEV;
1049 goto out_free;
1050 }
1051 dvb->i2c_client_demod[0] = client;
1052
1053 /* attach second demodulator chip */
1054 si2168_config.ts_mode = SI2168_TS_SERIAL;
1055 si2168_config.fe = &dev->dvb->frontend[1];
1056 si2168_config.i2c_adapter = &adapter2;
1057 si2168_config.ts_clock_inv = true;
1058
1059 /* perform probe/init/attach */
1060 client = dvb_module_probe(module_name: "si2168", NULL, adap: adapter,
1061 addr: dev->board.demod_addr2,
1062 platform_data: &si2168_config);
1063 if (!client) {
1064 result = -ENODEV;
1065 goto out_free;
1066 }
1067 dvb->i2c_client_demod[1] = client;
1068 dvb->frontend[1]->id = 1;
1069
1070 /* define general-purpose callback pointer */
1071 dvb->frontend[0]->callback = cx231xx_tuner_callback;
1072 dvb->frontend[1]->callback = cx231xx_tuner_callback;
1073
1074 /* attach tuner */
1075 si2157_config.fe = dev->dvb->frontend[0];
1076#ifdef CONFIG_MEDIA_CONTROLLER_DVB
1077 si2157_config.mdev = dev->media_dev;
1078#endif
1079 si2157_config.if_port = 1;
1080 si2157_config.inversion = true;
1081
1082 /* perform probe/init/attach */
1083 client = dvb_module_probe(module_name: "si2157", NULL, adap: adapter,
1084 addr: dev->board.tuner_addr,
1085 platform_data: &si2157_config);
1086 if (!client) {
1087 result = -ENODEV;
1088 goto out_free;
1089 }
1090 dev->cx231xx_reset_analog_tuner = NULL;
1091 dvb->i2c_client_tuner = client;
1092
1093 dvb->frontend[1]->tuner_priv = dvb->frontend[0]->tuner_priv;
1094
1095 memcpy(&dvb->frontend[1]->ops.tuner_ops,
1096 &dvb->frontend[0]->ops.tuner_ops,
1097 sizeof(struct dvb_tuner_ops));
1098 break;
1099 }
1100 default:
1101 dev_err(dev->dev,
1102 "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
1103 dev->name);
1104 break;
1105 }
1106 if (!dvb->frontend[0]) {
1107 dev_err(dev->dev,
1108 "%s/2: frontend initialization failed\n", dev->name);
1109 result = -EINVAL;
1110 goto out_free;
1111 }
1112
1113 /* register everything */
1114 result = register_dvb(dvb, THIS_MODULE, dev, device: dev->dev);
1115
1116 if (result < 0)
1117 goto out_free;
1118
1119
1120 dev_info(dev->dev, "Successfully loaded cx231xx-dvb\n");
1121
1122ret:
1123 cx231xx_set_mode(dev, set_mode: CX231XX_SUSPEND);
1124 mutex_unlock(lock: &dev->lock);
1125 return result;
1126
1127out_free:
1128 /* remove I2C tuner */
1129 dvb_module_release(client: dvb->i2c_client_tuner);
1130 dvb->i2c_client_tuner = NULL;
1131 /* remove I2C demod(s) */
1132 dvb_module_release(client: dvb->i2c_client_demod[1]);
1133 dvb->i2c_client_demod[1] = NULL;
1134 dvb_module_release(client: dvb->i2c_client_demod[0]);
1135 dvb->i2c_client_demod[0] = NULL;
1136 kfree(objp: dvb);
1137 dev->dvb = NULL;
1138 goto ret;
1139}
1140
1141static int dvb_fini(struct cx231xx *dev)
1142{
1143 if (!dev->board.has_dvb) {
1144 /* This device does not support the extension */
1145 return 0;
1146 }
1147
1148 if (dev->dvb) {
1149 unregister_dvb(dvb: dev->dvb);
1150 kfree(objp: dev->dvb);
1151 dev->dvb = NULL;
1152 }
1153
1154 return 0;
1155}
1156
1157static struct cx231xx_ops dvb_ops = {
1158 .id = CX231XX_DVB,
1159 .name = "Cx231xx dvb Extension",
1160 .init = dvb_init,
1161 .fini = dvb_fini,
1162};
1163
1164static int __init cx231xx_dvb_register(void)
1165{
1166 return cx231xx_register_extension(dev: &dvb_ops);
1167}
1168
1169static void __exit cx231xx_dvb_unregister(void)
1170{
1171 cx231xx_unregister_extension(dev: &dvb_ops);
1172}
1173
1174module_init(cx231xx_dvb_register);
1175module_exit(cx231xx_dvb_unregister);
1176

source code of linux/drivers/media/usb/cx231xx/cx231xx-dvb.c