2 * dvb-dibusb-dvb.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
7 * see dvb-dibusb-core.c for more copyright details.
9 * This file contains functions for initializing and handling the
12 #include "dvb-dibusb.h"
14 #include <linux/usb.h>
15 #include <linux/version.h>
17 static u32 urb_compl_count
;
22 void dibusb_urb_complete(struct urb
*urb
, struct pt_regs
*ptregs
)
24 struct usb_dibusb
*dib
= urb
->context
;
26 deb_ts("urb complete feedcount: %d, status: %d, length: %d\n",dib
->feedcount
,urb
->status
,
30 if (urb_compl_count
% 1000 == 0)
31 deb_info("%d urbs completed so far.\n",urb_compl_count
);
33 switch (urb
->status
) {
35 case -ETIMEDOUT
: /* NAK */
37 case -ECONNRESET
: /* kill */
42 deb_ts("urb completition error %d.", urb
->status
);
46 if (dib
->feedcount
> 0 && urb
->actual_length
> 0) {
47 if (dib
->init_state
& DIBUSB_STATE_DVB
)
48 dvb_dmx_swfilter(&dib
->demux
, (u8
*) urb
->transfer_buffer
,urb
->actual_length
);
50 deb_ts("URB dropped because of feedcount.\n");
52 usb_submit_urb(urb
,GFP_ATOMIC
);
55 static int dibusb_ctrl_feed(struct dvb_demux_feed
*dvbdmxfeed
, int onoff
)
57 struct usb_dibusb
*dib
= dvbdmxfeed
->demux
->priv
;
63 newfeedcount
= dib
->feedcount
+ (onoff
? 1 : -1);
66 * stop feed before setting a new pid if there will be no pid anymore
68 if (newfeedcount
== 0) {
69 deb_ts("stop feeding\n");
70 if (dib
->xfer_ops
.fifo_ctrl
!= NULL
) {
71 if (dib
->xfer_ops
.fifo_ctrl(dib
->fe
,0)) {
72 err("error while inhibiting fifo.");
76 dibusb_streaming(dib
,0);
79 dib
->feedcount
= newfeedcount
;
81 /* activate the pid on the device specific pid_filter */
82 deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed
->pid
,dvbdmxfeed
->pid
,dvbdmxfeed
->index
,onoff
? "on" : "off");
83 if (dib
->pid_parse
&& dib
->xfer_ops
.pid_ctrl
!= NULL
)
84 dib
->xfer_ops
.pid_ctrl(dib
->fe
,dvbdmxfeed
->index
,dvbdmxfeed
->pid
,onoff
);
87 * start the feed if this was the first pid to set and there is still a pid
90 if (dib
->feedcount
== onoff
&& dib
->feedcount
> 0) {
92 deb_ts("controlling pid parser\n");
93 if (dib
->xfer_ops
.pid_parse
!= NULL
) {
94 if (dib
->xfer_ops
.pid_parse(dib
->fe
,dib
->pid_parse
) < 0) {
95 err("could not handle pid_parser");
99 deb_ts("start feeding\n");
100 if (dib
->xfer_ops
.fifo_ctrl
!= NULL
) {
101 if (dib
->xfer_ops
.fifo_ctrl(dib
->fe
,1)) {
102 err("error while enabling fifo.");
106 dibusb_streaming(dib
,1);
111 static int dibusb_start_feed(struct dvb_demux_feed
*dvbdmxfeed
)
113 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed
->pid
,dvbdmxfeed
->type
);
114 return dibusb_ctrl_feed(dvbdmxfeed
,1);
117 static int dibusb_stop_feed(struct dvb_demux_feed
*dvbdmxfeed
)
119 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed
->pid
, dvbdmxfeed
->type
);
120 return dibusb_ctrl_feed(dvbdmxfeed
,0);
123 int dibusb_dvb_init(struct usb_dibusb
*dib
)
129 if ((ret
= dvb_register_adapter(&dib
->adapter
, DRIVER_DESC
,
131 deb_info("dvb_register_adapter failed: error %d", ret
);
134 dib
->adapter
.priv
= dib
;
136 /* i2c is done in dibusb_i2c_init */
138 dib
->demux
.dmx
.capabilities
= DMX_TS_FILTERING
| DMX_SECTION_FILTERING
;
140 dib
->demux
.priv
= (void *)dib
;
141 /* get pidcount from demod */
142 dib
->demux
.feednum
= dib
->demux
.filternum
= 255;
143 dib
->demux
.start_feed
= dibusb_start_feed
;
144 dib
->demux
.stop_feed
= dibusb_stop_feed
;
145 dib
->demux
.write_to_decoder
= NULL
;
146 if ((ret
= dvb_dmx_init(&dib
->demux
)) < 0) {
147 err("dvb_dmx_init failed: error %d",ret
);
151 dib
->dmxdev
.filternum
= dib
->demux
.filternum
;
152 dib
->dmxdev
.demux
= &dib
->demux
.dmx
;
153 dib
->dmxdev
.capabilities
= 0;
154 if ((ret
= dvb_dmxdev_init(&dib
->dmxdev
, &dib
->adapter
)) < 0) {
155 err("dvb_dmxdev_init failed: error %d",ret
);
159 dvb_net_init(&dib
->adapter
, &dib
->dvb_net
, &dib
->demux
.dmx
);
163 dvb_dmx_release(&dib
->demux
);
165 dvb_unregister_adapter(&dib
->adapter
);
169 dib
->init_state
|= DIBUSB_STATE_DVB
;
173 int dibusb_dvb_exit(struct usb_dibusb
*dib
)
175 if (dib
->init_state
& DIBUSB_STATE_DVB
) {
176 dib
->init_state
&= ~DIBUSB_STATE_DVB
;
177 deb_info("unregistering DVB part\n");
178 dvb_net_release(&dib
->dvb_net
);
179 dib
->demux
.dmx
.close(&dib
->demux
.dmx
);
180 dvb_dmxdev_release(&dib
->dmxdev
);
181 dvb_dmx_release(&dib
->demux
);
182 dvb_unregister_adapter(&dib
->adapter
);