2 * pvrusb2-dvb.c - linux-dvb api interface to the pvrusb2 driver.
4 * Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
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
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/kthread.h>
22 #include <linux/freezer.h>
23 #include <linux/slab.h>
26 #include "pvrusb2-debug.h"
27 #include "pvrusb2-hdw-internal.h"
28 #include "pvrusb2-hdw.h"
29 #include "pvrusb2-io.h"
30 #include "pvrusb2-dvb.h"
32 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
34 static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter
*adap
)
38 struct pvr2_buffer
*bp
;
39 struct pvr2_stream
*stream
;
41 pvr2_trace(PVR2_TRACE_DVB_FEED
, "dvb feed thread started");
44 stream
= adap
->channel
.stream
->stream
;
47 if (kthread_should_stop()) break;
49 /* Not sure about this... */
52 bp
= pvr2_stream_get_ready_buffer(stream
);
54 count
= pvr2_buffer_get_count(bp
);
59 pvr2_buffer_get_id(bp
)],
62 ret
= pvr2_buffer_get_status(bp
);
65 ret
= pvr2_buffer_queue(bp
);
68 /* Since we know we did something to a buffer,
69 just go back and try again. No point in
70 blocking unless we really ran out of
71 buffers to process. */
76 /* Wait until more buffers become available or we're
77 told not to wait any longer. */
78 ret
= wait_event_interruptible(
79 adap
->buffer_wait_data
,
80 (pvr2_stream_get_ready_count(stream
) > 0) ||
81 kthread_should_stop());
85 /* If we get here and ret is < 0, then an error has occurred.
86 Probably would be a good idea to communicate that to DVB core... */
88 pvr2_trace(PVR2_TRACE_DVB_FEED
, "dvb feed thread stopped");
93 static int pvr2_dvb_feed_thread(void *data
)
95 int stat
= pvr2_dvb_feed_func(data
);
96 /* from videobuf-dvb.c: */
97 while (!kthread_should_stop()) {
98 set_current_state(TASK_INTERRUPTIBLE
);
104 static void pvr2_dvb_notify(struct pvr2_dvb_adapter
*adap
)
106 wake_up(&adap
->buffer_wait_data
);
109 static void pvr2_dvb_stream_end(struct pvr2_dvb_adapter
*adap
)
112 struct pvr2_stream
*stream
;
115 kthread_stop(adap
->thread
);
119 if (adap
->channel
.stream
) {
120 stream
= adap
->channel
.stream
->stream
;
125 pvr2_hdw_set_streaming(adap
->channel
.hdw
, 0);
126 pvr2_stream_set_callback(stream
, NULL
, NULL
);
127 pvr2_stream_kill(stream
);
128 pvr2_stream_set_buffer_count(stream
, 0);
129 pvr2_channel_claim_stream(&adap
->channel
, NULL
);
132 if (adap
->stream_run
) {
133 for (idx
= 0; idx
< PVR2_DVB_BUFFER_COUNT
; idx
++) {
134 if (!(adap
->buffer_storage
[idx
])) continue;
135 kfree(adap
->buffer_storage
[idx
]);
136 adap
->buffer_storage
[idx
] = NULL
;
138 adap
->stream_run
= 0;
142 static int pvr2_dvb_stream_do_start(struct pvr2_dvb_adapter
*adap
)
144 struct pvr2_context
*pvr
= adap
->channel
.mc_head
;
147 struct pvr2_buffer
*bp
;
148 struct pvr2_stream
*stream
= NULL
;
150 if (adap
->stream_run
) return -EIO
;
152 ret
= pvr2_channel_claim_stream(&adap
->channel
, &pvr
->video_stream
);
153 /* somebody else already has the stream */
154 if (ret
< 0) return ret
;
156 stream
= adap
->channel
.stream
->stream
;
158 for (idx
= 0; idx
< PVR2_DVB_BUFFER_COUNT
; idx
++) {
159 adap
->buffer_storage
[idx
] = kmalloc(PVR2_DVB_BUFFER_SIZE
,
161 if (!(adap
->buffer_storage
[idx
])) return -ENOMEM
;
164 pvr2_stream_set_callback(pvr
->video_stream
.stream
,
165 (pvr2_stream_callback
) pvr2_dvb_notify
, adap
);
167 ret
= pvr2_stream_set_buffer_count(stream
, PVR2_DVB_BUFFER_COUNT
);
168 if (ret
< 0) return ret
;
170 for (idx
= 0; idx
< PVR2_DVB_BUFFER_COUNT
; idx
++) {
171 bp
= pvr2_stream_get_buffer(stream
, idx
);
172 pvr2_buffer_set_buffer(bp
,
173 adap
->buffer_storage
[idx
],
174 PVR2_DVB_BUFFER_SIZE
);
177 ret
= pvr2_hdw_set_streaming(adap
->channel
.hdw
, 1);
178 if (ret
< 0) return ret
;
180 while ((bp
= pvr2_stream_get_idle_buffer(stream
)) != NULL
) {
181 ret
= pvr2_buffer_queue(bp
);
182 if (ret
< 0) return ret
;
185 adap
->thread
= kthread_run(pvr2_dvb_feed_thread
, adap
, "pvrusb2-dvb");
187 if (IS_ERR(adap
->thread
)) {
188 ret
= PTR_ERR(adap
->thread
);
193 adap
->stream_run
= !0;
198 static int pvr2_dvb_stream_start(struct pvr2_dvb_adapter
*adap
)
200 int ret
= pvr2_dvb_stream_do_start(adap
);
201 if (ret
< 0) pvr2_dvb_stream_end(adap
);
205 static int pvr2_dvb_ctrl_feed(struct dvb_demux_feed
*dvbdmxfeed
, int onoff
)
207 struct pvr2_dvb_adapter
*adap
= dvbdmxfeed
->demux
->priv
;
210 if (adap
== NULL
) return -ENODEV
;
212 mutex_lock(&adap
->lock
);
215 if (!adap
->feedcount
) {
216 pvr2_trace(PVR2_TRACE_DVB_FEED
,
217 "start feeding demux");
218 ret
= pvr2_dvb_stream_start(adap
);
222 } else if (adap
->feedcount
> 0) {
224 if (!adap
->feedcount
) {
225 pvr2_trace(PVR2_TRACE_DVB_FEED
,
226 "stop feeding demux");
227 pvr2_dvb_stream_end(adap
);
231 mutex_unlock(&adap
->lock
);
236 static int pvr2_dvb_start_feed(struct dvb_demux_feed
*dvbdmxfeed
)
238 pvr2_trace(PVR2_TRACE_DVB_FEED
, "start pid: 0x%04x", dvbdmxfeed
->pid
);
239 return pvr2_dvb_ctrl_feed(dvbdmxfeed
, 1);
242 static int pvr2_dvb_stop_feed(struct dvb_demux_feed
*dvbdmxfeed
)
244 pvr2_trace(PVR2_TRACE_DVB_FEED
, "stop pid: 0x%04x", dvbdmxfeed
->pid
);
245 return pvr2_dvb_ctrl_feed(dvbdmxfeed
, 0);
248 static int pvr2_dvb_bus_ctrl(struct dvb_frontend
*fe
, int acquire
)
250 struct pvr2_dvb_adapter
*adap
= fe
->dvb
->priv
;
251 return pvr2_channel_limit_inputs(
253 (acquire
? (1 << PVR2_CVAL_INPUT_DTV
) : 0));
256 static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter
*adap
)
260 ret
= dvb_register_adapter(&adap
->dvb_adap
, "pvrusb2-dvb",
261 THIS_MODULE
/*&hdw->usb_dev->owner*/,
262 &adap
->channel
.hdw
->usb_dev
->dev
,
265 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
266 "dvb_register_adapter failed: error %d", ret
);
269 adap
->dvb_adap
.priv
= adap
;
271 adap
->demux
.dmx
.capabilities
= DMX_TS_FILTERING
|
272 DMX_SECTION_FILTERING
|
273 DMX_MEMORY_BASED_FILTERING
;
274 adap
->demux
.priv
= adap
;
275 adap
->demux
.filternum
= 256;
276 adap
->demux
.feednum
= 256;
277 adap
->demux
.start_feed
= pvr2_dvb_start_feed
;
278 adap
->demux
.stop_feed
= pvr2_dvb_stop_feed
;
279 adap
->demux
.write_to_decoder
= NULL
;
281 ret
= dvb_dmx_init(&adap
->demux
);
283 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
284 "dvb_dmx_init failed: error %d", ret
);
288 adap
->dmxdev
.filternum
= adap
->demux
.filternum
;
289 adap
->dmxdev
.demux
= &adap
->demux
.dmx
;
290 adap
->dmxdev
.capabilities
= 0;
292 ret
= dvb_dmxdev_init(&adap
->dmxdev
, &adap
->dvb_adap
);
294 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
295 "dvb_dmxdev_init failed: error %d", ret
);
299 dvb_net_init(&adap
->dvb_adap
, &adap
->dvb_net
, &adap
->demux
.dmx
);
304 dvb_dmx_release(&adap
->demux
);
306 dvb_unregister_adapter(&adap
->dvb_adap
);
311 static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter
*adap
)
313 pvr2_trace(PVR2_TRACE_INFO
, "unregistering DVB devices");
314 dvb_net_release(&adap
->dvb_net
);
315 adap
->demux
.dmx
.close(&adap
->demux
.dmx
);
316 dvb_dmxdev_release(&adap
->dmxdev
);
317 dvb_dmx_release(&adap
->demux
);
318 dvb_unregister_adapter(&adap
->dvb_adap
);
322 static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter
*adap
)
324 struct pvr2_hdw
*hdw
= adap
->channel
.hdw
;
325 const struct pvr2_dvb_props
*dvb_props
= hdw
->hdw_desc
->dvb_props
;
328 if (dvb_props
== NULL
) {
329 pvr2_trace(PVR2_TRACE_ERROR_LEGS
, "fe_props not defined!");
333 ret
= pvr2_channel_limit_inputs(
335 (1 << PVR2_CVAL_INPUT_DTV
));
337 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
338 "failed to grab control of dtv input (code=%d)",
343 if (dvb_props
->frontend_attach
== NULL
) {
344 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
345 "frontend_attach not defined!");
350 if ((dvb_props
->frontend_attach(adap
) == 0) && (adap
->fe
)) {
352 if (dvb_register_frontend(&adap
->dvb_adap
, adap
->fe
)) {
353 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
354 "frontend registration failed!");
355 dvb_frontend_detach(adap
->fe
);
361 if (dvb_props
->tuner_attach
)
362 dvb_props
->tuner_attach(adap
);
364 if (adap
->fe
->ops
.analog_ops
.standby
)
365 adap
->fe
->ops
.analog_ops
.standby(adap
->fe
);
367 /* Ensure all frontends negotiate bus access */
368 adap
->fe
->ops
.ts_bus_ctrl
= pvr2_dvb_bus_ctrl
;
371 pvr2_trace(PVR2_TRACE_ERROR_LEGS
,
372 "no frontend was attached!");
378 pvr2_channel_limit_inputs(&adap
->channel
, 0);
382 static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter
*adap
)
384 if (adap
->fe
!= NULL
) {
385 dvb_unregister_frontend(adap
->fe
);
386 dvb_frontend_detach(adap
->fe
);
391 static void pvr2_dvb_destroy(struct pvr2_dvb_adapter
*adap
)
393 pvr2_dvb_stream_end(adap
);
394 pvr2_dvb_frontend_exit(adap
);
395 pvr2_dvb_adapter_exit(adap
);
396 pvr2_channel_done(&adap
->channel
);
400 static void pvr2_dvb_internal_check(struct pvr2_channel
*chp
)
402 struct pvr2_dvb_adapter
*adap
;
403 adap
= container_of(chp
, struct pvr2_dvb_adapter
, channel
);
404 if (!adap
->channel
.mc_head
->disconnect_flag
) return;
405 pvr2_dvb_destroy(adap
);
408 struct pvr2_dvb_adapter
*pvr2_dvb_create(struct pvr2_context
*pvr
)
411 struct pvr2_dvb_adapter
*adap
;
412 if (!pvr
->hdw
->hdw_desc
->dvb_props
) {
413 /* Device lacks a digital interface so don't set up
414 the DVB side of the driver either. For now. */
417 adap
= kzalloc(sizeof(*adap
), GFP_KERNEL
);
418 if (!adap
) return adap
;
419 pvr2_channel_init(&adap
->channel
, pvr
);
420 adap
->channel
.check_func
= pvr2_dvb_internal_check
;
421 init_waitqueue_head(&adap
->buffer_wait_data
);
422 mutex_init(&adap
->lock
);
423 ret
= pvr2_dvb_adapter_init(adap
);
424 if (ret
< 0) goto fail1
;
425 ret
= pvr2_dvb_frontend_init(adap
);
426 if (ret
< 0) goto fail2
;
430 pvr2_dvb_adapter_exit(adap
);
432 pvr2_channel_done(&adap
->channel
);