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

source code of linux/drivers/media/pci/cx88/cx88-dvb.c