This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / media / video / cx88 / cx88-dvb.c
1 /*
2  * $Id: cx88-dvb.c,v 1.19 2004/11/07 14:44:59 kraxel Exp $
3  *
4  * device driver for Conexant 2388x based TV cards
5  * MPEG Transport Stream (DVB) routines
6  *
7  * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
8  * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
9  *
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.
14  *
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.
19  *
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.
23  */
24
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/device.h>
28 #include <linux/fs.h>
29 #include <linux/kthread.h>
30 #include <linux/file.h>
31 #include <linux/suspend.h>
32
33 #include "cx88.h"
34 #include "cx22702.h"
35 #include "mt352.h"
36 #include "mt352_priv.h" /* FIXME */
37
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");
42
43 static unsigned int debug = 0;
44 module_param(debug, int, 0644);
45 MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
46
47 #define dprintk(level,fmt, arg...)      if (debug >= level) \
48         printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg)
49
50 /* ------------------------------------------------------------------ */
51
52 static int dvb_buf_setup(struct videobuf_queue *q,
53                          unsigned int *count, unsigned int *size)
54 {
55         struct cx8802_dev *dev = q->priv_data;
56
57         dev->ts_packet_size  = 188 * 4;
58         dev->ts_packet_count = 32;
59
60         *size  = dev->ts_packet_size * dev->ts_packet_count;
61         *count = 32;
62         return 0;
63 }
64
65 static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
66                            enum v4l2_field field)
67 {
68         struct cx8802_dev *dev = q->priv_data;
69         return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb);
70 }
71
72 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
73 {
74         struct cx8802_dev *dev = q->priv_data;
75         cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
76 }
77
78 static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
79 {
80         struct cx8802_dev *dev = q->priv_data;
81         cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
82 }
83
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,
89 };
90
91 /* ------------------------------------------------------------------ */
92
93 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
94 {
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 };
101
102         mt352_write(fe, clock_config,   sizeof(clock_config));
103         udelay(200);
104         mt352_write(fe, reset,          sizeof(reset));
105         mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
106
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));
110         return 0;
111 }
112
113 #define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
114
115 static int lg_z201_pll_set(struct dvb_frontend* fe,
116                            struct dvb_frontend_parameters* params, u8* pllbuf)
117 {
118         u32 div;
119         unsigned char cp = 0;
120         unsigned char bs = 0;
121
122         div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
123
124         if (params->frequency < 542000000) cp = 0xbc;
125         else if (params->frequency < 830000000) cp = 0xf4;
126         else cp = 0xfc;
127
128         if (params->frequency == 0) bs = 0x03;
129         else if (params->frequency < 157500000) bs = 0x01;
130         else if (params->frequency < 443250000) bs = 0x02;
131         else bs = 0x04;
132
133         pllbuf[0] = 0xC2; /* Note: non-linux standard PLL I2C address */
134         pllbuf[1] = div >> 8;
135         pllbuf[2] = div & 0xff;
136         pllbuf[3] = cp;
137         pllbuf[4] = bs;
138
139         return 0;
140 }
141
142 static int thomson_dtt7579_pll_set(struct dvb_frontend* fe,
143                                    struct dvb_frontend_parameters* params,
144                                    u8* pllbuf)
145 {
146         u32 div;
147         unsigned char cp = 0;
148         unsigned char bs = 0;
149
150         div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
151
152         if (params->frequency < 542000000) cp = 0xb4;
153         else if (params->frequency < 771000000) cp = 0xbc;
154         else cp = 0xf4;
155
156         if (params->frequency == 0) bs = 0x03;
157         else if (params->frequency < 443250000) bs = 0x02;
158         else bs = 0x08;
159
160         pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
161         pllbuf[1] = div >> 8;
162         pllbuf[2] = div & 0xff;
163         pllbuf[3] = cp;
164         pllbuf[4] = bs;
165
166         return 0;
167 }
168
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,
173 };
174
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,
179 };
180
181 static int dvb_register(struct cx8802_dev *dev)
182 {
183         /* init struct videobuf_dvb */
184         dev->dvb.name = dev->core->name;
185
186         /* init frontend */
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,
191                                                    dev->core->pll_addr,
192                                                    dev->core->pll_type,
193                                                    dev->core->demod_addr);
194                 break;
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;
201                 }
202                 break;
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;
209                 }
210                 break;
211         default:
212                 printk("%s: FIXME: frontend handling not here yet ...\n",
213                        dev->core->name);
214                 break;
215         }
216         if (NULL == dev->dvb.frontend)
217                 return -1;
218
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));
223
224         /* register everything */
225         return videobuf_dvb_register(&dev->dvb);
226 }
227
228 /* ----------------------------------------------------------- */
229
230 static int __devinit dvb_probe(struct pci_dev *pci_dev,
231                                const struct pci_device_id *pci_id)
232 {
233         struct cx8802_dev *dev;
234         struct cx88_core  *core;
235         int err;
236
237         /* general setup */
238         core = cx88_core_get(pci_dev);
239         if (NULL == core)
240                 return -EINVAL;
241
242         err = -ENODEV;
243         if (!cx88_boards[core->board].dvb)
244                 goto fail_core;
245
246         err = -ENOMEM;
247         dev = kmalloc(sizeof(*dev),GFP_KERNEL);
248         if (NULL == dev)
249                 goto fail_core;
250         memset(dev,0,sizeof(*dev));
251         dev->pci = pci_dev;
252         dev->core = core;
253
254         err = cx8802_init_common(dev);
255         if (0 != err)
256                 goto fail_free;
257
258         /* dvb stuff */
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,
263                             V4L2_FIELD_TOP,
264                             sizeof(struct cx88_buffer),
265                             dev);
266         err = dvb_register(dev);
267         if (0 != err)
268                 goto fail_free;
269         return 0;
270
271  fail_free:
272         kfree(dev);
273  fail_core:
274         cx88_core_put(core,pci_dev);
275         return err;
276 }
277
278 static void __devexit dvb_remove(struct pci_dev *pci_dev)
279 {
280         struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
281
282         /* dvb */
283         videobuf_dvb_unregister(&dev->dvb);
284
285         /* common */
286         cx8802_fini_common(dev);
287         cx88_core_put(dev->core,dev->pci);
288         kfree(dev);
289 }
290
291 static struct pci_device_id cx8802_pci_tbl[] = {
292         {
293                 .vendor       = 0x14f1,
294                 .device       = 0x8802,
295                 .subvendor    = PCI_ANY_ID,
296                 .subdevice    = PCI_ANY_ID,
297         },{
298                 /* --- end of list --- */
299         }
300 };
301 MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
302
303 static struct pci_driver dvb_pci_driver = {
304         .name     = "cx88-dvb",
305         .id_table = cx8802_pci_tbl,
306         .probe    = dvb_probe,
307         .remove   = __devexit_p(dvb_remove),
308         .suspend  = cx8802_suspend_common,
309         .resume   = cx8802_resume_common,
310 };
311
312 static int dvb_init(void)
313 {
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);
318 #ifdef SNAPSHOT
319         printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
320                SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
321 #endif
322         return pci_module_init(&dvb_pci_driver);
323 }
324
325 static void dvb_fini(void)
326 {
327         pci_unregister_driver(&dvb_pci_driver);
328 }
329
330 module_init(dvb_init);
331 module_exit(dvb_fini);
332
333 /*
334  * Local variables:
335  * c-basic-offset: 8
336  * compile-command: "make DVB=1"
337  * End:
338  */