mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 05:34:00 +08:00
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
This commit is contained in:
commit
46671b0355
@ -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,
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
/* 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;
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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[] = {
|
|||||||
* 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,
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
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 {
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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 */
|
||||||
* The next firmware call is time sensitive. Time it to
|
itv->std_out = *std;
|
||||||
* avoid risk of a hard lock, by trying to ensure the call
|
itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
|
||||||
* happens within the first 100 lines of the top field.
|
itv->is_out_50hz = !itv->is_out_60hz;
|
||||||
* Make 4 attempts to sync to the decoder before giving up.
|
ivtv_call_all(itv, video, s_std_output, itv->std_out);
|
||||||
*/
|
|
||||||
for (f = 0; f < 4; f++) {
|
|
||||||
prepare_to_wait(&itv->vsync_waitq, &wait,
|
|
||||||
TASK_UNINTERRUPTIBLE);
|
|
||||||
if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
|
|
||||||
break;
|
|
||||||
schedule_timeout(msecs_to_jiffies(25));
|
|
||||||
}
|
|
||||||
finish_wait(&itv->vsync_waitq, &wait);
|
|
||||||
|
|
||||||
if (f == 4)
|
/*
|
||||||
IVTV_WARN("Mode change failed to sync to decoder\n");
|
* The next firmware call is time sensitive. Time it to
|
||||||
|
* avoid risk of a hard lock, by trying to ensure the call
|
||||||
ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
|
* happens within the first 100 lines of the top field.
|
||||||
itv->main_rect.left = itv->main_rect.top = 0;
|
* Make 4 attempts to sync to the decoder before giving up.
|
||||||
itv->main_rect.width = 720;
|
*/
|
||||||
itv->main_rect.height = itv->cxhdl.height;
|
for (f = 0; f < 4; f++) {
|
||||||
ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
|
prepare_to_wait(&itv->vsync_waitq, &wait,
|
||||||
720, itv->main_rect.height, 0, 0);
|
TASK_UNINTERRUPTIBLE);
|
||||||
yi->main_rect = itv->main_rect;
|
if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
|
||||||
if (!itv->osd_info) {
|
break;
|
||||||
yi->osd_full_w = 720;
|
schedule_timeout(msecs_to_jiffies(25));
|
||||||
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);
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
|||||||
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
|
|||||||
|
|
||||||
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
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
};
|
};
|
||||||
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)
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
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
|
|||||||
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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user