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 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 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 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 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 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 1310b6b6302SHans Verkuil static void stop_streaming(struct vb2_queue *q) 1320b6b6302SHans Verkuil { 1330b6b6302SHans Verkuil struct cx8802_dev *dev = q->drv_priv; 1340b6b6302SHans Verkuil struct cx88_dmaqueue *dmaq = &dev->mpegq; 1350b6b6302SHans Verkuil unsigned long flags; 1360b6b6302SHans Verkuil 1370b6b6302SHans Verkuil cx8802_cancel_buffers(dev); 1380b6b6302SHans Verkuil 1390b6b6302SHans Verkuil spin_lock_irqsave(&dev->slock, flags); 1400b6b6302SHans Verkuil while (!list_empty(&dmaq->active)) { 1410b6b6302SHans Verkuil struct cx88_buffer *buf = list_entry(dmaq->active.next, 1420b6b6302SHans Verkuil struct cx88_buffer, list); 1430b6b6302SHans Verkuil 1440b6b6302SHans Verkuil list_del(&buf->list); 1452d700715SJunghak Sung vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); 1460b6b6302SHans Verkuil } 1470b6b6302SHans Verkuil spin_unlock_irqrestore(&dev->slock, flags); 1480b6b6302SHans Verkuil } 1490b6b6302SHans Verkuil 15010accd2eSJulia Lawall static const struct vb2_ops dvb_qops = { 1510b6b6302SHans Verkuil .queue_setup = queue_setup, 1520b6b6302SHans Verkuil .buf_prepare = buffer_prepare, 1530b6b6302SHans Verkuil .buf_finish = buffer_finish, 1540b6b6302SHans Verkuil .buf_queue = buffer_queue, 1550b6b6302SHans Verkuil .wait_prepare = vb2_ops_wait_prepare, 1560b6b6302SHans Verkuil .wait_finish = vb2_ops_wait_finish, 1570b6b6302SHans Verkuil .start_streaming = start_streaming, 1580b6b6302SHans Verkuil .stop_streaming = stop_streaming, 1591da177e4SLinus Torvalds }; 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds /* ------------------------------------------------------------------ */ 16222f3f17dSMichael Krufky 16322f3f17dSMichael Krufky static int cx88_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) 16422f3f17dSMichael Krufky { 16522f3f17dSMichael Krufky struct cx8802_dev *dev = fe->dvb->priv; 16622f3f17dSMichael Krufky struct cx8802_driver *drv = NULL; 16722f3f17dSMichael Krufky int ret = 0; 168363c35fcSSteven Toth int fe_id; 169363c35fcSSteven Toth 1700b6b6302SHans Verkuil fe_id = vb2_dvb_find_frontend(&dev->frontends, fe); 171363c35fcSSteven Toth if (!fe_id) { 17265bc2fe8SMauro Carvalho Chehab pr_err("%s() No frontend found\n", __func__); 173363c35fcSSteven Toth return -EINVAL; 174363c35fcSSteven Toth } 175363c35fcSSteven Toth 1768a317a87SJonathan Nieder mutex_lock(&dev->core->lock); 17722f3f17dSMichael Krufky drv = cx8802_get_driver(dev, CX88_MPEG_DVB); 17822f3f17dSMichael Krufky if (drv) { 179363c35fcSSteven Toth if (acquire) { 180363c35fcSSteven Toth dev->frontends.active_fe_id = fe_id; 18122f3f17dSMichael Krufky ret = drv->request_acquire(drv); 182363c35fcSSteven Toth } else { 18322f3f17dSMichael Krufky ret = drv->request_release(drv); 184363c35fcSSteven Toth dev->frontends.active_fe_id = 0; 185363c35fcSSteven Toth } 18622f3f17dSMichael Krufky } 1871fe70e96SJonathan Nieder mutex_unlock(&dev->core->lock); 18822f3f17dSMichael Krufky 18922f3f17dSMichael Krufky return ret; 19022f3f17dSMichael Krufky } 19122f3f17dSMichael Krufky 192e32fadc4SMauro Carvalho Chehab static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open) 193e32fadc4SMauro Carvalho Chehab { 1940b6b6302SHans Verkuil struct vb2_dvb_frontends *f; 1950b6b6302SHans Verkuil struct vb2_dvb_frontend *fe; 196e32fadc4SMauro Carvalho Chehab 197e32fadc4SMauro Carvalho Chehab if (!core->dvbdev) 198e32fadc4SMauro Carvalho Chehab return; 199e32fadc4SMauro Carvalho Chehab 200e32fadc4SMauro Carvalho Chehab f = &core->dvbdev->frontends; 201e32fadc4SMauro Carvalho Chehab 202e32fadc4SMauro Carvalho Chehab if (!f) 203e32fadc4SMauro Carvalho Chehab return; 204e32fadc4SMauro Carvalho Chehab 205e32fadc4SMauro Carvalho Chehab if (f->gate <= 1) /* undefined or fe0 */ 2060b6b6302SHans Verkuil fe = vb2_dvb_get_frontend(f, 1); 207e32fadc4SMauro Carvalho Chehab else 2080b6b6302SHans Verkuil fe = vb2_dvb_get_frontend(f, f->gate); 209e32fadc4SMauro Carvalho Chehab 210e32fadc4SMauro Carvalho Chehab if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) 211e32fadc4SMauro Carvalho Chehab fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); 212e32fadc4SMauro Carvalho Chehab } 213e32fadc4SMauro Carvalho Chehab 21422f3f17dSMichael Krufky /* ------------------------------------------------------------------ */ 21522f3f17dSMichael Krufky 2163d7d027aSChris Pascoe static int dvico_fusionhdtv_demod_init(struct dvb_frontend *fe) 2171da177e4SLinus Torvalds { 2182e4e98e7Slawrence rust static const u8 clock_config[] = { CLOCK_CTL, 0x38, 0x39 }; 2192e4e98e7Slawrence rust static const u8 reset[] = { RESET, 0x80 }; 2202e4e98e7Slawrence rust static const u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; 2212e4e98e7Slawrence rust static const u8 agc_cfg[] = { AGC_TARGET, 0x24, 0x20 }; 2222e4e98e7Slawrence rust static const u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 }; 2232e4e98e7Slawrence rust static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds mt352_write(fe, clock_config, sizeof(clock_config)); 2261da177e4SLinus Torvalds udelay(200); 2271da177e4SLinus Torvalds mt352_write(fe, reset, sizeof(reset)); 2281da177e4SLinus Torvalds mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 2291da177e4SLinus Torvalds 2301da177e4SLinus Torvalds mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 2311da177e4SLinus Torvalds mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); 2321da177e4SLinus Torvalds mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 2331da177e4SLinus Torvalds return 0; 2341da177e4SLinus Torvalds } 2351da177e4SLinus Torvalds 23643eabb4eSChris Pascoe static int dvico_dual_demod_init(struct dvb_frontend *fe) 23743eabb4eSChris Pascoe { 2382e4e98e7Slawrence rust static const u8 clock_config[] = { CLOCK_CTL, 0x38, 0x38 }; 2392e4e98e7Slawrence rust static const u8 reset[] = { RESET, 0x80 }; 2402e4e98e7Slawrence rust static const u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; 2412e4e98e7Slawrence rust static const u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 }; 2422e4e98e7Slawrence rust static const u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 }; 2432e4e98e7Slawrence rust static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 24443eabb4eSChris Pascoe 24543eabb4eSChris Pascoe mt352_write(fe, clock_config, sizeof(clock_config)); 24643eabb4eSChris Pascoe udelay(200); 24743eabb4eSChris Pascoe mt352_write(fe, reset, sizeof(reset)); 24843eabb4eSChris Pascoe mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 24943eabb4eSChris Pascoe 25043eabb4eSChris Pascoe mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 25143eabb4eSChris Pascoe mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); 25243eabb4eSChris Pascoe mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 25343eabb4eSChris Pascoe 25443eabb4eSChris Pascoe return 0; 25543eabb4eSChris Pascoe } 25643eabb4eSChris Pascoe 2571da177e4SLinus Torvalds static int dntv_live_dvbt_demod_init(struct dvb_frontend *fe) 2581da177e4SLinus Torvalds { 2592e4e98e7Slawrence rust static const u8 clock_config[] = { 0x89, 0x38, 0x39 }; 2602e4e98e7Slawrence rust static const u8 reset[] = { 0x50, 0x80 }; 2612e4e98e7Slawrence rust static const u8 adc_ctl_1_cfg[] = { 0x8E, 0x40 }; 2622e4e98e7Slawrence rust static const u8 agc_cfg[] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 2631da177e4SLinus Torvalds 0x00, 0xFF, 0x00, 0x40, 0x40 }; 2642e4e98e7Slawrence rust static const u8 dntv_extra[] = { 0xB5, 0x7A }; 2652e4e98e7Slawrence rust static const u8 capt_range_cfg[] = { 0x75, 0x32 }; 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds mt352_write(fe, clock_config, sizeof(clock_config)); 2681da177e4SLinus Torvalds udelay(2000); 2691da177e4SLinus Torvalds mt352_write(fe, reset, sizeof(reset)); 2701da177e4SLinus Torvalds mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 2731da177e4SLinus Torvalds udelay(2000); 2741da177e4SLinus Torvalds mt352_write(fe, dntv_extra, sizeof(dntv_extra)); 2751da177e4SLinus Torvalds mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 2761da177e4SLinus Torvalds 2771da177e4SLinus Torvalds return 0; 2781da177e4SLinus Torvalds } 2791da177e4SLinus Torvalds 2802e4e98e7Slawrence rust static const struct mt352_config dvico_fusionhdtv = { 281f7b54b10SMichael Krufky .demod_address = 0x0f, 2823d7d027aSChris Pascoe .demod_init = dvico_fusionhdtv_demod_init, 2831da177e4SLinus Torvalds }; 2841da177e4SLinus Torvalds 2852e4e98e7Slawrence rust static const struct mt352_config dntv_live_dvbt_config = { 2861da177e4SLinus Torvalds .demod_address = 0x0f, 2871da177e4SLinus Torvalds .demod_init = dntv_live_dvbt_demod_init, 2881da177e4SLinus Torvalds }; 289fc40b261SChris Pascoe 2902e4e98e7Slawrence rust static const struct mt352_config dvico_fusionhdtv_dual = { 291f7b54b10SMichael Krufky .demod_address = 0x0f, 29243eabb4eSChris Pascoe .demod_init = dvico_dual_demod_init, 29343eabb4eSChris Pascoe }; 29443eabb4eSChris Pascoe 2952e4e98e7Slawrence rust static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = { 29670101a27SStephan Wienczny .demod_address = (0x1e >> 1), 29770101a27SStephan Wienczny .no_tuner = 1, 29870101a27SStephan Wienczny .if2 = 45600, 29970101a27SStephan Wienczny }; 30070101a27SStephan Wienczny 3010244fd78SBhumika Goyal static const struct mb86a16_config twinhan_vp1027 = { 302111ac84aSSergey Ivanov .demod_address = 0x08, 303111ac84aSSergey Ivanov }; 304111ac84aSSergey Ivanov 3057b34be71SPeter Senna Tschudin #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054) 3063d7d027aSChris Pascoe static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend *fe) 3073d7d027aSChris Pascoe { 3082e4e98e7Slawrence rust static const u8 clock_config[] = { 0x89, 0x38, 0x38 }; 3092e4e98e7Slawrence rust static const u8 reset[] = { 0x50, 0x80 }; 3102e4e98e7Slawrence rust static const u8 adc_ctl_1_cfg[] = { 0x8E, 0x40 }; 3112e4e98e7Slawrence rust static const u8 agc_cfg[] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, 3123d7d027aSChris Pascoe 0x00, 0xFF, 0x00, 0x40, 0x40 }; 3132e4e98e7Slawrence rust static const u8 dntv_extra[] = { 0xB5, 0x7A }; 3142e4e98e7Slawrence rust static const u8 capt_range_cfg[] = { 0x75, 0x32 }; 3153d7d027aSChris Pascoe 3163d7d027aSChris Pascoe mt352_write(fe, clock_config, sizeof(clock_config)); 3173d7d027aSChris Pascoe udelay(2000); 3183d7d027aSChris Pascoe mt352_write(fe, reset, sizeof(reset)); 3193d7d027aSChris Pascoe mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 3203d7d027aSChris Pascoe 3213d7d027aSChris Pascoe mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 3223d7d027aSChris Pascoe udelay(2000); 3233d7d027aSChris Pascoe mt352_write(fe, dntv_extra, sizeof(dntv_extra)); 3243d7d027aSChris Pascoe mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 3253d7d027aSChris Pascoe 3263d7d027aSChris Pascoe return 0; 3273d7d027aSChris Pascoe } 3283d7d027aSChris Pascoe 3292e4e98e7Slawrence rust static const struct mt352_config dntv_live_dvbt_pro_config = { 330fc40b261SChris Pascoe .demod_address = 0x0f, 331fc40b261SChris Pascoe .no_tuner = 1, 3323d7d027aSChris Pascoe .demod_init = dntv_live_dvbt_pro_demod_init, 333fc40b261SChris Pascoe }; 334fc40b261SChris Pascoe #endif 3351da177e4SLinus Torvalds 3362e4e98e7Slawrence rust static const struct zl10353_config dvico_fusionhdtv_hybrid = { 337f7b54b10SMichael Krufky .demod_address = 0x0f, 338f54376e2SAndrew de Quincey .no_tuner = 1, 339780dfef3SChris Pascoe }; 340780dfef3SChris Pascoe 3412e4e98e7Slawrence rust static const struct zl10353_config dvico_fusionhdtv_xc3028 = { 342b3fb91d2SChris Pascoe .demod_address = 0x0f, 343b3fb91d2SChris Pascoe .if2 = 45600, 344b3fb91d2SChris Pascoe .no_tuner = 1, 345b3fb91d2SChris Pascoe }; 346b3fb91d2SChris Pascoe 3472e4e98e7Slawrence rust static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = { 348b3fb91d2SChris Pascoe .demod_address = 0x0f, 349b3fb91d2SChris Pascoe .if2 = 4560, 350b3fb91d2SChris Pascoe .no_tuner = 1, 351b3fb91d2SChris Pascoe .demod_init = dvico_fusionhdtv_demod_init, 352b3fb91d2SChris Pascoe }; 353b3fb91d2SChris Pascoe 3542e4e98e7Slawrence rust static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { 355f7b54b10SMichael Krufky .demod_address = 0x0f, 356780dfef3SChris Pascoe }; 357780dfef3SChris Pascoe 3582e4e98e7Slawrence rust static const struct cx22702_config connexant_refboard_config = { 3591da177e4SLinus Torvalds .demod_address = 0x43, 36038d84c3bSPatrick Boettcher .output_mode = CX22702_SERIAL_OUTPUT, 3611da177e4SLinus Torvalds }; 3621da177e4SLinus Torvalds 3632e4e98e7Slawrence rust static const struct cx22702_config hauppauge_hvr_config = { 364aa481a65SSteven Toth .demod_address = 0x63, 365aa481a65SSteven Toth .output_mode = CX22702_SERIAL_OUTPUT, 366aa481a65SSteven Toth }; 3671da177e4SLinus Torvalds 3684a390558SMichael Krufky static int or51132_set_ts_param(struct dvb_frontend *fe, int is_punctured) 3691da177e4SLinus Torvalds { 3701da177e4SLinus Torvalds struct cx8802_dev *dev = fe->dvb->priv; 3717b61ba8fSMauro Carvalho Chehab 3721da177e4SLinus Torvalds dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; 3731da177e4SLinus Torvalds return 0; 3741da177e4SLinus Torvalds } 3751da177e4SLinus Torvalds 3762e4e98e7Slawrence rust static const struct or51132_config pchdtv_hd3000 = { 3771da177e4SLinus Torvalds .demod_address = 0x15, 3781da177e4SLinus Torvalds .set_ts_params = or51132_set_ts_param, 3791da177e4SLinus Torvalds }; 3801da177e4SLinus Torvalds 3816ddcc919SMichael Krufky static int lgdt330x_pll_rf_set(struct dvb_frontend *fe, int index) 3820ccef6dbSMichael Krufky { 3830ccef6dbSMichael Krufky struct cx8802_dev *dev = fe->dvb->priv; 3840ccef6dbSMichael Krufky struct cx88_core *core = dev->core; 3850ccef6dbSMichael Krufky 38632d83efcSHarvey Harrison dprintk(1, "%s: index = %d\n", __func__, index); 3870ccef6dbSMichael Krufky if (index == 0) 3880ccef6dbSMichael Krufky cx_clear(MO_GP0_IO, 8); 3890ccef6dbSMichael Krufky else 3900ccef6dbSMichael Krufky cx_set(MO_GP0_IO, 8); 3910ccef6dbSMichael Krufky return 0; 3920ccef6dbSMichael Krufky } 3930ccef6dbSMichael Krufky 3946ddcc919SMichael Krufky static int lgdt330x_set_ts_param(struct dvb_frontend *fe, int is_punctured) 395f1798495SMichael Krufky { 396f1798495SMichael Krufky struct cx8802_dev *dev = fe->dvb->priv; 3977b61ba8fSMauro Carvalho Chehab 398f1798495SMichael Krufky if (is_punctured) 399f1798495SMichael Krufky dev->ts_gen_cntrl |= 0x04; 400f1798495SMichael Krufky else 401f1798495SMichael Krufky dev->ts_gen_cntrl &= ~0x04; 402f1798495SMichael Krufky return 0; 403f1798495SMichael Krufky } 404f1798495SMichael Krufky 4056ddcc919SMichael Krufky static struct lgdt330x_config fusionhdtv_3_gold = { 4061963c907SMichael Krufky .demod_chip = LGDT3302, 4071963c907SMichael Krufky .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ 4086ddcc919SMichael Krufky .set_ts_params = lgdt330x_set_ts_param, 4090d723c09SMichael Krufky }; 410e52e98a7SMauro Carvalho Chehab 4112e4e98e7Slawrence rust static const struct lgdt330x_config fusionhdtv_5_gold = { 412e52e98a7SMauro Carvalho Chehab .demod_chip = LGDT3303, 413e52e98a7SMauro Carvalho Chehab .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ 414e52e98a7SMauro Carvalho Chehab .set_ts_params = lgdt330x_set_ts_param, 415e52e98a7SMauro Carvalho Chehab }; 416da215d22SRusty Scott 4172e4e98e7Slawrence rust static const struct lgdt330x_config pchdtv_hd5500 = { 418da215d22SRusty Scott .demod_chip = LGDT3303, 419da215d22SRusty Scott .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ 420da215d22SRusty Scott .set_ts_params = lgdt330x_set_ts_param, 421da215d22SRusty Scott }; 422f1798495SMichael Krufky 4234a390558SMichael Krufky static int nxt200x_set_ts_param(struct dvb_frontend *fe, int is_punctured) 424fde6d31eSKirk Lapray { 425fde6d31eSKirk Lapray struct cx8802_dev *dev = fe->dvb->priv; 4267b61ba8fSMauro Carvalho Chehab 427fde6d31eSKirk Lapray dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; 428fde6d31eSKirk Lapray return 0; 429fde6d31eSKirk Lapray } 430fde6d31eSKirk Lapray 4312e4e98e7Slawrence rust static const struct nxt200x_config ati_hdtvwonder = { 432fde6d31eSKirk Lapray .demod_address = 0x0a, 433fde6d31eSKirk Lapray .set_ts_params = nxt200x_set_ts_param, 434fde6d31eSKirk Lapray }; 435fde6d31eSKirk Lapray 4360fa14aa6SSteven Toth static int cx24123_set_ts_param(struct dvb_frontend *fe, 4370fa14aa6SSteven Toth int is_punctured) 4380fa14aa6SSteven Toth { 4390fa14aa6SSteven Toth struct cx8802_dev *dev = fe->dvb->priv; 4407b61ba8fSMauro Carvalho Chehab 441f7b54b10SMichael Krufky dev->ts_gen_cntrl = 0x02; 4420fa14aa6SSteven Toth return 0; 4430fa14aa6SSteven Toth } 4440fa14aa6SSteven Toth 445f7b54b10SMichael Krufky static int kworld_dvbs_100_set_voltage(struct dvb_frontend *fe, 4460df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage) 4470e0351e3SVadim Catana { 4480e0351e3SVadim Catana struct cx8802_dev *dev = fe->dvb->priv; 4490e0351e3SVadim Catana struct cx88_core *core = dev->core; 4500e0351e3SVadim Catana 4514a390558SMichael Krufky if (voltage == SEC_VOLTAGE_OFF) 452f7b54b10SMichael Krufky cx_write(MO_GP0_IO, 0x000006fb); 4534a390558SMichael Krufky else 454cd20ca9fSAndrew de Quincey cx_write(MO_GP0_IO, 0x000006f9); 455cd20ca9fSAndrew de Quincey 456cd20ca9fSAndrew de Quincey if (core->prev_set_voltage) 457cd20ca9fSAndrew de Quincey return core->prev_set_voltage(fe, voltage); 458cd20ca9fSAndrew de Quincey return 0; 4590e0351e3SVadim Catana } 4600e0351e3SVadim Catana 461f7b54b10SMichael Krufky static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, 4620df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage) 463c02a34f4SSaqeb Akhter { 464c02a34f4SSaqeb Akhter struct cx8802_dev *dev = fe->dvb->priv; 465c02a34f4SSaqeb Akhter struct cx88_core *core = dev->core; 466c02a34f4SSaqeb Akhter 467c02a34f4SSaqeb Akhter if (voltage == SEC_VOLTAGE_OFF) { 468c02a34f4SSaqeb Akhter dprintk(1, "LNB Voltage OFF\n"); 469c02a34f4SSaqeb Akhter cx_write(MO_GP0_IO, 0x0000efff); 470c02a34f4SSaqeb Akhter } 471c02a34f4SSaqeb Akhter 472c02a34f4SSaqeb Akhter if (core->prev_set_voltage) 473c02a34f4SSaqeb Akhter return core->prev_set_voltage(fe, voltage); 474c02a34f4SSaqeb Akhter return 0; 475c02a34f4SSaqeb Akhter } 476c02a34f4SSaqeb Akhter 477af832623SIgor M. Liplianin static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, 4780df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage) 479af832623SIgor M. Liplianin { 480af832623SIgor M. Liplianin struct cx8802_dev *dev = fe->dvb->priv; 481af832623SIgor M. Liplianin struct cx88_core *core = dev->core; 482af832623SIgor M. Liplianin 483ad5f74c0SIgor M. Liplianin cx_set(MO_GP0_IO, 0x6040); 484af832623SIgor M. Liplianin switch (voltage) { 485af832623SIgor M. Liplianin case SEC_VOLTAGE_13: 486ad5f74c0SIgor M. Liplianin cx_clear(MO_GP0_IO, 0x20); 487af832623SIgor M. Liplianin break; 488af832623SIgor M. Liplianin case SEC_VOLTAGE_18: 489ad5f74c0SIgor M. Liplianin cx_set(MO_GP0_IO, 0x20); 490af832623SIgor M. Liplianin break; 491af832623SIgor M. Liplianin case SEC_VOLTAGE_OFF: 492ad5f74c0SIgor M. Liplianin cx_clear(MO_GP0_IO, 0x20); 493af832623SIgor M. Liplianin break; 494af832623SIgor M. Liplianin } 495af832623SIgor M. Liplianin 496af832623SIgor M. Liplianin if (core->prev_set_voltage) 497af832623SIgor M. Liplianin return core->prev_set_voltage(fe, voltage); 498af832623SIgor M. Liplianin return 0; 499af832623SIgor M. Liplianin } 500af832623SIgor M. Liplianin 501111ac84aSSergey Ivanov static int vp1027_set_voltage(struct dvb_frontend *fe, 5020df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage) 503111ac84aSSergey Ivanov { 504111ac84aSSergey Ivanov struct cx8802_dev *dev = fe->dvb->priv; 505111ac84aSSergey Ivanov struct cx88_core *core = dev->core; 506111ac84aSSergey Ivanov 507111ac84aSSergey Ivanov switch (voltage) { 508111ac84aSSergey Ivanov case SEC_VOLTAGE_13: 509111ac84aSSergey Ivanov dprintk(1, "LNB SEC Voltage=13\n"); 510111ac84aSSergey Ivanov cx_write(MO_GP0_IO, 0x00001220); 511111ac84aSSergey Ivanov break; 512111ac84aSSergey Ivanov case SEC_VOLTAGE_18: 513111ac84aSSergey Ivanov dprintk(1, "LNB SEC Voltage=18\n"); 514111ac84aSSergey Ivanov cx_write(MO_GP0_IO, 0x00001222); 515111ac84aSSergey Ivanov break; 516111ac84aSSergey Ivanov case SEC_VOLTAGE_OFF: 517111ac84aSSergey Ivanov dprintk(1, "LNB Voltage OFF\n"); 518111ac84aSSergey Ivanov cx_write(MO_GP0_IO, 0x00001230); 519111ac84aSSergey Ivanov break; 520111ac84aSSergey Ivanov } 521111ac84aSSergey Ivanov 522111ac84aSSergey Ivanov if (core->prev_set_voltage) 523111ac84aSSergey Ivanov return core->prev_set_voltage(fe, voltage); 524111ac84aSSergey Ivanov return 0; 525111ac84aSSergey Ivanov } 526111ac84aSSergey Ivanov 5272e4e98e7Slawrence rust static const struct cx24123_config geniatech_dvbs_config = { 528c02a34f4SSaqeb Akhter .demod_address = 0x55, 529c02a34f4SSaqeb Akhter .set_ts_params = cx24123_set_ts_param, 530c02a34f4SSaqeb Akhter }; 531c02a34f4SSaqeb Akhter 5322e4e98e7Slawrence rust static const struct cx24123_config hauppauge_novas_config = { 5330fa14aa6SSteven Toth .demod_address = 0x55, 5340fa14aa6SSteven Toth .set_ts_params = cx24123_set_ts_param, 5350fa14aa6SSteven Toth }; 5360e0351e3SVadim Catana 5372e4e98e7Slawrence rust static const struct cx24123_config kworld_dvbs_100_config = { 5380e0351e3SVadim Catana .demod_address = 0x15, 5390e0351e3SVadim Catana .set_ts_params = cx24123_set_ts_param, 540ef76856dSYeasah Pell .lnb_polarity = 1, 5410e0351e3SVadim Catana }; 5420fa14aa6SSteven Toth 5432e4e98e7Slawrence rust static const struct s5h1409_config pinnacle_pctv_hd_800i_config = { 54460464da8SSteven Toth .demod_address = 0x32 >> 1, 54560464da8SSteven Toth .output_mode = S5H1409_PARALLEL_OUTPUT, 54660464da8SSteven Toth .gpio = S5H1409_GPIO_ON, 54760464da8SSteven Toth .qam_if = 44000, 54860464da8SSteven Toth .inversion = S5H1409_INVERSION_OFF, 54960464da8SSteven Toth .status_mode = S5H1409_DEMODLOCKING, 550ad05ff09SMauro Carvalho Chehab .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK, 55160464da8SSteven Toth }; 55260464da8SSteven Toth 5532e4e98e7Slawrence rust static const struct s5h1409_config dvico_hdtv5_pci_nano_config = { 5545c00fac0SSteven Toth .demod_address = 0x32 >> 1, 5555c00fac0SSteven Toth .output_mode = S5H1409_SERIAL_OUTPUT, 5565c00fac0SSteven Toth .gpio = S5H1409_GPIO_OFF, 5575c00fac0SSteven Toth .inversion = S5H1409_INVERSION_OFF, 5585c00fac0SSteven Toth .status_mode = S5H1409_DEMODLOCKING, 559ad05ff09SMauro Carvalho Chehab .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, 5605c00fac0SSteven Toth }; 5615c00fac0SSteven Toth 5622e4e98e7Slawrence rust static const struct s5h1409_config kworld_atsc_120_config = { 56399e09eacSMauro Carvalho Chehab .demod_address = 0x32 >> 1, 56499e09eacSMauro Carvalho Chehab .output_mode = S5H1409_SERIAL_OUTPUT, 56599e09eacSMauro Carvalho Chehab .gpio = S5H1409_GPIO_OFF, 56699e09eacSMauro Carvalho Chehab .inversion = S5H1409_INVERSION_OFF, 56799e09eacSMauro Carvalho Chehab .status_mode = S5H1409_DEMODLOCKING, 568ad05ff09SMauro Carvalho Chehab .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, 56999e09eacSMauro Carvalho Chehab }; 57099e09eacSMauro Carvalho Chehab 5712e4e98e7Slawrence rust static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { 57260464da8SSteven Toth .i2c_address = 0x64, 57360464da8SSteven Toth .if_khz = 5380, 57460464da8SSteven Toth }; 57560464da8SSteven Toth 5762e4e98e7Slawrence rust static const struct zl10353_config cx88_pinnacle_hybrid_pctv = { 5773f6014fcSStéphane Voltz .demod_address = (0x1e >> 1), 5783f6014fcSStéphane Voltz .no_tuner = 1, 5793f6014fcSStéphane Voltz .if2 = 45600, 5803f6014fcSStéphane Voltz }; 5813f6014fcSStéphane Voltz 5822e4e98e7Slawrence rust static const struct zl10353_config cx88_geniatech_x8000_mt = { 5839507901eSMauro Carvalho Chehab .demod_address = (0x1e >> 1), 5849507901eSMauro Carvalho Chehab .no_tuner = 1, 58511db9069SDevin Heitmueller .disable_i2c_gate_ctrl = 1, 5869507901eSMauro Carvalho Chehab }; 5879507901eSMauro Carvalho Chehab 5882e4e98e7Slawrence rust static const struct s5h1411_config dvico_fusionhdtv7_config = { 589d893d5dcSSteven Toth .output_mode = S5H1411_SERIAL_OUTPUT, 590d893d5dcSSteven Toth .gpio = S5H1411_GPIO_ON, 591ad05ff09SMauro Carvalho Chehab .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, 592d893d5dcSSteven Toth .qam_if = S5H1411_IF_44000, 593d893d5dcSSteven Toth .vsb_if = S5H1411_IF_44000, 594d893d5dcSSteven Toth .inversion = S5H1411_INVERSION_OFF, 595d893d5dcSSteven Toth .status_mode = S5H1411_DEMODLOCKING 596d893d5dcSSteven Toth }; 597d893d5dcSSteven Toth 5982e4e98e7Slawrence rust static const struct xc5000_config dvico_fusionhdtv7_tuner_config = { 599d893d5dcSSteven Toth .i2c_address = 0xc2 >> 1, 600d893d5dcSSteven Toth .if_khz = 5380, 601d893d5dcSSteven Toth }; 602d893d5dcSSteven Toth 60323fb348dSMauro Carvalho Chehab static int attach_xc3028(u8 addr, struct cx8802_dev *dev) 60423fb348dSMauro Carvalho Chehab { 60523fb348dSMauro Carvalho Chehab struct dvb_frontend *fe; 6060b6b6302SHans Verkuil struct vb2_dvb_frontend *fe0 = NULL; 60799e09eacSMauro Carvalho Chehab struct xc2028_ctrl ctl; 60823fb348dSMauro Carvalho Chehab struct xc2028_config cfg = { 60923fb348dSMauro Carvalho Chehab .i2c_adap = &dev->core->i2c_adap, 61023fb348dSMauro Carvalho Chehab .i2c_addr = addr, 61199e09eacSMauro Carvalho Chehab .ctrl = &ctl, 61223fb348dSMauro Carvalho Chehab }; 61323fb348dSMauro Carvalho Chehab 614363c35fcSSteven Toth /* Get the first frontend */ 6150b6b6302SHans Verkuil fe0 = vb2_dvb_get_frontend(&dev->frontends, 1); 616363c35fcSSteven Toth if (!fe0) 617363c35fcSSteven Toth return -EINVAL; 618363c35fcSSteven Toth 619363c35fcSSteven Toth if (!fe0->dvb.frontend) { 62065bc2fe8SMauro Carvalho Chehab pr_err("dvb frontend not attached. Can't attach xc3028\n"); 621ddd5441dSMauro Carvalho Chehab return -EINVAL; 622ddd5441dSMauro Carvalho Chehab } 623ddd5441dSMauro Carvalho Chehab 62499e09eacSMauro Carvalho Chehab /* 62599e09eacSMauro Carvalho Chehab * Some xc3028 devices may be hidden by an I2C gate. This is known 62699e09eacSMauro Carvalho Chehab * to happen with some s5h1409-based devices. 62799e09eacSMauro Carvalho Chehab * Now that I2C gate is open, sets up xc3028 configuration 62899e09eacSMauro Carvalho Chehab */ 62999e09eacSMauro Carvalho Chehab cx88_setup_xc3028(dev->core, &ctl); 63099e09eacSMauro Carvalho Chehab 631363c35fcSSteven Toth fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); 63223fb348dSMauro Carvalho Chehab if (!fe) { 63365bc2fe8SMauro Carvalho Chehab pr_err("xc3028 attach failed\n"); 634363c35fcSSteven Toth dvb_frontend_detach(fe0->dvb.frontend); 635363c35fcSSteven Toth dvb_unregister_frontend(fe0->dvb.frontend); 636363c35fcSSteven Toth fe0->dvb.frontend = NULL; 63723fb348dSMauro Carvalho Chehab return -EINVAL; 63823fb348dSMauro Carvalho Chehab } 63923fb348dSMauro Carvalho Chehab 64065bc2fe8SMauro Carvalho Chehab pr_info("xc3028 attached\n"); 64123fb348dSMauro Carvalho Chehab 64223fb348dSMauro Carvalho Chehab return 0; 64323fb348dSMauro Carvalho Chehab } 6449507901eSMauro Carvalho Chehab 645c21973e8Sistvan_v@mailbox.hu static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg) 646c21973e8Sistvan_v@mailbox.hu { 647c21973e8Sistvan_v@mailbox.hu struct dvb_frontend *fe; 6480b6b6302SHans Verkuil struct vb2_dvb_frontend *fe0 = NULL; 649c21973e8Sistvan_v@mailbox.hu 650c21973e8Sistvan_v@mailbox.hu /* Get the first frontend */ 6510b6b6302SHans Verkuil fe0 = vb2_dvb_get_frontend(&dev->frontends, 1); 652c21973e8Sistvan_v@mailbox.hu if (!fe0) 653c21973e8Sistvan_v@mailbox.hu return -EINVAL; 654c21973e8Sistvan_v@mailbox.hu 655c21973e8Sistvan_v@mailbox.hu if (!fe0->dvb.frontend) { 65665bc2fe8SMauro Carvalho Chehab pr_err("dvb frontend not attached. Can't attach xc4000\n"); 657c21973e8Sistvan_v@mailbox.hu return -EINVAL; 658c21973e8Sistvan_v@mailbox.hu } 659c21973e8Sistvan_v@mailbox.hu 660c21973e8Sistvan_v@mailbox.hu fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->core->i2c_adap, 661c21973e8Sistvan_v@mailbox.hu cfg); 662c21973e8Sistvan_v@mailbox.hu if (!fe) { 66365bc2fe8SMauro Carvalho Chehab pr_err("xc4000 attach failed\n"); 664c21973e8Sistvan_v@mailbox.hu dvb_frontend_detach(fe0->dvb.frontend); 665c21973e8Sistvan_v@mailbox.hu dvb_unregister_frontend(fe0->dvb.frontend); 666c21973e8Sistvan_v@mailbox.hu fe0->dvb.frontend = NULL; 667c21973e8Sistvan_v@mailbox.hu return -EINVAL; 668c21973e8Sistvan_v@mailbox.hu } 669c21973e8Sistvan_v@mailbox.hu 67065bc2fe8SMauro Carvalho Chehab pr_info("xc4000 attached\n"); 671c21973e8Sistvan_v@mailbox.hu 672c21973e8Sistvan_v@mailbox.hu return 0; 673c21973e8Sistvan_v@mailbox.hu } 674c21973e8Sistvan_v@mailbox.hu 6755bd1b663SSteven Toth static int cx24116_set_ts_param(struct dvb_frontend *fe, 6765bd1b663SSteven Toth int is_punctured) 6775bd1b663SSteven Toth { 6785bd1b663SSteven Toth struct cx8802_dev *dev = fe->dvb->priv; 6797b61ba8fSMauro Carvalho Chehab 6805bd1b663SSteven Toth dev->ts_gen_cntrl = 0x2; 6815bd1b663SSteven Toth 6825bd1b663SSteven Toth return 0; 6835bd1b663SSteven Toth } 6845bd1b663SSteven Toth 685b699c271SIgor M. Liplianin static int stv0900_set_ts_param(struct dvb_frontend *fe, 686b699c271SIgor M. Liplianin int is_punctured) 687b699c271SIgor M. Liplianin { 688b699c271SIgor M. Liplianin struct cx8802_dev *dev = fe->dvb->priv; 6897b61ba8fSMauro Carvalho Chehab 690b699c271SIgor M. Liplianin dev->ts_gen_cntrl = 0; 691b699c271SIgor M. Liplianin 692b699c271SIgor M. Liplianin return 0; 693b699c271SIgor M. Liplianin } 694b699c271SIgor M. Liplianin 6955bd1b663SSteven Toth static int cx24116_reset_device(struct dvb_frontend *fe) 6965bd1b663SSteven Toth { 6975bd1b663SSteven Toth struct cx8802_dev *dev = fe->dvb->priv; 6985bd1b663SSteven Toth struct cx88_core *core = dev->core; 6995bd1b663SSteven Toth 7005bd1b663SSteven Toth /* Reset the part */ 701363c35fcSSteven Toth /* Put the cx24116 into reset */ 7025bd1b663SSteven Toth cx_write(MO_SRST_IO, 0); 703399426caSMauro Carvalho Chehab usleep_range(10000, 20000); 704363c35fcSSteven Toth /* Take the cx24116 out of reset */ 7055bd1b663SSteven Toth cx_write(MO_SRST_IO, 1); 706399426caSMauro Carvalho Chehab usleep_range(10000, 20000); 7075bd1b663SSteven Toth 7085bd1b663SSteven Toth return 0; 7095bd1b663SSteven Toth } 7105bd1b663SSteven Toth 7112e4e98e7Slawrence rust static const struct cx24116_config hauppauge_hvr4000_config = { 7125bd1b663SSteven Toth .demod_address = 0x05, 7135bd1b663SSteven Toth .set_ts_params = cx24116_set_ts_param, 7145bd1b663SSteven Toth .reset_device = cx24116_reset_device, 7155bd1b663SSteven Toth }; 7165bd1b663SSteven Toth 7172e4e98e7Slawrence rust static const struct cx24116_config tevii_s460_config = { 718af832623SIgor M. Liplianin .demod_address = 0x55, 719af832623SIgor M. Liplianin .set_ts_params = cx24116_set_ts_param, 720af832623SIgor M. Liplianin .reset_device = cx24116_reset_device, 721af832623SIgor M. Liplianin }; 722af832623SIgor M. Liplianin 7230cb73639SIgor M. Liplianin static int ds3000_set_ts_param(struct dvb_frontend *fe, 7240cb73639SIgor M. Liplianin int is_punctured) 7250cb73639SIgor M. Liplianin { 7260cb73639SIgor M. Liplianin struct cx8802_dev *dev = fe->dvb->priv; 7277b61ba8fSMauro Carvalho Chehab 7280cb73639SIgor M. Liplianin dev->ts_gen_cntrl = 4; 7290cb73639SIgor M. Liplianin 7300cb73639SIgor M. Liplianin return 0; 7310cb73639SIgor M. Liplianin } 7320cb73639SIgor M. Liplianin 7330cb73639SIgor M. Liplianin static struct ds3000_config tevii_ds3000_config = { 7340cb73639SIgor M. Liplianin .demod_address = 0x68, 7350cb73639SIgor M. Liplianin .set_ts_params = ds3000_set_ts_param, 7360cb73639SIgor M. Liplianin }; 7370cb73639SIgor M. Liplianin 73873f0af44SKonstantin Dimitrov static struct ts2020_config tevii_ts2020_config = { 73973f0af44SKonstantin Dimitrov .tuner_address = 0x60, 740b858c331SIgor M. Liplianin .clk_out_div = 1, 74173f0af44SKonstantin Dimitrov }; 74273f0af44SKonstantin Dimitrov 7432e4e98e7Slawrence rust static const struct stv0900_config prof_7301_stv0900_config = { 744b699c271SIgor M. Liplianin .demod_address = 0x6a, 745b699c271SIgor M. Liplianin /* demod_mode = 0,*/ 746b699c271SIgor M. Liplianin .xtal = 27000000, 747b699c271SIgor M. Liplianin .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 748b699c271SIgor M. Liplianin .diseqc_mode = 2,/* 2/3 PWM */ 749b699c271SIgor M. Liplianin .tun1_maddress = 0,/* 0x60 */ 750b699c271SIgor M. Liplianin .tun1_adc = 0,/* 2 Vpp */ 751b699c271SIgor M. Liplianin .path1_mode = 3, 752b699c271SIgor M. Liplianin .set_ts_params = stv0900_set_ts_param, 753b699c271SIgor M. Liplianin }; 754b699c271SIgor M. Liplianin 7552e4e98e7Slawrence rust static const struct stb6100_config prof_7301_stb6100_config = { 756b699c271SIgor M. Liplianin .tuner_address = 0x60, 757b699c271SIgor M. Liplianin .refclock = 27000000, 758b699c271SIgor M. Liplianin }; 759b699c271SIgor M. Liplianin 7602e4e98e7Slawrence rust static const struct stv0299_config tevii_tuner_sharp_config = { 761e4aab64cSIgor M. Liplianin .demod_address = 0x68, 762d4305c68SIgor M. Liplianin .inittab = sharp_z0194a_inittab, 763e4aab64cSIgor M. Liplianin .mclk = 88000000UL, 764e4aab64cSIgor M. Liplianin .invert = 1, 765e4aab64cSIgor M. Liplianin .skip_reinit = 0, 766e4aab64cSIgor M. Liplianin .lock_output = 1, 767e4aab64cSIgor M. Liplianin .volt13_op0_op1 = STV0299_VOLT13_OP1, 768e4aab64cSIgor M. Liplianin .min_delay_ms = 100, 769d4305c68SIgor M. Liplianin .set_symbol_rate = sharp_z0194a_set_symbol_rate, 770e4aab64cSIgor M. Liplianin .set_ts_params = cx24116_set_ts_param, 771e4aab64cSIgor M. Liplianin }; 772e4aab64cSIgor M. Liplianin 7732e4e98e7Slawrence rust static const struct stv0288_config tevii_tuner_earda_config = { 774e4aab64cSIgor M. Liplianin .demod_address = 0x68, 775e4aab64cSIgor M. Liplianin .min_delay_ms = 100, 776e4aab64cSIgor M. Liplianin .set_ts_params = cx24116_set_ts_param, 777e4aab64cSIgor M. Liplianin }; 778e4aab64cSIgor M. Liplianin 7796e0e12f1SAndy Walls static int cx8802_alloc_frontends(struct cx8802_dev *dev) 7806e0e12f1SAndy Walls { 7816e0e12f1SAndy Walls struct cx88_core *core = dev->core; 7820b6b6302SHans Verkuil struct vb2_dvb_frontend *fe = NULL; 7836e0e12f1SAndy Walls int i; 7846e0e12f1SAndy Walls 7856e0e12f1SAndy Walls mutex_init(&dev->frontends.lock); 7866e0e12f1SAndy Walls INIT_LIST_HEAD(&dev->frontends.felist); 7876e0e12f1SAndy Walls 7886e0e12f1SAndy Walls if (!core->board.num_frontends) 7896e0e12f1SAndy Walls return -ENODEV; 7906e0e12f1SAndy Walls 79165bc2fe8SMauro Carvalho Chehab pr_info("%s: allocating %d frontend(s)\n", __func__, 7926e0e12f1SAndy Walls core->board.num_frontends); 7936e0e12f1SAndy Walls for (i = 1; i <= core->board.num_frontends; i++) { 7940b6b6302SHans Verkuil fe = vb2_dvb_alloc_frontend(&dev->frontends, i); 7956e0e12f1SAndy Walls if (!fe) { 79665bc2fe8SMauro Carvalho Chehab pr_err("%s() failed to alloc\n", __func__); 7970b6b6302SHans Verkuil vb2_dvb_dealloc_frontends(&dev->frontends); 7986e0e12f1SAndy Walls return -ENOMEM; 7996e0e12f1SAndy Walls } 8006e0e12f1SAndy Walls } 8016e0e12f1SAndy Walls return 0; 8026e0e12f1SAndy Walls } 8036e0e12f1SAndy Walls 8042e4e98e7Slawrence rust static const u8 samsung_smt_7020_inittab[] = { 8054f3ca2f1SDirk Herrendoerfer 0x01, 0x15, 8064f3ca2f1SDirk Herrendoerfer 0x02, 0x00, 8074f3ca2f1SDirk Herrendoerfer 0x03, 0x00, 8084f3ca2f1SDirk Herrendoerfer 0x04, 0x7D, 8094f3ca2f1SDirk Herrendoerfer 0x05, 0x0F, 8104f3ca2f1SDirk Herrendoerfer 0x06, 0x02, 8114f3ca2f1SDirk Herrendoerfer 0x07, 0x00, 8124f3ca2f1SDirk Herrendoerfer 0x08, 0x60, 8134f3ca2f1SDirk Herrendoerfer 8144f3ca2f1SDirk Herrendoerfer 0x0A, 0xC2, 8154f3ca2f1SDirk Herrendoerfer 0x0B, 0x00, 8164f3ca2f1SDirk Herrendoerfer 0x0C, 0x01, 8174f3ca2f1SDirk Herrendoerfer 0x0D, 0x81, 8184f3ca2f1SDirk Herrendoerfer 0x0E, 0x44, 8194f3ca2f1SDirk Herrendoerfer 0x0F, 0x09, 8204f3ca2f1SDirk Herrendoerfer 0x10, 0x3C, 8214f3ca2f1SDirk Herrendoerfer 0x11, 0x84, 8224f3ca2f1SDirk Herrendoerfer 0x12, 0xDA, 8234f3ca2f1SDirk Herrendoerfer 0x13, 0x99, 8244f3ca2f1SDirk Herrendoerfer 0x14, 0x8D, 8254f3ca2f1SDirk Herrendoerfer 0x15, 0xCE, 8264f3ca2f1SDirk Herrendoerfer 0x16, 0xE8, 8274f3ca2f1SDirk Herrendoerfer 0x17, 0x43, 8284f3ca2f1SDirk Herrendoerfer 0x18, 0x1C, 8294f3ca2f1SDirk Herrendoerfer 0x19, 0x1B, 8304f3ca2f1SDirk Herrendoerfer 0x1A, 0x1D, 8314f3ca2f1SDirk Herrendoerfer 8324f3ca2f1SDirk Herrendoerfer 0x1C, 0x12, 8334f3ca2f1SDirk Herrendoerfer 0x1D, 0x00, 8344f3ca2f1SDirk Herrendoerfer 0x1E, 0x00, 8354f3ca2f1SDirk Herrendoerfer 0x1F, 0x00, 8364f3ca2f1SDirk Herrendoerfer 0x20, 0x00, 8374f3ca2f1SDirk Herrendoerfer 0x21, 0x00, 8384f3ca2f1SDirk Herrendoerfer 0x22, 0x00, 8394f3ca2f1SDirk Herrendoerfer 0x23, 0x00, 8404f3ca2f1SDirk Herrendoerfer 8414f3ca2f1SDirk Herrendoerfer 0x28, 0x02, 8424f3ca2f1SDirk Herrendoerfer 0x29, 0x28, 8434f3ca2f1SDirk Herrendoerfer 0x2A, 0x14, 8444f3ca2f1SDirk Herrendoerfer 0x2B, 0x0F, 8454f3ca2f1SDirk Herrendoerfer 0x2C, 0x09, 8464f3ca2f1SDirk Herrendoerfer 0x2D, 0x05, 8474f3ca2f1SDirk Herrendoerfer 8484f3ca2f1SDirk Herrendoerfer 0x31, 0x1F, 8494f3ca2f1SDirk Herrendoerfer 0x32, 0x19, 8504f3ca2f1SDirk Herrendoerfer 0x33, 0xFC, 8514f3ca2f1SDirk Herrendoerfer 0x34, 0x13, 8524f3ca2f1SDirk Herrendoerfer 0xff, 0xff, 8534f3ca2f1SDirk Herrendoerfer }; 8544f3ca2f1SDirk Herrendoerfer 85514d24d14SMauro Carvalho Chehab static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe) 8564f3ca2f1SDirk Herrendoerfer { 857b738ae16SMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache; 8584f3ca2f1SDirk Herrendoerfer struct cx8802_dev *dev = fe->dvb->priv; 8594f3ca2f1SDirk Herrendoerfer u8 buf[4]; 8604f3ca2f1SDirk Herrendoerfer u32 div; 8614f3ca2f1SDirk Herrendoerfer struct i2c_msg msg = { 8624f3ca2f1SDirk Herrendoerfer .addr = 0x61, 8634f3ca2f1SDirk Herrendoerfer .flags = 0, 8644f3ca2f1SDirk Herrendoerfer .buf = buf, 8654f3ca2f1SDirk Herrendoerfer .len = sizeof(buf) }; 8664f3ca2f1SDirk Herrendoerfer 867b738ae16SMauro Carvalho Chehab div = c->frequency / 125; 8684f3ca2f1SDirk Herrendoerfer 8694f3ca2f1SDirk Herrendoerfer buf[0] = (div >> 8) & 0x7f; 8704f3ca2f1SDirk Herrendoerfer buf[1] = div & 0xff; 8714f3ca2f1SDirk Herrendoerfer buf[2] = 0x84; /* 0xC4 */ 8724f3ca2f1SDirk Herrendoerfer buf[3] = 0x00; 8734f3ca2f1SDirk Herrendoerfer 874b738ae16SMauro Carvalho Chehab if (c->frequency < 1500000) 8754f3ca2f1SDirk Herrendoerfer buf[3] |= 0x10; 8764f3ca2f1SDirk Herrendoerfer 8774f3ca2f1SDirk Herrendoerfer if (fe->ops.i2c_gate_ctrl) 8784f3ca2f1SDirk Herrendoerfer fe->ops.i2c_gate_ctrl(fe, 1); 8794f3ca2f1SDirk Herrendoerfer 8804f3ca2f1SDirk Herrendoerfer if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1) 8814f3ca2f1SDirk Herrendoerfer return -EIO; 8824f3ca2f1SDirk Herrendoerfer 8834f3ca2f1SDirk Herrendoerfer return 0; 8844f3ca2f1SDirk Herrendoerfer } 8854f3ca2f1SDirk Herrendoerfer 8864f3ca2f1SDirk Herrendoerfer static int samsung_smt_7020_set_tone(struct dvb_frontend *fe, 8870df289a2SMauro Carvalho Chehab enum fe_sec_tone_mode tone) 8884f3ca2f1SDirk Herrendoerfer { 8894f3ca2f1SDirk Herrendoerfer struct cx8802_dev *dev = fe->dvb->priv; 8904f3ca2f1SDirk Herrendoerfer struct cx88_core *core = dev->core; 8914f3ca2f1SDirk Herrendoerfer 8924f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x0800); 8934f3ca2f1SDirk Herrendoerfer 8944f3ca2f1SDirk Herrendoerfer switch (tone) { 8954f3ca2f1SDirk Herrendoerfer case SEC_TONE_ON: 8964f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x08); 8974f3ca2f1SDirk Herrendoerfer break; 8984f3ca2f1SDirk Herrendoerfer case SEC_TONE_OFF: 8994f3ca2f1SDirk Herrendoerfer cx_clear(MO_GP0_IO, 0x08); 9004f3ca2f1SDirk Herrendoerfer break; 9014f3ca2f1SDirk Herrendoerfer default: 9024f3ca2f1SDirk Herrendoerfer return -EINVAL; 9034f3ca2f1SDirk Herrendoerfer } 9044f3ca2f1SDirk Herrendoerfer 9054f3ca2f1SDirk Herrendoerfer return 0; 9064f3ca2f1SDirk Herrendoerfer } 9074f3ca2f1SDirk Herrendoerfer 9084f3ca2f1SDirk Herrendoerfer static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe, 9090df289a2SMauro Carvalho Chehab enum fe_sec_voltage voltage) 9104f3ca2f1SDirk Herrendoerfer { 9114f3ca2f1SDirk Herrendoerfer struct cx8802_dev *dev = fe->dvb->priv; 9124f3ca2f1SDirk Herrendoerfer struct cx88_core *core = dev->core; 9134f3ca2f1SDirk Herrendoerfer 9144f3ca2f1SDirk Herrendoerfer u8 data; 9154f3ca2f1SDirk Herrendoerfer struct i2c_msg msg = { 9164f3ca2f1SDirk Herrendoerfer .addr = 8, 9174f3ca2f1SDirk Herrendoerfer .flags = 0, 9184f3ca2f1SDirk Herrendoerfer .buf = &data, 9194f3ca2f1SDirk Herrendoerfer .len = sizeof(data) }; 9204f3ca2f1SDirk Herrendoerfer 9214f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x8000); 9224f3ca2f1SDirk Herrendoerfer 9234f3ca2f1SDirk Herrendoerfer switch (voltage) { 9244f3ca2f1SDirk Herrendoerfer case SEC_VOLTAGE_OFF: 9254f3ca2f1SDirk Herrendoerfer break; 9264f3ca2f1SDirk Herrendoerfer case SEC_VOLTAGE_13: 9274f3ca2f1SDirk Herrendoerfer data = ISL6421_EN1 | ISL6421_LLC1; 9284f3ca2f1SDirk Herrendoerfer cx_clear(MO_GP0_IO, 0x80); 9294f3ca2f1SDirk Herrendoerfer break; 9304f3ca2f1SDirk Herrendoerfer case SEC_VOLTAGE_18: 9314f3ca2f1SDirk Herrendoerfer data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1; 9324f3ca2f1SDirk Herrendoerfer cx_clear(MO_GP0_IO, 0x80); 9334f3ca2f1SDirk Herrendoerfer break; 9344f3ca2f1SDirk Herrendoerfer default: 9354f3ca2f1SDirk Herrendoerfer return -EINVAL; 936c2c1b415SPeter Senna Tschudin } 9374f3ca2f1SDirk Herrendoerfer 9384f3ca2f1SDirk Herrendoerfer return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO; 9394f3ca2f1SDirk Herrendoerfer } 9404f3ca2f1SDirk Herrendoerfer 9414f3ca2f1SDirk Herrendoerfer static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe, 9424f3ca2f1SDirk Herrendoerfer u32 srate, u32 ratio) 9434f3ca2f1SDirk Herrendoerfer { 9444f3ca2f1SDirk Herrendoerfer u8 aclk = 0; 9454f3ca2f1SDirk Herrendoerfer u8 bclk = 0; 9464f3ca2f1SDirk Herrendoerfer 9474f3ca2f1SDirk Herrendoerfer if (srate < 1500000) { 9484f3ca2f1SDirk Herrendoerfer aclk = 0xb7; 9494f3ca2f1SDirk Herrendoerfer bclk = 0x47; 9504f3ca2f1SDirk Herrendoerfer } else if (srate < 3000000) { 9514f3ca2f1SDirk Herrendoerfer aclk = 0xb7; 9524f3ca2f1SDirk Herrendoerfer bclk = 0x4b; 9534f3ca2f1SDirk Herrendoerfer } else if (srate < 7000000) { 9544f3ca2f1SDirk Herrendoerfer aclk = 0xb7; 9554f3ca2f1SDirk Herrendoerfer bclk = 0x4f; 9564f3ca2f1SDirk Herrendoerfer } else if (srate < 14000000) { 9574f3ca2f1SDirk Herrendoerfer aclk = 0xb7; 9584f3ca2f1SDirk Herrendoerfer bclk = 0x53; 9594f3ca2f1SDirk Herrendoerfer } else if (srate < 30000000) { 9604f3ca2f1SDirk Herrendoerfer aclk = 0xb6; 9614f3ca2f1SDirk Herrendoerfer bclk = 0x53; 9624f3ca2f1SDirk Herrendoerfer } else if (srate < 45000000) { 9634f3ca2f1SDirk Herrendoerfer aclk = 0xb4; 9644f3ca2f1SDirk Herrendoerfer bclk = 0x51; 9654f3ca2f1SDirk Herrendoerfer } 9664f3ca2f1SDirk Herrendoerfer 9674f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x13, aclk); 9684f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x14, bclk); 9694f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); 9704f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); 9714f3ca2f1SDirk Herrendoerfer stv0299_writereg(fe, 0x21, ratio & 0xf0); 9724f3ca2f1SDirk Herrendoerfer 9734f3ca2f1SDirk Herrendoerfer return 0; 9744f3ca2f1SDirk Herrendoerfer } 9754f3ca2f1SDirk Herrendoerfer 9762e4e98e7Slawrence rust static const struct stv0299_config samsung_stv0299_config = { 9774f3ca2f1SDirk Herrendoerfer .demod_address = 0x68, 9784f3ca2f1SDirk Herrendoerfer .inittab = samsung_smt_7020_inittab, 9794f3ca2f1SDirk Herrendoerfer .mclk = 88000000UL, 9804f3ca2f1SDirk Herrendoerfer .invert = 0, 9814f3ca2f1SDirk Herrendoerfer .skip_reinit = 0, 9824f3ca2f1SDirk Herrendoerfer .lock_output = STV0299_LOCKOUTPUT_LK, 9834f3ca2f1SDirk Herrendoerfer .volt13_op0_op1 = STV0299_VOLT13_OP1, 9844f3ca2f1SDirk Herrendoerfer .min_delay_ms = 100, 9854f3ca2f1SDirk Herrendoerfer .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate, 9864f3ca2f1SDirk Herrendoerfer }; 9874f3ca2f1SDirk Herrendoerfer 9881da177e4SLinus Torvalds static int dvb_register(struct cx8802_dev *dev) 9891da177e4SLinus Torvalds { 990363c35fcSSteven Toth struct cx88_core *core = dev->core; 9910b6b6302SHans Verkuil struct vb2_dvb_frontend *fe0, *fe1 = NULL; 99259b1842dSDarron Broad int mfe_shared = 0; /* bus not shared by default */ 9937b0962d3SDavid Fries int res = -EINVAL; 994363c35fcSSteven Toth 9957b61ba8fSMauro Carvalho Chehab if (core->i2c_rc != 0) { 99665bc2fe8SMauro Carvalho Chehab pr_err("no i2c-bus available, cannot attach dvb drivers\n"); 9970e8bac97SMatthias Schwarzott goto frontend_detach; 9980e8bac97SMatthias Schwarzott } 9990e8bac97SMatthias Schwarzott 1000363c35fcSSteven Toth /* Get the first frontend */ 10010b6b6302SHans Verkuil fe0 = vb2_dvb_get_frontend(&dev->frontends, 1); 1002363c35fcSSteven Toth if (!fe0) 100360a5a927SDarron Broad goto frontend_detach; 10041da177e4SLinus Torvalds 10058e739090SDarron Broad /* multi-frontend gate control is undefined or defaults to fe0 */ 10068e739090SDarron Broad dev->frontends.gate = 0; 10078e739090SDarron Broad 1008e32fadc4SMauro Carvalho Chehab /* Sets the gate control callback to be used by i2c command calls */ 1009e32fadc4SMauro Carvalho Chehab core->gate_ctrl = cx88_dvb_gate_ctrl; 1010e32fadc4SMauro Carvalho Chehab 10118e739090SDarron Broad /* init frontend(s) */ 10120590d91cSMauro Carvalho Chehab switch (core->boardnr) { 10131da177e4SLinus Torvalds case CX88_BOARD_HAUPPAUGE_DVB_T1: 1014363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx22702_attach, 1015ed355260SMichael Krufky &connexant_refboard_config, 10160590d91cSMauro Carvalho Chehab &core->i2c_adap); 1017399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1018363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 10190590d91cSMauro Carvalho Chehab 0x61, &core->i2c_adap, 10200590d91cSMauro Carvalho Chehab DVB_PLL_THOMSON_DTT759X)) 10210590d91cSMauro Carvalho Chehab goto frontend_detach; 1022f54376e2SAndrew de Quincey } 10231da177e4SLinus Torvalds break; 1024e057ee11SMichael Krufky case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 10251da177e4SLinus Torvalds case CX88_BOARD_CONEXANT_DVB_T1: 1026f39624fdSManenti Marco case CX88_BOARD_KWORLD_DVB_T_CX22702: 10272b5200a7SDavid Shirley case CX88_BOARD_WINFAST_DTV1000: 1028363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx22702_attach, 1029f7b54b10SMichael Krufky &connexant_refboard_config, 10300590d91cSMauro Carvalho Chehab &core->i2c_adap); 1031399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1032363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 10330590d91cSMauro Carvalho Chehab 0x60, &core->i2c_adap, 10340590d91cSMauro Carvalho Chehab DVB_PLL_THOMSON_DTT7579)) 10350590d91cSMauro Carvalho Chehab goto frontend_detach; 1036f54376e2SAndrew de Quincey } 10371da177e4SLinus Torvalds break; 10384bd6e9d9SMalcolm Valentine case CX88_BOARD_WINFAST_DTV2000H: 1039611900c1SSteven Toth case CX88_BOARD_HAUPPAUGE_HVR1100: 1040611900c1SSteven Toth case CX88_BOARD_HAUPPAUGE_HVR1100LP: 1041a5a2ecfcSTrent Piepho case CX88_BOARD_HAUPPAUGE_HVR1300: 1042363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx22702_attach, 1043ed355260SMichael Krufky &hauppauge_hvr_config, 10440590d91cSMauro Carvalho Chehab &core->i2c_adap); 1045399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1046363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 10470590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 10480590d91cSMauro Carvalho Chehab TUNER_PHILIPS_FMD1216ME_MK3)) 10490590d91cSMauro Carvalho Chehab goto frontend_detach; 1050f54376e2SAndrew de Quincey } 1051611900c1SSteven Toth break; 105227b93d8aSMiroslav Slugen case CX88_BOARD_WINFAST_DTV2000H_J: 105327b93d8aSMiroslav Slugen fe0->dvb.frontend = dvb_attach(cx22702_attach, 105427b93d8aSMiroslav Slugen &hauppauge_hvr_config, 105527b93d8aSMiroslav Slugen &core->i2c_adap); 1056399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 105727b93d8aSMiroslav Slugen if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 105827b93d8aSMiroslav Slugen &core->i2c_adap, 0x61, 105927b93d8aSMiroslav Slugen TUNER_PHILIPS_FMD1216MEX_MK3)) 106027b93d8aSMiroslav Slugen goto frontend_detach; 106127b93d8aSMiroslav Slugen } 106227b93d8aSMiroslav Slugen break; 1063363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR3000: 106460a5a927SDarron Broad /* MFE frontend 1 */ 106560a5a927SDarron Broad mfe_shared = 1; 106660a5a927SDarron Broad dev->frontends.gate = 2; 1067363c35fcSSteven Toth /* DVB-S init */ 1068363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24123_attach, 1069363c35fcSSteven Toth &hauppauge_novas_config, 1070363c35fcSSteven Toth &dev->core->i2c_adap); 1071363c35fcSSteven Toth if (fe0->dvb.frontend) { 107260a5a927SDarron Broad if (!dvb_attach(isl6421_attach, 107360a5a927SDarron Broad fe0->dvb.frontend, 107460a5a927SDarron Broad &dev->core->i2c_adap, 107548a8a03bSMauro Carvalho Chehab 0x08, ISL6421_DCL, 0x00, false)) 107660a5a927SDarron Broad goto frontend_detach; 1077363c35fcSSteven Toth } 107860a5a927SDarron Broad /* MFE frontend 2 */ 10790b6b6302SHans Verkuil fe1 = vb2_dvb_get_frontend(&dev->frontends, 2); 108060a5a927SDarron Broad if (!fe1) 108160a5a927SDarron Broad goto frontend_detach; 108260a5a927SDarron Broad /* DVB-T init */ 1083363c35fcSSteven Toth fe1->dvb.frontend = dvb_attach(cx22702_attach, 1084363c35fcSSteven Toth &hauppauge_hvr_config, 1085363c35fcSSteven Toth &dev->core->i2c_adap); 1086363c35fcSSteven Toth if (fe1->dvb.frontend) { 1087363c35fcSSteven Toth fe1->dvb.frontend->id = 1; 108860a5a927SDarron Broad if (!dvb_attach(simple_tuner_attach, 108960a5a927SDarron Broad fe1->dvb.frontend, 109060a5a927SDarron Broad &dev->core->i2c_adap, 109160a5a927SDarron Broad 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) 109260a5a927SDarron Broad goto frontend_detach; 1093363c35fcSSteven Toth } 1094363c35fcSSteven Toth break; 1095780dfef3SChris Pascoe case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 1096363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach, 1097f7b54b10SMichael Krufky &dvico_fusionhdtv, 10980590d91cSMauro Carvalho Chehab &core->i2c_adap); 1099399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1100363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 11010590d91cSMauro Carvalho Chehab 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) 11020590d91cSMauro Carvalho Chehab goto frontend_detach; 1103780dfef3SChris Pascoe break; 1104f54376e2SAndrew de Quincey } 1105780dfef3SChris Pascoe /* ZL10353 replaces MT352 on later cards */ 1106363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach, 1107f7b54b10SMichael Krufky &dvico_fusionhdtv_plus_v1_1, 11080590d91cSMauro Carvalho Chehab &core->i2c_adap); 1109399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1110363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 11110590d91cSMauro Carvalho Chehab 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) 11120590d91cSMauro Carvalho Chehab goto frontend_detach; 1113f54376e2SAndrew de Quincey } 1114780dfef3SChris Pascoe break; 1115c2af3cd6SMichael Krufky case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: 1116399426caSMauro Carvalho Chehab /* 1117399426caSMauro Carvalho Chehab * The tin box says DEE1601, but it seems to be DTT7579 1118399426caSMauro Carvalho Chehab * compatible, with a slightly different MT352 AGC gain. 1119399426caSMauro Carvalho Chehab */ 1120363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach, 1121f7b54b10SMichael Krufky &dvico_fusionhdtv_dual, 11220590d91cSMauro Carvalho Chehab &core->i2c_adap); 1123399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1124363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 11250590d91cSMauro Carvalho Chehab 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) 11260590d91cSMauro Carvalho Chehab goto frontend_detach; 1127c2af3cd6SMichael Krufky break; 1128c2af3cd6SMichael Krufky } 1129c2af3cd6SMichael Krufky /* ZL10353 replaces MT352 on later cards */ 1130363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach, 1131f7b54b10SMichael Krufky &dvico_fusionhdtv_plus_v1_1, 11320590d91cSMauro Carvalho Chehab &core->i2c_adap); 1133399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1134363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 11350590d91cSMauro Carvalho Chehab 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) 11360590d91cSMauro Carvalho Chehab goto frontend_detach; 1137c2af3cd6SMichael Krufky } 1138c2af3cd6SMichael Krufky break; 11391da177e4SLinus Torvalds case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 1140363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach, 1141f7b54b10SMichael Krufky &dvico_fusionhdtv, 11420590d91cSMauro Carvalho Chehab &core->i2c_adap); 1143399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1144363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 11450590d91cSMauro Carvalho Chehab 0x61, NULL, DVB_PLL_LG_Z201)) 11460590d91cSMauro Carvalho Chehab goto frontend_detach; 1147f54376e2SAndrew de Quincey } 11481da177e4SLinus Torvalds break; 11491da177e4SLinus Torvalds case CX88_BOARD_KWORLD_DVB_T: 11501da177e4SLinus Torvalds case CX88_BOARD_DNTV_LIVE_DVB_T: 1151a82decf6SMauro Carvalho Chehab case CX88_BOARD_ADSTECH_DVB_T_PCI: 1152363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach, 1153f7b54b10SMichael Krufky &dntv_live_dvbt_config, 11540590d91cSMauro Carvalho Chehab &core->i2c_adap); 1155399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1156363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 11570590d91cSMauro Carvalho Chehab 0x61, NULL, DVB_PLL_UNKNOWN_1)) 11580590d91cSMauro Carvalho Chehab goto frontend_detach; 1159f54376e2SAndrew de Quincey } 11601da177e4SLinus Torvalds break; 1161fc40b261SChris Pascoe case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 11627b34be71SPeter Senna Tschudin #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054) 1163f0ad9097STrent Piepho /* MT352 is on a secondary I2C bus made from some GPIO lines */ 1164399426caSMauro Carvalho Chehab fe0->dvb.frontend = dvb_attach(mt352_attach, 1165399426caSMauro Carvalho Chehab &dntv_live_dvbt_pro_config, 1166f0ad9097STrent Piepho &dev->vp3054->adap); 1167399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1168363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 11690590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 11700590d91cSMauro Carvalho Chehab TUNER_PHILIPS_FMD1216ME_MK3)) 11710590d91cSMauro Carvalho Chehab goto frontend_detach; 1172f54376e2SAndrew de Quincey } 1173fc40b261SChris Pascoe #else 117465bc2fe8SMauro Carvalho Chehab pr_err("built without vp3054 support\n"); 1175fc40b261SChris Pascoe #endif 1176fc40b261SChris Pascoe break; 1177780dfef3SChris Pascoe case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: 1178363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach, 1179f7b54b10SMichael Krufky &dvico_fusionhdtv_hybrid, 11800590d91cSMauro Carvalho Chehab &core->i2c_adap); 1181399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1182363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 11830590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 11840590d91cSMauro Carvalho Chehab TUNER_THOMSON_FE6600)) 11850590d91cSMauro Carvalho Chehab goto frontend_detach; 1186f54376e2SAndrew de Quincey } 1187780dfef3SChris Pascoe break; 1188b3fb91d2SChris Pascoe case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: 1189363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach, 1190b3fb91d2SChris Pascoe &dvico_fusionhdtv_xc3028, 11910590d91cSMauro Carvalho Chehab &core->i2c_adap); 1192399426caSMauro Carvalho Chehab if (!fe0->dvb.frontend) 1193363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(mt352_attach, 1194b3fb91d2SChris Pascoe &dvico_fusionhdtv_mt352_xc3028, 11950590d91cSMauro Carvalho Chehab &core->i2c_adap); 11968765561fSChris Pascoe /* 11978765561fSChris Pascoe * On this board, the demod provides the I2C bus pullup. 11988765561fSChris Pascoe * We must not permit gate_ctrl to be performed, or 11998765561fSChris Pascoe * the xc3028 cannot communicate on the bus. 12008765561fSChris Pascoe */ 1201363c35fcSSteven Toth if (fe0->dvb.frontend) 1202363c35fcSSteven Toth fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; 120323fb348dSMauro Carvalho Chehab if (attach_xc3028(0x61, dev) < 0) 1204becd4305SDarron Broad goto frontend_detach; 1205b3fb91d2SChris Pascoe break; 12061da177e4SLinus Torvalds case CX88_BOARD_PCHDTV_HD3000: 1207363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, 12080590d91cSMauro Carvalho Chehab &core->i2c_adap); 1209399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1210363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 12110590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 12120590d91cSMauro Carvalho Chehab TUNER_THOMSON_DTT761X)) 12130590d91cSMauro Carvalho Chehab goto frontend_detach; 1214f54376e2SAndrew de Quincey } 12151da177e4SLinus Torvalds break; 1216f1798495SMichael Krufky case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: 1217f1798495SMichael Krufky dev->ts_gen_cntrl = 0x08; 1218f1798495SMichael Krufky 12190590d91cSMauro Carvalho Chehab /* Do a hardware reset of chip before using it. */ 1220f1798495SMichael Krufky cx_clear(MO_GP0_IO, 1); 12219d08ba6dSJia-Ju Bai msleep(100); 12220ccef6dbSMichael Krufky cx_set(MO_GP0_IO, 1); 12239d08ba6dSJia-Ju Bai msleep(200); 12240ccef6dbSMichael Krufky 12250ccef6dbSMichael Krufky /* Select RF connector callback */ 12266ddcc919SMichael Krufky fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; 1227363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(lgdt330x_attach, 1228f7b54b10SMichael Krufky &fusionhdtv_3_gold, 122923ba635dSMauro Carvalho Chehab 0x0e, 12300590d91cSMauro Carvalho Chehab &core->i2c_adap); 1231399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1232363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 12330590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 12340590d91cSMauro Carvalho Chehab TUNER_MICROTUNE_4042FI5)) 12350590d91cSMauro Carvalho Chehab goto frontend_detach; 1236f1798495SMichael Krufky } 1237f1798495SMichael Krufky break; 12380d723c09SMichael Krufky case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: 12390d723c09SMichael Krufky dev->ts_gen_cntrl = 0x08; 12400d723c09SMichael Krufky 12410590d91cSMauro Carvalho Chehab /* Do a hardware reset of chip before using it. */ 12420d723c09SMichael Krufky cx_clear(MO_GP0_IO, 1); 12439d08ba6dSJia-Ju Bai msleep(100); 1244d975872cSMichael Krufky cx_set(MO_GP0_IO, 9); 12459d08ba6dSJia-Ju Bai msleep(200); 1246363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(lgdt330x_attach, 1247f7b54b10SMichael Krufky &fusionhdtv_3_gold, 124823ba635dSMauro Carvalho Chehab 0x0e, 12490590d91cSMauro Carvalho Chehab &core->i2c_adap); 1250399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1251363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 12520590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 12530590d91cSMauro Carvalho Chehab TUNER_THOMSON_DTT761X)) 12540590d91cSMauro Carvalho Chehab goto frontend_detach; 12550d723c09SMichael Krufky } 12560d723c09SMichael Krufky break; 1257e52e98a7SMauro Carvalho Chehab case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: 1258e52e98a7SMauro Carvalho Chehab dev->ts_gen_cntrl = 0x08; 1259e52e98a7SMauro Carvalho Chehab 12600590d91cSMauro Carvalho Chehab /* Do a hardware reset of chip before using it. */ 1261e52e98a7SMauro Carvalho Chehab cx_clear(MO_GP0_IO, 1); 12629d08ba6dSJia-Ju Bai msleep(100); 1263e52e98a7SMauro Carvalho Chehab cx_set(MO_GP0_IO, 1); 12649d08ba6dSJia-Ju Bai msleep(200); 1265363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(lgdt330x_attach, 1266f7b54b10SMichael Krufky &fusionhdtv_5_gold, 126723ba635dSMauro Carvalho Chehab 0x0e, 12680590d91cSMauro Carvalho Chehab &core->i2c_adap); 1269399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1270363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 12710590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 12720590d91cSMauro Carvalho Chehab TUNER_LG_TDVS_H06XF)) 12730590d91cSMauro Carvalho Chehab goto frontend_detach; 1274363c35fcSSteven Toth if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, 12750590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x43)) 12760590d91cSMauro Carvalho Chehab goto frontend_detach; 1277e52e98a7SMauro Carvalho Chehab } 1278e52e98a7SMauro Carvalho Chehab break; 1279da215d22SRusty Scott case CX88_BOARD_PCHDTV_HD5500: 1280da215d22SRusty Scott dev->ts_gen_cntrl = 0x08; 1281da215d22SRusty Scott 12820590d91cSMauro Carvalho Chehab /* Do a hardware reset of chip before using it. */ 1283da215d22SRusty Scott cx_clear(MO_GP0_IO, 1); 12849d08ba6dSJia-Ju Bai msleep(100); 1285da215d22SRusty Scott cx_set(MO_GP0_IO, 1); 12869d08ba6dSJia-Ju Bai msleep(200); 1287363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(lgdt330x_attach, 1288f7b54b10SMichael Krufky &pchdtv_hd5500, 128923ba635dSMauro Carvalho Chehab 0x59, 12900590d91cSMauro Carvalho Chehab &core->i2c_adap); 1291399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1292363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 12930590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 12940590d91cSMauro Carvalho Chehab TUNER_LG_TDVS_H06XF)) 12950590d91cSMauro Carvalho Chehab goto frontend_detach; 1296363c35fcSSteven Toth if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, 12970590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x43)) 12980590d91cSMauro Carvalho Chehab goto frontend_detach; 1299da215d22SRusty Scott } 1300da215d22SRusty Scott break; 1301fde6d31eSKirk Lapray case CX88_BOARD_ATI_HDTVWONDER: 1302363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(nxt200x_attach, 1303f7b54b10SMichael Krufky &ati_hdtvwonder, 13040590d91cSMauro Carvalho Chehab &core->i2c_adap); 1305399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1306363c35fcSSteven Toth if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 13070590d91cSMauro Carvalho Chehab &core->i2c_adap, 0x61, 13080590d91cSMauro Carvalho Chehab TUNER_PHILIPS_TUV1236D)) 13090590d91cSMauro Carvalho Chehab goto frontend_detach; 1310f54376e2SAndrew de Quincey } 1311fde6d31eSKirk Lapray break; 13120fa14aa6SSteven Toth case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 13130fa14aa6SSteven Toth case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 1314363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24123_attach, 1315f7b54b10SMichael Krufky &hauppauge_novas_config, 13160590d91cSMauro Carvalho Chehab &core->i2c_adap); 1317363c35fcSSteven Toth if (fe0->dvb.frontend) { 131848a8a03bSMauro Carvalho Chehab bool override_tone; 131948a8a03bSMauro Carvalho Chehab 132048a8a03bSMauro Carvalho Chehab if (core->model == 92001) 132148a8a03bSMauro Carvalho Chehab override_tone = true; 132248a8a03bSMauro Carvalho Chehab else 132348a8a03bSMauro Carvalho Chehab override_tone = false; 132448a8a03bSMauro Carvalho Chehab 1325363c35fcSSteven Toth if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, 1326399426caSMauro Carvalho Chehab &core->i2c_adap, 0x08, ISL6421_DCL, 1327399426caSMauro Carvalho Chehab 0x00, override_tone)) 13280590d91cSMauro Carvalho Chehab goto frontend_detach; 1329cd20ca9fSAndrew de Quincey } 13300fa14aa6SSteven Toth break; 13310e0351e3SVadim Catana case CX88_BOARD_KWORLD_DVBS_100: 1332363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24123_attach, 1333f7b54b10SMichael Krufky &kworld_dvbs_100_config, 13340590d91cSMauro Carvalho Chehab &core->i2c_adap); 1335363c35fcSSteven Toth if (fe0->dvb.frontend) { 1336363c35fcSSteven Toth core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; 1337363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; 1338cd20ca9fSAndrew de Quincey } 13390e0351e3SVadim Catana break; 1340c02a34f4SSaqeb Akhter case CX88_BOARD_GENIATECH_DVBS: 1341363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24123_attach, 1342f7b54b10SMichael Krufky &geniatech_dvbs_config, 13430590d91cSMauro Carvalho Chehab &core->i2c_adap); 1344363c35fcSSteven Toth if (fe0->dvb.frontend) { 1345363c35fcSSteven Toth core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; 1346363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; 1347c02a34f4SSaqeb Akhter } 1348c02a34f4SSaqeb Akhter break; 134960464da8SSteven Toth case CX88_BOARD_PINNACLE_PCTV_HD_800i: 1350363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(s5h1409_attach, 135160464da8SSteven Toth &pinnacle_pctv_hd_800i_config, 13520590d91cSMauro Carvalho Chehab &core->i2c_adap); 1353399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1354363c35fcSSteven Toth if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, 13550590d91cSMauro Carvalho Chehab &core->i2c_adap, 135630650961SMichael Krufky &pinnacle_pctv_hd_800i_tuner_config)) 13570590d91cSMauro Carvalho Chehab goto frontend_detach; 135860464da8SSteven Toth } 135960464da8SSteven Toth break; 13605c00fac0SSteven Toth case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: 1361363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(s5h1409_attach, 13625c00fac0SSteven Toth &dvico_hdtv5_pci_nano_config, 13630590d91cSMauro Carvalho Chehab &core->i2c_adap); 1364399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 13655c00fac0SSteven Toth struct dvb_frontend *fe; 13665c00fac0SSteven Toth struct xc2028_config cfg = { 13670590d91cSMauro Carvalho Chehab .i2c_adap = &core->i2c_adap, 13685c00fac0SSteven Toth .i2c_addr = 0x61, 13695c00fac0SSteven Toth }; 13705c00fac0SSteven Toth static struct xc2028_ctrl ctl = { 1371ef80bfebSMichael Krufky .fname = XC2028_DEFAULT_FIRMWARE, 13725c00fac0SSteven Toth .max_len = 64, 137333e53161SMauro Carvalho Chehab .scode_table = XC3028_FE_OREN538, 13745c00fac0SSteven Toth }; 13755c00fac0SSteven Toth 13765c00fac0SSteven Toth fe = dvb_attach(xc2028_attach, 1377363c35fcSSteven Toth fe0->dvb.frontend, &cfg); 1378399426caSMauro Carvalho Chehab if (fe && fe->ops.tuner_ops.set_config) 13795c00fac0SSteven Toth fe->ops.tuner_ops.set_config(fe, &ctl); 13805c00fac0SSteven Toth } 13815c00fac0SSteven Toth break; 1382e6f45ea2SDaniel Gonzalez Cabanelas case CX88_BOARD_NOTONLYTV_LV3H: 13839507901eSMauro Carvalho Chehab case CX88_BOARD_PINNACLE_HYBRID_PCTV: 13843047a176SMiroslav Sustek case CX88_BOARD_WINFAST_DTV1800H: 1385363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach, 13863f6014fcSStéphane Voltz &cx88_pinnacle_hybrid_pctv, 13870590d91cSMauro Carvalho Chehab &core->i2c_adap); 1388363c35fcSSteven Toth if (fe0->dvb.frontend) { 1389363c35fcSSteven Toth fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; 139023fb348dSMauro Carvalho Chehab if (attach_xc3028(0x61, dev) < 0) 13910590d91cSMauro Carvalho Chehab goto frontend_detach; 13923f6014fcSStéphane Voltz } 13939507901eSMauro Carvalho Chehab break; 13948eb79c0bSistvan_v@mailbox.hu case CX88_BOARD_WINFAST_DTV1800H_XC4000: 1395f271a3afSistvan_v@mailbox.hu case CX88_BOARD_WINFAST_DTV2000H_PLUS: 1396f271a3afSistvan_v@mailbox.hu fe0->dvb.frontend = dvb_attach(zl10353_attach, 1397f271a3afSistvan_v@mailbox.hu &cx88_pinnacle_hybrid_pctv, 1398f271a3afSistvan_v@mailbox.hu &core->i2c_adap); 1399f271a3afSistvan_v@mailbox.hu if (fe0->dvb.frontend) { 1400f271a3afSistvan_v@mailbox.hu struct xc4000_config cfg = { 1401f271a3afSistvan_v@mailbox.hu .i2c_address = 0x61, 1402f271a3afSistvan_v@mailbox.hu .default_pm = 0, 1403f271a3afSistvan_v@mailbox.hu .dvb_amplitude = 134, 1404f271a3afSistvan_v@mailbox.hu .set_smoothedcvbs = 1, 1405f271a3afSistvan_v@mailbox.hu .if_khz = 4560 1406f271a3afSistvan_v@mailbox.hu }; 1407f271a3afSistvan_v@mailbox.hu fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; 1408f271a3afSistvan_v@mailbox.hu if (attach_xc4000(dev, &cfg) < 0) 1409f271a3afSistvan_v@mailbox.hu goto frontend_detach; 1410f271a3afSistvan_v@mailbox.hu } 1411f271a3afSistvan_v@mailbox.hu break; 14129507901eSMauro Carvalho Chehab case CX88_BOARD_GENIATECH_X8000_MT: 14139507901eSMauro Carvalho Chehab dev->ts_gen_cntrl = 0x00; 14149507901eSMauro Carvalho Chehab 1415363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(zl10353_attach, 14169507901eSMauro Carvalho Chehab &cx88_geniatech_x8000_mt, 14170590d91cSMauro Carvalho Chehab &core->i2c_adap); 141823fb348dSMauro Carvalho Chehab if (attach_xc3028(0x61, dev) < 0) 14190590d91cSMauro Carvalho Chehab goto frontend_detach; 14209507901eSMauro Carvalho Chehab break; 142199e09eacSMauro Carvalho Chehab case CX88_BOARD_KWORLD_ATSC_120: 1422363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(s5h1409_attach, 142399e09eacSMauro Carvalho Chehab &kworld_atsc_120_config, 14240590d91cSMauro Carvalho Chehab &core->i2c_adap); 142599e09eacSMauro Carvalho Chehab if (attach_xc3028(0x61, dev) < 0) 14260590d91cSMauro Carvalho Chehab goto frontend_detach; 142799e09eacSMauro Carvalho Chehab break; 1428d893d5dcSSteven Toth case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: 1429363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(s5h1411_attach, 1430d893d5dcSSteven Toth &dvico_fusionhdtv7_config, 14310590d91cSMauro Carvalho Chehab &core->i2c_adap); 1432399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1433363c35fcSSteven Toth if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, 14340590d91cSMauro Carvalho Chehab &core->i2c_adap, 143530650961SMichael Krufky &dvico_fusionhdtv7_tuner_config)) 14360590d91cSMauro Carvalho Chehab goto frontend_detach; 1437d893d5dcSSteven Toth } 1438d893d5dcSSteven Toth break; 14395bd1b663SSteven Toth case CX88_BOARD_HAUPPAUGE_HVR4000: 144060a5a927SDarron Broad /* MFE frontend 1 */ 144160a5a927SDarron Broad mfe_shared = 1; 144260a5a927SDarron Broad dev->frontends.gate = 2; 1443363c35fcSSteven Toth /* DVB-S/S2 Init */ 1444363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24116_attach, 14455bd1b663SSteven Toth &hauppauge_hvr4000_config, 14465bd1b663SSteven Toth &dev->core->i2c_adap); 1447363c35fcSSteven Toth if (fe0->dvb.frontend) { 144860a5a927SDarron Broad if (!dvb_attach(isl6421_attach, 144960a5a927SDarron Broad fe0->dvb.frontend, 145060a5a927SDarron Broad &dev->core->i2c_adap, 145148a8a03bSMauro Carvalho Chehab 0x08, ISL6421_DCL, 0x00, false)) 145260a5a927SDarron Broad goto frontend_detach; 1453363c35fcSSteven Toth } 145460a5a927SDarron Broad /* MFE frontend 2 */ 14550b6b6302SHans Verkuil fe1 = vb2_dvb_get_frontend(&dev->frontends, 2); 145660a5a927SDarron Broad if (!fe1) 145760a5a927SDarron Broad goto frontend_detach; 145860a5a927SDarron Broad /* DVB-T Init */ 1459363c35fcSSteven Toth fe1->dvb.frontend = dvb_attach(cx22702_attach, 1460363c35fcSSteven Toth &hauppauge_hvr_config, 1461363c35fcSSteven Toth &dev->core->i2c_adap); 1462363c35fcSSteven Toth if (fe1->dvb.frontend) { 1463363c35fcSSteven Toth fe1->dvb.frontend->id = 1; 146460a5a927SDarron Broad if (!dvb_attach(simple_tuner_attach, 146560a5a927SDarron Broad fe1->dvb.frontend, 146660a5a927SDarron Broad &dev->core->i2c_adap, 146760a5a927SDarron Broad 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) 146860a5a927SDarron Broad goto frontend_detach; 1469363c35fcSSteven Toth } 1470363c35fcSSteven Toth break; 1471363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR4000LITE: 1472363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24116_attach, 1473363c35fcSSteven Toth &hauppauge_hvr4000_config, 1474363c35fcSSteven Toth &dev->core->i2c_adap); 1475363c35fcSSteven Toth if (fe0->dvb.frontend) { 147660a5a927SDarron Broad if (!dvb_attach(isl6421_attach, 147760a5a927SDarron Broad fe0->dvb.frontend, 14785bd1b663SSteven Toth &dev->core->i2c_adap, 147948a8a03bSMauro Carvalho Chehab 0x08, ISL6421_DCL, 0x00, false)) 148060a5a927SDarron Broad goto frontend_detach; 14815bd1b663SSteven Toth } 14825bd1b663SSteven Toth break; 1483cd3cde12SIgor M. Liplianin case CX88_BOARD_PROF_6200: 14844b29631dSIgor M. Liplianin case CX88_BOARD_TBS_8910: 1485e4aab64cSIgor M. Liplianin case CX88_BOARD_TEVII_S420: 1486363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(stv0299_attach, 1487e4aab64cSIgor M. Liplianin &tevii_tuner_sharp_config, 1488e4aab64cSIgor M. Liplianin &core->i2c_adap); 1489399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1490363c35fcSSteven Toth if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, 1491e4aab64cSIgor M. Liplianin &core->i2c_adap, DVB_PLL_OPERA1)) 1492e4aab64cSIgor M. Liplianin goto frontend_detach; 1493363c35fcSSteven Toth core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; 1494363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1495e4aab64cSIgor M. Liplianin 1496e4aab64cSIgor M. Liplianin } else { 1497363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(stv0288_attach, 1498e4aab64cSIgor M. Liplianin &tevii_tuner_earda_config, 1499e4aab64cSIgor M. Liplianin &core->i2c_adap); 1500399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1501399426caSMauro Carvalho Chehab if (!dvb_attach(stb6000_attach, 1502399426caSMauro Carvalho Chehab fe0->dvb.frontend, 0x61, 1503e4aab64cSIgor M. Liplianin &core->i2c_adap)) 1504e4aab64cSIgor M. Liplianin goto frontend_detach; 1505363c35fcSSteven Toth core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; 1506363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1507e4aab64cSIgor M. Liplianin } 1508e4aab64cSIgor M. Liplianin } 1509e4aab64cSIgor M. Liplianin break; 1510af832623SIgor M. Liplianin case CX88_BOARD_TEVII_S460: 1511363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24116_attach, 1512af832623SIgor M. Liplianin &tevii_s460_config, 1513af832623SIgor M. Liplianin &core->i2c_adap); 1514399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) 1515363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1516af832623SIgor M. Liplianin break; 15170cb73639SIgor M. Liplianin case CX88_BOARD_TEVII_S464: 15180cb73639SIgor M. Liplianin fe0->dvb.frontend = dvb_attach(ds3000_attach, 15190cb73639SIgor M. Liplianin &tevii_ds3000_config, 15200cb73639SIgor M. Liplianin &core->i2c_adap); 1521399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 152273f0af44SKonstantin Dimitrov dvb_attach(ts2020_attach, fe0->dvb.frontend, 152373f0af44SKonstantin Dimitrov &tevii_ts2020_config, &core->i2c_adap); 15240cb73639SIgor M. Liplianin fe0->dvb.frontend->ops.set_voltage = 15250cb73639SIgor M. Liplianin tevii_dvbs_set_voltage; 152673f0af44SKonstantin Dimitrov } 15270cb73639SIgor M. Liplianin break; 15284cd7fb87SOleg Roitburd case CX88_BOARD_OMICOM_SS4_PCI: 1529ee73042cSOleg Roitburd case CX88_BOARD_TBS_8920: 153057f51dbcSOleg Roitburd case CX88_BOARD_PROF_7300: 15314b29631dSIgor M. Liplianin case CX88_BOARD_SATTRADE_ST4200: 1532363c35fcSSteven Toth fe0->dvb.frontend = dvb_attach(cx24116_attach, 1533ee73042cSOleg Roitburd &hauppauge_hvr4000_config, 1534ee73042cSOleg Roitburd &core->i2c_adap); 1535399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) 1536363c35fcSSteven Toth fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1537ee73042cSOleg Roitburd break; 153870101a27SStephan Wienczny case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII: 153970101a27SStephan Wienczny fe0->dvb.frontend = dvb_attach(zl10353_attach, 154070101a27SStephan Wienczny &cx88_terratec_cinergy_ht_pci_mkii_config, 154170101a27SStephan Wienczny &core->i2c_adap); 154270101a27SStephan Wienczny if (fe0->dvb.frontend) { 154370101a27SStephan Wienczny fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; 154470101a27SStephan Wienczny if (attach_xc3028(0x61, dev) < 0) 154570101a27SStephan Wienczny goto frontend_detach; 154670101a27SStephan Wienczny } 154770101a27SStephan Wienczny break; 1548b699c271SIgor M. Liplianin case CX88_BOARD_PROF_7301:{ 1549b699c271SIgor M. Liplianin struct dvb_tuner_ops *tuner_ops = NULL; 1550b699c271SIgor M. Liplianin 1551b699c271SIgor M. Liplianin fe0->dvb.frontend = dvb_attach(stv0900_attach, 1552b699c271SIgor M. Liplianin &prof_7301_stv0900_config, 1553b699c271SIgor M. Liplianin &core->i2c_adap, 0); 1554399426caSMauro Carvalho Chehab if (fe0->dvb.frontend) { 1555b699c271SIgor M. Liplianin if (!dvb_attach(stb6100_attach, fe0->dvb.frontend, 1556b699c271SIgor M. Liplianin &prof_7301_stb6100_config, 1557b699c271SIgor M. Liplianin &core->i2c_adap)) 1558b699c271SIgor M. Liplianin goto frontend_detach; 1559b699c271SIgor M. Liplianin 1560b699c271SIgor M. Liplianin tuner_ops = &fe0->dvb.frontend->ops.tuner_ops; 1561b699c271SIgor M. Liplianin tuner_ops->set_frequency = stb6100_set_freq; 1562b699c271SIgor M. Liplianin tuner_ops->get_frequency = stb6100_get_freq; 1563b699c271SIgor M. Liplianin tuner_ops->set_bandwidth = stb6100_set_bandw; 1564b699c271SIgor M. Liplianin tuner_ops->get_bandwidth = stb6100_get_bandw; 1565b699c271SIgor M. Liplianin 1566b699c271SIgor M. Liplianin core->prev_set_voltage = 1567b699c271SIgor M. Liplianin fe0->dvb.frontend->ops.set_voltage; 1568b699c271SIgor M. Liplianin fe0->dvb.frontend->ops.set_voltage = 1569b699c271SIgor M. Liplianin tevii_dvbs_set_voltage; 1570b699c271SIgor M. Liplianin } 1571b699c271SIgor M. Liplianin break; 1572b699c271SIgor M. Liplianin } 15734f3ca2f1SDirk Herrendoerfer case CX88_BOARD_SAMSUNG_SMT_7020: 15744f3ca2f1SDirk Herrendoerfer dev->ts_gen_cntrl = 0x08; 15754f3ca2f1SDirk Herrendoerfer 15764f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x0101); 15774f3ca2f1SDirk Herrendoerfer 15784f3ca2f1SDirk Herrendoerfer cx_clear(MO_GP0_IO, 0x01); 15799d08ba6dSJia-Ju Bai msleep(100); 15804f3ca2f1SDirk Herrendoerfer cx_set(MO_GP0_IO, 0x01); 15819d08ba6dSJia-Ju Bai msleep(200); 15824f3ca2f1SDirk Herrendoerfer 15834f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend = dvb_attach(stv0299_attach, 15844f3ca2f1SDirk Herrendoerfer &samsung_stv0299_config, 15854f3ca2f1SDirk Herrendoerfer &dev->core->i2c_adap); 15864f3ca2f1SDirk Herrendoerfer if (fe0->dvb.frontend) { 15874f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend->ops.tuner_ops.set_params = 15884f3ca2f1SDirk Herrendoerfer samsung_smt_7020_tuner_set_params; 15894f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend->tuner_priv = 15904f3ca2f1SDirk Herrendoerfer &dev->core->i2c_adap; 15914f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend->ops.set_voltage = 15924f3ca2f1SDirk Herrendoerfer samsung_smt_7020_set_voltage; 15934f3ca2f1SDirk Herrendoerfer fe0->dvb.frontend->ops.set_tone = 15944f3ca2f1SDirk Herrendoerfer samsung_smt_7020_set_tone; 15954f3ca2f1SDirk Herrendoerfer } 15964f3ca2f1SDirk Herrendoerfer 15974f3ca2f1SDirk Herrendoerfer break; 1598111ac84aSSergey Ivanov case CX88_BOARD_TWINHAN_VP1027_DVBS: 1599111ac84aSSergey Ivanov dev->ts_gen_cntrl = 0x00; 1600111ac84aSSergey Ivanov fe0->dvb.frontend = dvb_attach(mb86a16_attach, 1601111ac84aSSergey Ivanov &twinhan_vp1027, 1602111ac84aSSergey Ivanov &core->i2c_adap); 1603111ac84aSSergey Ivanov if (fe0->dvb.frontend) { 1604111ac84aSSergey Ivanov core->prev_set_voltage = 1605111ac84aSSergey Ivanov fe0->dvb.frontend->ops.set_voltage; 1606111ac84aSSergey Ivanov fe0->dvb.frontend->ops.set_voltage = 1607111ac84aSSergey Ivanov vp1027_set_voltage; 1608111ac84aSSergey Ivanov } 1609111ac84aSSergey Ivanov break; 16104f3ca2f1SDirk Herrendoerfer 16111da177e4SLinus Torvalds default: 161265bc2fe8SMauro Carvalho Chehab pr_err("The frontend of your DVB/ATSC card isn't supported yet\n"); 16131da177e4SLinus Torvalds break; 16141da177e4SLinus Torvalds } 1615363c35fcSSteven Toth 1616363c35fcSSteven Toth if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) { 161765bc2fe8SMauro Carvalho Chehab pr_err("frontend initialization failed\n"); 161860a5a927SDarron Broad goto frontend_detach; 16199507901eSMauro Carvalho Chehab } 1620d7cba043SMichael Krufky /* define general-purpose callback pointer */ 1621363c35fcSSteven Toth fe0->dvb.frontend->callback = cx88_tuner_callback; 16229507901eSMauro Carvalho Chehab 16236c5be74cSSteven Toth /* Ensure all frontends negotiate bus access */ 1624363c35fcSSteven Toth fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 1625363c35fcSSteven Toth if (fe1) 1626363c35fcSSteven Toth fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 16271da177e4SLinus Torvalds 16283aab15afSHans Verkuil /* Put the tuner in standby to keep it quiet */ 16293aab15afSHans Verkuil call_all(core, tuner, standby); 163093352f5cSMauro Carvalho Chehab 16311da177e4SLinus Torvalds /* register everything */ 16320b6b6302SHans Verkuil res = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 16332773b0e9SMauro Carvalho Chehab &dev->pci->dev, NULL, adapter_nr, 16342773b0e9SMauro Carvalho Chehab mfe_shared); 16357b0962d3SDavid Fries if (res) 16367b0962d3SDavid Fries goto frontend_detach; 16377b0962d3SDavid Fries return res; 16380590d91cSMauro Carvalho Chehab 16390590d91cSMauro Carvalho Chehab frontend_detach: 1640e32fadc4SMauro Carvalho Chehab core->gate_ctrl = NULL; 16410b6b6302SHans Verkuil vb2_dvb_dealloc_frontends(&dev->frontends); 16427b0962d3SDavid Fries return res; 16431da177e4SLinus Torvalds } 16441da177e4SLinus Torvalds 16451da177e4SLinus Torvalds /* ----------------------------------------------------------- */ 16461da177e4SLinus Torvalds 16476c5be74cSSteven Toth /* CX8802 MPEG -> mini driver - We have been given the hardware */ 16486c5be74cSSteven Toth static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) 16491da177e4SLinus Torvalds { 16506c5be74cSSteven Toth struct cx88_core *core = drv->core; 16516c5be74cSSteven Toth int err = 0; 16527b61ba8fSMauro Carvalho Chehab 165332d83efcSHarvey Harrison dprintk(1, "%s\n", __func__); 16546c5be74cSSteven Toth 16556a59d64cSTrent Piepho switch (core->boardnr) { 16566c5be74cSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR1300: 16576c5be74cSSteven Toth /* We arrive here with either the cx23416 or the cx22702 16586c5be74cSSteven Toth * on the bus. Take the bus from the cx23416 and enable the 16596c5be74cSSteven Toth * cx22702 demod 16606c5be74cSSteven Toth */ 166179392737SDarron Broad /* Toggle reset on cx22702 leaving i2c active */ 166279392737SDarron Broad cx_set(MO_GP0_IO, 0x00000080); 166379392737SDarron Broad udelay(1000); 166479392737SDarron Broad cx_clear(MO_GP0_IO, 0x00000080); 166579392737SDarron Broad udelay(50); 166679392737SDarron Broad cx_set(MO_GP0_IO, 0x00000080); 166779392737SDarron Broad udelay(1000); 166879392737SDarron Broad /* enable the cx22702 pins */ 16696c5be74cSSteven Toth cx_clear(MO_GP0_IO, 0x00000004); 16706c5be74cSSteven Toth udelay(1000); 16716c5be74cSSteven Toth break; 1672363c35fcSSteven Toth 167392abe9eeSDarron Broad case CX88_BOARD_HAUPPAUGE_HVR3000: 1674363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR4000: 1675363c35fcSSteven Toth /* Toggle reset on cx22702 leaving i2c active */ 167679392737SDarron Broad cx_set(MO_GP0_IO, 0x00000080); 1677363c35fcSSteven Toth udelay(1000); 1678363c35fcSSteven Toth cx_clear(MO_GP0_IO, 0x00000080); 1679363c35fcSSteven Toth udelay(50); 168079392737SDarron Broad cx_set(MO_GP0_IO, 0x00000080); 1681363c35fcSSteven Toth udelay(1000); 168279392737SDarron Broad switch (core->dvbdev->frontends.active_fe_id) { 168379392737SDarron Broad case 1: /* DVB-S/S2 Enabled */ 168479392737SDarron Broad /* tri-state the cx22702 pins */ 168579392737SDarron Broad cx_set(MO_GP0_IO, 0x00000004); 168679392737SDarron Broad /* Take the cx24116/cx24123 out of reset */ 168779392737SDarron Broad cx_write(MO_SRST_IO, 1); 1688363c35fcSSteven Toth core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */ 168979392737SDarron Broad break; 169079392737SDarron Broad case 2: /* DVB-T Enabled */ 1691363c35fcSSteven Toth /* Put the cx24116/cx24123 into reset */ 1692363c35fcSSteven Toth cx_write(MO_SRST_IO, 0); 169379392737SDarron Broad /* enable the cx22702 pins */ 1694363c35fcSSteven Toth cx_clear(MO_GP0_IO, 0x00000004); 1695363c35fcSSteven Toth core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */ 169679392737SDarron Broad break; 1697363c35fcSSteven Toth } 169879392737SDarron Broad udelay(1000); 1699363c35fcSSteven Toth break; 1700363c35fcSSteven Toth 1701f271a3afSistvan_v@mailbox.hu case CX88_BOARD_WINFAST_DTV2000H_PLUS: 1702f271a3afSistvan_v@mailbox.hu /* set RF input to AIR for DVB-T (GPIO 16) */ 1703f271a3afSistvan_v@mailbox.hu cx_write(MO_GP2_IO, 0x0101); 1704f271a3afSistvan_v@mailbox.hu break; 1705f271a3afSistvan_v@mailbox.hu 17066c5be74cSSteven Toth default: 17076c5be74cSSteven Toth err = -ENODEV; 17086c5be74cSSteven Toth } 17096c5be74cSSteven Toth return err; 17106c5be74cSSteven Toth } 17116c5be74cSSteven Toth 17126c5be74cSSteven Toth /* CX8802 MPEG -> mini driver - We no longer have the hardware */ 17136c5be74cSSteven Toth static int cx8802_dvb_advise_release(struct cx8802_driver *drv) 17146c5be74cSSteven Toth { 17156c5be74cSSteven Toth struct cx88_core *core = drv->core; 17166c5be74cSSteven Toth int err = 0; 17177b61ba8fSMauro Carvalho Chehab 171832d83efcSHarvey Harrison dprintk(1, "%s\n", __func__); 17196c5be74cSSteven Toth 17206a59d64cSTrent Piepho switch (core->boardnr) { 17216c5be74cSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR1300: 17226c5be74cSSteven Toth /* Do Nothing, leave the cx22702 on the bus. */ 17236c5be74cSSteven Toth break; 1724363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR3000: 1725363c35fcSSteven Toth case CX88_BOARD_HAUPPAUGE_HVR4000: 1726363c35fcSSteven Toth break; 17276c5be74cSSteven Toth default: 17286c5be74cSSteven Toth err = -ENODEV; 17296c5be74cSSteven Toth } 17306c5be74cSSteven Toth return err; 17316c5be74cSSteven Toth } 17326c5be74cSSteven Toth 17336c5be74cSSteven Toth static int cx8802_dvb_probe(struct cx8802_driver *drv) 17346c5be74cSSteven Toth { 17356c5be74cSSteven Toth struct cx88_core *core = drv->core; 17366c5be74cSSteven Toth struct cx8802_dev *dev = drv->core->dvbdev; 1737cbd82441SDarron Broad int err; 17380b6b6302SHans Verkuil struct vb2_dvb_frontend *fe; 17396e0e12f1SAndy Walls int i; 17401da177e4SLinus Torvalds 174132d83efcSHarvey Harrison dprintk(1, "%s\n", __func__); 17426c5be74cSSteven Toth dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", 17436a59d64cSTrent Piepho core->boardnr, 17446c5be74cSSteven Toth core->name, 17456c5be74cSSteven Toth core->pci_bus, 17466c5be74cSSteven Toth core->pci_slot); 17471da177e4SLinus Torvalds 17481da177e4SLinus Torvalds err = -ENODEV; 17496a59d64cSTrent Piepho if (!(core->board.mpeg & CX88_MPEG_DVB)) 17501da177e4SLinus Torvalds goto fail_core; 17511da177e4SLinus Torvalds 1752ecf854dfSTrent Piepho /* If vp3054 isn't enabled, a stub will just return 0 */ 1753fc40b261SChris Pascoe err = vp3054_i2c_probe(dev); 17547b61ba8fSMauro Carvalho Chehab if (err != 0) 17556e0e12f1SAndy Walls goto fail_core; 1756fc40b261SChris Pascoe 17571da177e4SLinus Torvalds /* dvb stuff */ 175865bc2fe8SMauro Carvalho Chehab pr_info("cx2388x based DVB/ATSC card\n"); 1759363c35fcSSteven Toth dev->ts_gen_cntrl = 0x0c; 1760363c35fcSSteven Toth 17616e0e12f1SAndy Walls err = cx8802_alloc_frontends(dev); 17626e0e12f1SAndy Walls if (err) 17636e0e12f1SAndy Walls goto fail_core; 1764cbd82441SDarron Broad 1765363c35fcSSteven Toth for (i = 1; i <= core->board.num_frontends; i++) { 17660b6b6302SHans Verkuil struct vb2_queue *q; 17670b6b6302SHans Verkuil 17680b6b6302SHans Verkuil fe = vb2_dvb_get_frontend(&core->dvbdev->frontends, i); 1769399426caSMauro Carvalho Chehab if (!fe) { 177065bc2fe8SMauro Carvalho Chehab pr_err("%s() failed to get frontend(%d)\n", 1771cbd82441SDarron Broad __func__, i); 1772e546b1efSWei Yongjun err = -ENODEV; 1773cbd82441SDarron Broad goto fail_probe; 1774363c35fcSSteven Toth } 17750b6b6302SHans Verkuil q = &fe->dvb.dvbq; 17760b6b6302SHans Verkuil q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 17770b6b6302SHans Verkuil q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; 17780b6b6302SHans Verkuil q->gfp_flags = GFP_DMA32; 17790b6b6302SHans Verkuil q->min_buffers_needed = 2; 17800b6b6302SHans Verkuil q->drv_priv = dev; 17810b6b6302SHans Verkuil q->buf_struct_size = sizeof(struct cx88_buffer); 17820b6b6302SHans Verkuil q->ops = &dvb_qops; 17830b6b6302SHans Verkuil q->mem_ops = &vb2_dma_sg_memops; 17840b6b6302SHans Verkuil q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 17850b6b6302SHans Verkuil q->lock = &core->lock; 17862bc46b3aSHans Verkuil q->dev = &dev->pci->dev; 17870b6b6302SHans Verkuil 17880b6b6302SHans Verkuil err = vb2_queue_init(q); 17890b6b6302SHans Verkuil if (err < 0) 17900b6b6302SHans Verkuil goto fail_probe; 17910b6b6302SHans Verkuil 17920b6b6302SHans Verkuil /* init struct vb2_dvb */ 1793363c35fcSSteven Toth fe->dvb.name = dev->core->name; 1794363c35fcSSteven Toth } 17956e0e12f1SAndy Walls 17961da177e4SLinus Torvalds err = dvb_register(dev); 1797cbd82441SDarron Broad if (err) 1798cbd82441SDarron Broad /* frontends/adapter de-allocated in dvb_register */ 179965bc2fe8SMauro Carvalho Chehab pr_err("dvb_register failed (err = %d)\n", err); 1800cbd82441SDarron Broad return err; 1801cbd82441SDarron Broad fail_probe: 18020b6b6302SHans Verkuil vb2_dvb_dealloc_frontends(&core->dvbdev->frontends); 18031da177e4SLinus Torvalds fail_core: 18041da177e4SLinus Torvalds return err; 18051da177e4SLinus Torvalds } 18061da177e4SLinus Torvalds 18076c5be74cSSteven Toth static int cx8802_dvb_remove(struct cx8802_driver *drv) 18081da177e4SLinus Torvalds { 18090fcd488dSDarron Broad struct cx88_core *core = drv->core; 18106c5be74cSSteven Toth struct cx8802_dev *dev = drv->core->dvbdev; 1811611900c1SSteven Toth 18120fcd488dSDarron Broad dprintk(1, "%s\n", __func__); 18130fcd488dSDarron Broad 18140b6b6302SHans Verkuil vb2_dvb_unregister_bus(&dev->frontends); 18151da177e4SLinus Torvalds 1816fc40b261SChris Pascoe vp3054_i2c_remove(dev); 1817fc40b261SChris Pascoe 1818e32fadc4SMauro Carvalho Chehab core->gate_ctrl = NULL; 1819e32fadc4SMauro Carvalho Chehab 18206c5be74cSSteven Toth return 0; 18211da177e4SLinus Torvalds } 18221da177e4SLinus Torvalds 18236c5be74cSSteven Toth static struct cx8802_driver cx8802_dvb_driver = { 18246c5be74cSSteven Toth .type_id = CX88_MPEG_DVB, 18256c5be74cSSteven Toth .hw_access = CX8802_DRVCTL_SHARED, 18266c5be74cSSteven Toth .probe = cx8802_dvb_probe, 18276c5be74cSSteven Toth .remove = cx8802_dvb_remove, 18286c5be74cSSteven Toth .advise_acquire = cx8802_dvb_advise_acquire, 18296c5be74cSSteven Toth .advise_release = cx8802_dvb_advise_release, 18301da177e4SLinus Torvalds }; 18311da177e4SLinus Torvalds 183231d0f845SPeter Huewe static int __init dvb_init(void) 18331da177e4SLinus Torvalds { 183465bc2fe8SMauro Carvalho Chehab pr_info("cx2388x dvb driver version %s loaded\n", CX88_VERSION); 18356c5be74cSSteven Toth return cx8802_register_driver(&cx8802_dvb_driver); 18361da177e4SLinus Torvalds } 18371da177e4SLinus Torvalds 183831d0f845SPeter Huewe static void __exit dvb_fini(void) 18391da177e4SLinus Torvalds { 18406c5be74cSSteven Toth cx8802_unregister_driver(&cx8802_dvb_driver); 18411da177e4SLinus Torvalds } 18421da177e4SLinus Torvalds 18431da177e4SLinus Torvalds module_init(dvb_init); 18441da177e4SLinus Torvalds module_exit(dvb_fini); 1845