diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 4555baa383b2..39696c6a4ed7 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -143,10 +143,12 @@ struct dvb_frontend_private { static void dvb_frontend_wakeup(struct dvb_frontend *fe); static int dtv_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p_out); +static int dtv_property_legacy_params_sync(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p); static bool has_get_frontend(struct dvb_frontend *fe) { - return fe->ops.get_frontend; + return fe->ops.get_frontend != NULL; } /* @@ -697,6 +699,7 @@ static int dvb_frontend_thread(void *data) fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; fepriv->delay = HZ / 2; } + dtv_property_legacy_params_sync(fe, &fepriv->parameters_out); fe->ops.read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); /* update event list */ @@ -1832,6 +1835,13 @@ static int dtv_set_frontend(struct dvb_frontend *fe) if (dvb_frontend_check_parameters(fe) < 0) return -EINVAL; + /* + * Initialize output parameters to match the values given by + * the user. FE_SET_FRONTEND triggers an initial frontend event + * with status = 0, which copies output parameters to userspace. + */ + dtv_property_legacy_params_sync(fe, &fepriv->parameters_out); + /* * Be sure that the bandwidth will be filled for all * non-satellite systems, as tuners need to know what diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index 3b7b102f20ae..482d249ca7f3 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -238,12 +238,27 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg) static u32 it913x_query(struct usb_device *udev, u8 pro) { - int ret; + int ret, i; u8 data[4]; - ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, - 0x1222, 0, &data[0], 3); + u8 ver; - it913x_config.chip_ver = data[0]; + for (i = 0; i < 5; i++) { + ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, + 0x1222, 0, &data[0], 3); + ver = data[0]; + if (ver > 0 && ver < 3) + break; + msleep(100); + } + + if (ver < 1 || ver > 2) { + info("Failed to identify chip version applying 1"); + it913x_config.chip_ver = 0x1; + it913x_config.chip_type = 0x9135; + return 0; + } + + it913x_config.chip_ver = ver; it913x_config.chip_type = (u16)(data[2] << 8) + data[1]; info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver, @@ -660,30 +675,41 @@ static int it913x_download_firmware(struct usb_device *udev, if ((packet_size > min_pkt) || (i == fw->size)) { fw_data = (u8 *)(fw->data + pos); pos += packet_size; - if (packet_size > 0) - ret |= it913x_io(udev, WRITE_DATA, + if (packet_size > 0) { + ret = it913x_io(udev, WRITE_DATA, DEV_0, CMD_SCATTER_WRITE, 0, 0, fw_data, packet_size); + if (ret < 0) + break; + } udelay(1000); } } i++; } - ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); - - msleep(100); - if (ret < 0) - info("FRM Firmware Download Failed (%04x)" , ret); + info("FRM Firmware Download Failed (%d)" , ret); else info("FRM Firmware Download Completed - Resetting Device"); - ret |= it913x_return_status(udev); + msleep(30); + + ret = it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); + if (ret < 0) + info("FRM Device not responding to reboot"); + + ret = it913x_return_status(udev); + if (ret == 0) { + info("FRM Failed to reboot device"); + return -ENODEV; + } msleep(30); - ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); + ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); + + msleep(30); /* Tuner function */ if (it913x_config.dual_mode) @@ -901,5 +927,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.27"); +MODULE_VERSION("1.28"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 5452beef8e11..989e556913ed 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1763,13 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); if (iarg > AUDIO_STEREO_SWAPPED) return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg); + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1); case AUDIO_BILINGUAL_CHANNEL_SELECT: IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); if (iarg > AUDIO_STEREO_SWAPPED) return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg); + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1); default: return -EINVAL; diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 4a44f9a1bae0..b76b0ac0958f 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, spin_unlock_irqrestore(&stream->clock.lock, flags); } +static void uvc_video_clock_reset(struct uvc_streaming *stream) +{ + struct uvc_clock *clock = &stream->clock; + + clock->head = 0; + clock->count = 0; + clock->last_sof = -1; + clock->sof_offset = -1; +} + static int uvc_video_clock_init(struct uvc_streaming *stream) { struct uvc_clock *clock = &stream->clock; spin_lock_init(&clock->lock); - clock->head = 0; - clock->count = 0; clock->size = 32; - clock->last_sof = -1; - clock->sof_offset = -1; clock->samples = kmalloc(clock->size * sizeof(*clock->samples), GFP_KERNEL); if (clock->samples == NULL) return -ENOMEM; + uvc_video_clock_reset(stream); + return 0; } @@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) if (free_buffers) uvc_free_urb_buffers(stream); - - uvc_video_clock_cleanup(stream); } /* @@ -1555,10 +1561,6 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) uvc_video_stats_start(stream); - ret = uvc_video_clock_init(stream); - if (ret < 0) - return ret; - if (intf->num_altsetting > 1) { struct usb_host_endpoint *best_ep = NULL; unsigned int best_psize = 3 * 1024; @@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) stream->frozen = 0; + uvc_video_clock_reset(stream); + ret = uvc_commit_video(stream, &stream->ctrl); if (ret < 0) { uvc_queue_enable(&stream->queue, 0); @@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) uvc_uninit_video(stream, 1); usb_set_interface(stream->dev->udev, stream->intfnum, 0); uvc_queue_enable(&stream->queue, 0); + uvc_video_clock_cleanup(stream); return 0; } - ret = uvc_queue_enable(&stream->queue, 1); + ret = uvc_video_clock_init(stream); if (ret < 0) return ret; + ret = uvc_queue_enable(&stream->queue, 1); + if (ret < 0) + goto error_queue; + /* Commit the streaming parameters. */ ret = uvc_commit_video(stream, &stream->ctrl); - if (ret < 0) { - uvc_queue_enable(&stream->queue, 0); - return ret; - } + if (ret < 0) + goto error_commit; ret = uvc_init_video(stream, GFP_KERNEL); - if (ret < 0) { - usb_set_interface(stream->dev->udev, stream->intfnum, 0); - uvc_queue_enable(&stream->queue, 0); - } + if (ret < 0) + goto error_video; + + return 0; + +error_video: + usb_set_interface(stream->dev->udev, stream->intfnum, 0); +error_commit: + uvc_queue_enable(&stream->queue, 0); +error_queue: + uvc_video_clock_cleanup(stream); return ret; } diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 88168044375f..5ca0939e4223 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -2,8 +2,8 @@ config SND_TEA575X tristate - depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 - default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 + depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO + default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO menuconfig SND_PCI bool "PCI sound devices"