Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 253245
b: refs/heads/master
c: c5874c9
h: refs/heads/master
i:
  253243: 4ae3915
v: v3
  • Loading branch information
Ian Armstrong authored and Mauro Carvalho Chehab committed Jun 1, 2011
1 parent 19c6b03 commit addb517
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 83 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6600cc301d0762e3db8bd2b44d2d5fef36a4fd68
refs/heads/master: c5874c9245d298c65f81c2f91f89e1da8ea66409
10 changes: 5 additions & 5 deletions trunk/drivers/media/video/ivtv/ivtv-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,8 @@ int ivtv_init_on_first_open(struct ivtv *itv)
if (!itv->has_cx23415)
write_reg_sync(0x03, IVTV_REG_DMACONTROL);

ivtv_s_std_enc(itv, &itv->tuner_std);

/* Default interrupts enabled. For the PVR350 this includes the
decoder VSYNC interrupt, which is always on. It is not only used
during decoding but also by the OSD.
Expand All @@ -1336,12 +1338,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
ivtv_set_osd_alpha(itv);
}
else
ivtv_s_std_dec(itv, &itv->tuner_std);
} else {
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 */
cx2341x_handler_setup(&itv->cxhdl);
Expand Down
11 changes: 7 additions & 4 deletions trunk/drivers/media/video/ivtv/ivtv-firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,6 @@ int ivtv_firmware_restart(struct ivtv *itv)
{
int rc = 0;
v4l2_std_id std;
struct ivtv_open_id fh;
fh.itv = itv;

if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
/* Display test image during restart */
Expand All @@ -301,14 +299,19 @@ int ivtv_firmware_restart(struct ivtv *itv)
/* Allow settings to reload */
ivtv_mailbox_cache_invalidate(itv);

/* Restore video standard */
/* Restore encoder video standard */
std = itv->std;
itv->std = 0;
ivtv_s_std(NULL, &fh, &std);
ivtv_s_std_enc(itv, &std);

if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
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 */
if (itv->ivtvfb_restore)
itv->ivtvfb_restore(itv);
Expand Down
129 changes: 70 additions & 59 deletions trunk/drivers/media/video/ivtv/ivtv-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,28 +1071,8 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
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->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
itv->is_50hz = !itv->is_60hz;
Expand All @@ -1106,48 +1086,79 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
if (itv->hw_flags & IVTV_HW_CX25840)
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 */
ivtv_call_all(itv, core, s_std, itv->std);
}

if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
/* set display standard */
itv->std_out = *std;
itv->is_out_60hz = itv->is_60hz;
itv->is_out_50hz = itv->is_50hz;
ivtv_call_all(itv, video, s_std_output, itv->std_out);

/*
* The next firmware call is time sensitive. Time it to
* avoid risk of a hard lock, by trying to ensure the call
* happens within the first 100 lines of the top field.
* Make 4 attempts to sync to the decoder before giving up.
*/
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");

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;
}
void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
{
struct yuv_playback_info *yi = &itv->yuv_info;
DEFINE_WAIT(wait);
int f;

/* set display standard */
itv->std_out = *std;
itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
itv->is_out_50hz = !itv->is_out_60hz;
ivtv_call_all(itv, video, s_std_output, itv->std_out);

/*
* The next firmware call is time sensitive. Time it to
* avoid risk of a hard lock, by trying to ensure the call
* happens within the first 100 lines of the top field.
* Make 4 attempts to sync to the decoder before giving up.
*/
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");

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;
}

Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/media/video/ivtv/ivtv-ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
void ivtv_set_osd_alpha(struct ivtv *itv);
int ivtv_set_speed(struct ivtv *itv, int speed);
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_input(struct file *file, void *fh, unsigned int inp);
long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/media/video/ivtv/ivtv-vbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
TVs. As far as I can tell there is no reason not to
transmit this signal. */
if ((itv->std & V4L2_STD_625_50) && !enabled) {
if ((itv->std_out & V4L2_STD_625_50) && !enabled) {
enabled = 1;
mode = 0x08; /* 4x3 full format */
}
Expand Down
26 changes: 14 additions & 12 deletions trunk/drivers/media/video/ivtv/ivtvfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
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. */
if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
Expand Down Expand Up @@ -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 |
FB_VBLANK_HAVE_VSYNC;
trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
if (itv->is_50hz && trace > 312)
if (itv->is_out_50hz && trace > 312)
trace -= 312;
else if (itv->is_60hz && trace > 262)
else if (itv->is_out_60hz && trace > 262)
trace -= 262;
if (trace == 1)
vblank.flags |= FB_VBLANK_VSYNCING;
Expand Down Expand Up @@ -656,7 +656,7 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");

/* Set base references for mode calcs. */
if (itv->is_50hz) {
if (itv->is_out_50hz) {
pixclock = 84316;
hlimit = 776;
vlimit = 591;
Expand Down Expand Up @@ -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
(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);
}
if (var->upper_margin + var->yres > (itv->is_50hz ? 577 : 481)) {
var->upper_margin = 1 + (((itv->is_50hz ? 576 : 480) - var->yres) / 2);
}

if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
var->yres) / 2);

/* Maintain overall 'size' for a constant refresh rate */
var->right_margin = hlimit - var->left_margin - var->xres;
Expand Down Expand Up @@ -1008,19 +1008,21 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
/* Hardware coords start at 0, user coords start at 1. */
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 =
start_window.width * oi->bytes_per_pixel;

/* Vertical size & position */

max_height = itv->is_50hz ? 576 : 480;
max_height = itv->is_out_50hz ? 576 : 480;

if (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). */
if (osd_upper + start_window.height > max_height + 1) {
Expand Down

0 comments on commit addb517

Please sign in to comment.