2 * $Id: cx88-dvb.c,v 1.19 2004/11/07 14:44:59 kraxel Exp $
4 * device driver for Conexant 2388x based TV cards
5 * MPEG Transport Stream (DVB) routines
7 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/device.h>
29 #include <linux/kthread.h>
30 #include <linux/file.h>
31 #include <linux/suspend.h>
36 #include "mt352_priv.h" /* FIXME */
38 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
39 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
40 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
41 MODULE_LICENSE("GPL");
43 static unsigned int debug = 0;
44 module_param(debug, int, 0644);
45 MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
47 #define dprintk(level,fmt, arg...) if (debug >= level) \
48 printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg)
50 /* ------------------------------------------------------------------ */
52 static int dvb_buf_setup(struct videobuf_queue *q,
53 unsigned int *count, unsigned int *size)
55 struct cx8802_dev *dev = q->priv_data;
57 dev->ts_packet_size = 188 * 4;
58 dev->ts_packet_count = 32;
60 *size = dev->ts_packet_size * dev->ts_packet_count;
65 static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
66 enum v4l2_field field)
68 struct cx8802_dev *dev = q->priv_data;
69 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb);
72 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
74 struct cx8802_dev *dev = q->priv_data;
75 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
78 static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
80 struct cx8802_dev *dev = q->priv_data;
81 cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
84 struct videobuf_queue_ops dvb_qops = {
85 .buf_setup = dvb_buf_setup,
86 .buf_prepare = dvb_buf_prepare,
87 .buf_queue = dvb_buf_queue,
88 .buf_release = dvb_buf_release,
91 /* ------------------------------------------------------------------ */
93 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
95 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
96 static u8 reset [] = { RESET, 0x80 };
97 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
98 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
99 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
100 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
102 mt352_write(fe, clock_config, sizeof(clock_config));
104 mt352_write(fe, reset, sizeof(reset));
105 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
107 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
108 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
109 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
113 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
115 static int lg_z201_pll_set(struct dvb_frontend* fe,
116 struct dvb_frontend_parameters* params, u8* pllbuf)
119 unsigned char cp = 0;
120 unsigned char bs = 0;
122 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
124 if (params->frequency < 542000000) cp = 0xbc;
125 else if (params->frequency < 830000000) cp = 0xf4;
128 if (params->frequency == 0) bs = 0x03;
129 else if (params->frequency < 157500000) bs = 0x01;
130 else if (params->frequency < 443250000) bs = 0x02;
133 pllbuf[0] = 0xC2; /* Note: non-linux standard PLL I2C address */
134 pllbuf[1] = div >> 8;
135 pllbuf[2] = div & 0xff;
142 static int thomson_dtt7579_pll_set(struct dvb_frontend* fe,
143 struct dvb_frontend_parameters* params,
147 unsigned char cp = 0;
148 unsigned char bs = 0;
150 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
152 if (params->frequency < 542000000) cp = 0xb4;
153 else if (params->frequency < 771000000) cp = 0xbc;
156 if (params->frequency == 0) bs = 0x03;
157 else if (params->frequency < 443250000) bs = 0x02;
160 pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
161 pllbuf[1] = div >> 8;
162 pllbuf[2] = div & 0xff;
169 struct mt352_config dvico_fusionhdtv_dvbt1 = {
170 .demod_address = 0x0F,
171 .demod_init = dvico_fusionhdtv_demod_init,
172 .pll_set = lg_z201_pll_set,
175 struct mt352_config dvico_fusionhdtv_dvbt_plus = {
176 .demod_address = 0x0F,
177 .demod_init = dvico_fusionhdtv_demod_init,
178 .pll_set = thomson_dtt7579_pll_set,
181 static int dvb_register(struct cx8802_dev *dev)
183 /* init struct videobuf_dvb */
184 dev->dvb.name = dev->core->name;
187 switch (dev->core->board) {
188 case CX88_BOARD_HAUPPAUGE_DVB_T1:
189 case CX88_BOARD_CONEXANT_DVB_T1:
190 dev->dvb.frontend = cx22702_create(&dev->core->i2c_adap,
193 dev->core->demod_addr);
195 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
196 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dvbt1,
197 &dev->core->i2c_adap);
198 if (dev->dvb.frontend) {
199 dev->dvb.frontend->ops->info.frequency_min = 174000000;
200 dev->dvb.frontend->ops->info.frequency_max = 862000000;
203 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
204 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dvbt_plus,
205 &dev->core->i2c_adap);
206 if (dev->dvb.frontend) {
207 dev->dvb.frontend->ops->info.frequency_min = 174000000;
208 dev->dvb.frontend->ops->info.frequency_max = 862000000;
212 printk("%s: FIXME: frontend handling not here yet ...\n",
216 if (NULL == dev->dvb.frontend)
219 /* Copy the board name into the DVB structure */
220 strlcpy(dev->dvb.frontend->ops->info.name,
221 cx88_boards[dev->core->board].name,
222 sizeof(dev->dvb.frontend->ops->info.name));
224 /* register everything */
225 return videobuf_dvb_register(&dev->dvb);
228 /* ----------------------------------------------------------- */
230 static int __devinit dvb_probe(struct pci_dev *pci_dev,
231 const struct pci_device_id *pci_id)
233 struct cx8802_dev *dev;
234 struct cx88_core *core;
238 core = cx88_core_get(pci_dev);
243 if (!cx88_boards[core->board].dvb)
247 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
250 memset(dev,0,sizeof(*dev));
254 err = cx8802_init_common(dev);
259 printk("%s/2: cx2388x based dvb card\n", core->name);
260 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
261 dev->pci, &dev->slock,
262 V4L2_BUF_TYPE_VIDEO_CAPTURE,
264 sizeof(struct cx88_buffer),
266 err = dvb_register(dev);
274 cx88_core_put(core,pci_dev);
278 static void __devexit dvb_remove(struct pci_dev *pci_dev)
280 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
283 videobuf_dvb_unregister(&dev->dvb);
286 cx8802_fini_common(dev);
287 cx88_core_put(dev->core,dev->pci);
291 static struct pci_device_id cx8802_pci_tbl[] = {
295 .subvendor = PCI_ANY_ID,
296 .subdevice = PCI_ANY_ID,
298 /* --- end of list --- */
301 MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
303 static struct pci_driver dvb_pci_driver = {
305 .id_table = cx8802_pci_tbl,
307 .remove = __devexit_p(dvb_remove),
308 .suspend = cx8802_suspend_common,
309 .resume = cx8802_resume_common,
312 static int dvb_init(void)
314 printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n",
315 (CX88_VERSION_CODE >> 16) & 0xff,
316 (CX88_VERSION_CODE >> 8) & 0xff,
317 CX88_VERSION_CODE & 0xff);
319 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
320 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
322 return pci_module_init(&dvb_pci_driver);
325 static void dvb_fini(void)
327 pci_unregister_driver(&dvb_pci_driver);
330 module_init(dvb_init);
331 module_exit(dvb_fini);
336 * compile-command: "make DVB=1"