]> err.no Git - linux-2.6/blob - drivers/media/video/au0828/au0828-dvb.c
453fb3efa3e04a775852bdd2e7b8d4785f1e521a
[linux-2.6] / drivers / media / video / au0828 / au0828-dvb.c
1 /*
2  *  Driver for the Auvitek USB bridge
3  *
4  *  Copyright (c) 2008 Steven Toth <stoth@hauppauge.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/device.h>
25 #include <linux/suspend.h>
26 #include <media/v4l2-common.h>
27
28 #include "au0828.h"
29 #include "au8522.h"
30 #include "xc5000.h"
31
32 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
33
34 static struct au8522_config hauppauge_hvr950q_config = {
35         .demod_address = 0x8e >> 1,
36         .status_mode   = AU8522_DEMODLOCKING,
37 };
38
39 static struct xc5000_config hauppauge_hvr950q_tunerconfig = {
40         .i2c_address      = 0x61,
41         .if_khz           = 6000,
42         .tuner_callback   = au0828_tuner_callback
43 };
44
45 /*-------------------------------------------------------------------*/
46 static void urb_completion(struct urb *purb)
47 {
48         u8 *ptr;
49         struct au0828_dev *dev = purb->context;
50         int ptype = usb_pipetype(purb->pipe);
51
52         dprintk(2, "%s()\n", __FUNCTION__);
53
54         if (!dev)
55                 return;
56
57         if (dev->urb_streaming == 0)
58                 return;
59
60         if (ptype != PIPE_BULK) {
61                 printk(KERN_ERR "%s() Unsupported URB type %d\n", __FUNCTION__, ptype);
62                 return;
63         }
64
65         ptr = (u8 *)purb->transfer_buffer;
66
67         /* Feed the transport payload into the kernel demux */
68         dvb_dmx_swfilter_packets(&dev->dvb.demux, purb->transfer_buffer, purb->actual_length / 188);
69
70         /* Clean the buffer before we requeue */
71         memset(purb->transfer_buffer, 0, URB_BUFSIZE);
72
73         /* Requeue URB */
74         usb_submit_urb(purb, GFP_ATOMIC);
75 }
76
77 static int stop_urb_transfer(struct au0828_dev *dev)
78 {
79         int i;
80
81         dprintk(2, "%s()\n", __FUNCTION__);
82
83         /* FIXME:  Do we need to free the transfer_buffers? */
84         for (i = 0; i < URB_COUNT; i++) {
85                 usb_kill_urb(dev->urbs[i]);
86                 kfree(dev->urbs[i]->transfer_buffer);
87                 usb_free_urb(dev->urbs[i]);
88         }
89
90         dev->urb_streaming = 0;
91
92         return 0;
93 }
94
95 #define _AU0828_BULKPIPE 0x83
96 #define _BULKPIPESIZE 0xe522
97
98 static int start_urb_transfer(struct au0828_dev *dev)
99 {
100         struct urb *purb;
101         int i, ret = -ENOMEM;
102
103         dprintk(2, "%s()\n", __FUNCTION__);
104
105         if (dev->urb_streaming) {
106                 dprintk(2, "%s: iso xfer already running!\n", __FUNCTION__);
107                 return 0;
108         }
109
110         for (i = 0; i < URB_COUNT; i++) {
111
112                 dev->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
113                 if (!dev->urbs[i]) {
114                         goto err;
115                 }
116
117                 purb = dev->urbs[i];
118
119                 purb->transfer_buffer = kzalloc(URB_BUFSIZE, GFP_KERNEL);
120                 if (!purb->transfer_buffer) {
121                         usb_free_urb(purb);
122                         dev->urbs[i] = 0;
123                         goto err;
124                 }
125
126                 purb->status = -EINPROGRESS;
127                 usb_fill_bulk_urb(purb,
128                                   dev->usbdev,
129                                   usb_rcvbulkpipe(dev->usbdev, _AU0828_BULKPIPE),
130                                   purb->transfer_buffer,
131                                   URB_BUFSIZE,
132                                   urb_completion,
133                                   dev);
134
135         }
136
137         for (i = 0; i < URB_COUNT; i++) {
138                 ret = usb_submit_urb(dev->urbs[i], GFP_ATOMIC);
139                 if (ret != 0) {
140                         stop_urb_transfer(dev);
141                         printk("%s: failed urb submission, err = %d\n", __FUNCTION__, ret);
142                         return ret;
143                 }
144         }
145
146         dev->urb_streaming = 1;
147         ret = 0;
148
149 err:
150         return ret;
151 }
152
153 static int au0828_dvb_start_feed(struct dvb_demux_feed *feed)
154 {
155         struct dvb_demux *demux = feed->demux;
156         struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
157         struct au0828_dvb *dvb = &dev->dvb;
158         int ret = 0;
159
160         dprintk(1, "%s()\n", __FUNCTION__);
161
162         if (!demux->dmx.frontend)
163                 return -EINVAL;
164
165         if (dvb) {
166                 mutex_lock(&dvb->lock);
167                 if (dvb->feeding++ == 0) {
168                         /* Start transport */
169                         au0828_write(dev, 0x608, 0x90);
170                         au0828_write(dev, 0x609, 0x72);
171                         au0828_write(dev, 0x60a, 0x71);
172                         au0828_write(dev, 0x60b, 0x01);
173                         ret = start_urb_transfer(dev);
174                 }
175                 mutex_unlock(&dvb->lock);
176         }
177
178         return ret;
179 }
180
181 static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
182 {
183         struct dvb_demux *demux = feed->demux;
184         struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
185         struct au0828_dvb *dvb = &dev->dvb;
186         int ret = 0;
187
188         dprintk(1, "%s()\n", __FUNCTION__);
189
190         if (dvb) {
191                 mutex_lock(&dvb->lock);
192                 if (--dvb->feeding == 0) {
193                         /* Stop transport */
194                         au0828_write(dev, 0x608, 0x00);
195                         au0828_write(dev, 0x609, 0x00);
196                         au0828_write(dev, 0x60a, 0x00);
197                         au0828_write(dev, 0x60b, 0x00);
198                         ret = stop_urb_transfer(dev);
199                 }
200                 mutex_unlock(&dvb->lock);
201         }
202
203         return ret;
204 }
205
206 int dvb_register(struct au0828_dev *dev)
207 {
208         struct au0828_dvb *dvb = &dev->dvb;
209         int result;
210
211         dprintk(1, "%s()\n", __FUNCTION__);
212
213         /* register adapter */
214         result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
215                                       &dev->usbdev->dev, adapter_nr);
216         if (result < 0) {
217                 printk(KERN_ERROR "%s: dvb_register_adapter failed (errno = %d)\n",
218                        DRIVER_NAME, result);
219                 goto fail_adapter;
220         }
221         dvb->adapter.priv = dev;
222
223         /* register frontend */
224         result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
225         if (result < 0) {
226                 printk(KERN_ERR "%s: dvb_register_frontend failed (errno = %d)\n",
227                        DRIVER_NAME, result);
228                 goto fail_frontend;
229         }
230
231         /* register demux stuff */
232         dvb->demux.dmx.capabilities =
233                 DMX_TS_FILTERING | DMX_SECTION_FILTERING |
234                 DMX_MEMORY_BASED_FILTERING;
235         dvb->demux.priv       = dev;
236         dvb->demux.filternum  = 256;
237         dvb->demux.feednum    = 256;
238         dvb->demux.start_feed = au0828_dvb_start_feed;
239         dvb->demux.stop_feed  = au0828_dvb_stop_feed;
240         result = dvb_dmx_init(&dvb->demux);
241         if (result < 0) {
242                 printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
243                        DRIVER_NAME, result);
244                 goto fail_dmx;
245         }
246
247         dvb->dmxdev.filternum    = 256;
248         dvb->dmxdev.demux        = &dvb->demux.dmx;
249         dvb->dmxdev.capabilities = 0;
250         result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
251         if (result < 0) {
252                 printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
253                        DRIVER_NAME, result);
254                 goto fail_dmxdev;
255         }
256
257         dvb->fe_hw.source = DMX_FRONTEND_0;
258         result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
259         if (result < 0) {
260                 printk(KERN_ERR "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
261                        DRIVER_NAME, result);
262                 goto fail_fe_hw;
263         }
264
265         dvb->fe_mem.source = DMX_MEMORY_FE;
266         result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
267         if (result < 0) {
268                 printk(KERN_ERR "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
269                        DRIVER_NAME, result);
270                 goto fail_fe_mem;
271         }
272
273         result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
274         if (result < 0) {
275                 printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
276                        DRIVER_NAME, result);
277                 goto fail_fe_conn;
278         }
279
280         /* register network adapter */
281         dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
282         return 0;
283
284 fail_fe_conn:
285         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
286 fail_fe_mem:
287         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
288 fail_fe_hw:
289         dvb_dmxdev_release(&dvb->dmxdev);
290 fail_dmxdev:
291         dvb_dmx_release(&dvb->demux);
292 fail_dmx:
293         dvb_unregister_frontend(dvb->frontend);
294 fail_frontend:
295         dvb_frontend_detach(dvb->frontend);
296         dvb_unregister_adapter(&dvb->adapter);
297 fail_adapter:
298         return result;
299 }
300
301 void au0828_dvb_unregister(struct au0828_dev *dev)
302 {
303         struct au0828_dvb *dvb = &dev->dvb;
304
305         dprintk(1, "%s()\n", __FUNCTION__);
306
307         if(dvb->frontend == NULL)
308                 return;
309
310         dvb_net_release(&dvb->net);
311         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
312         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
313         dvb_dmxdev_release(&dvb->dmxdev);
314         dvb_dmx_release(&dvb->demux);
315         dvb_unregister_frontend(dvb->frontend);
316         dvb_frontend_detach(dvb->frontend);
317         dvb_unregister_adapter(&dvb->adapter);
318 }
319
320 /* All the DVB attach calls go here, this function get's modified
321  * for each new card. No other function in this file needs
322  * to change.
323  */
324 int au0828_dvb_register(struct au0828_dev *dev)
325 {
326         struct au0828_dvb *dvb = &dev->dvb;
327         int ret;
328
329         dprintk(1, "%s()\n", __FUNCTION__);
330
331         /* init frontend */
332         switch (dev->board) {
333         case AU0828_BOARD_HAUPPAUGE_HVR850:
334         case AU0828_BOARD_HAUPPAUGE_HVR950Q:
335         case AU0828_BOARD_DVICO_FUSIONHDTV7:
336                 dvb->frontend = dvb_attach(au8522_attach,
337                                 &hauppauge_hvr950q_config,
338                                 &dev->i2c_adap);
339                 if (dvb->frontend != NULL) {
340                         hauppauge_hvr950q_tunerconfig.priv = dev;
341                         dvb_attach(xc5000_attach, dvb->frontend,
342                                 &dev->i2c_adap,
343                                 &hauppauge_hvr950q_tunerconfig);
344                 }
345                 break;
346         default:
347                 printk("The frontend of your DVB/ATSC card isn't supported yet\n");
348                 break;
349         }
350         if (NULL == dvb->frontend) {
351                 printk(KERN_ERR "%s() Frontend initialization failed\n", __FUNCTION__);
352                 return -1;
353         }
354
355         /* Put the analog decoder in standby to keep it quiet */
356         au0828_call_i2c_clients(dev, TUNER_SET_STANDBY, NULL);
357
358         if (dvb->frontend->ops.analog_ops.standby)
359                 dvb->frontend->ops.analog_ops.standby(dvb->frontend);
360
361         /* register everything */
362         ret = dvb_register(dev);
363         if (ret < 0) {
364                 if (dvb->frontend->ops.release)
365                         dvb->frontend->ops.release(dvb->frontend);
366                 return ret;
367         }
368
369         return 0;
370 }