Commit 39f86a60 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fixes from Mauro Carvalho Chehab:

 - dvb core: there is a regression found when used with xine.  For
   whatever unknown reason, xine (and xine-lib clients) wants that the
   frontend to tell what frequency he is using even before the PLL lock
   (or at least, it expects a non-zero frequency).

   On DVB, the frequency is only actually known after a frequency
   zig-zag seek, done by the DVB core.  Anyway, the fix was trivial.
   That solves Fedora BZ#808871.

 - ivtv: fix a regression when selecting the language channel

 - uvc: fix a race-related crash

 - it913x: fixes firmware loading

 - two trivial patches (a dependency issue at a radio driver at sound
   Kconfig, and a warning fix on dvb).

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
  [media] uvcvideo: Fix race-related crash in uvc_video_clock_update()
  [media] Drivers/media/radio: Fix build error
  [media] dvb_frontend: fix compiler warning
  [media] it913x: fix firmware loading errors
  [media] ivtv: Fix AUDIO_(BILINGUAL_)CHANNEL_SELECT regression
  [media] dvb_frontend: regression fix: userspace ABI broken for xine
parents 1b6150fe ed0ee0ce
...@@ -143,10 +143,12 @@ struct dvb_frontend_private { ...@@ -143,10 +143,12 @@ struct dvb_frontend_private {
static void dvb_frontend_wakeup(struct dvb_frontend *fe); static void dvb_frontend_wakeup(struct dvb_frontend *fe);
static int dtv_get_frontend(struct dvb_frontend *fe, static int dtv_get_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p_out); 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) 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) ...@@ -697,6 +699,7 @@ static int dvb_frontend_thread(void *data)
fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
fepriv->delay = HZ / 2; fepriv->delay = HZ / 2;
} }
dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
fe->ops.read_status(fe, &s); fe->ops.read_status(fe, &s);
if (s != fepriv->status) { if (s != fepriv->status) {
dvb_frontend_add_event(fe, s); /* update event list */ dvb_frontend_add_event(fe, s); /* update event list */
...@@ -1832,6 +1835,13 @@ static int dtv_set_frontend(struct dvb_frontend *fe) ...@@ -1832,6 +1835,13 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
if (dvb_frontend_check_parameters(fe) < 0) if (dvb_frontend_check_parameters(fe) < 0)
return -EINVAL; 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 * Be sure that the bandwidth will be filled for all
* non-satellite systems, as tuners need to know what * non-satellite systems, as tuners need to know what
......
...@@ -238,12 +238,27 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg) ...@@ -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) static u32 it913x_query(struct usb_device *udev, u8 pro)
{ {
int ret; int ret, i;
u8 data[4]; u8 data[4];
ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, u8 ver;
0x1222, 0, &data[0], 3);
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);
}
it913x_config.chip_ver = data[0]; 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]; it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver, info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver,
...@@ -660,30 +675,41 @@ static int it913x_download_firmware(struct usb_device *udev, ...@@ -660,30 +675,41 @@ static int it913x_download_firmware(struct usb_device *udev,
if ((packet_size > min_pkt) || (i == fw->size)) { if ((packet_size > min_pkt) || (i == fw->size)) {
fw_data = (u8 *)(fw->data + pos); fw_data = (u8 *)(fw->data + pos);
pos += packet_size; pos += packet_size;
if (packet_size > 0) if (packet_size > 0) {
ret |= it913x_io(udev, WRITE_DATA, ret = it913x_io(udev, WRITE_DATA,
DEV_0, CMD_SCATTER_WRITE, 0, DEV_0, CMD_SCATTER_WRITE, 0,
0, fw_data, packet_size); 0, fw_data, packet_size);
if (ret < 0)
break;
}
udelay(1000); udelay(1000);
} }
} }
i++; i++;
} }
ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
msleep(100);
if (ret < 0) if (ret < 0)
info("FRM Firmware Download Failed (%04x)" , ret); info("FRM Firmware Download Failed (%d)" , ret);
else else
info("FRM Firmware Download Completed - Resetting Device"); 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); 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 */ /* Tuner function */
if (it913x_config.dual_mode) if (it913x_config.dual_mode)
...@@ -901,5 +927,5 @@ module_usb_driver(it913x_driver); ...@@ -901,5 +927,5 @@ module_usb_driver(it913x_driver);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("it913x USB 2 Driver"); MODULE_DESCRIPTION("it913x USB 2 Driver");
MODULE_VERSION("1.27"); MODULE_VERSION("1.28");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -1763,13 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) ...@@ -1763,13 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
if (iarg > AUDIO_STEREO_SWAPPED) if (iarg > AUDIO_STEREO_SWAPPED)
return -EINVAL; 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: case AUDIO_BILINGUAL_CHANNEL_SELECT:
IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
if (iarg > AUDIO_STEREO_SWAPPED) if (iarg > AUDIO_STEREO_SWAPPED)
return -EINVAL; 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: default:
return -EINVAL; return -EINVAL;
......
...@@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, ...@@ -468,22 +468,30 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
spin_unlock_irqrestore(&stream->clock.lock, flags); spin_unlock_irqrestore(&stream->clock.lock, flags);
} }
static int uvc_video_clock_init(struct uvc_streaming *stream) static void uvc_video_clock_reset(struct uvc_streaming *stream)
{ {
struct uvc_clock *clock = &stream->clock; struct uvc_clock *clock = &stream->clock;
spin_lock_init(&clock->lock);
clock->head = 0; clock->head = 0;
clock->count = 0; clock->count = 0;
clock->size = 32;
clock->last_sof = -1; clock->last_sof = -1;
clock->sof_offset = -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->size = 32;
clock->samples = kmalloc(clock->size * sizeof(*clock->samples), clock->samples = kmalloc(clock->size * sizeof(*clock->samples),
GFP_KERNEL); GFP_KERNEL);
if (clock->samples == NULL) if (clock->samples == NULL)
return -ENOMEM; return -ENOMEM;
uvc_video_clock_reset(stream);
return 0; return 0;
} }
...@@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) ...@@ -1424,8 +1432,6 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
if (free_buffers) if (free_buffers)
uvc_free_urb_buffers(stream); 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) ...@@ -1555,10 +1561,6 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
uvc_video_stats_start(stream); uvc_video_stats_start(stream);
ret = uvc_video_clock_init(stream);
if (ret < 0)
return ret;
if (intf->num_altsetting > 1) { if (intf->num_altsetting > 1) {
struct usb_host_endpoint *best_ep = NULL; struct usb_host_endpoint *best_ep = NULL;
unsigned int best_psize = 3 * 1024; unsigned int best_psize = 3 * 1024;
...@@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) ...@@ -1683,6 +1685,8 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset)
stream->frozen = 0; stream->frozen = 0;
uvc_video_clock_reset(stream);
ret = uvc_commit_video(stream, &stream->ctrl); ret = uvc_commit_video(stream, &stream->ctrl);
if (ret < 0) { if (ret < 0) {
uvc_queue_enable(&stream->queue, 0); uvc_queue_enable(&stream->queue, 0);
...@@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) ...@@ -1819,25 +1823,35 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
uvc_uninit_video(stream, 1); uvc_uninit_video(stream, 1);
usb_set_interface(stream->dev->udev, stream->intfnum, 0); usb_set_interface(stream->dev->udev, stream->intfnum, 0);
uvc_queue_enable(&stream->queue, 0); uvc_queue_enable(&stream->queue, 0);
uvc_video_clock_cleanup(stream);
return 0; return 0;
} }
ret = uvc_queue_enable(&stream->queue, 1); ret = uvc_video_clock_init(stream);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = uvc_queue_enable(&stream->queue, 1);
if (ret < 0)
goto error_queue;
/* Commit the streaming parameters. */ /* Commit the streaming parameters. */
ret = uvc_commit_video(stream, &stream->ctrl); ret = uvc_commit_video(stream, &stream->ctrl);
if (ret < 0) { if (ret < 0)
uvc_queue_enable(&stream->queue, 0); goto error_commit;
return ret;
}
ret = uvc_init_video(stream, GFP_KERNEL); ret = uvc_init_video(stream, GFP_KERNEL);
if (ret < 0) { if (ret < 0)
usb_set_interface(stream->dev->udev, stream->intfnum, 0); goto error_video;
uvc_queue_enable(&stream->queue, 0);
} 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; return ret;
} }
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
config SND_TEA575X config SND_TEA575X
tristate tristate
depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO
default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO
menuconfig SND_PCI menuconfig SND_PCI
bool "PCI sound devices" bool "PCI sound devices"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment