diff --git a/drivers/media/dvb/dvb-usb/dvb_usb.h b/drivers/media/dvb/dvb-usb/dvb_usb.h index 08d148b23c71..51cb388f928c 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb.h +++ b/drivers/media/dvb/dvb-usb/dvb_usb.h @@ -242,6 +242,7 @@ struct dvb_usb_device_properties { int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *); int (*get_usb_stream_config) (struct dvb_frontend *, struct usb_data_stream_properties *); + int (*get_ts_config) (struct dvb_frontend *, unsigned int *); struct i2c_algorithm *i2c_algo; diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c b/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c index 841b2d9a4058..f196c0dc420e 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb_usb_dvb.c @@ -8,6 +8,60 @@ */ #include "dvb_usb_common.h" +static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, + size_t length) +{ + struct dvb_usb_adapter *adap = stream->user_priv; + if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) + dvb_dmx_swfilter(&adap->demux, buffer, length); +} + +static void dvb_usb_data_complete_204(struct usb_data_stream *stream, + u8 *buffer, size_t length) +{ + struct dvb_usb_adapter *adap = stream->user_priv; + if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) + dvb_dmx_swfilter_204(&adap->demux, buffer, length); +} + +static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, + u8 *buffer, size_t length) +{ + struct dvb_usb_adapter *adap = stream->user_priv; + if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) + dvb_dmx_swfilter_raw(&adap->demux, buffer, length); +} + +int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap) +{ + int ret; + struct usb_data_stream_properties stream_props; + + adap->stream.udev = adap->dev->udev; + adap->stream.user_priv = adap; + + /* resolve USB stream configuration for buffer alloc */ + if (adap->dev->props.get_usb_stream_config) { + ret = adap->dev->props.get_usb_stream_config(NULL, + &stream_props); + if (ret < 0) + return ret; + } else { + stream_props = adap->props.fe[0].stream; + } + + /* FIXME: can be removed as set later in anyway */ + adap->stream.complete = dvb_usb_data_complete; + + return usb_urb_init(&adap->stream, &stream_props); +} + +int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap) +{ + usb_urb_exit(&adap->stream); + return 0; +} + /* does the complete input transfer handling */ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) { @@ -57,6 +111,25 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) */ if (adap->feedcount == onoff && adap->feedcount > 0) { struct usb_data_stream_properties stream_props; + unsigned int ts_props; + + /* resolve TS configuration */ + if (adap->dev->props.get_ts_config) { + ret = adap->dev->props.get_ts_config( + adap->fe_adap[adap->active_fe].fe, + &ts_props); + if (ret < 0) + return ret; + } else { + ts_props = 0; /* normal 188 payload only TS */ + } + + if (ts_props & DVB_USB_ADAP_RECEIVES_204_BYTE_TS) + adap->stream.complete = dvb_usb_data_complete_204; + else if (ts_props & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD) + adap->stream.complete = dvb_usb_data_complete_raw; + else + adap->stream.complete = dvb_usb_data_complete; /* resolve USB stream configuration */ if (adap->dev->props.get_usb_stream_config) { diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_urb.c b/drivers/media/dvb/dvb-usb/dvb_usb_urb.c index 8200e0983f07..43563b341b80 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_urb.c +++ b/drivers/media/dvb/dvb-usb/dvb_usb_urb.c @@ -66,66 +66,3 @@ int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len) return dvb_usbv2_generic_rw(d, buf, len, NULL, 0, 0); } EXPORT_SYMBOL(dvb_usbv2_generic_write); - -static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, - size_t length) -{ - struct dvb_usb_adapter *adap = stream->user_priv; - if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) - dvb_dmx_swfilter(&adap->demux, buffer, length); -} - -static void dvb_usb_data_complete_204(struct usb_data_stream *stream, - u8 *buffer, size_t length) -{ - struct dvb_usb_adapter *adap = stream->user_priv; - if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) - dvb_dmx_swfilter_204(&adap->demux, buffer, length); -} - -static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, - u8 *buffer, size_t length) -{ - struct dvb_usb_adapter *adap = stream->user_priv; - if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) - dvb_dmx_swfilter_raw(&adap->demux, buffer, length); -} - -int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap) -{ - int ret; - struct usb_data_stream_properties stream_props; - - /* - * FIXME: We should config demux callback for each time streaming is - * started. Same for the USB data stream config. - */ - - adap->stream.udev = adap->dev->udev; - if (adap->props.fe[0].caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS) - adap->stream.complete = dvb_usb_data_complete_204; - else if (adap->props.fe[0].caps & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD) - adap->stream.complete = dvb_usb_data_complete_raw; - else - adap->stream.complete = dvb_usb_data_complete; - - adap->stream.user_priv = adap; - - /* resolve USB stream configuration */ - if (adap->dev->props.get_usb_stream_config) { - ret = adap->dev->props.get_usb_stream_config(NULL, - &stream_props); - if (ret < 0) - return ret; - } else { - stream_props = adap->props.fe[0].stream; - } - - return usb_urb_init(&adap->stream, &stream_props); -} - -int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap) -{ - usb_urb_exit(&adap->stream); - return 0; -}