diff options
Diffstat (limited to 'drivers/media/usb')
| -rw-r--r-- | drivers/media/usb/au0828/au0828-dvb.c | 57 | ||||
| -rw-r--r-- | drivers/media/usb/au0828/au0828.h | 2 | ||||
| -rw-r--r-- | drivers/media/usb/dvb-usb-v2/af9035.c | 40 | ||||
| -rw-r--r-- | drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 6 | ||||
| -rw-r--r-- | drivers/media/usb/dvb-usb/az6027.c | 7 | ||||
| -rw-r--r-- | drivers/media/usb/dvb-usb/dib0700.h | 2 | ||||
| -rw-r--r-- | drivers/media/usb/dvb-usb/dib0700_core.c | 43 | ||||
| -rw-r--r-- | drivers/media/usb/dvb-usb/dib0700_devices.c | 2 | ||||
| -rw-r--r-- | drivers/media/usb/gspca/pac7302.c | 1 | ||||
| -rw-r--r-- | drivers/media/usb/hdpvr/hdpvr-video.c | 6 |
10 files changed, 137 insertions, 29 deletions
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index 4ae8b107464..d8b5d948027 100644 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c @@ -114,16 +114,20 @@ static void urb_completion(struct urb *purb) int ptype = usb_pipetype(purb->pipe); unsigned char *ptr; - dprintk(2, "%s()\n", __func__); + dprintk(2, "%s: %d\n", __func__, purb->actual_length); - if (!dev) + if (!dev) { + dprintk(2, "%s: no dev!\n", __func__); return; + } - if (dev->urb_streaming == 0) + if (dev->urb_streaming == 0) { + dprintk(2, "%s: not streaming!\n", __func__); return; + } if (ptype != PIPE_BULK) { - printk(KERN_ERR "%s() Unsupported URB type %d\n", + printk(KERN_ERR "%s: Unsupported URB type %d\n", __func__, ptype); return; } @@ -252,8 +256,6 @@ static void au0828_stop_transport(struct au0828_dev *dev, int full_stop) au0828_write(dev, 0x60b, 0x00); } - - static int au0828_dvb_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; @@ -296,6 +298,8 @@ static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed) dprintk(1, "%s()\n", __func__); if (dvb) { + cancel_work_sync(&dev->restart_streaming); + mutex_lock(&dvb->lock); dvb->stop_count++; dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__, @@ -338,6 +342,41 @@ static void au0828_restart_dvb_streaming(struct work_struct *work) mutex_unlock(&dvb->lock); } +static int au0828_set_frontend(struct dvb_frontend *fe) +{ + struct au0828_dev *dev = fe->dvb->priv; + struct au0828_dvb *dvb = &dev->dvb; + int ret, was_streaming; + + mutex_lock(&dvb->lock); + was_streaming = dev->urb_streaming; + if (was_streaming) { + au0828_stop_transport(dev, 1); + + /* + * We can't hold a mutex here, as the restart_streaming + * kthread may also hold it. + */ + mutex_unlock(&dvb->lock); + cancel_work_sync(&dev->restart_streaming); + mutex_lock(&dvb->lock); + + stop_urb_transfer(dev); + } + mutex_unlock(&dvb->lock); + + ret = dvb->set_frontend(fe); + + if (was_streaming) { + mutex_lock(&dvb->lock); + au0828_start_transport(dev); + start_urb_transfer(dev); + mutex_unlock(&dvb->lock); + } + + return ret; +} + static int dvb_register(struct au0828_dev *dev) { struct au0828_dvb *dvb = &dev->dvb; @@ -382,6 +421,10 @@ static int dvb_register(struct au0828_dev *dev) goto fail_frontend; } + /* Hook dvb frontend */ + dvb->set_frontend = dvb->frontend->ops.set_frontend; + dvb->frontend->ops.set_frontend = au0828_set_frontend; + /* register demux stuff */ dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | @@ -471,6 +514,8 @@ void au0828_dvb_unregister(struct au0828_dev *dev) if (dvb->frontend == NULL) return; + cancel_work_sync(&dev->restart_streaming); + dvb_net_release(&dvb->net); dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 5439772c155..7112b9d956f 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -104,6 +104,8 @@ struct au0828_dvb { int feeding; int start_count; int stop_count; + + int (*set_frontend)(struct dvb_frontend *fe); }; enum au0828_stream_state { diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 021e4d35e4d..7b9b75f6077 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -704,15 +704,41 @@ static int af9035_read_config(struct dvb_usb_device *d) if (ret < 0) goto err; - if (tmp == 0x00) - dev_dbg(&d->udev->dev, - "%s: [%d]tuner not set, using default\n", - __func__, i); - else + dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n", + __func__, i, tmp); + + /* tuner sanity check */ + if (state->chip_type == 0x9135) { + if (state->chip_version == 0x02) { + /* IT9135 BX (v2) */ + switch (tmp) { + case AF9033_TUNER_IT9135_60: + case AF9033_TUNER_IT9135_61: + case AF9033_TUNER_IT9135_62: + state->af9033_config[i].tuner = tmp; + break; + } + } else { + /* IT9135 AX (v1) */ + switch (tmp) { + case AF9033_TUNER_IT9135_38: + case AF9033_TUNER_IT9135_51: + case AF9033_TUNER_IT9135_52: + state->af9033_config[i].tuner = tmp; + break; + } + } + } else { + /* AF9035 */ state->af9033_config[i].tuner = tmp; + } - dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n", - __func__, i, state->af9033_config[i].tuner); + if (state->af9033_config[i].tuner != tmp) { + dev_info(&d->udev->dev, + "%s: [%d] overriding tuner from %02x to %02x\n", + KBUILD_MODNAME, i, tmp, + state->af9033_config[i].tuner); + } switch (state->af9033_config[i].tuner) { case AF9033_TUNER_TUA9001: diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index de02db802ac..e3558061893 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -399,7 +399,7 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) /* clear 'streaming' status bit */ clear_bit(ADAP_STREAMING, &adap->state_bits); - smp_mb__after_clear_bit(); + smp_mb__after_atomic(); wake_up_bit(&adap->state_bits, ADAP_STREAMING); skip_feed_stop: @@ -550,7 +550,7 @@ static int dvb_usb_fe_init(struct dvb_frontend *fe) err: if (!adap->suspend_resume_active) { clear_bit(ADAP_INIT, &adap->state_bits); - smp_mb__after_clear_bit(); + smp_mb__after_atomic(); wake_up_bit(&adap->state_bits, ADAP_INIT); } @@ -591,7 +591,7 @@ err: if (!adap->suspend_resume_active) { adap->active_fe = -1; clear_bit(ADAP_SLEEP, &adap->state_bits); - smp_mb__after_clear_bit(); + smp_mb__after_atomic(); wake_up_bit(&adap->state_bits, ADAP_SLEEP); } diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index c11138ebf6f..0df52ab32a7 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c @@ -1088,6 +1088,7 @@ static struct usb_device_id az6027_usb_table[] = { { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) }, { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) }, { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) }, + { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT_V2) }, { }, }; @@ -1136,7 +1137,7 @@ static struct dvb_usb_device_properties az6027_properties = { .i2c_algo = &az6027_i2c_algo, - .num_device_descs = 6, + .num_device_descs = 7, .devices = { { .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)", @@ -1162,6 +1163,10 @@ static struct dvb_usb_device_properties az6027_properties = { .name = "Elgato EyeTV Sat", .cold_ids = { &az6027_usb_table[5], NULL }, .warm_ids = { NULL }, + }, { + .name = "Elgato EyeTV Sat", + .cold_ids = { &az6027_usb_table[6], NULL }, + .warm_ids = { NULL }, }, { NULL }, } diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h index 637b6123f39..927617d9561 100644 --- a/drivers/media/usb/dvb-usb/dib0700.h +++ b/drivers/media/usb/dvb-usb/dib0700.h @@ -59,7 +59,7 @@ extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); -extern int dib0700_rc_setup(struct dvb_usb_device *d); +extern int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf); extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); extern struct i2c_algorithm dib0700_i2c_algo; extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index bf2a908d74c..c14285fa827 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c @@ -754,17 +754,20 @@ resubmit: usb_submit_urb(purb, GFP_ATOMIC); } -int dib0700_rc_setup(struct dvb_usb_device *d) +int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf) { struct dib0700_state *st = d->priv; struct urb *purb; - int ret; + const struct usb_endpoint_descriptor *e; + int ret, rc_ep = 1; + unsigned int pipe = 0; /* Poll-based. Don't initialize bulk mode */ - if (st->fw_version < 0x10200) + if (st->fw_version < 0x10200 || !intf) return 0; /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */ + purb = usb_alloc_urb(0, GFP_KERNEL); if (purb == NULL) { err("rc usb alloc urb failed"); @@ -779,9 +782,35 @@ int dib0700_rc_setup(struct dvb_usb_device *d) } purb->status = -EINPROGRESS; - usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1), - purb->transfer_buffer, RC_MSG_SIZE_V1_20, - dib0700_rc_urb_completion, d); + + /* + * Some devices like the Hauppauge NovaTD model 52009 use an interrupt + * endpoint, while others use a bulk one. + */ + e = &intf->altsetting[0].endpoint[rc_ep].desc; + if (usb_endpoint_dir_in(e)) { + if (usb_endpoint_xfer_bulk(e)) { + pipe = usb_rcvbulkpipe(d->udev, rc_ep); + usb_fill_bulk_urb(purb, d->udev, pipe, + purb->transfer_buffer, + RC_MSG_SIZE_V1_20, + dib0700_rc_urb_completion, d); + + } else if (usb_endpoint_xfer_int(e)) { + pipe = usb_rcvintpipe(d->udev, rc_ep); + usb_fill_int_urb(purb, d->udev, pipe, + purb->transfer_buffer, + RC_MSG_SIZE_V1_20, + dib0700_rc_urb_completion, d, 1); + } + } + + if (!pipe) { + err("There's no endpoint for remote controller"); + kfree(purb->transfer_buffer); + usb_free_urb(purb); + return 0; + } ret = usb_submit_urb(purb, GFP_ATOMIC); if (ret) { @@ -820,7 +849,7 @@ static int dib0700_probe(struct usb_interface *intf, else dev->props.rc.core.bulk_mode = false; - dib0700_rc_setup(dev); + dib0700_rc_setup(dev, intf); return 0; } diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 829323e42ca..10e0db8d185 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -514,7 +514,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */ - dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */ + dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */ d->last_event = 0; switch (d->props.rc.core.protocol) { diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c index 2fd1c5e31a0..339adce7c7a 100644 --- a/drivers/media/usb/gspca/pac7302.c +++ b/drivers/media/usb/gspca/pac7302.c @@ -928,6 +928,7 @@ static const struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2620)}, {USB_DEVICE(0x093a, 0x2621)}, {USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP}, + {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP}, {USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP}, {USB_DEVICE(0x093a, 0x2625)}, {USB_DEVICE(0x093a, 0x2626)}, diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 0500c4175d5..6bce01a674f 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c @@ -82,7 +82,7 @@ static void hdpvr_read_bulk_callback(struct urb *urb) } /*=========================================================================*/ -/* bufffer bits */ +/* buffer bits */ /* function expects dev->io_mutex to be hold by caller */ int hdpvr_cancel_queue(struct hdpvr_device *dev) @@ -926,7 +926,7 @@ static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_MPEG_AUDIO_ENCODING: if (dev->flags & HDPVR_FLAG_AC3_CAP) { opt->audio_codec = ctrl->val; - return hdpvr_set_audio(dev, opt->audio_input, + return hdpvr_set_audio(dev, opt->audio_input + 1, opt->audio_codec); } return 0; @@ -1198,7 +1198,7 @@ int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent, v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops, V4L2_CID_MPEG_AUDIO_ENCODING, ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC, - 0x7, V4L2_MPEG_AUDIO_ENCODING_AAC); + 0x7, ac3 ? dev->options.audio_codec : V4L2_MPEG_AUDIO_ENCODING_AAC); v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops, V4L2_CID_MPEG_VIDEO_ENCODING, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3, |
