1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * device driver for Conexant 2388x based TV cards
41da177e4SLinus Torvalds * MPEG Transport Stream (DVB) routines
51da177e4SLinus Torvalds *
6fc40b261SChris Pascoe * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
71da177e4SLinus Torvalds * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
81da177e4SLinus Torvalds */
91da177e4SLinus Torvalds
1065bc2fe8SMauro Carvalho Chehab #include "cx88.h"
1165bc2fe8SMauro Carvalho Chehab #include "dvb-pll.h"
1265bc2fe8SMauro Carvalho Chehab
131da177e4SLinus Torvalds #include <linux/module.h>
141da177e4SLinus Torvalds #include <linux/init.h>
151da177e4SLinus Torvalds #include <linux/device.h>
161da177e4SLinus Torvalds #include <linux/fs.h>
171da177e4SLinus Torvalds #include <linux/kthread.h>
181da177e4SLinus Torvalds #include <linux/file.h>
191da177e4SLinus Torvalds #include <linux/suspend.h>
201da177e4SLinus Torvalds
215e453dc7SMichael Krufky #include <media/v4l2-common.h>
2241ef7c1eSMauro Carvalho Chehab
231da177e4SLinus Torvalds #include "mt352.h"
241da177e4SLinus Torvalds #include "mt352_priv.h"
25fc40b261SChris Pascoe #include "cx88-vp3054-i2c.h"
26780dfef3SChris Pascoe #include "zl10353.h"
271da177e4SLinus Torvalds #include "cx22702.h"
281da177e4SLinus Torvalds #include "or51132.h"
296ddcc919SMichael Krufky #include "lgdt330x.h"
3060464da8SSteven Toth #include "s5h1409.h"
31c21973e8Sistvan_v@mailbox.hu #include "xc4000.h"
3260464da8SSteven Toth #include "xc5000.h"
33fde6d31eSKirk Lapray #include "nxt200x.h"
340fa14aa6SSteven Toth #include "cx24123.h"
35cd20ca9fSAndrew de Quincey #include "isl6421.h"
360df31f83SMichael Krufky #include "tuner-simple.h"
37827855d3SMichael Krufky #include "tda9887.h"
38d893d5dcSSteven Toth #include "s5h1411.h"
39e4aab64cSIgor M. Liplianin #include "stv0299.h"
40e4aab64cSIgor M. Liplianin #include "z0194a.h"
41e4aab64cSIgor M. Liplianin #include "stv0288.h"
42e4aab64cSIgor M. Liplianin #include "stb6000.h"
435bd1b663SSteven Toth #include "cx24116.h"
44b699c271SIgor M. Liplianin #include "stv0900.h"
45b699c271SIgor M. Liplianin #include "stb6100.h"
46b699c271SIgor M. Liplianin #include "stb6100_proc.h"
47111ac84aSSergey Ivanov #include "mb86a16.h"
4873f0af44SKonstantin Dimitrov #include "ts2020.h"
490cb73639SIgor M. Liplianin #include "ds3000.h"
501da177e4SLinus Torvalds
511da177e4SLinus Torvalds MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
521da177e4SLinus Torvalds MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
531da177e4SLinus Torvalds MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
541da177e4SLinus Torvalds MODULE_LICENSE("GPL");
551990d50bSMauro Carvalho Chehab MODULE_VERSION(CX88_VERSION);
561da177e4SLinus Torvalds
57ff699e6bSDouglas Schilling Landgraf static unsigned int debug;
581da177e4SLinus Torvalds module_param(debug, int, 0644);
591da177e4SLinus Torvalds MODULE_PARM_DESC(debug, "enable debug messages [dvb]");
601da177e4SLinus Torvalds
6144c6e2a7SAng Way Chuang static unsigned int dvb_buf_tscnt = 32;
6244c6e2a7SAng Way Chuang module_param(dvb_buf_tscnt, int, 0644);
6344c6e2a7SAng Way Chuang MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]");
6444c6e2a7SAng Way Chuang
6578e92006SJanne Grunau DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
6678e92006SJanne Grunau
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)
721da177e4SLinus Torvalds
731da177e4SLinus Torvalds /* ------------------------------------------------------------------ */
741da177e4SLinus Torvalds
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[])
781da177e4SLinus Torvalds {
790b6b6302SHans Verkuil struct cx8802_dev *dev = q->drv_priv;
801da177e4SLinus Torvalds
810b6b6302SHans Verkuil *num_planes = 1;
821da177e4SLinus Torvalds dev->ts_packet_size = 188 * 4;
8344c6e2a7SAng Way Chuang 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;
861da177e4SLinus Torvalds return 0;
871da177e4SLinus Torvalds }
881da177e4SLinus Torvalds
buffer_prepare(struct vb2_buffer * vb)890b6b6302SHans Verkuil static int buffer_prepare(struct vb2_buffer *vb)
901da177e4SLinus Torvalds {
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);
961da177e4SLinus Torvalds }
971da177e4SLinus Torvalds
buffer_finish(struct vb2_buffer * vb)980b6b6302SHans Verkuil static void buffer_finish(struct vb2_buffer *vb)
991da177e4SLinus Torvalds {
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)
10600ae4ebcSChristophe JAILLET dma_free_coherent(&dev->pci->dev, risc->size, risc->cpu,
10700ae4ebcSChristophe JAILLET risc->dma);
1085e7045e3SHans Verkuil memset(risc, 0, sizeof(*risc));
1091da177e4SLinus Torvalds }
1101da177e4SLinus Torvalds
buffer_queue(struct vb2_buffer * vb)1110b6b6302SHans Verkuil static void buffer_queue(struct vb2_buffer *vb)
1121da177e4SLinus Torvalds {
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);
1181da177e4SLinus Torvalds }
1191da177e4SLinus Torvalds
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 .start_streaming = start_streaming,
1560b6b6302SHans Verkuil .stop_streaming = stop_streaming,
1571da177e4SLinus Torvalds };
1581da177e4SLinus Torvalds
1591da177e4SLinus Torvalds /* ------------------------------------------------------------------ */
16022f3f17dSMichael Krufky
cx88_dvb_bus_ctrl(struct dvb_frontend * fe,int acquire)16122f3f17dSMichael Krufky static int cx88_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
16222f3f17dSMichael Krufky {
16322f3f17dSMichael Krufky struct cx8802_dev *dev = fe->dvb->priv;
16422f3f17dSMichael Krufky struct cx8802_driver *drv = NULL;
16522f3f17dSMichael Krufky int ret = 0;
166363c35fcSSteven Toth int fe_id;
167363c35fcSSteven Toth
1680b6b6302SHans Verkuil fe_id = vb2_dvb_find_frontend(&dev->frontends, fe);
169363c35fcSSteven Toth if (!fe_id) {
17065bc2fe8SMauro Carvalho Chehab pr_err("%s() No frontend found\n", __func__);
171363c35fcSSteven Toth return -EINVAL;
172363c35fcSSteven Toth }
173363c35fcSSteven Toth
1748a317a87SJonathan Nieder mutex_lock(&dev->core->lock);
17522f3f17dSMichael Krufky drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
17622f3f17dSMichael Krufky if (drv) {
177363c35fcSSteven Toth if (acquire) {
178363c35fcSSteven Toth dev->frontends.active_fe_id = fe_id;
17922f3f17dSMichael Krufky ret = drv->request_acquire(drv);
180363c35fcSSteven Toth } else {
18122f3f17dSMichael Krufky ret = drv->request_release(drv);
182363c35fcSSteven Toth dev->frontends.active_fe_id = 0;
183363c35fcSSteven Toth }
18422f3f17dSMichael Krufky }
1851fe70e96SJonathan Nieder mutex_unlock(&dev->core->lock);
18622f3f17dSMichael Krufky
18722f3f17dSMichael Krufky return ret;
18822f3f17dSMichael Krufky }
18922f3f17dSMichael Krufky
cx88_dvb_gate_ctrl(struct cx88_core * core,int open)190e32fadc4SMauro Carvalho Chehab static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open)
191e32fadc4SMauro Carvalho Chehab {
1920b6b6302SHans Verkuil struct vb2_dvb_frontends *f;
1930b6b6302SHans Verkuil struct vb2_dvb_frontend *fe;
194e32fadc4SMauro Carvalho Chehab
195e32fadc4SMauro Carvalho Chehab if (!core->dvbdev)
196e32fadc4SMauro Carvalho Chehab return;
197e32fadc4SMauro Carvalho Chehab
198e32fadc4SMauro Carvalho Chehab f = &core->dvbdev->frontends;
199e32fadc4SMauro Carvalho Chehab
200e32fadc4SMauro Carvalho Chehab if (!f)
201e32fadc4SMauro Carvalho Chehab return;
202e32fadc4SMauro Carvalho Chehab
203e32fadc4SMauro Carvalho Chehab if (f->gate <= 1) /* undefined or fe0 */
2040b6b6302SHans Verkuil fe = vb2_dvb_get_frontend(f, 1);
205e32fadc4SMauro Carvalho Chehab else
2060b6b6302SHans Verkuil fe = vb2_dvb_get_frontend(f, f->gate);
207e32fadc4SMauro Carvalho Chehab
208e32fadc4SMauro Carvalho Chehab if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
209e32fadc4SMauro Carvalho Chehab fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
210e32fadc4SMauro Carvalho Chehab }
211e32fadc4SMauro Carvalho Chehab
21222f3f17dSMichael Krufky /* ------------------------------------------------------------------ */
21322f3f17dSMichael Krufky
dvico_fusionhdtv_demod_init(struct dvb_frontend * fe)2143d7d027aSChris Pascoe static int dvico_fusionhdtv_demod_init(struct dvb_frontend *fe)
2151da177e4SLinus Torvalds {
2162e4e98e7Slawrence rust static const u8 clock_config[] = { CLOCK_CTL, 0x38, 0x39 };
2172e4e98e7Slawrence rust static const u8 reset[] = { RESET, 0x80 };
2182e4e98e7Slawrence rust static const u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
2192e4e98e7Slawrence rust static const u8 agc_cfg[] = { AGC_TARGET, 0x24, 0x20 };
2202e4e98e7Slawrence rust static const u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
2212e4e98e7Slawrence rust static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
2221da177e4SLinus Torvalds
2231da177e4SLinus Torvalds mt352_write(fe, clock_config, sizeof(clock_config));
2241da177e4SLinus Torvalds udelay(200);
2251da177e4SLinus Torvalds mt352_write(fe, reset, sizeof(reset));
2261da177e4SLinus Torvalds mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
2271da177e4SLinus Torvalds
2281da177e4SLinus Torvalds mt352_write(fe, agc_cfg, sizeof(agc_cfg));
2291da177e4SLinus Torvalds mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
2301da177e4SLinus Torvalds mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
2311da177e4SLinus Torvalds return 0;
2321da177e4SLinus Torvalds }
2331da177e4SLinus Torvalds
dvico_dual_demod_init(struct dvb_frontend * fe)23443eabb4eSChris Pascoe static int dvico_dual_demod_init(struct dvb_frontend *fe)
23543eabb4eSChris Pascoe {
2362e4e98e7Slawrence rust static const u8 clock_config[] = { CLOCK_CTL, 0x38, 0x38 };
2372e4e98e7Slawrence rust static const u8 reset[] = { RESET, 0x80 };
2382e4e98e7Slawrence rust static const u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
2392e4e98e7Slawrence rust static const u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
2402e4e98e7Slawrence rust static const u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
2412e4e98e7Slawrence rust static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
24243eabb4eSChris Pascoe
24343eabb4eSChris Pascoe mt352_write(fe, clock_config, sizeof(clock_config));
24443eabb4eSChris Pascoe udelay(200);
24543eabb4eSChris Pascoe mt352_write(fe, reset, sizeof(reset));
24643eabb4eSChris Pascoe mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
24743eabb4eSChris Pascoe
24843eabb4eSChris Pascoe mt352_write(fe, agc_cfg, sizeof(agc_cfg));
24943eabb4eSChris Pascoe mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
25043eabb4eSChris Pascoe mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
25143eabb4eSChris Pascoe
25243eabb4eSChris Pascoe return 0;
25343eabb4eSChris Pascoe }
25443eabb4eSChris Pascoe
dntv_live_dvbt_demod_init(struct dvb_frontend * fe)2551da177e4SLinus Torvalds static int dntv_live_dvbt_demod_init(struct dvb_frontend *fe)
2561da177e4SLinus Torvalds {
2572e4e98e7Slawrence rust static const u8 clock_config[] = { 0x89, 0x38, 0x39 };
2582e4e98e7Slawrence rust static const u8 reset[] = { 0x50, 0x80 };
2592e4e98e7Slawrence rust static const u8 adc_ctl_1_cfg[] = { 0x8E, 0x40 };
2602e4e98e7Slawrence rust static const u8 agc_cfg[] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
2611da177e4SLinus Torvalds 0x00, 0xFF, 0x00, 0x40, 0x40 };
2622e4e98e7Slawrence rust static const u8 dntv_extra[] = { 0xB5, 0x7A };
2632e4e98e7Slawrence rust static const u8 capt_range_cfg[] = { 0x75, 0x32 };
2641da177e4SLinus Torvalds
2651da177e4SLinus Torvalds mt352_write(fe, clock_config, sizeof(clock_config));
2661da177e4SLinus Torvalds udelay(2000);
2671da177e4SLinus Torvalds mt352_write(fe, reset, sizeof(reset));
2681da177e4SLinus Torvalds mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
2691da177e4SLinus Torvalds
2701da177e4SLinus Torvalds mt352_write(fe, agc_cfg, sizeof(agc_cfg));
2711da177e4SLinus Torvalds udelay(2000);
2721da177e4SLinus Torvalds mt352_write(fe, dntv_extra, sizeof(dntv_extra));
2731da177e4SLinus Torvalds mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
2741da177e4SLinus Torvalds
2751da177e4SLinus Torvalds return 0;
2761da177e4SLinus Torvalds }
2771da177e4SLinus Torvalds
2782e4e98e7Slawrence rust static const struct mt352_config dvico_fusionhdtv = {
279f7b54b10SMichael Krufky .demod_address = 0x0f,
2803d7d027aSChris Pascoe .demod_init = dvico_fusionhdtv_demod_init,
2811da177e4SLinus Torvalds };
2821da177e4SLinus Torvalds
2832e4e98e7Slawrence rust static const struct mt352_config dntv_live_dvbt_config = {
2841da177e4SLinus Torvalds .demod_address = 0x0f,
2851da177e4SLinus Torvalds .demod_init = dntv_live_dvbt_demod_init,
2861da177e4SLinus Torvalds };
287fc40b261SChris Pascoe
2882e4e98e7Slawrence rust static const struct mt352_config dvico_fusionhdtv_dual = {
289f7b54b10SMichael Krufky .demod_address = 0x0f,
29043eabb4eSChris Pascoe .demod_init = dvico_dual_demod_init,
29143eabb4eSChris Pascoe };
29243eabb4eSChris Pascoe
2932e4e98e7Slawrence rust static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
29470101a27SStephan Wienczny .demod_address = (0x1e >> 1),
29570101a27SStephan Wienczny .no_tuner = 1,
29670101a27SStephan Wienczny .if2 = 45600,
29770101a27SStephan Wienczny };
29870101a27SStephan Wienczny
2990244fd78SBhumika Goyal static const struct mb86a16_config twinhan_vp1027 = {
300111ac84aSSergey Ivanov .demod_address = 0x08,
301111ac84aSSergey Ivanov };
302111ac84aSSergey Ivanov
3037b34be71SPeter Senna Tschudin #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054)
dntv_live_dvbt_pro_demod_init(struct dvb_frontend * fe)3043d7d027aSChris Pascoe static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend *fe)
3053d7d027aSChris Pascoe {
3062e4e98e7Slawrence rust static const u8 clock_config[] = { 0x89, 0x38, 0x38 };
3072e4e98e7Slawrence rust static const u8 reset[] = { 0x50, 0x80 };
3082e4e98e7Slawrence rust static const u8 adc_ctl_1_cfg[] = { 0x8E, 0x40 };
3092e4e98e7Slawrence rust static const u8 agc_cfg[] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
3103d7d027aSChris Pascoe 0x00, 0xFF, 0x00, 0x40, 0x40 };
3112e4e98e7Slawrence rust static const u8 dntv_extra[] = { 0xB5, 0x7A };
3122e4e98e7Slawrence rust static const u8 capt_range_cfg[] = { 0x75, 0x32 };
3133d7d027aSChris Pascoe
3143d7d027aSChris Pascoe mt352_write(fe, clock_config, sizeof(clock_config));
3153d7d027aSChris Pascoe udelay(2000);
3163d7d027aSChris Pascoe mt352_write(fe, reset, sizeof(reset));
3173d7d027aSChris Pascoe mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
3183d7d027aSChris Pascoe
3193d7d027aSChris Pascoe mt352_write(fe, agc_cfg, sizeof(agc_cfg));
3203d7d027aSChris Pascoe udelay(2000);
3213d7d027aSChris Pascoe mt352_write(fe, dntv_extra, sizeof(dntv_extra));
3223d7d027aSChris Pascoe mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
3233d7d027aSChris Pascoe
3243d7d027aSChris Pascoe return 0;
3253d7d027aSChris Pascoe }
3263d7d027aSChris Pascoe
3272e4e98e7Slawrence rust static const struct mt352_config dntv_live_dvbt_pro_config = {
328fc40b261SChris Pascoe .demod_address = 0x0f,
329fc40b261SChris Pascoe .no_tuner = 1,
3303d7d027aSChris Pascoe .demod_init = dntv_live_dvbt_pro_demod_init,
331fc40b261SChris Pascoe };
332fc40b261SChris Pascoe #endif
3331da177e4SLinus Torvalds
3342e4e98e7Slawrence rust static const struct zl10353_config dvico_fusionhdtv_hybrid = {
335f7b54b10SMichael Krufky .demod_address = 0x0f,
336f54376e2SAndrew de Quincey .no_tuner = 1,
337780dfef3SChris Pascoe };
338780dfef3SChris Pascoe
3392e4e98e7Slawrence rust static const struct zl10353_config dvico_fusionhdtv_xc3028 = {
340b3fb91d2SChris Pascoe .demod_address = 0x0f,
341b3fb91d2SChris Pascoe .if2 = 45600,
342b3fb91d2SChris Pascoe .no_tuner = 1,
343b3fb91d2SChris Pascoe };
344b3fb91d2SChris Pascoe
3452e4e98e7Slawrence rust static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = {
346b3fb91d2SChris Pascoe .demod_address = 0x0f,
347b3fb91d2SChris Pascoe .if2 = 4560,
348b3fb91d2SChris Pascoe .no_tuner = 1,
349b3fb91d2SChris Pascoe .demod_init = dvico_fusionhdtv_demod_init,
350b3fb91d2SChris Pascoe };
351b3fb91d2SChris Pascoe
3522e4e98e7Slawrence rust static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = {
353f7b54b10SMichael Krufky .demod_address = 0x0f,
354780dfef3SChris Pascoe };
355780dfef3SChris Pascoe
3562e4e98e7Slawrence rust static const struct cx22702_config connexant_refboard_config = {
3571da177e4SLinus Torvalds .demod_address = 0x43,
35838d84c3bSPatrick Boettcher .output_mode = CX22702_SERIAL_OUTPUT,
3591da177e4SLinus Torvalds };
3601da177e4SLinus Torvalds
3612e4e98e7Slawrence rust static const struct cx22702_config hauppauge_hvr_config = {
362aa481a65SSteven Toth .demod_address = 0x63,
363aa481a65SSteven Toth .output_mode = CX22702_SERIAL_OUTPUT,
364aa481a65SSteven Toth };
3651da177e4SLinus Torvalds
or51132_set_ts_param(struct dvb_frontend * fe,int is_punctured)3664a390558SMichael Krufky static int or51132_set_ts_param(struct dvb_frontend *fe, int is_punctured)
3671da177e4SLinus Torvalds {
3681da177e4SLinus Torvalds struct cx8802_dev *dev = fe->dvb->priv;
3697b61ba8fSMauro Carvalho Chehab
3701da177e4SLinus Torvalds dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
3711da177e4SLinus Torvalds return 0;
3721da177e4SLinus Torvalds }
3731da177e4SLinus Torvalds
3742e4e98e7Slawrence rust static const struct or51132_config pchdtv_hd3000 = {
3751da177e4SLinus Torvalds .demod_address = 0x15,
3761da177e4SLinus Torvalds .set_ts_params = or51132_set_ts_param,
3771da177e4SLinus Torvalds };
3781da177e4SLinus Torvalds
lgdt330x_pll_rf_set(struct dvb_frontend * fe,int index)3796ddcc919SMichael Krufky static int lgdt330x_pll_rf_set(struct dvb_frontend *fe, int index)
3800ccef6dbSMichael Krufky {
3810ccef6dbSMichael Krufky struct cx8802_dev *dev = fe->dvb->priv;
3820ccef6dbSMichael Krufky struct cx88_core *core = dev->core;
3830ccef6dbSMichael Krufky
38432d83efcSHarvey Harrison dprintk(1, "%s: index = %d\n", __func__, index);
3850ccef6dbSMichael Krufky if (index == 0)
3860ccef6dbSMichael Krufky cx_clear(MO_GP0_IO, 8);
3870ccef6dbSMichael Krufky else
3880ccef6dbSMichael Krufky cx_set(MO_GP0_IO, 8);
3890ccef6dbSMichael Krufky return 0;
3900ccef6dbSMichael Krufky }
3910ccef6dbSMichael Krufky
lgdt330x_set_ts_param(struct dvb_frontend * fe,int is_punctured)3926ddcc919SMichael Krufky static int lgdt330x_set_ts_param(struct dvb_frontend *fe, int is_punctured)
393f1798495SMichael Krufky {
394f1798495SMichael Krufky struct cx8802_dev *dev = fe->dvb->priv;
3957b61ba8fSMauro Carvalho Chehab
396f1798495SMichael Krufky if (is_punctured)
397f1798495SMichael Krufky dev->ts_gen_cntrl |= 0x04;
398f1798495SMichael Krufky else
399f1798495SMichael Krufky dev->ts_gen_cntrl &= ~0x04;
400f1798495SMichael Krufky return 0;
401f1798495SMichael Krufky }
402f1798495SMichael Krufky
4036ddcc919SMichael Krufky static struct lgdt330x_config fusionhdtv_3_gold = {
4041963c907SMichael Krufky .demod_chip = LGDT3302,
4051963c907SMichael Krufky .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
4066ddcc919SMichael Krufky .set_ts_params = lgdt330x_set_ts_param,
4070d723c09SMichael Krufky };
408e52e98a7SMauro Carvalho Chehab
4092e4e98e7Slawrence rust static const struct lgdt330x_config fusionhdtv_5_gold = {
410e52e98a7SMauro Carvalho Chehab .demod_chip = LGDT3303,
411e52e98a7SMauro Carvalho Chehab .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
412e52e98a7SMauro Carvalho Chehab .set_ts_params = lgdt330x_set_ts_param,
413e52e98a7SMauro Carvalho Chehab };
414da215d22SRusty Scott
4152e4e98e7Slawrence rust static const struct lgdt330x_config pchdtv_hd5500 = {
416da215d22SRusty Scott .demod_chip = LGDT3303,
417da215d22SRusty Scott .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
418da215d22SRusty Scott .set_ts_params = lgdt330x_set_ts_param,
419da215d22SRusty Scott };
420f1798495SMichael Krufky
nxt200x_set_ts_param(struct dvb_frontend * fe,int is_punctured)4214a390558SMichael Krufky static int nxt200x_set_ts_param(struct dvb_frontend *fe, int is_punctured)
422fde6d31eSKirk Lapray {
423fde6d31eSKirk Lapray struct cx8802_dev *dev = fe->dvb->priv;
4247b61ba8fSMauro Carvalho Chehab
425fde6d31eSKirk Lapray dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
426fde6d31eSKirk Lapray return 0;
427fde6d31eSKirk Lapray }
428fde6d31eSKirk Lapray
4292e4e98e7Slawrence rust static const struct nxt200x_config ati_hdtvwonder = {
430fde6d31eSKirk Lapray .demod_address = 0x0a,
431fde6d31eSKirk Lapray .set_ts_params = nxt200x_set_ts_param,
432fde6d31eSKirk Lapray };
433fde6d31eSKirk Lapray
cx24123_set_ts_param(struct dvb_frontend * fe,int is_punctured)4340fa14aa6SSteven Toth static int cx24123_set_ts_param(struct dvb_frontend *fe,
4350fa14aa6SSteven Toth int is_punctured)
4360fa14aa6SSteven Toth {
4370fa14aa6SSteven Toth struct cx8802_dev *dev = fe->dvb->priv;
4387b61ba8fSMauro Carvalho Chehab
439f7b54b10SMichael Krufky dev->ts_gen_cntrl = 0x02;
4400fa14aa6SSteven Toth return 0;
4410fa14aa6SSteven Toth }
4420fa14aa6SSteven Toth
kworld_dvbs_100_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)443f7b54b10SMichael Krufky static int kworld_dvbs_100_set_voltage(struct dvb_frontend *fe,
4440df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage)
4450e0351e3SVadim Catana {
4460e0351e3SVadim Catana struct cx8802_dev *dev = fe->dvb->priv;
4470e0351e3SVadim Catana struct cx88_core *core = dev->core;
4480e0351e3SVadim Catana
4494a390558SMichael Krufky if (voltage == SEC_VOLTAGE_OFF)
450f7b54b10SMichael Krufky cx_write(MO_GP0_IO, 0x000006fb);
4514a390558SMichael Krufky else
452cd20ca9fSAndrew de Quincey cx_write(MO_GP0_IO, 0x000006f9);
453cd20ca9fSAndrew de Quincey
454cd20ca9fSAndrew de Quincey if (core->prev_set_voltage)
455cd20ca9fSAndrew de Quincey return core->prev_set_voltage(fe, voltage);
456cd20ca9fSAndrew de Quincey return 0;
4570e0351e3SVadim Catana }
4580e0351e3SVadim Catana
geniatech_dvbs_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)459f7b54b10SMichael Krufky static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe,
4600df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage)
461c02a34f4SSaqeb Akhter {
462c02a34f4SSaqeb Akhter struct cx8802_dev *dev = fe->dvb->priv;
463c02a34f4SSaqeb Akhter struct cx88_core *core = dev->core;
464c02a34f4SSaqeb Akhter
465c02a34f4SSaqeb Akhter if (voltage == SEC_VOLTAGE_OFF) {
466c02a34f4SSaqeb Akhter dprintk(1, "LNB Voltage OFF\n");
467c02a34f4SSaqeb Akhter cx_write(MO_GP0_IO, 0x0000efff);
468c02a34f4SSaqeb Akhter }
469c02a34f4SSaqeb Akhter
470c02a34f4SSaqeb Akhter if (core->prev_set_voltage)
471c02a34f4SSaqeb Akhter return core->prev_set_voltage(fe, voltage);
472c02a34f4SSaqeb Akhter return 0;
473c02a34f4SSaqeb Akhter }
474c02a34f4SSaqeb Akhter
tevii_dvbs_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)475af832623SIgor M. Liplianin static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
4760df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage)
477af832623SIgor M. Liplianin {
478af832623SIgor M. Liplianin struct cx8802_dev *dev = fe->dvb->priv;
479af832623SIgor M. Liplianin struct cx88_core *core = dev->core;
480af832623SIgor M. Liplianin
481ad5f74c0SIgor M. Liplianin cx_set(MO_GP0_IO, 0x6040);
482af832623SIgor M. Liplianin switch (voltage) {
483af832623SIgor M. Liplianin case SEC_VOLTAGE_13:
484ad5f74c0SIgor M. Liplianin cx_clear(MO_GP0_IO, 0x20);
485af832623SIgor M. Liplianin break;
486af832623SIgor M. Liplianin case SEC_VOLTAGE_18:
487ad5f74c0SIgor M. Liplianin cx_set(MO_GP0_IO, 0x20);
488af832623SIgor M. Liplianin break;
489af832623SIgor M. Liplianin case SEC_VOLTAGE_OFF:
490ad5f74c0SIgor M. Liplianin cx_clear(MO_GP0_IO, 0x20);
491af832623SIgor M. Liplianin break;
492af832623SIgor M. Liplianin }
493af832623SIgor M. Liplianin
494af832623SIgor M. Liplianin if (core->prev_set_voltage)
495af832623SIgor M. Liplianin return core->prev_set_voltage(fe, voltage);
496af832623SIgor M. Liplianin return 0;
497af832623SIgor M. Liplianin }
498af832623SIgor M. Liplianin
vp1027_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)499111ac84aSSergey Ivanov static int vp1027_set_voltage(struct dvb_frontend *fe,
5000df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage)
501111ac84aSSergey Ivanov {
502111ac84aSSergey Ivanov struct cx8802_dev *dev = fe->dvb->priv;
503111ac84aSSergey Ivanov struct cx88_core *core = dev->core;
504111ac84aSSergey Ivanov
505111ac84aSSergey Ivanov switch (voltage) {
506111ac84aSSergey Ivanov case SEC_VOLTAGE_13:
507111ac84aSSergey Ivanov dprintk(1, "LNB SEC Voltage=13\n");
508111ac84aSSergey Ivanov cx_write(MO_GP0_IO, 0x00001220);
509111ac84aSSergey Ivanov break;
510111ac84aSSergey Ivanov case SEC_VOLTAGE_18:
511111ac84aSSergey Ivanov dprintk(1, "LNB SEC Voltage=18\n");
512111ac84aSSergey Ivanov cx_write(MO_GP0_IO, 0x00001222);
513111ac84aSSergey Ivanov break;
514111ac84aSSergey Ivanov case SEC_VOLTAGE_OFF:
515111ac84aSSergey Ivanov dprintk(1, "LNB Voltage OFF\n");
516111ac84aSSergey Ivanov cx_write(MO_GP0_IO, 0x00001230);
517111ac84aSSergey Ivanov break;
518111ac84aSSergey Ivanov }
519111ac84aSSergey Ivanov
520111ac84aSSergey Ivanov if (core->prev_set_voltage)
521111ac84aSSergey Ivanov return core->prev_set_voltage(fe, voltage);
522111ac84aSSergey Ivanov return 0;
523111ac84aSSergey Ivanov }
524111ac84aSSergey Ivanov
5252e4e98e7Slawrence rust static const struct cx24123_config geniatech_dvbs_config = {
526c02a34f4SSaqeb Akhter .demod_address = 0x55,
527c02a34f4SSaqeb Akhter .set_ts_params = cx24123_set_ts_param,
528c02a34f4SSaqeb Akhter };
529c02a34f4SSaqeb Akhter
5302e4e98e7Slawrence rust static const struct cx24123_config hauppauge_novas_config = {
5310fa14aa6SSteven Toth .demod_address = 0x55,
5320fa14aa6SSteven Toth .set_ts_params = cx24123_set_ts_param,
5330fa14aa6SSteven Toth };
5340e0351e3SVadim Catana
5352e4e98e7Slawrence rust static const struct cx24123_config kworld_dvbs_100_config = {
5360e0351e3SVadim Catana .demod_address = 0x15,
5370e0351e3SVadim Catana .set_ts_params = cx24123_set_ts_param,
538ef76856dSYeasah Pell .lnb_polarity = 1,
5390e0351e3SVadim Catana };
5400fa14aa6SSteven Toth
5412e4e98e7Slawrence rust static const struct s5h1409_config pinnacle_pctv_hd_800i_config = {
54260464da8SSteven Toth .demod_address = 0x32 >> 1,
54360464da8SSteven Toth .output_mode = S5H1409_PARALLEL_OUTPUT,
54460464da8SSteven Toth .gpio = S5H1409_GPIO_ON,
54560464da8SSteven Toth .qam_if = 44000,
54660464da8SSteven Toth .inversion = S5H1409_INVERSION_OFF,
54760464da8SSteven Toth .status_mode = S5H1409_DEMODLOCKING,
548ad05ff09SMauro Carvalho Chehab .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK,
54960464da8SSteven Toth };
55060464da8SSteven Toth
5512e4e98e7Slawrence rust static const struct s5h1409_config dvico_hdtv5_pci_nano_config = {
5525c00fac0SSteven Toth .demod_address = 0x32 >> 1,
5535c00fac0SSteven Toth .output_mode = S5H1409_SERIAL_OUTPUT,
5545c00fac0SSteven Toth .gpio = S5H1409_GPIO_OFF,
5555c00fac0SSteven Toth .inversion = S5H1409_INVERSION_OFF,
5565c00fac0SSteven Toth .status_mode = S5H1409_DEMODLOCKING,
557ad05ff09SMauro Carvalho Chehab .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
5585c00fac0SSteven Toth };
5595c00fac0SSteven Toth
5602e4e98e7Slawrence rust static const struct s5h1409_config kworld_atsc_120_config = {
56199e09eacSMauro Carvalho Chehab .demod_address = 0x32 >> 1,
56299e09eacSMauro Carvalho Chehab .output_mode = S5H1409_SERIAL_OUTPUT,
56399e09eacSMauro Carvalho Chehab .gpio = S5H1409_GPIO_OFF,
56499e09eacSMauro Carvalho Chehab .inversion = S5H1409_INVERSION_OFF,
56599e09eacSMauro Carvalho Chehab .status_mode = S5H1409_DEMODLOCKING,
566ad05ff09SMauro Carvalho Chehab .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
56799e09eacSMauro Carvalho Chehab };
56899e09eacSMauro Carvalho Chehab
5692e4e98e7Slawrence rust static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = {
57060464da8SSteven Toth .i2c_address = 0x64,
57160464da8SSteven Toth .if_khz = 5380,
57260464da8SSteven Toth };
57360464da8SSteven Toth
5742e4e98e7Slawrence rust static const struct zl10353_config cx88_pinnacle_hybrid_pctv = {
5753f6014fcSStéphane Voltz .demod_address = (0x1e >> 1),
5763f6014fcSStéphane Voltz .no_tuner = 1,
5773f6014fcSStéphane Voltz .if2 = 45600,
5783f6014fcSStéphane Voltz };
5793f6014fcSStéphane Voltz
5802e4e98e7Slawrence rust static const struct zl10353_config cx88_geniatech_x8000_mt = {
5819507901eSMauro Carvalho Chehab .demod_address = (0x1e >> 1),
5829507901eSMauro Carvalho Chehab .no_tuner = 1,
58311db9069SDevin Heitmueller .disable_i2c_gate_ctrl = 1,
5849507901eSMauro Carvalho Chehab };
5859507901eSMauro Carvalho Chehab
5862e4e98e7Slawrence rust static const struct s5h1411_config dvico_fusionhdtv7_config = {
587d893d5dcSSteven Toth .output_mode = S5H1411_SERIAL_OUTPUT,
588d893d5dcSSteven Toth .gpio = S5H1411_GPIO_ON,
589ad05ff09SMauro Carvalho Chehab .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK,
590d893d5dcSSteven Toth .qam_if = S5H1411_IF_44000,
591d893d5dcSSteven Toth .vsb_if = S5H1411_IF_44000,
592d893d5dcSSteven Toth .inversion = S5H1411_INVERSION_OFF,
593d893d5dcSSteven Toth .status_mode = S5H1411_DEMODLOCKING
594d893d5dcSSteven Toth };
595d893d5dcSSteven Toth
5962e4e98e7Slawrence rust static const struct xc5000_config dvico_fusionhdtv7_tuner_config = {
597d893d5dcSSteven Toth .i2c_address = 0xc2 >> 1,
598d893d5dcSSteven Toth .if_khz = 5380,
599d893d5dcSSteven Toth };
600d893d5dcSSteven Toth
attach_xc3028(u8 addr,struct cx8802_dev * dev)60123fb348dSMauro Carvalho Chehab static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
60223fb348dSMauro Carvalho Chehab {
60323fb348dSMauro Carvalho Chehab struct dvb_frontend *fe;
6040b6b6302SHans Verkuil struct vb2_dvb_frontend *fe0 = NULL;
60599e09eacSMauro Carvalho Chehab struct xc2028_ctrl ctl;
60623fb348dSMauro Carvalho Chehab struct xc2028_config cfg = {
60723fb348dSMauro Carvalho Chehab .i2c_adap = &dev->core->i2c_adap,
60823fb348dSMauro Carvalho Chehab .i2c_addr = addr,
60999e09eacSMauro Carvalho Chehab .ctrl = &ctl,
61023fb348dSMauro Carvalho Chehab };
61123fb348dSMauro Carvalho Chehab
612363c35fcSSteven Toth /* Get the first frontend */
6130b6b6302SHans Verkuil fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);
614363c35fcSSteven Toth if (!fe0)
615363c35fcSSteven Toth return -EINVAL;
616363c35fcSSteven Toth
617363c35fcSSteven Toth if (!fe0->dvb.frontend) {
61865bc2fe8SMauro Carvalho Chehab pr_err("dvb frontend not attached. Can't attach xc3028\n");
619ddd5441dSMauro Carvalho Chehab return -EINVAL;
620ddd5441dSMauro Carvalho Chehab }
621ddd5441dSMauro Carvalho Chehab
62299e09eacSMauro Carvalho Chehab /*
62399e09eacSMauro Carvalho Chehab * Some xc3028 devices may be hidden by an I2C gate. This is known
62499e09eacSMauro Carvalho Chehab * to happen with some s5h1409-based devices.
62599e09eacSMauro Carvalho Chehab * Now that I2C gate is open, sets up xc3028 configuration
62699e09eacSMauro Carvalho Chehab */
62799e09eacSMauro Carvalho Chehab cx88_setup_xc3028(dev->core, &ctl);
62899e09eacSMauro Carvalho Chehab
629363c35fcSSteven Toth fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
63023fb348dSMauro Carvalho Chehab if (!fe) {
63165bc2fe8SMauro Carvalho Chehab pr_err("xc3028 attach failed\n");
632363c35fcSSteven Toth dvb_frontend_detach(fe0->dvb.frontend);
633363c35fcSSteven Toth dvb_unregister_frontend(fe0->dvb.frontend);
634363c35fcSSteven Toth fe0->dvb.frontend = NULL;
63523fb348dSMauro Carvalho Chehab return -EINVAL;
63623fb348dSMauro Carvalho Chehab }
63723fb348dSMauro Carvalho Chehab
63865bc2fe8SMauro Carvalho Chehab pr_info("xc3028 attached\n");
63923fb348dSMauro Carvalho Chehab
64023fb348dSMauro Carvalho Chehab return 0;
64123fb348dSMauro Carvalho Chehab }
6429507901eSMauro Carvalho Chehab
attach_xc4000(struct cx8802_dev * dev,struct xc4000_config * cfg)643c21973e8Sistvan_v@mailbox.hu static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg)
644c21973e8Sistvan_v@mailbox.hu {
645c21973e8Sistvan_v@mailbox.hu struct dvb_frontend *fe;
6460b6b6302SHans Verkuil struct vb2_dvb_frontend *fe0 = NULL;
647c21973e8Sistvan_v@mailbox.hu
648c21973e8Sistvan_v@mailbox.hu /* Get the first frontend */
6490b6b6302SHans Verkuil fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);
650c21973e8Sistvan_v@mailbox.hu if (!fe0)
651c21973e8Sistvan_v@mailbox.hu return -EINVAL;
652c21973e8Sistvan_v@mailbox.hu
653c21973e8Sistvan_v@mailbox.hu if (!fe0->dvb.frontend) {
65465bc2fe8SMauro Carvalho Chehab pr_err("dvb frontend not attached. Can't attach xc4000\n");
655c21973e8Sistvan_v@mailbox.hu return -EINVAL;
656c21973e8Sistvan_v@mailbox.hu }
657c21973e8Sistvan_v@mailbox.hu
658c21973e8Sistvan_v@mailbox.hu fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->core->i2c_adap,
659c21973e8Sistvan_v@mailbox.hu cfg);
660c21973e8Sistvan_v@mailbox.hu if (!fe) {
66165bc2fe8SMauro Carvalho Chehab pr_err("xc4000 attach failed\n");
662c21973e8Sistvan_v@mailbox.hu dvb_frontend_detach(fe0->dvb.frontend);
663c21973e8Sistvan_v@mailbox.hu dvb_unregister_frontend(fe0->dvb.frontend);
664c21973e8Sistvan_v@mailbox.hu fe0->dvb.frontend = NULL;
665c21973e8Sistvan_v@mailbox.hu return -EINVAL;
666c21973e8Sistvan_v@mailbox.hu }
667c21973e8Sistvan_v@mailbox.hu
66865bc2fe8SMauro Carvalho Chehab pr_info("xc4000 attached\n");
669c21973e8Sistvan_v@mailbox.hu
670c21973e8Sistvan_v@mailbox.hu return 0;
671c21973e8Sistvan_v@mailbox.hu }
672c21973e8Sistvan_v@mailbox.hu
cx24116_set_ts_param(struct dvb_frontend * fe,int is_punctured)6735bd1b663SSteven Toth static int cx24116_set_ts_param(struct dvb_frontend *fe,
6745bd1b663SSteven Toth int is_punctured)
6755bd1b663SSteven Toth {
6765bd1b663SSteven Toth struct cx8802_dev *dev = fe->dvb->priv;
6777b61ba8fSMauro Carvalho Chehab
6785bd1b663SSteven Toth dev->ts_gen_cntrl = 0x2;
6795bd1b663SSteven Toth
6805bd1b663SSteven Toth return 0;
6815bd1b663SSteven Toth }
6825bd1b663SSteven Toth
stv0900_set_ts_param(struct dvb_frontend * fe,int is_punctured)683b699c271SIgor M. Liplianin static int stv0900_set_ts_param(struct dvb_frontend *fe,
684b699c271SIgor M. Liplianin int is_punctured)
685b699c271SIgor M. Liplianin {
686b699c271SIgor M. Liplianin struct cx8802_dev *dev = fe->dvb->priv;
6877b61ba8fSMauro Carvalho Chehab
688b699c271SIgor M. Liplianin dev->ts_gen_cntrl = 0;
689b699c271SIgor M. Liplianin
690b699c271SIgor M. Liplianin return 0;
691b699c271SIgor M. Liplianin }
692b699c271SIgor M. Liplianin
cx24116_reset_device(struct dvb_frontend * fe)6935bd1b663SSteven Toth static int cx24116_reset_device(struct dvb_frontend *fe)
6945bd1b663SSteven Toth {
6955bd1b663SSteven Toth struct cx8802_dev *dev = fe->dvb->priv;
6965bd1b663SSteven Toth struct cx88_core *core = dev->core;
6975bd1b663SSteven Toth
6985bd1b663SSteven Toth /* Reset the part */
699363c35fcSSteven Toth /* Put the cx24116 into reset */
7005bd1b663SSteven Toth cx_write(MO_SRST_IO, 0);
701399426caSMauro Carvalho Chehab usleep_range(10000, 20000);
702363c35fcSSteven Toth /* Take the cx24116 out of reset */
7035bd1b663SSteven Toth cx_write(MO_SRST_IO, 1);
704399426caSMauro Carvalho Chehab usleep_range(10000, 20000);
7055bd1b663SSteven Toth
7065bd1b663SSteven Toth return 0;
7075bd1b663SSteven Toth }
7085bd1b663SSteven Toth
7092e4e98e7Slawrence rust static const struct cx24116_config hauppauge_hvr4000_config = {
7105bd1b663SSteven Toth .demod_address = 0x05,
7115bd1b663SSteven Toth .set_ts_params = cx24116_set_ts_param,
7125bd1b663SSteven Toth .reset_device = cx24116_reset_device,
7135bd1b663SSteven Toth };
7145bd1b663SSteven Toth
7152e4e98e7Slawrence rust static const struct cx24116_config tevii_s460_config = {
716af832623SIgor M. Liplianin .demod_address = 0x55,
717af832623SIgor M. Liplianin .set_ts_params = cx24116_set_ts_param,
718af832623SIgor M. Liplianin .reset_device = cx24116_reset_device,
719af832623SIgor M. Liplianin };
720af832623SIgor M. Liplianin
ds3000_set_ts_param(struct dvb_frontend * fe,int is_punctured)7210cb73639SIgor M. Liplianin static int ds3000_set_ts_param(struct dvb_frontend *fe,
7220cb73639SIgor M. Liplianin int is_punctured)
7230cb73639SIgor M. Liplianin {
7240cb73639SIgor M. Liplianin struct cx8802_dev *dev = fe->dvb->priv;
7257b61ba8fSMauro Carvalho Chehab
7260cb73639SIgor M. Liplianin dev->ts_gen_cntrl = 4;
7270cb73639SIgor M. Liplianin
7280cb73639SIgor M. Liplianin return 0;
7290cb73639SIgor M. Liplianin }
7300cb73639SIgor M. Liplianin
7310cb73639SIgor M. Liplianin static struct ds3000_config tevii_ds3000_config = {
7320cb73639SIgor M. Liplianin .demod_address = 0x68,
7330cb73639SIgor M. Liplianin .set_ts_params = ds3000_set_ts_param,
7340cb73639SIgor M. Liplianin };
7350cb73639SIgor M. Liplianin
73673f0af44SKonstantin Dimitrov static struct ts2020_config tevii_ts2020_config = {
73773f0af44SKonstantin Dimitrov .tuner_address = 0x60,
738b858c331SIgor M. Liplianin .clk_out_div = 1,
73973f0af44SKonstantin Dimitrov };
74073f0af44SKonstantin Dimitrov
7412e4e98e7Slawrence rust static const struct stv0900_config prof_7301_stv0900_config = {
742b699c271SIgor M. Liplianin .demod_address = 0x6a,
743b699c271SIgor M. Liplianin /* demod_mode = 0,*/
744b699c271SIgor M. Liplianin .xtal = 27000000,
745b699c271SIgor M. Liplianin .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
746b699c271SIgor M. Liplianin .diseqc_mode = 2,/* 2/3 PWM */
747b699c271SIgor M. Liplianin .tun1_maddress = 0,/* 0x60 */
748b699c271SIgor M. Liplianin .tun1_adc = 0,/* 2 Vpp */
749b699c271SIgor M. Liplianin .path1_mode = 3,
750b699c271SIgor M. Liplianin .set_ts_params = stv0900_set_ts_param,
751b699c271SIgor M. Liplianin };
752b699c271SIgor M. Liplianin
7532e4e98e7Slawrence rust static const struct stb6100_config prof_7301_stb6100_config = {
754b699c271SIgor M. Liplianin .tuner_address = 0x60,
755b699c271SIgor M. Liplianin .refclock = 27000000,
756b699c271SIgor M. Liplianin };
757b699c271SIgor M. Liplianin
7582e4e98e7Slawrence rust static const struct stv0299_config tevii_tuner_sharp_config = {
759e4aab64cSIgor M. Liplianin .demod_address = 0x68,
760d4305c68SIgor M. Liplianin .inittab = sharp_z0194a_inittab,
761e4aab64cSIgor M. Liplianin .mclk = 88000000UL,
762e4aab64cSIgor M. Liplianin .invert = 1,
763e4aab64cSIgor M. Liplianin .skip_reinit = 0,
764e4aab64cSIgor M. Liplianin .lock_output = 1,
765e4aab64cSIgor M. Liplianin .volt13_op0_op1 = STV0299_VOLT13_OP1,
766e4aab64cSIgor M. Liplianin .min_delay_ms = 100,
767d4305c68SIgor M. Liplianin .set_symbol_rate = sharp_z0194a_set_symbol_rate,
768e4aab64cSIgor M. Liplianin .set_ts_params = cx24116_set_ts_param,
769e4aab64cSIgor M. Liplianin };
770e4aab64cSIgor M. Liplianin
7712e4e98e7Slawrence rust static const struct stv0288_config tevii_tuner_earda_config = {
772e4aab64cSIgor M. Liplianin .demod_address = 0x68,
773e4aab64cSIgor M. Liplianin .min_delay_ms = 100,
774e4aab64cSIgor M. Liplianin .set_ts_params = cx24116_set_ts_param,
775e4aab64cSIgor M. Liplianin };
776e4aab64cSIgor M. Liplianin
cx8802_alloc_frontends(struct cx8802_dev * dev)7776e0e12f1SAndy Walls static int cx8802_alloc_frontends(struct cx8802_dev *dev)
7786e0e12f1SAndy Walls {
7796e0e12f1SAndy Walls struct cx88_core *core = dev->core;
7800b6b6302SHans Verkuil struct vb2_dvb_frontend *fe = NULL;
7816e0e12f1SAndy Walls int i;
7826e0e12f1SAndy Walls
7836e0e12f1SAndy Walls mutex_init(&dev->frontends.lock);
7846e0e12f1SAndy Walls INIT_LIST_HEAD(&dev->frontends.felist);
7856e0e12f1SAndy Walls
7866e0e12f1SAndy Walls if (!core->board.num_frontends)
7876e0e12f1SAndy Walls return -ENODEV;
7886e0e12f1SAndy Walls
78965bc2fe8SMauro Carvalho Chehab pr_info("%s: allocating %d frontend(s)\n", __func__,
7906e0e12f1SAndy Walls core->board.num_frontends);
7916e0e12f1SAndy Walls for (i = 1; i <= core->board.num_frontends; i++) {
7920b6b6302SHans Verkuil fe = vb2_dvb_alloc_frontend(&dev->frontends, i);
7936e0e12f1SAndy Walls if (!fe) {
79465bc2fe8SMauro Carvalho Chehab pr_err("%s() failed to alloc\n", __func__);
7950b6b6302SHans Verkuil vb2_dvb_dealloc_frontends(&dev->frontends);
7966e0e12f1SAndy Walls return -ENOMEM;
7976e0e12f1SAndy Walls }
7986e0e12f1SAndy Walls }
7996e0e12f1SAndy Walls return 0;
8006e0e12f1SAndy Walls }
8016e0e12f1SAndy Walls
8022e4e98e7Slawrence rust static const u8 samsung_smt_7020_inittab[] = {
8034f3ca2f1SDirk Herrendoerfer 0x01, 0x15,
8044f3ca2f1SDirk Herrendoerfer 0x02, 0x00,
8054f3ca2f1SDirk Herrendoerfer 0x03, 0x00,
8064f3ca2f1SDirk Herrendoerfer 0x04, 0x7D,
8074f3ca2f1SDirk Herrendoerfer 0x05, 0x0F,
8084f3ca2f1SDirk Herrendoerfer 0x06, 0x02,
8094f3ca2f1SDirk Herrendoerfer 0x07, 0x00,
8104f3ca2f1SDirk Herrendoerfer 0x08, 0x60,
8114f3ca2f1SDirk Herrendoerfer
8124f3ca2f1SDirk Herrendoerfer 0x0A, 0xC2,
8134f3ca2f1SDirk Herrendoerfer 0x0B, 0x00,
8144f3ca2f1SDirk Herrendoerfer 0x0C, 0x01,
8154f3ca2f1SDirk Herrendoerfer 0x0D, 0x81,
8164f3ca2f1SDirk Herrendoerfer 0x0E, 0x44,
8174f3ca2f1SDirk Herrendoerfer 0x0F, 0x09,
8184f3ca2f1SDirk Herrendoerfer 0x10, 0x3C,
8194f3ca2f1SDirk Herrendoerfer 0x11, 0x84,
8204f3ca2f1SDirk Herrendoerfer 0x12, 0xDA,
8214f3ca2f1SDirk Herrendoerfer 0x13, 0x99,
8224f3ca2f1SDirk Herrendoerfer 0x14, 0x8D,
8234f3ca2f1SDirk Herrendoerfer 0x15, 0xCE,
8244f3ca2f1SDirk Herrendoerfer 0x16, 0xE8,
8254f3ca2f1SDirk Herrendoerfer 0x17, 0x43,
8264f3ca2f1SDirk Herrendoerfer 0x18, 0x1C,
8274f3ca2f1SDirk Herrendoerfer 0x19, 0x1B,
8284f3ca2f1SDirk Herrendoerfer 0x1A, 0x1D,
8294f3ca2f1SDirk Herrendoerfer
8304f3ca2f1SDirk Herrendoerfer 0x1C, 0x12,
8314f3ca2f1SDirk Herrendoerfer 0x1D, 0x00,
8324f3ca2f1SDirk Herrendoerfer 0x1E, 0x00,
8334f3ca2f1SDirk Herrendoerfer 0x1F, 0x00,
8344f3ca2f1SDirk Herrendoerfer 0x20, 0x00,
8354f3ca2f1SDirk Herrendoerfer 0x21, 0x00,
8364f3ca2f1SDirk Herrendoerfer 0x22, 0x00,
8374f3ca2f1SDirk Herrendoerfer 0x23, 0x00,
8384f3ca2f1SDirk Herrendoerfer
8394f3ca2f1SDirk Herrendoerfer 0x28, 0x02,
8404f3ca2f1SDirk Herrendoerfer 0x29, 0x28,
8414f3ca2f1SDirk Herrendoerfer 0x2A, 0x14,
8424f3ca2f1SDirk Herrendoerfer 0x2B, 0x0F,
8434f3ca2f1SDirk Herrendoerfer 0x2C, 0x09,
8444f3ca2f1SDirk Herrendoerfer 0x2D, 0x05,
8454f3ca2f1SDirk Herrendoerfer
8464f3ca2f1SDirk Herrendoerfer 0x31, 0x1F,
8474f3ca2f1SDirk Herrendoerfer 0x32, 0x19,
8484f3ca2f1SDirk Herrendoerfer 0x33, 0xFC,
8494f3ca2f1SDirk Herrendoerfer 0x34, 0x13,
8504f3ca2f1SDirk Herrendoerfer 0xff, 0xff,
8514f3ca2f1SDirk Herrendoerfer };
8524f3ca2f1SDirk Herrendoerfer
samsung_smt_7020_tuner_set_params(struct dvb_frontend * fe)85314d24d14SMauro Carvalho Chehab static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe)
8544f3ca2f1SDirk Herrendoerfer {
855b738ae16SMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache;
8564f3ca2f1SDirk Herrendoerfer struct cx8802_dev *dev = fe->dvb->priv;
8574f3ca2f1SDirk Herrendoerfer u8 buf[4];
8584f3ca2f1SDirk Herrendoerfer u32 div;
8594f3ca2f1SDirk Herrendoerfer struct i2c_msg msg = {
8604f3ca2f1SDirk Herrendoerfer .addr = 0x61,
8614f3ca2f1SDirk Herrendoerfer .flags = 0,
8624f3ca2f1SDirk Herrendoerfer .buf = buf,
8634f3ca2f1SDirk Herrendoerfer .len = sizeof(buf) };
8644f3ca2f1SDirk Herrendoerfer
865b738ae16SMauro Carvalho Chehab div = c->frequency / 125;
8664f3ca2f1SDirk Herrendoerfer
8674f3ca2f1SDirk Herrendoerfer buf[0] = (div >> 8) & 0x7f;
8684f3ca2f1SDirk Herrendoerfer buf[1] = div & 0xff;
8694f3ca2f1SDirk Herrendoerfer buf[2] = 0x84; /* 0xC4 */
8704f3ca2f1SDirk Herrendoerfer buf[3] = 0x00;
8714f3ca2f1SDirk Herrendoerfer
872b738ae16SMauro Carvalho Chehab if (c->frequency < 1500000)
8734f3ca2f1SDirk Herrendoerfer buf[3] |= 0x10;
8744f3ca2f1SDirk Herrendoerfer
8754f3ca2f1SDirk Herrendoerfer if (fe->ops.i2c_gate_ctrl)
8764f3ca2f1SDirk Herrendoerfer fe->ops.i2c_gate_ctrl(fe, 1);
8774f3ca2f1SDirk Herrendoerfer
8784f3ca2f1SDirk Herrendoerfer if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1)
8794f3ca2f1SDirk Herrendoerfer return -EIO;
8804f3ca2f1SDirk Herrendoerfer
8814f3ca2f1SDirk Herrendoerfer return 0;
8824f3ca2f1SDirk Herrendoerfer }
8834f3ca2f1SDirk Herrendoerfer
samsung_smt_7020_set_tone(struct dvb_frontend * fe,enum fe_sec_tone_mode tone)8844f3ca2f1SDirk Herrendoerfer static int samsung_smt_7020_set_tone(struct dvb_frontend *fe,
8850df289a2SMauro Carvalho Chehab enum fe_sec_tone_mode tone)
8864f3ca2f1SDirk Herrendoerfer {
8874f3ca2f1SDirk Herrendoerfer struct cx8802_dev *dev = fe->dvb->priv;
8884f3ca2f1SDirk Herrendoerfer struct cx88_core *core = dev->core;
8894f3ca2f1SDirk Herrendoerfer
8904f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x0800);
8914f3ca2f1SDirk Herrendoerfer
8924f3ca2f1SDirk Herrendoerfer switch (tone) {
8934f3ca2f1SDirk Herrendoerfer case SEC_TONE_ON:
8944f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x08);
8954f3ca2f1SDirk Herrendoerfer break;
8964f3ca2f1SDirk Herrendoerfer case SEC_TONE_OFF:
8974f3ca2f1SDirk Herrendoerfer cx_clear(MO_GP0_IO, 0x08);
8984f3ca2f1SDirk Herrendoerfer break;
8994f3ca2f1SDirk Herrendoerfer default:
9004f3ca2f1SDirk Herrendoerfer return -EINVAL;
9014f3ca2f1SDirk Herrendoerfer }
9024f3ca2f1SDirk Herrendoerfer
9034f3ca2f1SDirk Herrendoerfer return 0;
9044f3ca2f1SDirk Herrendoerfer }
9054f3ca2f1SDirk Herrendoerfer
samsung_smt_7020_set_voltage(struct dvb_frontend * fe,enum fe_sec_voltage voltage)9064f3ca2f1SDirk Herrendoerfer static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe,
9070df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage)
9084f3ca2f1SDirk Herrendoerfer {
9094f3ca2f1SDirk Herrendoerfer struct cx8802_dev *dev = fe->dvb->priv;
9104f3ca2f1SDirk Herrendoerfer struct cx88_core *core = dev->core;
9114f3ca2f1SDirk Herrendoerfer
9124f3ca2f1SDirk Herrendoerfer u8 data;
9134f3ca2f1SDirk Herrendoerfer struct i2c_msg msg = {
9144f3ca2f1SDirk Herrendoerfer .addr = 8,
9154f3ca2f1SDirk Herrendoerfer .flags = 0,
9164f3ca2f1SDirk Herrendoerfer .buf = &data,
9174f3ca2f1SDirk Herrendoerfer .len = sizeof(data) };
9184f3ca2f1SDirk Herrendoerfer
9194f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x8000);
9204f3ca2f1SDirk Herrendoerfer
9214f3ca2f1SDirk Herrendoerfer switch (voltage) {
9224f3ca2f1SDirk Herrendoerfer case SEC_VOLTAGE_OFF:
9234f3ca2f1SDirk Herrendoerfer break;
9244f3ca2f1SDirk Herrendoerfer case SEC_VOLTAGE_13:
9254f3ca2f1SDirk Herrendoerfer data = ISL6421_EN1 | ISL6421_LLC1;
9264f3ca2f1SDirk Herrendoerfer cx_clear(MO_GP0_IO, 0x80);
9274f3ca2f1SDirk Herrendoerfer break;
9284f3ca2f1SDirk Herrendoerfer case SEC_VOLTAGE_18:
9294f3ca2f1SDirk Herrendoerfer data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1;
9304f3ca2f1SDirk Herrendoerfer cx_clear(MO_GP0_IO, 0x80);
9314f3ca2f1SDirk Herrendoerfer break;
9324f3ca2f1SDirk Herrendoerfer default:
9334f3ca2f1SDirk Herrendoerfer return -EINVAL;
934c2c1b415SPeter Senna Tschudin }
9354f3ca2f1SDirk Herrendoerfer
9364f3ca2f1SDirk Herrendoerfer return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO;
9374f3ca2f1SDirk Herrendoerfer }
9384f3ca2f1SDirk Herrendoerfer
samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend * fe,u32 srate,u32 ratio)9394f3ca2f1SDirk Herrendoerfer static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe,
9404f3ca2f1SDirk Herrendoerfer u32 srate, u32 ratio)
9414f3ca2f1SDirk Herrendoerfer {
9424f3ca2f1SDirk Herrendoerfer u8 aclk = 0;
9434f3ca2f1SDirk Herrendoerfer u8 bclk = 0;
9444f3ca2f1SDirk Herrendoerfer
9454f3ca2f1SDirk Herrendoerfer if (srate < 1500000) {
9464f3ca2f1SDirk Herrendoerfer aclk = 0xb7;
9474f3ca2f1SDirk Herrendoerfer bclk = 0x47;
9484f3ca2f1SDirk Herrendoerfer } else if (srate < 3000000) {
9494f3ca2f1SDirk Herrendoerfer aclk = 0xb7;
9504f3ca2f1SDirk Herrendoerfer bclk = 0x4b;
9514f3ca2f1SDirk Herrendoerfer } else if (srate < 7000000) {
9524f3ca2f1SDirk Herrendoerfer aclk = 0xb7;
9534f3ca2f1SDirk Herrendoerfer bclk = 0x4f;
9544f3ca2f1SDirk Herrendoerfer } else if (srate < 14000000) {
9554f3ca2f1SDirk Herrendoerfer aclk = 0xb7;
9564f3ca2f1SDirk Herrendoerfer bclk = 0x53;
9574f3ca2f1SDirk Herrendoerfer } else if (srate < 30000000) {
9584f3ca2f1SDirk Herrendoerfer aclk = 0xb6;
9594f3ca2f1SDirk Herrendoerfer bclk = 0x53;
9604f3ca2f1SDirk Herrendoerfer } else if (srate < 45000000) {
9614f3ca2f1SDirk Herrendoerfer aclk = 0xb4;
9624f3ca2f1SDirk Herrendoerfer bclk = 0x51;
9634f3ca2f1SDirk Herrendoerfer }
9644f3ca2f1SDirk Herrendoerfer
9654f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x13, aclk);
9664f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x14, bclk);
9674f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
9684f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
9694f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x21, ratio & 0xf0);
9704f3ca2f1SDirk Herrendoerfer
9714f3ca2f1SDirk Herrendoerfer return 0;
9724f3ca2f1SDirk Herrendoerfer }
9734f3ca2f1SDirk Herrendoerfer
9742e4e98e7Slawrence rust static const struct stv0299_config samsung_stv0299_config = {
9754f3ca2f1SDirk Herrendoerfer .demod_address = 0x68,
9764f3ca2f1SDirk Herrendoerfer .inittab = samsung_smt_7020_inittab,
9774f3ca2f1SDirk Herrendoerfer .mclk = 88000000UL,
9784f3ca2f1SDirk Herrendoerfer .invert = 0,
9794f3ca2f1SDirk Herrendoerfer .skip_reinit = 0,
9804f3ca2f1SDirk Herrendoerfer .lock_output = STV0299_LOCKOUTPUT_LK,
9814f3ca2f1SDirk Herrendoerfer .volt13_op0_op1 = STV0299_VOLT13_OP1,
9824f3ca2f1SDirk Herrendoerfer .min_delay_ms = 100,
9834f3ca2f1SDirk Herrendoerfer .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate,
9844f3ca2f1SDirk Herrendoerfer };
9854f3ca2f1SDirk Herrendoerfer
dvb_register(struct cx8802_dev * dev)9861da177e4SLinus Torvalds static int dvb_register(struct cx8802_dev *dev)
9871da177e4SLinus Torvalds {
988363c35fcSSteven Toth struct cx88_core *core = dev->core;
9890b6b6302SHans Verkuil struct vb2_dvb_frontend *fe0, *fe1 = NULL;
99059b1842dSDarron Broad int mfe_shared = 0; /* bus not shared by default */
9917b0962d3SDavid Fries int res = -EINVAL;
992363c35fcSSteven Toth
9937b61ba8fSMauro Carvalho Chehab if (core->i2c_rc != 0) {
99465bc2fe8SMauro Carvalho Chehab pr_err("no i2c-bus available, cannot attach dvb drivers\n");
9950e8bac97SMatthias Schwarzott goto frontend_detach;
9960e8bac97SMatthias Schwarzott }
9970e8bac97SMatthias Schwarzott
998363c35fcSSteven Toth /* Get the first frontend */
9990b6b6302SHans Verkuil fe0 = vb2_dvb_get_frontend(&dev->frontends, 1);
1000363c35fcSSteven Toth if (!fe0)
100160a5a927SDarron Broad goto frontend_detach;
10021da177e4SLinus Torvalds
10038e739090SDarron Broad /* multi-frontend gate control is undefined or defaults to fe0 */
10048e739090SDarron Broad dev->frontends.gate = 0;
10058e739090SDarron Broad
1006e32fadc4SMauro Carvalho Chehab /* Sets the gate control callback to be used by i2c command calls */
1007e32fadc4SMauro Carvalho Chehab core->gate_ctrl = cx88_dvb_gate_ctrl;
1008e32fadc4SMauro Carvalho Chehab
10098e739090SDarron Broad /* init frontend(s) */
10100590d91cSMauro Carvalho Chehab switch (core->boardnr) {
10111da177e4SLinus Torvalds case CX88_BOARD_HAUPPAUGE_DVB_T1:
1012363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx22702_attach,
1013ed355260SMichael Krufky &connexant_refboard_config,
10140590d91cSMauro Carvalho Chehab &core->i2c_adap);
1015399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1016363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
10170590d91cSMauro Carvalho Chehab 0x61, &core->i2c_adap,
10180590d91cSMauro Carvalho Chehab DVB_PLL_THOMSON_DTT759X))
10190590d91cSMauro Carvalho Chehab goto frontend_detach;
1020f54376e2SAndrew de Quincey }
10211da177e4SLinus Torvalds break;
1022e057ee11SMichael Krufky case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
10231da177e4SLinus Torvalds case CX88_BOARD_CONEXANT_DVB_T1:
1024f39624fdSManenti Marco case CX88_BOARD_KWORLD_DVB_T_CX22702:
10252b5200a7SDavid Shirley case CX88_BOARD_WINFAST_DTV1000:
1026363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx22702_attach,
1027f7b54b10SMichael Krufky &connexant_refboard_config,
10280590d91cSMauro Carvalho Chehab &core->i2c_adap);
1029399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1030363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
10310590d91cSMauro Carvalho Chehab 0x60, &core->i2c_adap,
10320590d91cSMauro Carvalho Chehab DVB_PLL_THOMSON_DTT7579))
10330590d91cSMauro Carvalho Chehab goto frontend_detach;
1034f54376e2SAndrew de Quincey }
10351da177e4SLinus Torvalds break;
10364bd6e9d9SMalcolm Valentine case CX88_BOARD_WINFAST_DTV2000H:
1037611900c1SSteven Toth case CX88_BOARD_HAUPPAUGE_HVR1100:
1038611900c1SSteven Toth case CX88_BOARD_HAUPPAUGE_HVR1100LP:
1039a5a2ecfcSTrent Piepho case CX88_BOARD_HAUPPAUGE_HVR1300:
1040363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx22702_attach,
1041ed355260SMichael Krufky &hauppauge_hvr_config,
10420590d91cSMauro Carvalho Chehab &core->i2c_adap);
1043399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1044363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
10450590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
10460590d91cSMauro Carvalho Chehab TUNER_PHILIPS_FMD1216ME_MK3))
10470590d91cSMauro Carvalho Chehab goto frontend_detach;
1048f54376e2SAndrew de Quincey }
1049611900c1SSteven Toth break;
105027b93d8aSMiroslav Slugen case CX88_BOARD_WINFAST_DTV2000H_J:
105127b93d8aSMiroslav Slugen fe0->dvb.frontend = dvb_attach(cx22702_attach,
105227b93d8aSMiroslav Slugen &hauppauge_hvr_config,
105327b93d8aSMiroslav Slugen &core->i2c_adap);
1054399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
105527b93d8aSMiroslav Slugen if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
105627b93d8aSMiroslav Slugen &core->i2c_adap, 0x61,
105727b93d8aSMiroslav Slugen TUNER_PHILIPS_FMD1216MEX_MK3))
105827b93d8aSMiroslav Slugen goto frontend_detach;
105927b93d8aSMiroslav Slugen }
106027b93d8aSMiroslav Slugen break;
1061363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR3000:
106260a5a927SDarron Broad /* MFE frontend 1 */
106360a5a927SDarron Broad mfe_shared = 1;
106460a5a927SDarron Broad dev->frontends.gate = 2;
1065363c35fcSSteven Toth /* DVB-S init */
1066363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24123_attach,
1067363c35fcSSteven Toth &hauppauge_novas_config,
1068363c35fcSSteven Toth &dev->core->i2c_adap);
1069363c35fcSSteven Toth if (fe0->dvb.frontend) {
107060a5a927SDarron Broad if (!dvb_attach(isl6421_attach,
107160a5a927SDarron Broad fe0->dvb.frontend,
107260a5a927SDarron Broad &dev->core->i2c_adap,
107348a8a03bSMauro Carvalho Chehab 0x08, ISL6421_DCL, 0x00, false))
107460a5a927SDarron Broad goto frontend_detach;
1075363c35fcSSteven Toth }
107660a5a927SDarron Broad /* MFE frontend 2 */
10770b6b6302SHans Verkuil fe1 = vb2_dvb_get_frontend(&dev->frontends, 2);
107860a5a927SDarron Broad if (!fe1)
107960a5a927SDarron Broad goto frontend_detach;
108060a5a927SDarron Broad /* DVB-T init */
1081363c35fcSSteven Toth fe1->dvb.frontend = dvb_attach(cx22702_attach,
1082363c35fcSSteven Toth &hauppauge_hvr_config,
1083363c35fcSSteven Toth &dev->core->i2c_adap);
1084363c35fcSSteven Toth if (fe1->dvb.frontend) {
1085363c35fcSSteven Toth fe1->dvb.frontend->id = 1;
108660a5a927SDarron Broad if (!dvb_attach(simple_tuner_attach,
108760a5a927SDarron Broad fe1->dvb.frontend,
108860a5a927SDarron Broad &dev->core->i2c_adap,
108960a5a927SDarron Broad 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
109060a5a927SDarron Broad goto frontend_detach;
1091363c35fcSSteven Toth }
1092363c35fcSSteven Toth break;
1093780dfef3SChris Pascoe case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
1094363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach,
1095f7b54b10SMichael Krufky &dvico_fusionhdtv,
10960590d91cSMauro Carvalho Chehab &core->i2c_adap);
1097399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1098363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
10990590d91cSMauro Carvalho Chehab 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
11000590d91cSMauro Carvalho Chehab goto frontend_detach;
1101780dfef3SChris Pascoe break;
1102f54376e2SAndrew de Quincey }
1103780dfef3SChris Pascoe /* ZL10353 replaces MT352 on later cards */
1104363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach,
1105f7b54b10SMichael Krufky &dvico_fusionhdtv_plus_v1_1,
11060590d91cSMauro Carvalho Chehab &core->i2c_adap);
1107399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1108363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
11090590d91cSMauro Carvalho Chehab 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
11100590d91cSMauro Carvalho Chehab goto frontend_detach;
1111f54376e2SAndrew de Quincey }
1112780dfef3SChris Pascoe break;
1113c2af3cd6SMichael Krufky case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
1114399426caSMauro Carvalho Chehab /*
1115399426caSMauro Carvalho Chehab * The tin box says DEE1601, but it seems to be DTT7579
1116399426caSMauro Carvalho Chehab * compatible, with a slightly different MT352 AGC gain.
1117399426caSMauro Carvalho Chehab */
1118363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach,
1119f7b54b10SMichael Krufky &dvico_fusionhdtv_dual,
11200590d91cSMauro Carvalho Chehab &core->i2c_adap);
1121399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1122363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
11230590d91cSMauro Carvalho Chehab 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
11240590d91cSMauro Carvalho Chehab goto frontend_detach;
1125c2af3cd6SMichael Krufky break;
1126c2af3cd6SMichael Krufky }
1127c2af3cd6SMichael Krufky /* ZL10353 replaces MT352 on later cards */
1128363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach,
1129f7b54b10SMichael Krufky &dvico_fusionhdtv_plus_v1_1,
11300590d91cSMauro Carvalho Chehab &core->i2c_adap);
1131399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1132363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
11330590d91cSMauro Carvalho Chehab 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
11340590d91cSMauro Carvalho Chehab goto frontend_detach;
1135c2af3cd6SMichael Krufky }
1136c2af3cd6SMichael Krufky break;
11371da177e4SLinus Torvalds case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
1138363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach,
1139f7b54b10SMichael Krufky &dvico_fusionhdtv,
11400590d91cSMauro Carvalho Chehab &core->i2c_adap);
1141399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1142363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
11430590d91cSMauro Carvalho Chehab 0x61, NULL, DVB_PLL_LG_Z201))
11440590d91cSMauro Carvalho Chehab goto frontend_detach;
1145f54376e2SAndrew de Quincey }
11461da177e4SLinus Torvalds break;
11471da177e4SLinus Torvalds case CX88_BOARD_KWORLD_DVB_T:
11481da177e4SLinus Torvalds case CX88_BOARD_DNTV_LIVE_DVB_T:
1149a82decf6SMauro Carvalho Chehab case CX88_BOARD_ADSTECH_DVB_T_PCI:
1150363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach,
1151f7b54b10SMichael Krufky &dntv_live_dvbt_config,
11520590d91cSMauro Carvalho Chehab &core->i2c_adap);
1153399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1154363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
11550590d91cSMauro Carvalho Chehab 0x61, NULL, DVB_PLL_UNKNOWN_1))
11560590d91cSMauro Carvalho Chehab goto frontend_detach;
1157f54376e2SAndrew de Quincey }
11581da177e4SLinus Torvalds break;
1159fc40b261SChris Pascoe case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
11607b34be71SPeter Senna Tschudin #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054)
1161f0ad9097STrent Piepho /* MT352 is on a secondary I2C bus made from some GPIO lines */
1162399426caSMauro Carvalho Chehab fe0->dvb.frontend = dvb_attach(mt352_attach,
1163399426caSMauro Carvalho Chehab &dntv_live_dvbt_pro_config,
1164f0ad9097STrent Piepho &dev->vp3054->adap);
1165399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1166363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
11670590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
11680590d91cSMauro Carvalho Chehab TUNER_PHILIPS_FMD1216ME_MK3))
11690590d91cSMauro Carvalho Chehab goto frontend_detach;
1170f54376e2SAndrew de Quincey }
1171fc40b261SChris Pascoe #else
117265bc2fe8SMauro Carvalho Chehab pr_err("built without vp3054 support\n");
1173fc40b261SChris Pascoe #endif
1174fc40b261SChris Pascoe break;
1175780dfef3SChris Pascoe case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
1176363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach,
1177f7b54b10SMichael Krufky &dvico_fusionhdtv_hybrid,
11780590d91cSMauro Carvalho Chehab &core->i2c_adap);
1179399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1180363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
11810590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
11820590d91cSMauro Carvalho Chehab TUNER_THOMSON_FE6600))
11830590d91cSMauro Carvalho Chehab goto frontend_detach;
1184f54376e2SAndrew de Quincey }
1185780dfef3SChris Pascoe break;
1186b3fb91d2SChris Pascoe case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
1187363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach,
1188b3fb91d2SChris Pascoe &dvico_fusionhdtv_xc3028,
11890590d91cSMauro Carvalho Chehab &core->i2c_adap);
1190399426caSMauro Carvalho Chehab if (!fe0->dvb.frontend)
1191363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach,
1192b3fb91d2SChris Pascoe &dvico_fusionhdtv_mt352_xc3028,
11930590d91cSMauro Carvalho Chehab &core->i2c_adap);
11948765561fSChris Pascoe /*
11958765561fSChris Pascoe * On this board, the demod provides the I2C bus pullup.
11968765561fSChris Pascoe * We must not permit gate_ctrl to be performed, or
11978765561fSChris Pascoe * the xc3028 cannot communicate on the bus.
11988765561fSChris Pascoe */
1199363c35fcSSteven Toth if (fe0->dvb.frontend)
1200363c35fcSSteven Toth fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
120123fb348dSMauro Carvalho Chehab if (attach_xc3028(0x61, dev) < 0)
1202becd4305SDarron Broad goto frontend_detach;
1203b3fb91d2SChris Pascoe break;
12041da177e4SLinus Torvalds case CX88_BOARD_PCHDTV_HD3000:
1205363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
12060590d91cSMauro Carvalho Chehab &core->i2c_adap);
1207399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1208363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
12090590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
12100590d91cSMauro Carvalho Chehab TUNER_THOMSON_DTT761X))
12110590d91cSMauro Carvalho Chehab goto frontend_detach;
1212f54376e2SAndrew de Quincey }
12131da177e4SLinus Torvalds break;
1214f1798495SMichael Krufky case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
1215f1798495SMichael Krufky dev->ts_gen_cntrl = 0x08;
1216f1798495SMichael Krufky
12170590d91cSMauro Carvalho Chehab /* Do a hardware reset of chip before using it. */
1218f1798495SMichael Krufky cx_clear(MO_GP0_IO, 1);
12199d08ba6dSJia-Ju Bai msleep(100);
12200ccef6dbSMichael Krufky cx_set(MO_GP0_IO, 1);
12219d08ba6dSJia-Ju Bai msleep(200);
12220ccef6dbSMichael Krufky
12230ccef6dbSMichael Krufky /* Select RF connector callback */
12246ddcc919SMichael Krufky fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
1225363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1226f7b54b10SMichael Krufky &fusionhdtv_3_gold,
122723ba635dSMauro Carvalho Chehab 0x0e,
12280590d91cSMauro Carvalho Chehab &core->i2c_adap);
1229399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1230363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
12310590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
12320590d91cSMauro Carvalho Chehab TUNER_MICROTUNE_4042FI5))
12330590d91cSMauro Carvalho Chehab goto frontend_detach;
1234f1798495SMichael Krufky }
1235f1798495SMichael Krufky break;
12360d723c09SMichael Krufky case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
12370d723c09SMichael Krufky dev->ts_gen_cntrl = 0x08;
12380d723c09SMichael Krufky
12390590d91cSMauro Carvalho Chehab /* Do a hardware reset of chip before using it. */
12400d723c09SMichael Krufky cx_clear(MO_GP0_IO, 1);
12419d08ba6dSJia-Ju Bai msleep(100);
1242d975872cSMichael Krufky cx_set(MO_GP0_IO, 9);
12439d08ba6dSJia-Ju Bai msleep(200);
1244363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1245f7b54b10SMichael Krufky &fusionhdtv_3_gold,
124623ba635dSMauro Carvalho Chehab 0x0e,
12470590d91cSMauro Carvalho Chehab &core->i2c_adap);
1248399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1249363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
12500590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
12510590d91cSMauro Carvalho Chehab TUNER_THOMSON_DTT761X))
12520590d91cSMauro Carvalho Chehab goto frontend_detach;
12530d723c09SMichael Krufky }
12540d723c09SMichael Krufky break;
1255e52e98a7SMauro Carvalho Chehab case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
1256e52e98a7SMauro Carvalho Chehab dev->ts_gen_cntrl = 0x08;
1257e52e98a7SMauro Carvalho Chehab
12580590d91cSMauro Carvalho Chehab /* Do a hardware reset of chip before using it. */
1259e52e98a7SMauro Carvalho Chehab cx_clear(MO_GP0_IO, 1);
12609d08ba6dSJia-Ju Bai msleep(100);
1261e52e98a7SMauro Carvalho Chehab cx_set(MO_GP0_IO, 1);
12629d08ba6dSJia-Ju Bai msleep(200);
1263363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1264f7b54b10SMichael Krufky &fusionhdtv_5_gold,
126523ba635dSMauro Carvalho Chehab 0x0e,
12660590d91cSMauro Carvalho Chehab &core->i2c_adap);
1267399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1268363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
12690590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
12700590d91cSMauro Carvalho Chehab TUNER_LG_TDVS_H06XF))
12710590d91cSMauro Carvalho Chehab goto frontend_detach;
1272363c35fcSSteven Toth if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
12730590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x43))
12740590d91cSMauro Carvalho Chehab goto frontend_detach;
1275e52e98a7SMauro Carvalho Chehab }
1276e52e98a7SMauro Carvalho Chehab break;
1277da215d22SRusty Scott case CX88_BOARD_PCHDTV_HD5500:
1278da215d22SRusty Scott dev->ts_gen_cntrl = 0x08;
1279da215d22SRusty Scott
12800590d91cSMauro Carvalho Chehab /* Do a hardware reset of chip before using it. */
1281da215d22SRusty Scott cx_clear(MO_GP0_IO, 1);
12829d08ba6dSJia-Ju Bai msleep(100);
1283da215d22SRusty Scott cx_set(MO_GP0_IO, 1);
12849d08ba6dSJia-Ju Bai msleep(200);
1285363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
1286f7b54b10SMichael Krufky &pchdtv_hd5500,
128723ba635dSMauro Carvalho Chehab 0x59,
12880590d91cSMauro Carvalho Chehab &core->i2c_adap);
1289399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1290363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
12910590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
12920590d91cSMauro Carvalho Chehab TUNER_LG_TDVS_H06XF))
12930590d91cSMauro Carvalho Chehab goto frontend_detach;
1294363c35fcSSteven Toth if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
12950590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x43))
12960590d91cSMauro Carvalho Chehab goto frontend_detach;
1297da215d22SRusty Scott }
1298da215d22SRusty Scott break;
1299fde6d31eSKirk Lapray case CX88_BOARD_ATI_HDTVWONDER:
1300363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(nxt200x_attach,
1301f7b54b10SMichael Krufky &ati_hdtvwonder,
13020590d91cSMauro Carvalho Chehab &core->i2c_adap);
1303399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1304363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
13050590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61,
13060590d91cSMauro Carvalho Chehab TUNER_PHILIPS_TUV1236D))
13070590d91cSMauro Carvalho Chehab goto frontend_detach;
1308f54376e2SAndrew de Quincey }
1309fde6d31eSKirk Lapray break;
13100fa14aa6SSteven Toth case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
13110fa14aa6SSteven Toth case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
1312363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24123_attach,
1313f7b54b10SMichael Krufky &hauppauge_novas_config,
13140590d91cSMauro Carvalho Chehab &core->i2c_adap);
1315363c35fcSSteven Toth if (fe0->dvb.frontend) {
131648a8a03bSMauro Carvalho Chehab bool override_tone;
131748a8a03bSMauro Carvalho Chehab
131848a8a03bSMauro Carvalho Chehab if (core->model == 92001)
131948a8a03bSMauro Carvalho Chehab override_tone = true;
132048a8a03bSMauro Carvalho Chehab else
132148a8a03bSMauro Carvalho Chehab override_tone = false;
132248a8a03bSMauro Carvalho Chehab
1323363c35fcSSteven Toth if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
1324399426caSMauro Carvalho Chehab &core->i2c_adap, 0x08, ISL6421_DCL,
1325399426caSMauro Carvalho Chehab 0x00, override_tone))
13260590d91cSMauro Carvalho Chehab goto frontend_detach;
1327cd20ca9fSAndrew de Quincey }
13280fa14aa6SSteven Toth break;
13290e0351e3SVadim Catana case CX88_BOARD_KWORLD_DVBS_100:
1330363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24123_attach,
1331f7b54b10SMichael Krufky &kworld_dvbs_100_config,
13320590d91cSMauro Carvalho Chehab &core->i2c_adap);
1333363c35fcSSteven Toth if (fe0->dvb.frontend) {
1334363c35fcSSteven Toth core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1335363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
1336cd20ca9fSAndrew de Quincey }
13370e0351e3SVadim Catana break;
1338c02a34f4SSaqeb Akhter case CX88_BOARD_GENIATECH_DVBS:
1339363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24123_attach,
1340f7b54b10SMichael Krufky &geniatech_dvbs_config,
13410590d91cSMauro Carvalho Chehab &core->i2c_adap);
1342363c35fcSSteven Toth if (fe0->dvb.frontend) {
1343363c35fcSSteven Toth core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1344363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
1345c02a34f4SSaqeb Akhter }
1346c02a34f4SSaqeb Akhter break;
134760464da8SSteven Toth case CX88_BOARD_PINNACLE_PCTV_HD_800i:
1348363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(s5h1409_attach,
134960464da8SSteven Toth &pinnacle_pctv_hd_800i_config,
13500590d91cSMauro Carvalho Chehab &core->i2c_adap);
1351399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1352363c35fcSSteven Toth if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
13530590d91cSMauro Carvalho Chehab &core->i2c_adap,
135430650961SMichael Krufky &pinnacle_pctv_hd_800i_tuner_config))
13550590d91cSMauro Carvalho Chehab goto frontend_detach;
135660464da8SSteven Toth }
135760464da8SSteven Toth break;
13585c00fac0SSteven Toth case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
1359363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(s5h1409_attach,
13605c00fac0SSteven Toth &dvico_hdtv5_pci_nano_config,
13610590d91cSMauro Carvalho Chehab &core->i2c_adap);
1362399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
13635c00fac0SSteven Toth struct dvb_frontend *fe;
13645c00fac0SSteven Toth struct xc2028_config cfg = {
13650590d91cSMauro Carvalho Chehab .i2c_adap = &core->i2c_adap,
13665c00fac0SSteven Toth .i2c_addr = 0x61,
13675c00fac0SSteven Toth };
13685c00fac0SSteven Toth static struct xc2028_ctrl ctl = {
1369ef80bfebSMichael Krufky .fname = XC2028_DEFAULT_FIRMWARE,
13705c00fac0SSteven Toth .max_len = 64,
137133e53161SMauro Carvalho Chehab .scode_table = XC3028_FE_OREN538,
13725c00fac0SSteven Toth };
13735c00fac0SSteven Toth
13745c00fac0SSteven Toth fe = dvb_attach(xc2028_attach,
1375363c35fcSSteven Toth fe0->dvb.frontend, &cfg);
1376399426caSMauro Carvalho Chehab if (fe && fe->ops.tuner_ops.set_config)
13775c00fac0SSteven Toth fe->ops.tuner_ops.set_config(fe, &ctl);
13785c00fac0SSteven Toth }
13795c00fac0SSteven Toth break;
1380e6f45ea2SDaniel Gonzalez Cabanelas case CX88_BOARD_NOTONLYTV_LV3H:
13819507901eSMauro Carvalho Chehab case CX88_BOARD_PINNACLE_HYBRID_PCTV:
13823047a176SMiroslav Sustek case CX88_BOARD_WINFAST_DTV1800H:
1383363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach,
13843f6014fcSStéphane Voltz &cx88_pinnacle_hybrid_pctv,
13850590d91cSMauro Carvalho Chehab &core->i2c_adap);
1386363c35fcSSteven Toth if (fe0->dvb.frontend) {
1387363c35fcSSteven Toth fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
138823fb348dSMauro Carvalho Chehab if (attach_xc3028(0x61, dev) < 0)
13890590d91cSMauro Carvalho Chehab goto frontend_detach;
13903f6014fcSStéphane Voltz }
13919507901eSMauro Carvalho Chehab break;
13928eb79c0bSistvan_v@mailbox.hu case CX88_BOARD_WINFAST_DTV1800H_XC4000:
1393f271a3afSistvan_v@mailbox.hu case CX88_BOARD_WINFAST_DTV2000H_PLUS:
1394f271a3afSistvan_v@mailbox.hu fe0->dvb.frontend = dvb_attach(zl10353_attach,
1395f271a3afSistvan_v@mailbox.hu &cx88_pinnacle_hybrid_pctv,
1396f271a3afSistvan_v@mailbox.hu &core->i2c_adap);
1397f271a3afSistvan_v@mailbox.hu if (fe0->dvb.frontend) {
1398f271a3afSistvan_v@mailbox.hu struct xc4000_config cfg = {
1399f271a3afSistvan_v@mailbox.hu .i2c_address = 0x61,
1400f271a3afSistvan_v@mailbox.hu .default_pm = 0,
1401f271a3afSistvan_v@mailbox.hu .dvb_amplitude = 134,
1402f271a3afSistvan_v@mailbox.hu .set_smoothedcvbs = 1,
1403f271a3afSistvan_v@mailbox.hu .if_khz = 4560
1404f271a3afSistvan_v@mailbox.hu };
1405f271a3afSistvan_v@mailbox.hu fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
1406f271a3afSistvan_v@mailbox.hu if (attach_xc4000(dev, &cfg) < 0)
1407f271a3afSistvan_v@mailbox.hu goto frontend_detach;
1408f271a3afSistvan_v@mailbox.hu }
1409f271a3afSistvan_v@mailbox.hu break;
14109507901eSMauro Carvalho Chehab case CX88_BOARD_GENIATECH_X8000_MT:
14119507901eSMauro Carvalho Chehab dev->ts_gen_cntrl = 0x00;
14129507901eSMauro Carvalho Chehab
1413363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach,
14149507901eSMauro Carvalho Chehab &cx88_geniatech_x8000_mt,
14150590d91cSMauro Carvalho Chehab &core->i2c_adap);
141623fb348dSMauro Carvalho Chehab if (attach_xc3028(0x61, dev) < 0)
14170590d91cSMauro Carvalho Chehab goto frontend_detach;
14189507901eSMauro Carvalho Chehab break;
141999e09eacSMauro Carvalho Chehab case CX88_BOARD_KWORLD_ATSC_120:
1420363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(s5h1409_attach,
142199e09eacSMauro Carvalho Chehab &kworld_atsc_120_config,
14220590d91cSMauro Carvalho Chehab &core->i2c_adap);
142399e09eacSMauro Carvalho Chehab if (attach_xc3028(0x61, dev) < 0)
14240590d91cSMauro Carvalho Chehab goto frontend_detach;
142599e09eacSMauro Carvalho Chehab break;
1426d893d5dcSSteven Toth case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
1427363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1428d893d5dcSSteven Toth &dvico_fusionhdtv7_config,
14290590d91cSMauro Carvalho Chehab &core->i2c_adap);
1430399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1431363c35fcSSteven Toth if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
14320590d91cSMauro Carvalho Chehab &core->i2c_adap,
143330650961SMichael Krufky &dvico_fusionhdtv7_tuner_config))
14340590d91cSMauro Carvalho Chehab goto frontend_detach;
1435d893d5dcSSteven Toth }
1436d893d5dcSSteven Toth break;
14375bd1b663SSteven Toth case CX88_BOARD_HAUPPAUGE_HVR4000:
143860a5a927SDarron Broad /* MFE frontend 1 */
143960a5a927SDarron Broad mfe_shared = 1;
144060a5a927SDarron Broad dev->frontends.gate = 2;
1441363c35fcSSteven Toth /* DVB-S/S2 Init */
1442363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24116_attach,
14435bd1b663SSteven Toth &hauppauge_hvr4000_config,
14445bd1b663SSteven Toth &dev->core->i2c_adap);
1445363c35fcSSteven Toth if (fe0->dvb.frontend) {
144660a5a927SDarron Broad if (!dvb_attach(isl6421_attach,
144760a5a927SDarron Broad fe0->dvb.frontend,
144860a5a927SDarron Broad &dev->core->i2c_adap,
144948a8a03bSMauro Carvalho Chehab 0x08, ISL6421_DCL, 0x00, false))
145060a5a927SDarron Broad goto frontend_detach;
1451363c35fcSSteven Toth }
145260a5a927SDarron Broad /* MFE frontend 2 */
14530b6b6302SHans Verkuil fe1 = vb2_dvb_get_frontend(&dev->frontends, 2);
145460a5a927SDarron Broad if (!fe1)
145560a5a927SDarron Broad goto frontend_detach;
145660a5a927SDarron Broad /* DVB-T Init */
1457363c35fcSSteven Toth fe1->dvb.frontend = dvb_attach(cx22702_attach,
1458363c35fcSSteven Toth &hauppauge_hvr_config,
1459363c35fcSSteven Toth &dev->core->i2c_adap);
1460363c35fcSSteven Toth if (fe1->dvb.frontend) {
1461363c35fcSSteven Toth fe1->dvb.frontend->id = 1;
146260a5a927SDarron Broad if (!dvb_attach(simple_tuner_attach,
146360a5a927SDarron Broad fe1->dvb.frontend,
146460a5a927SDarron Broad &dev->core->i2c_adap,
146560a5a927SDarron Broad 0x61, TUNER_PHILIPS_FMD1216ME_MK3))
146660a5a927SDarron Broad goto frontend_detach;
1467363c35fcSSteven Toth }
1468363c35fcSSteven Toth break;
1469363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
1470363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24116_attach,
1471363c35fcSSteven Toth &hauppauge_hvr4000_config,
1472363c35fcSSteven Toth &dev->core->i2c_adap);
1473363c35fcSSteven Toth if (fe0->dvb.frontend) {
147460a5a927SDarron Broad if (!dvb_attach(isl6421_attach,
147560a5a927SDarron Broad fe0->dvb.frontend,
14765bd1b663SSteven Toth &dev->core->i2c_adap,
147748a8a03bSMauro Carvalho Chehab 0x08, ISL6421_DCL, 0x00, false))
147860a5a927SDarron Broad goto frontend_detach;
14795bd1b663SSteven Toth }
14805bd1b663SSteven Toth break;
1481cd3cde12SIgor M. Liplianin case CX88_BOARD_PROF_6200:
14824b29631dSIgor M. Liplianin case CX88_BOARD_TBS_8910:
1483e4aab64cSIgor M. Liplianin case CX88_BOARD_TEVII_S420:
1484363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(stv0299_attach,
1485e4aab64cSIgor M. Liplianin &tevii_tuner_sharp_config,
1486e4aab64cSIgor M. Liplianin &core->i2c_adap);
1487399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1488363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
1489e4aab64cSIgor M. Liplianin &core->i2c_adap, DVB_PLL_OPERA1))
1490e4aab64cSIgor M. Liplianin goto frontend_detach;
1491363c35fcSSteven Toth core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1492363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1493e4aab64cSIgor M. Liplianin
1494e4aab64cSIgor M. Liplianin } else {
1495363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(stv0288_attach,
1496e4aab64cSIgor M. Liplianin &tevii_tuner_earda_config,
1497e4aab64cSIgor M. Liplianin &core->i2c_adap);
1498399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1499399426caSMauro Carvalho Chehab if (!dvb_attach(stb6000_attach,
1500399426caSMauro Carvalho Chehab fe0->dvb.frontend, 0x61,
1501e4aab64cSIgor M. Liplianin &core->i2c_adap))
1502e4aab64cSIgor M. Liplianin goto frontend_detach;
1503363c35fcSSteven Toth core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
1504363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1505e4aab64cSIgor M. Liplianin }
1506e4aab64cSIgor M. Liplianin }
1507e4aab64cSIgor M. Liplianin break;
1508af832623SIgor M. Liplianin case CX88_BOARD_TEVII_S460:
1509363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24116_attach,
1510af832623SIgor M. Liplianin &tevii_s460_config,
1511af832623SIgor M. Liplianin &core->i2c_adap);
1512399426caSMauro Carvalho Chehab if (fe0->dvb.frontend)
1513363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1514af832623SIgor M. Liplianin break;
15150cb73639SIgor M. Liplianin case CX88_BOARD_TEVII_S464:
15160cb73639SIgor M. Liplianin fe0->dvb.frontend = dvb_attach(ds3000_attach,
15170cb73639SIgor M. Liplianin &tevii_ds3000_config,
15180cb73639SIgor M. Liplianin &core->i2c_adap);
1519399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
152073f0af44SKonstantin Dimitrov dvb_attach(ts2020_attach, fe0->dvb.frontend,
152173f0af44SKonstantin Dimitrov &tevii_ts2020_config, &core->i2c_adap);
15220cb73639SIgor M. Liplianin fe0->dvb.frontend->ops.set_voltage =
15230cb73639SIgor M. Liplianin tevii_dvbs_set_voltage;
152473f0af44SKonstantin Dimitrov }
15250cb73639SIgor M. Liplianin break;
15264cd7fb87SOleg Roitburd case CX88_BOARD_OMICOM_SS4_PCI:
1527ee73042cSOleg Roitburd case CX88_BOARD_TBS_8920:
152857f51dbcSOleg Roitburd case CX88_BOARD_PROF_7300:
15294b29631dSIgor M. Liplianin case CX88_BOARD_SATTRADE_ST4200:
1530363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24116_attach,
1531ee73042cSOleg Roitburd &hauppauge_hvr4000_config,
1532ee73042cSOleg Roitburd &core->i2c_adap);
1533399426caSMauro Carvalho Chehab if (fe0->dvb.frontend)
1534363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1535ee73042cSOleg Roitburd break;
153670101a27SStephan Wienczny case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
153770101a27SStephan Wienczny fe0->dvb.frontend = dvb_attach(zl10353_attach,
153870101a27SStephan Wienczny &cx88_terratec_cinergy_ht_pci_mkii_config,
153970101a27SStephan Wienczny &core->i2c_adap);
154070101a27SStephan Wienczny if (fe0->dvb.frontend) {
154170101a27SStephan Wienczny fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
154270101a27SStephan Wienczny if (attach_xc3028(0x61, dev) < 0)
154370101a27SStephan Wienczny goto frontend_detach;
154470101a27SStephan Wienczny }
154570101a27SStephan Wienczny break;
1546b699c271SIgor M. Liplianin case CX88_BOARD_PROF_7301:{
1547b699c271SIgor M. Liplianin struct dvb_tuner_ops *tuner_ops = NULL;
1548b699c271SIgor M. Liplianin
1549b699c271SIgor M. Liplianin fe0->dvb.frontend = dvb_attach(stv0900_attach,
1550b699c271SIgor M. Liplianin &prof_7301_stv0900_config,
1551b699c271SIgor M. Liplianin &core->i2c_adap, 0);
1552399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) {
1553b699c271SIgor M. Liplianin if (!dvb_attach(stb6100_attach, fe0->dvb.frontend,
1554b699c271SIgor M. Liplianin &prof_7301_stb6100_config,
1555b699c271SIgor M. Liplianin &core->i2c_adap))
1556b699c271SIgor M. Liplianin goto frontend_detach;
1557b699c271SIgor M. Liplianin
1558b699c271SIgor M. Liplianin tuner_ops = &fe0->dvb.frontend->ops.tuner_ops;
1559b699c271SIgor M. Liplianin tuner_ops->set_frequency = stb6100_set_freq;
1560b699c271SIgor M. Liplianin tuner_ops->get_frequency = stb6100_get_freq;
1561b699c271SIgor M. Liplianin tuner_ops->set_bandwidth = stb6100_set_bandw;
1562b699c271SIgor M. Liplianin tuner_ops->get_bandwidth = stb6100_get_bandw;
1563b699c271SIgor M. Liplianin
1564b699c271SIgor M. Liplianin core->prev_set_voltage =
1565b699c271SIgor M. Liplianin fe0->dvb.frontend->ops.set_voltage;
1566b699c271SIgor M. Liplianin fe0->dvb.frontend->ops.set_voltage =
1567b699c271SIgor M. Liplianin tevii_dvbs_set_voltage;
1568b699c271SIgor M. Liplianin }
1569b699c271SIgor M. Liplianin break;
1570b699c271SIgor M. Liplianin }
15714f3ca2f1SDirk Herrendoerfer case CX88_BOARD_SAMSUNG_SMT_7020:
15724f3ca2f1SDirk Herrendoerfer dev->ts_gen_cntrl = 0x08;
15734f3ca2f1SDirk Herrendoerfer
15744f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x0101);
15754f3ca2f1SDirk Herrendoerfer
15764f3ca2f1SDirk Herrendoerfer cx_clear(MO_GP0_IO, 0x01);
15779d08ba6dSJia-Ju Bai msleep(100);
15784f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x01);
15799d08ba6dSJia-Ju Bai msleep(200);
15804f3ca2f1SDirk Herrendoerfer
15814f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend = dvb_attach(stv0299_attach,
15824f3ca2f1SDirk Herrendoerfer &samsung_stv0299_config,
15834f3ca2f1SDirk Herrendoerfer &dev->core->i2c_adap);
15844f3ca2f1SDirk Herrendoerfer if (fe0->dvb.frontend) {
15854f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend->ops.tuner_ops.set_params =
15864f3ca2f1SDirk Herrendoerfer samsung_smt_7020_tuner_set_params;
15874f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend->tuner_priv =
15884f3ca2f1SDirk Herrendoerfer &dev->core->i2c_adap;
15894f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend->ops.set_voltage =
15904f3ca2f1SDirk Herrendoerfer samsung_smt_7020_set_voltage;
15914f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend->ops.set_tone =
15924f3ca2f1SDirk Herrendoerfer samsung_smt_7020_set_tone;
15934f3ca2f1SDirk Herrendoerfer }
15944f3ca2f1SDirk Herrendoerfer
15954f3ca2f1SDirk Herrendoerfer break;
1596111ac84aSSergey Ivanov case CX88_BOARD_TWINHAN_VP1027_DVBS:
1597111ac84aSSergey Ivanov dev->ts_gen_cntrl = 0x00;
1598111ac84aSSergey Ivanov fe0->dvb.frontend = dvb_attach(mb86a16_attach,
1599111ac84aSSergey Ivanov &twinhan_vp1027,
1600111ac84aSSergey Ivanov &core->i2c_adap);
1601111ac84aSSergey Ivanov if (fe0->dvb.frontend) {
1602111ac84aSSergey Ivanov core->prev_set_voltage =
1603111ac84aSSergey Ivanov fe0->dvb.frontend->ops.set_voltage;
1604111ac84aSSergey Ivanov fe0->dvb.frontend->ops.set_voltage =
1605111ac84aSSergey Ivanov vp1027_set_voltage;
1606111ac84aSSergey Ivanov }
1607111ac84aSSergey Ivanov break;
16084f3ca2f1SDirk Herrendoerfer
16091da177e4SLinus Torvalds default:
161065bc2fe8SMauro Carvalho Chehab pr_err("The frontend of your DVB/ATSC card isn't supported yet\n");
16111da177e4SLinus Torvalds break;
16121da177e4SLinus Torvalds }
1613363c35fcSSteven Toth
1614363c35fcSSteven Toth if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) {
161565bc2fe8SMauro Carvalho Chehab pr_err("frontend initialization failed\n");
161660a5a927SDarron Broad goto frontend_detach;
16179507901eSMauro Carvalho Chehab }
1618d7cba043SMichael Krufky /* define general-purpose callback pointer */
1619363c35fcSSteven Toth fe0->dvb.frontend->callback = cx88_tuner_callback;
16209507901eSMauro Carvalho Chehab
16216c5be74cSSteven Toth /* Ensure all frontends negotiate bus access */
1622363c35fcSSteven Toth fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
1623363c35fcSSteven Toth if (fe1)
1624363c35fcSSteven Toth fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
16251da177e4SLinus Torvalds
16263aab15afSHans Verkuil /* Put the tuner in standby to keep it quiet */
16273aab15afSHans Verkuil call_all(core, tuner, standby);
162893352f5cSMauro Carvalho Chehab
16291da177e4SLinus Torvalds /* register everything */
16300b6b6302SHans Verkuil res = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
16312773b0e9SMauro Carvalho Chehab &dev->pci->dev, NULL, adapter_nr,
16322773b0e9SMauro Carvalho Chehab mfe_shared);
16337b0962d3SDavid Fries if (res)
16347b0962d3SDavid Fries goto frontend_detach;
16357b0962d3SDavid Fries return res;
16360590d91cSMauro Carvalho Chehab
16370590d91cSMauro Carvalho Chehab frontend_detach:
1638e32fadc4SMauro Carvalho Chehab core->gate_ctrl = NULL;
16390b6b6302SHans Verkuil vb2_dvb_dealloc_frontends(&dev->frontends);
16407b0962d3SDavid Fries return res;
16411da177e4SLinus Torvalds }
16421da177e4SLinus Torvalds
16431da177e4SLinus Torvalds /* ----------------------------------------------------------- */
16441da177e4SLinus Torvalds
16456c5be74cSSteven Toth /* CX8802 MPEG -> mini driver - We have been given the hardware */
cx8802_dvb_advise_acquire(struct cx8802_driver * drv)16466c5be74cSSteven Toth static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
16471da177e4SLinus Torvalds {
16486c5be74cSSteven Toth struct cx88_core *core = drv->core;
16496c5be74cSSteven Toth int err = 0;
16507b61ba8fSMauro Carvalho Chehab
165132d83efcSHarvey Harrison dprintk(1, "%s\n", __func__);
16526c5be74cSSteven Toth
16536a59d64cSTrent Piepho switch (core->boardnr) {
16546c5be74cSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR1300:
16556c5be74cSSteven Toth /* We arrive here with either the cx23416 or the cx22702
16566c5be74cSSteven Toth * on the bus. Take the bus from the cx23416 and enable the
16576c5be74cSSteven Toth * cx22702 demod
16586c5be74cSSteven Toth */
165979392737SDarron Broad /* Toggle reset on cx22702 leaving i2c active */
166079392737SDarron Broad cx_set(MO_GP0_IO, 0x00000080);
166179392737SDarron Broad udelay(1000);
166279392737SDarron Broad cx_clear(MO_GP0_IO, 0x00000080);
166379392737SDarron Broad udelay(50);
166479392737SDarron Broad cx_set(MO_GP0_IO, 0x00000080);
166579392737SDarron Broad udelay(1000);
166679392737SDarron Broad /* enable the cx22702 pins */
16676c5be74cSSteven Toth cx_clear(MO_GP0_IO, 0x00000004);
16686c5be74cSSteven Toth udelay(1000);
16696c5be74cSSteven Toth break;
1670363c35fcSSteven Toth
167192abe9eeSDarron Broad case CX88_BOARD_HAUPPAUGE_HVR3000:
1672363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR4000:
1673363c35fcSSteven Toth /* Toggle reset on cx22702 leaving i2c active */
167479392737SDarron Broad cx_set(MO_GP0_IO, 0x00000080);
1675363c35fcSSteven Toth udelay(1000);
1676363c35fcSSteven Toth cx_clear(MO_GP0_IO, 0x00000080);
1677363c35fcSSteven Toth udelay(50);
167879392737SDarron Broad cx_set(MO_GP0_IO, 0x00000080);
1679363c35fcSSteven Toth udelay(1000);
168079392737SDarron Broad switch (core->dvbdev->frontends.active_fe_id) {
168179392737SDarron Broad case 1: /* DVB-S/S2 Enabled */
168279392737SDarron Broad /* tri-state the cx22702 pins */
168379392737SDarron Broad cx_set(MO_GP0_IO, 0x00000004);
168479392737SDarron Broad /* Take the cx24116/cx24123 out of reset */
168579392737SDarron Broad cx_write(MO_SRST_IO, 1);
1686363c35fcSSteven Toth core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
168779392737SDarron Broad break;
168879392737SDarron Broad case 2: /* DVB-T Enabled */
1689363c35fcSSteven Toth /* Put the cx24116/cx24123 into reset */
1690363c35fcSSteven Toth cx_write(MO_SRST_IO, 0);
169179392737SDarron Broad /* enable the cx22702 pins */
1692363c35fcSSteven Toth cx_clear(MO_GP0_IO, 0x00000004);
1693363c35fcSSteven Toth core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
169479392737SDarron Broad break;
1695363c35fcSSteven Toth }
169679392737SDarron Broad udelay(1000);
1697363c35fcSSteven Toth break;
1698363c35fcSSteven Toth
1699f271a3afSistvan_v@mailbox.hu case CX88_BOARD_WINFAST_DTV2000H_PLUS:
1700f271a3afSistvan_v@mailbox.hu /* set RF input to AIR for DVB-T (GPIO 16) */
1701f271a3afSistvan_v@mailbox.hu cx_write(MO_GP2_IO, 0x0101);
1702f271a3afSistvan_v@mailbox.hu break;
1703f271a3afSistvan_v@mailbox.hu
17046c5be74cSSteven Toth default:
17056c5be74cSSteven Toth err = -ENODEV;
17066c5be74cSSteven Toth }
17076c5be74cSSteven Toth return err;
17086c5be74cSSteven Toth }
17096c5be74cSSteven Toth
17106c5be74cSSteven Toth /* CX8802 MPEG -> mini driver - We no longer have the hardware */
cx8802_dvb_advise_release(struct cx8802_driver * drv)17116c5be74cSSteven Toth static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
17126c5be74cSSteven Toth {
17136c5be74cSSteven Toth struct cx88_core *core = drv->core;
17146c5be74cSSteven Toth int err = 0;
17157b61ba8fSMauro Carvalho Chehab
171632d83efcSHarvey Harrison dprintk(1, "%s\n", __func__);
17176c5be74cSSteven Toth
17186a59d64cSTrent Piepho switch (core->boardnr) {
17196c5be74cSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR1300:
17206c5be74cSSteven Toth /* Do Nothing, leave the cx22702 on the bus. */
17216c5be74cSSteven Toth break;
1722363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR3000:
1723363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR4000:
1724363c35fcSSteven Toth break;
17256c5be74cSSteven Toth default:
17266c5be74cSSteven Toth err = -ENODEV;
17276c5be74cSSteven Toth }
17286c5be74cSSteven Toth return err;
17296c5be74cSSteven Toth }
17306c5be74cSSteven Toth
cx8802_dvb_probe(struct cx8802_driver * drv)17316c5be74cSSteven Toth static int cx8802_dvb_probe(struct cx8802_driver *drv)
17326c5be74cSSteven Toth {
17336c5be74cSSteven Toth struct cx88_core *core = drv->core;
17346c5be74cSSteven Toth struct cx8802_dev *dev = drv->core->dvbdev;
1735cbd82441SDarron Broad int err;
17360b6b6302SHans Verkuil struct vb2_dvb_frontend *fe;
17376e0e12f1SAndy Walls int i;
17381da177e4SLinus Torvalds
173932d83efcSHarvey Harrison dprintk(1, "%s\n", __func__);
17406c5be74cSSteven Toth dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
17416a59d64cSTrent Piepho core->boardnr,
17426c5be74cSSteven Toth core->name,
17436c5be74cSSteven Toth core->pci_bus,
17446c5be74cSSteven Toth core->pci_slot);
17451da177e4SLinus Torvalds
17461da177e4SLinus Torvalds err = -ENODEV;
17476a59d64cSTrent Piepho if (!(core->board.mpeg & CX88_MPEG_DVB))
17481da177e4SLinus Torvalds goto fail_core;
17491da177e4SLinus Torvalds
1750ecf854dfSTrent Piepho /* If vp3054 isn't enabled, a stub will just return 0 */
1751fc40b261SChris Pascoe err = vp3054_i2c_probe(dev);
17527b61ba8fSMauro Carvalho Chehab if (err != 0)
17536e0e12f1SAndy Walls goto fail_core;
1754fc40b261SChris Pascoe
17551da177e4SLinus Torvalds /* dvb stuff */
175665bc2fe8SMauro Carvalho Chehab pr_info("cx2388x based DVB/ATSC card\n");
1757363c35fcSSteven Toth dev->ts_gen_cntrl = 0x0c;
1758363c35fcSSteven Toth
17596e0e12f1SAndy Walls err = cx8802_alloc_frontends(dev);
17606e0e12f1SAndy Walls if (err)
17616e0e12f1SAndy Walls goto fail_core;
1762cbd82441SDarron Broad
1763363c35fcSSteven Toth for (i = 1; i <= core->board.num_frontends; i++) {
17640b6b6302SHans Verkuil struct vb2_queue *q;
17650b6b6302SHans Verkuil
17660b6b6302SHans Verkuil fe = vb2_dvb_get_frontend(&core->dvbdev->frontends, i);
1767399426caSMauro Carvalho Chehab if (!fe) {
176865bc2fe8SMauro Carvalho Chehab pr_err("%s() failed to get frontend(%d)\n",
1769cbd82441SDarron Broad __func__, i);
1770e546b1efSWei Yongjun err = -ENODEV;
1771cbd82441SDarron Broad goto fail_probe;
1772363c35fcSSteven Toth }
17730b6b6302SHans Verkuil q = &fe->dvb.dvbq;
17740b6b6302SHans Verkuil q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
17750b6b6302SHans Verkuil q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
17760b6b6302SHans Verkuil q->gfp_flags = GFP_DMA32;
177780c2b40aSBenjamin Gaignard q->min_queued_buffers = 2;
17780b6b6302SHans Verkuil q->drv_priv = dev;
17790b6b6302SHans Verkuil q->buf_struct_size = sizeof(struct cx88_buffer);
17800b6b6302SHans Verkuil q->ops = &dvb_qops;
17810b6b6302SHans Verkuil q->mem_ops = &vb2_dma_sg_memops;
17820b6b6302SHans Verkuil q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
17830b6b6302SHans Verkuil q->lock = &core->lock;
17842bc46b3aSHans Verkuil q->dev = &dev->pci->dev;
17850b6b6302SHans Verkuil
17860b6b6302SHans Verkuil err = vb2_queue_init(q);
17870b6b6302SHans Verkuil if (err < 0)
17880b6b6302SHans Verkuil goto fail_probe;
17890b6b6302SHans Verkuil
17900b6b6302SHans Verkuil /* init struct vb2_dvb */
1791363c35fcSSteven Toth fe->dvb.name = dev->core->name;
1792363c35fcSSteven Toth }
17936e0e12f1SAndy Walls
17941da177e4SLinus Torvalds err = dvb_register(dev);
1795cbd82441SDarron Broad if (err)
1796cbd82441SDarron Broad /* frontends/adapter de-allocated in dvb_register */
179765bc2fe8SMauro Carvalho Chehab pr_err("dvb_register failed (err = %d)\n", err);
1798cbd82441SDarron Broad return err;
1799cbd82441SDarron Broad fail_probe:
18000b6b6302SHans Verkuil vb2_dvb_dealloc_frontends(&core->dvbdev->frontends);
18011da177e4SLinus Torvalds fail_core:
18021da177e4SLinus Torvalds return err;
18031da177e4SLinus Torvalds }
18041da177e4SLinus Torvalds
cx8802_dvb_remove(struct cx8802_driver * drv)18056c5be74cSSteven Toth static int cx8802_dvb_remove(struct cx8802_driver *drv)
18061da177e4SLinus Torvalds {
18070fcd488dSDarron Broad struct cx88_core *core = drv->core;
18086c5be74cSSteven Toth struct cx8802_dev *dev = drv->core->dvbdev;
1809611900c1SSteven Toth
18100fcd488dSDarron Broad dprintk(1, "%s\n", __func__);
18110fcd488dSDarron Broad
18120b6b6302SHans Verkuil vb2_dvb_unregister_bus(&dev->frontends);
18131da177e4SLinus Torvalds
1814fc40b261SChris Pascoe vp3054_i2c_remove(dev);
1815fc40b261SChris Pascoe
1816e32fadc4SMauro Carvalho Chehab core->gate_ctrl = NULL;
1817e32fadc4SMauro Carvalho Chehab
18186c5be74cSSteven Toth return 0;
18191da177e4SLinus Torvalds }
18201da177e4SLinus Torvalds
18216c5be74cSSteven Toth static struct cx8802_driver cx8802_dvb_driver = {
18226c5be74cSSteven Toth .type_id = CX88_MPEG_DVB,
18236c5be74cSSteven Toth .hw_access = CX8802_DRVCTL_SHARED,
18246c5be74cSSteven Toth .probe = cx8802_dvb_probe,
18256c5be74cSSteven Toth .remove = cx8802_dvb_remove,
18266c5be74cSSteven Toth .advise_acquire = cx8802_dvb_advise_acquire,
18276c5be74cSSteven Toth .advise_release = cx8802_dvb_advise_release,
18281da177e4SLinus Torvalds };
18291da177e4SLinus Torvalds
dvb_init(void)183031d0f845SPeter Huewe static int __init dvb_init(void)
18311da177e4SLinus Torvalds {
183265bc2fe8SMauro Carvalho Chehab pr_info("cx2388x dvb driver version %s loaded\n", CX88_VERSION);
18336c5be74cSSteven Toth return cx8802_register_driver(&cx8802_dvb_driver);
18341da177e4SLinus Torvalds }
18351da177e4SLinus Torvalds
dvb_fini(void)183631d0f845SPeter Huewe static void __exit dvb_fini(void)
18371da177e4SLinus Torvalds {
18386c5be74cSSteven Toth cx8802_unregister_driver(&cx8802_dvb_driver);
18391da177e4SLinus Torvalds }
18401da177e4SLinus Torvalds
18411da177e4SLinus Torvalds module_init(dvb_init);
18421da177e4SLinus Torvalds module_exit(dvb_fini);
1843