@@ -162,8 +162,8 @@ static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
dvb_usb_device_power_ctrl(adap->dev, 1);
- if (adap->fe_init)
- adap->fe_init(fe);
+ if (adap->mfe_init[fe->id])
+ adap->mfe_init[fe->id](fe);
return 0;
}
@@ -172,35 +172,66 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
{
struct dvb_usb_adapter *adap = fe->dvb->priv;
- if (adap->fe_sleep)
- adap->fe_sleep(fe);
+ if (adap->mfe_sleep[fe->id])
+ adap->mfe_sleep[fe->id](fe);
return dvb_usb_device_power_ctrl(adap->dev, 0);
}
int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
{
+ int ret, i, num_frontends;
+
if (adap->props.frontend_attach == NULL) {
- err("strange: '%s' #%d doesn't want to attach a frontend.",adap->dev->desc->name, adap->id);
+ err("strange: '%s' #%d doesn't want to attach a frontend.",
+ adap->dev->desc->name, adap->id);
return 0;
}
- /* re-assign sleep and wakeup functions */
- if (adap->props.frontend_attach(adap) == 0 && adap->fe != NULL) {
- adap->fe_init = adap->fe->ops.init; adap->fe->ops.init = dvb_usb_fe_wakeup;
- adap->fe_sleep = adap->fe->ops.sleep; adap->fe->ops.sleep = dvb_usb_fe_sleep;
+ if (adap->props.num_frontends)
+ num_frontends = adap->props.num_frontends;
+ else
+ num_frontends = 1;
+
+ for (i = 0; i < num_frontends; i++) {
+
+ ret = adap->props.frontend_attach(adap);
+ if (ret)
+ break;
+
+ /* glue for backward compatibility */
+ if (i == 0) {
+ if (adap->mfe[i])
+ adap->fe = adap->mfe[i];
+ else
+ adap->mfe[i] = adap->fe;
+ }
+
+ if (adap->mfe[i] == NULL)
+ break;
+
+ /* re-assign sleep and wakeup functions */
+ adap->mfe_init[i] = adap->mfe[i]->ops.init;
+ adap->mfe_sleep[i] = adap->mfe[i]->ops.sleep;
+ adap->mfe[i]->ops.init = dvb_usb_fe_wakeup;
+ adap->mfe[i]->ops.sleep = dvb_usb_fe_sleep;
- if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
- err("Frontend registration failed.");
+ adap->mfe[i]->id = i;
+ if (dvb_register_frontend(&adap->dvb_adap, adap->mfe[i])) {
+ err("Frontend %d registration failed.", i);
dvb_frontend_detach(adap->fe);
- adap->fe = NULL;
+ adap->mfe[i] = NULL;
+ if (adap->mfe[0] == NULL)
+ adap->fe = NULL;
return -ENODEV;
}
/* only attach the tuner if the demod is there */
if (adap->props.tuner_attach != NULL)
adap->props.tuner_attach(adap);
- } else
+ }
+
+ if (adap->mfe[0] == NULL)
err("no frontend was attached by '%s'",adap->dev->desc->name);
return 0;
@@ -208,9 +239,22 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
{
- if (adap->fe != NULL) {
- dvb_unregister_frontend(adap->fe);
- dvb_frontend_detach(adap->fe);
+ int i, num_frontends;
+
+ if (adap->props.num_frontends)
+ num_frontends = adap->props.num_frontends;
+ else
+ num_frontends = 1;
+
+ for (i = 0; i < num_frontends; i++) {
+ if (adap->mfe[i] != NULL) {
+ dvb_unregister_frontend(adap->mfe[i]);
+ dvb_frontend_detach(adap->mfe[i]);
+ }
}
+
+ if (adap->mfe[0] == NULL)
+ adap->fe = NULL;
+
return 0;
}
@@ -146,6 +146,7 @@ struct dvb_usb_adapter_properties {
int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
+ int num_frontends;
int (*frontend_attach) (struct dvb_usb_adapter *);
int (*tuner_attach) (struct dvb_usb_adapter *);
@@ -359,15 +360,19 @@ struct dvb_usb_adapter {
int pid_filtering;
/* dvb */
+#define DVB_USB_FE_MAX_NUM 2
struct dvb_adapter dvb_adap;
struct dmxdev dmxdev;
struct dvb_demux demux;
struct dvb_net dvb_net;
struct dvb_frontend *fe;
+ struct dvb_frontend *mfe[DVB_USB_FE_MAX_NUM];
int max_feed_count;
int (*fe_init) (struct dvb_frontend *);
int (*fe_sleep) (struct dvb_frontend *);
+ int (*mfe_init[DVB_USB_FE_MAX_NUM]) (struct dvb_frontend *);
+ int (*mfe_sleep[DVB_USB_FE_MAX_NUM]) (struct dvb_frontend *);
struct usb_data_stream stream;