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