Commit 46671b03 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-2.6

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6:
  [media] soc_camera: preserve const attribute
  [media] uvc_entity: initialize return value
  [media] media: Fix media device minor registration
  [media] Make nchg variable signed because the code compares this variable against negative values
  [media] omap3isp: fix compiler warning
  [media] v4l: Fix media_entity_to_video_device macro argument name
  [media] ivtv: Internally separate encoder & decoder standard setting
  [media] ivtvfb: Add sanity check to ivtvfb_pan_display()
  [media] ivtvfb: use display information in info not in var for panning
  [media] ivtv: Make two ivtv_msleep_timeout calls uninterruptable
  [media] anysee: return EOPNOTSUPP for unsupported I2C messages
  [media] gspca - ov519: Set the default frame rate to 15 fps
  [media] gspca - stv06xx: Set a lower default value of gain for hdcs sensors
  [media] gspca: Remove coarse_expo_autogain.h
  [media] gspca - ov519: Change the ovfx2 bulk transfer size
  [media] gspca - ov519: Fix a regression for ovfx2 webcams
parents 18367c0e d364ee4f
...@@ -60,8 +60,6 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, ...@@ -60,8 +60,6 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
int act_len, ret; int act_len, ret;
u8 buf[64]; u8 buf[64];
if (slen > sizeof(buf))
slen = sizeof(buf);
memcpy(&buf[0], sbuf, slen); memcpy(&buf[0], sbuf, slen);
buf[60] = state->seq++; buf[60] = state->seq++;
...@@ -180,30 +178,37 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, ...@@ -180,30 +178,37 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
{ {
struct dvb_usb_device *d = i2c_get_adapdata(adap); struct dvb_usb_device *d = i2c_get_adapdata(adap);
int ret = 0, inc, i = 0; int ret = 0, inc, i = 0;
u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
if (mutex_lock_interruptible(&d->i2c_mutex) < 0) if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN; return -EAGAIN;
while (i < num) { while (i < num) {
if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
u8 buf[6]; if (msg[i].len > 2 || msg[i+1].len > 60) {
ret = -EOPNOTSUPP;
break;
}
buf[0] = CMD_I2C_READ; buf[0] = CMD_I2C_READ;
buf[1] = (msg[i].addr << 1) | 0x01; buf[1] = (msg[i].addr << 1) | 0x01;
buf[2] = msg[i].buf[0]; buf[2] = msg[i].buf[0];
buf[3] = msg[i].buf[1]; buf[3] = msg[i].buf[1];
buf[4] = msg[i].len-1; buf[4] = msg[i].len-1;
buf[5] = msg[i+1].len; buf[5] = msg[i+1].len;
ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf, ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
msg[i+1].len); msg[i+1].len);
inc = 2; inc = 2;
} else { } else {
u8 buf[4+msg[i].len]; if (msg[i].len > 48) {
ret = -EOPNOTSUPP;
break;
}
buf[0] = CMD_I2C_WRITE; buf[0] = CMD_I2C_WRITE;
buf[1] = (msg[i].addr << 1); buf[1] = (msg[i].addr << 1);
buf[2] = msg[i].len; buf[2] = msg[i].len;
buf[3] = 0x01; buf[3] = 0x01;
memcpy(&buf[4], msg[i].buf, msg[i].len); memcpy(&buf[4], msg[i].buf, msg[i].len);
ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
inc = 1; inc = 1;
} }
if (ret) if (ret)
......
...@@ -213,14 +213,14 @@ int __must_check media_devnode_register(struct media_devnode *mdev) ...@@ -213,14 +213,14 @@ int __must_check media_devnode_register(struct media_devnode *mdev)
/* Part 1: Find a free minor number */ /* Part 1: Find a free minor number */
mutex_lock(&media_devnode_lock); mutex_lock(&media_devnode_lock);
minor = find_next_zero_bit(media_devnode_nums, 0, MEDIA_NUM_DEVICES); minor = find_next_zero_bit(media_devnode_nums, MEDIA_NUM_DEVICES, 0);
if (minor == MEDIA_NUM_DEVICES) { if (minor == MEDIA_NUM_DEVICES) {
mutex_unlock(&media_devnode_lock); mutex_unlock(&media_devnode_lock);
printk(KERN_ERR "could not get a free minor\n"); printk(KERN_ERR "could not get a free minor\n");
return -ENFILE; return -ENFILE;
} }
set_bit(mdev->minor, media_devnode_nums); set_bit(minor, media_devnode_nums);
mutex_unlock(&media_devnode_lock); mutex_unlock(&media_devnode_lock);
mdev->minor = minor; mdev->minor = minor;
......
/*
* Auto gain algorithm for camera's with a coarse exposure control
*
* Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Autogain + exposure algorithm for cameras with a coarse exposure control
(usually this means we can only control the clockdiv to change exposure)
As changing the clockdiv so that the fps drops from 30 to 15 fps for
example, will lead to a huge exposure change (it effectively doubles),
this algorithm normally tries to only adjust the gain (between 40 and
80 %) and if that does not help, only then changes exposure. This leads
to a much more stable image then using the knee algorithm which at
certain points of the knee graph will only try to adjust exposure,
which leads to oscilating as one exposure step is huge.
Note this assumes that the sd struct for the cam in question has
exp_too_high_cnt and exp_too_high_cnt int members for use by this function.
Returns 0 if no changes were made, 1 if the gain and or exposure settings
where changed. */
static int gspca_coarse_grained_expo_autogain(struct gspca_dev *gspca_dev,
int avg_lum, int desired_avg_lum, int deadzone)
{
int i, steps, gain, orig_gain, exposure, orig_exposure;
int gain_low, gain_high;
const struct ctrl *gain_ctrl = NULL;
const struct ctrl *exposure_ctrl = NULL;
struct sd *sd = (struct sd *) gspca_dev;
int retval = 0;
for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
if (gspca_dev->ctrl_dis & (1 << i))
continue;
if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];
}
if (!gain_ctrl || !exposure_ctrl) {
PDEBUG(D_ERR, "Error: gspca_coarse_grained_expo_autogain "
"called on cam without gain or exposure");
return 0;
}
if (gain_ctrl->get(gspca_dev, &gain) ||
exposure_ctrl->get(gspca_dev, &exposure))
return 0;
orig_gain = gain;
orig_exposure = exposure;
gain_low =
(gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 2;
gain_low += gain_ctrl->qctrl.minimum;
gain_high =
(gain_ctrl->qctrl.maximum - gain_ctrl->qctrl.minimum) / 5 * 4;
gain_high += gain_ctrl->qctrl.minimum;
/* If we are of a multiple of deadzone, do multiple steps to reach the
desired lumination fast (with the risc of a slight overshoot) */
steps = (desired_avg_lum - avg_lum) / deadzone;
PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
avg_lum, desired_avg_lum, steps);
if ((gain + steps) > gain_high &&
sd->exposure < exposure_ctrl->qctrl.maximum) {
gain = gain_high;
sd->exp_too_low_cnt++;
} else if ((gain + steps) < gain_low &&
sd->exposure > exposure_ctrl->qctrl.minimum) {
gain = gain_low;
sd->exp_too_high_cnt++;
} else {
gain += steps;
if (gain > gain_ctrl->qctrl.maximum)
gain = gain_ctrl->qctrl.maximum;
else if (gain < gain_ctrl->qctrl.minimum)
gain = gain_ctrl->qctrl.minimum;
sd->exp_too_high_cnt = 0;
sd->exp_too_low_cnt = 0;
}
if (sd->exp_too_high_cnt > 3) {
exposure--;
sd->exp_too_high_cnt = 0;
} else if (sd->exp_too_low_cnt > 3) {
exposure++;
sd->exp_too_low_cnt = 0;
}
if (gain != orig_gain) {
gain_ctrl->set(gspca_dev, gain);
retval = 1;
}
if (exposure != orig_exposure) {
exposure_ctrl->set(gspca_dev, exposure);
retval = 1;
}
return retval;
}
...@@ -609,7 +609,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { ...@@ -609,7 +609,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
* buffers, there are some pretty strict real time constraints for * buffers, there are some pretty strict real time constraints for
* isochronous transfer for larger frame sizes). * isochronous transfer for larger frame sizes).
*/ */
/*jfm: this value works well for 1600x1200, but not 800x600 - see isoc_init */ /*jfm: this value does not work for 800x600 - see isoc_init */
#define OVFX2_BULK_SIZE (13 * 4096) #define OVFX2_BULK_SIZE (13 * 4096)
/* I2C registers */ /* I2C registers */
...@@ -3307,6 +3307,7 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -3307,6 +3307,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
gspca_dev->cam.ctrls = sd->ctrls; gspca_dev->cam.ctrls = sd->ctrls;
sd->quality = QUALITY_DEF; sd->quality = QUALITY_DEF;
sd->frame_rate = 15;
return 0; return 0;
} }
...@@ -3469,7 +3470,6 @@ static int sd_init(struct gspca_dev *gspca_dev) ...@@ -3469,7 +3470,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
ARRAY_SIZE(init_519_ov7660)); ARRAY_SIZE(init_519_ov7660));
write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660)); write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
sd->gspca_dev.curr_mode = 1; /* 640x480 */ sd->gspca_dev.curr_mode = 1; /* 640x480 */
sd->frame_rate = 15;
ov519_set_mode(sd); ov519_set_mode(sd);
ov519_set_fr(sd); ov519_set_fr(sd);
sd->ctrls[COLORS].max = 4; /* 0..4 */ sd->ctrls[COLORS].max = 4; /* 0..4 */
...@@ -3511,7 +3511,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) ...@@ -3511,7 +3511,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev)
switch (sd->bridge) { switch (sd->bridge) {
case BRIDGE_OVFX2: case BRIDGE_OVFX2:
if (gspca_dev->width == 1600) if (gspca_dev->width != 800)
gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE; gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
else else
gspca_dev->cam.bulk_size = 7 * 4096; gspca_dev->cam.bulk_size = 7 * 4096;
...@@ -4478,7 +4478,7 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev, ...@@ -4478,7 +4478,7 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, data, len); gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
/* A short read signals EOF */ /* A short read signals EOF */
if (len < OVFX2_BULK_SIZE) { if (len < gspca_dev->cam.bulk_size) {
/* If the frame is short, and it is one of the first ones /* If the frame is short, and it is one of the first ones
the sensor and bridge are still syncing, so drop it. */ the sensor and bridge are still syncing, so drop it. */
if (sd->first_frame) { if (sd->first_frame) {
......
...@@ -60,7 +60,7 @@ struct sd { ...@@ -60,7 +60,7 @@ struct sd {
u32 pktsz; /* (used by pkt_scan) */ u32 pktsz; /* (used by pkt_scan) */
u16 npkt; u16 npkt;
u8 nchg; s8 nchg;
s8 short_mark; s8 short_mark;
u8 quality; /* image quality */ u8 quality; /* image quality */
......
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
#define HDCS_SLEEP_MODE (1 << 1) #define HDCS_SLEEP_MODE (1 << 1)
#define HDCS_DEFAULT_EXPOSURE 48 #define HDCS_DEFAULT_EXPOSURE 48
#define HDCS_DEFAULT_GAIN 128 #define HDCS_DEFAULT_GAIN 50
static int hdcs_probe_1x00(struct sd *sd); static int hdcs_probe_1x00(struct sd *sd);
static int hdcs_probe_1020(struct sd *sd); static int hdcs_probe_1020(struct sd *sd);
......
...@@ -1328,6 +1328,8 @@ int ivtv_init_on_first_open(struct ivtv *itv) ...@@ -1328,6 +1328,8 @@ int ivtv_init_on_first_open(struct ivtv *itv)
if (!itv->has_cx23415) if (!itv->has_cx23415)
write_reg_sync(0x03, IVTV_REG_DMACONTROL); write_reg_sync(0x03, IVTV_REG_DMACONTROL);
ivtv_s_std_enc(itv, &itv->tuner_std);
/* Default interrupts enabled. For the PVR350 this includes the /* Default interrupts enabled. For the PVR350 this includes the
decoder VSYNC interrupt, which is always on. It is not only used decoder VSYNC interrupt, which is always on. It is not only used
during decoding but also by the OSD. during decoding but also by the OSD.
...@@ -1336,12 +1338,10 @@ int ivtv_init_on_first_open(struct ivtv *itv) ...@@ -1336,12 +1338,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC); ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
ivtv_set_osd_alpha(itv); ivtv_set_osd_alpha(itv);
} ivtv_s_std_dec(itv, &itv->tuner_std);
else } else {
ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
}
/* For cards with video out, this call needs interrupts enabled */
ivtv_s_std(NULL, &fh, &itv->tuner_std);
/* Setup initial controls */ /* Setup initial controls */
cx2341x_handler_setup(&itv->cxhdl); cx2341x_handler_setup(&itv->cxhdl);
......
...@@ -280,8 +280,6 @@ int ivtv_firmware_restart(struct ivtv *itv) ...@@ -280,8 +280,6 @@ int ivtv_firmware_restart(struct ivtv *itv)
{ {
int rc = 0; int rc = 0;
v4l2_std_id std; v4l2_std_id std;
struct ivtv_open_id fh;
fh.itv = itv;
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
/* Display test image during restart */ /* Display test image during restart */
...@@ -301,14 +299,19 @@ int ivtv_firmware_restart(struct ivtv *itv) ...@@ -301,14 +299,19 @@ int ivtv_firmware_restart(struct ivtv *itv)
/* Allow settings to reload */ /* Allow settings to reload */
ivtv_mailbox_cache_invalidate(itv); ivtv_mailbox_cache_invalidate(itv);
/* Restore video standard */ /* Restore encoder video standard */
std = itv->std; std = itv->std;
itv->std = 0; itv->std = 0;
ivtv_s_std(NULL, &fh, &std); ivtv_s_std_enc(itv, &std);
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
ivtv_init_mpeg_decoder(itv); ivtv_init_mpeg_decoder(itv);
/* Restore decoder video standard */
std = itv->std_out;
itv->std_out = 0;
ivtv_s_std_dec(itv, &std);
/* Restore framebuffer if active */ /* Restore framebuffer if active */
if (itv->ivtvfb_restore) if (itv->ivtvfb_restore)
itv->ivtvfb_restore(itv); itv->ivtvfb_restore(itv);
......
...@@ -1071,28 +1071,8 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) ...@@ -1071,28 +1071,8 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
return 0; return 0;
} }
int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
{ {
DEFINE_WAIT(wait);
struct ivtv *itv = fh2id(fh)->itv;
struct yuv_playback_info *yi = &itv->yuv_info;
int f;
if ((*std & V4L2_STD_ALL) == 0)
return -EINVAL;
if (*std == itv->std)
return 0;
if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
atomic_read(&itv->capturing) > 0 ||
atomic_read(&itv->decoding) > 0) {
/* Switching standard would turn off the radio or mess
with already running streams, prevent that by
returning EBUSY. */
return -EBUSY;
}
itv->std = *std; itv->std = *std;
itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
itv->is_50hz = !itv->is_60hz; itv->is_50hz = !itv->is_60hz;
...@@ -1106,48 +1086,79 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) ...@@ -1106,48 +1086,79 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
if (itv->hw_flags & IVTV_HW_CX25840) if (itv->hw_flags & IVTV_HW_CX25840)
itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
/* Tuner */ /* Tuner */
ivtv_call_all(itv, core, s_std, itv->std); ivtv_call_all(itv, core, s_std, itv->std);
}
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
/* set display standard */ {
itv->std_out = *std; struct yuv_playback_info *yi = &itv->yuv_info;
itv->is_out_60hz = itv->is_60hz; DEFINE_WAIT(wait);
itv->is_out_50hz = itv->is_50hz; int f;
ivtv_call_all(itv, video, s_std_output, itv->std_out);
/* set display standard */
/* itv->std_out = *std;
* The next firmware call is time sensitive. Time it to itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
* avoid risk of a hard lock, by trying to ensure the call itv->is_out_50hz = !itv->is_out_60hz;
* happens within the first 100 lines of the top field. ivtv_call_all(itv, video, s_std_output, itv->std_out);
* Make 4 attempts to sync to the decoder before giving up.
*/ /*
for (f = 0; f < 4; f++) { * The next firmware call is time sensitive. Time it to
prepare_to_wait(&itv->vsync_waitq, &wait, * avoid risk of a hard lock, by trying to ensure the call
TASK_UNINTERRUPTIBLE); * happens within the first 100 lines of the top field.
if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100) * Make 4 attempts to sync to the decoder before giving up.
break; */
schedule_timeout(msecs_to_jiffies(25)); for (f = 0; f < 4; f++) {
} prepare_to_wait(&itv->vsync_waitq, &wait,
finish_wait(&itv->vsync_waitq, &wait); TASK_UNINTERRUPTIBLE);
if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
if (f == 4) break;
IVTV_WARN("Mode change failed to sync to decoder\n"); schedule_timeout(msecs_to_jiffies(25));
ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
itv->main_rect.left = itv->main_rect.top = 0;
itv->main_rect.width = 720;
itv->main_rect.height = itv->cxhdl.height;
ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
720, itv->main_rect.height, 0, 0);
yi->main_rect = itv->main_rect;
if (!itv->osd_info) {
yi->osd_full_w = 720;
yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
}
} }
finish_wait(&itv->vsync_waitq, &wait);
if (f == 4)
IVTV_WARN("Mode change failed to sync to decoder\n");
ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
itv->main_rect.left = 0;
itv->main_rect.top = 0;
itv->main_rect.width = 720;
itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
720, itv->main_rect.height, 0, 0);
yi->main_rect = itv->main_rect;
if (!itv->osd_info) {
yi->osd_full_w = 720;
yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
}
}
int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
{
struct ivtv *itv = fh2id(fh)->itv;
if ((*std & V4L2_STD_ALL) == 0)
return -EINVAL;
if (*std == itv->std)
return 0;
if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
atomic_read(&itv->capturing) > 0 ||
atomic_read(&itv->decoding) > 0) {
/* Switching standard would mess with already running
streams, prevent that by returning EBUSY. */
return -EBUSY;
}
IVTV_DEBUG_INFO("Switching standard to %llx.\n",
(unsigned long long)itv->std);
ivtv_s_std_enc(itv, std);
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
ivtv_s_std_dec(itv, std);
return 0; return 0;
} }
......
...@@ -27,7 +27,8 @@ u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt); ...@@ -27,7 +27,8 @@ u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
void ivtv_set_osd_alpha(struct ivtv *itv); void ivtv_set_osd_alpha(struct ivtv *itv);
int ivtv_set_speed(struct ivtv *itv, int speed); int ivtv_set_speed(struct ivtv *itv, int speed);
void ivtv_set_funcs(struct video_device *vdev); void ivtv_set_funcs(struct video_device *vdev);
int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std); void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std);
void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std);
int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
int ivtv_s_input(struct file *file, void *fh, unsigned int inp); int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
......
...@@ -589,7 +589,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) ...@@ -589,7 +589,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1); v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
/* Avoid unpredictable PCI bus hang - disable video clocks */ /* Avoid unpredictable PCI bus hang - disable video clocks */
v4l2_subdev_call(itv->sd_video, video, s_stream, 0); v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
ivtv_msleep_timeout(300, 1); ivtv_msleep_timeout(300, 0);
ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0); ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
v4l2_subdev_call(itv->sd_video, video, s_stream, 1); v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
} }
...@@ -834,7 +834,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) ...@@ -834,7 +834,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
} }
/* Handle any pending interrupts */ /* Handle any pending interrupts */
ivtv_msleep_timeout(100, 1); ivtv_msleep_timeout(100, 0);
} }
atomic_dec(&itv->capturing); atomic_dec(&itv->capturing);
......
...@@ -71,7 +71,7 @@ static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode) ...@@ -71,7 +71,7 @@ static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
Turning this signal on and off can confuse certain Turning this signal on and off can confuse certain
TVs. As far as I can tell there is no reason not to TVs. As far as I can tell there is no reason not to
transmit this signal. */ transmit this signal. */
if ((itv->std & V4L2_STD_625_50) && !enabled) { if ((itv->std_out & V4L2_STD_625_50) && !enabled) {
enabled = 1; enabled = 1;
mode = 0x08; /* 4x3 full format */ mode = 0x08; /* 4x3 full format */
} }
......
...@@ -247,7 +247,7 @@ static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords ...@@ -247,7 +247,7 @@ static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords
static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window) static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
{ {
int osd_height_limit = itv->is_50hz ? 576 : 480; int osd_height_limit = itv->is_out_50hz ? 576 : 480;
/* Only fail if resolution too high, otherwise fudge the start coords. */ /* Only fail if resolution too high, otherwise fudge the start coords. */
if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH)) if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
...@@ -471,9 +471,9 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar ...@@ -471,9 +471,9 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
FB_VBLANK_HAVE_VSYNC; FB_VBLANK_HAVE_VSYNC;
trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16; trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
if (itv->is_50hz && trace > 312) if (itv->is_out_50hz && trace > 312)
trace -= 312; trace -= 312;
else if (itv->is_60hz && trace > 262) else if (itv->is_out_60hz && trace > 262)
trace -= 262; trace -= 262;
if (trace == 1) if (trace == 1)
vblank.flags |= FB_VBLANK_VSYNCING; vblank.flags |= FB_VBLANK_VSYNCING;
...@@ -656,7 +656,7 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) ...@@ -656,7 +656,7 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
IVTVFB_DEBUG_INFO("ivtvfb_check_var\n"); IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
/* Set base references for mode calcs. */ /* Set base references for mode calcs. */
if (itv->is_50hz) { if (itv->is_out_50hz) {
pixclock = 84316; pixclock = 84316;
hlimit = 776; hlimit = 776;
vlimit = 591; vlimit = 591;
...@@ -784,12 +784,12 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) ...@@ -784,12 +784,12 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
If the margins are too large, just center the screen If the margins are too large, just center the screen
(enforcing margins causes too many problems) */ (enforcing margins causes too many problems) */
if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1) { if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2); var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
}
if (var->upper_margin + var->yres > (itv->is_50hz ? 577 : 481)) { if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
var->upper_margin = 1 + (((itv->is_50hz ? 576 : 480) - var->yres) / 2); var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
} var->yres) / 2);
/* Maintain overall 'size' for a constant refresh rate */ /* Maintain overall 'size' for a constant refresh rate */
var->right_margin = hlimit - var->left_margin - var->xres; var->right_margin = hlimit - var->left_margin - var->xres;
...@@ -836,7 +836,12 @@ static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf ...@@ -836,7 +836,12 @@ static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf
u32 osd_pan_index; u32 osd_pan_index;
struct ivtv *itv = (struct ivtv *) info->par; struct ivtv *itv = (struct ivtv *) info->par;
osd_pan_index = (var->xoffset + (var->yoffset * var->xres_virtual))*var->bits_per_pixel/8; if (var->yoffset + info->var.yres > info->var.yres_virtual ||
var->xoffset + info->var.xres > info->var.xres_virtual)
return -EINVAL;
osd_pan_index = var->yoffset * info->fix.line_length
+ var->xoffset * info->var.bits_per_pixel / 8;
write_reg(osd_pan_index, 0x02A0C); write_reg(osd_pan_index, 0x02A0C);
/* Pass this info back the yuv handler */ /* Pass this info back the yuv handler */
...@@ -1003,19 +1008,21 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) ...@@ -1003,19 +1008,21 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
/* Hardware coords start at 0, user coords start at 1. */ /* Hardware coords start at 0, user coords start at 1. */
osd_left--; osd_left--;
start_window.left = osd_left >= 0 ? osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2); start_window.left = osd_left >= 0 ?
osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
oi->display_byte_stride = oi->display_byte_stride =
start_window.width * oi->bytes_per_pixel; start_window.width * oi->bytes_per_pixel;
/* Vertical size & position */ /* Vertical size & position */
max_height = itv->is_50hz ? 576 : 480; max_height = itv->is_out_50hz ? 576 : 480;
if (osd_yres > max_height) if (osd_yres > max_height)
osd_yres = max_height; osd_yres = max_height;
start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400; start_window.height = osd_yres ?
osd_yres : itv->is_out_50hz ? 480 : 400;
/* Check vertical start (osd_upper). */ /* Check vertical start (osd_upper). */
if (osd_upper + start_window.height > max_height + 1) { if (osd_upper + start_window.height > max_height + 1) {
......
...@@ -391,7 +391,7 @@ static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus) ...@@ -391,7 +391,7 @@ static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus)
}; };
int i; int i;
dev_dbg(isp->dev, ""); dev_dbg(isp->dev, "ISP IRQ: ");
for (i = 0; i < ARRAY_SIZE(name); i++) { for (i = 0; i < ARRAY_SIZE(name); i++) {
if ((1 << i) & irqstatus) if ((1 << i) & irqstatus)
......
...@@ -1512,7 +1512,7 @@ static int video_dev_create(struct soc_camera_device *icd) ...@@ -1512,7 +1512,7 @@ static int video_dev_create(struct soc_camera_device *icd)
*/ */
static int soc_camera_video_start(struct soc_camera_device *icd) static int soc_camera_video_start(struct soc_camera_device *icd)
{ {
struct device_type *type = icd->vdev->dev.type; const struct device_type *type = icd->vdev->dev.type;
int ret; int ret;
if (!icd->dev.parent) if (!icd->dev.parent)
......
...@@ -30,7 +30,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, ...@@ -30,7 +30,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
struct uvc_entity *remote; struct uvc_entity *remote;
unsigned int i; unsigned int i;
u8 remote_pad; u8 remote_pad;
int ret; int ret = 0;
for (i = 0; i < entity->num_pads; ++i) { for (i = 0; i < entity->num_pads; ++i) {
struct media_entity *source; struct media_entity *source;
......
...@@ -128,8 +128,8 @@ struct video_device ...@@ -128,8 +128,8 @@ struct video_device
struct mutex *lock; struct mutex *lock;
}; };
#define media_entity_to_video_device(entity) \ #define media_entity_to_video_device(__e) \
container_of(entity, struct video_device, entity) container_of(__e, struct video_device, entity)
/* dev to video-device */ /* dev to video-device */
#define to_video_device(cd) container_of(cd, struct video_device, dev) #define to_video_device(cd) container_of(cd, struct video_device, dev)
......
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