diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-22 22:20:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-22 22:20:22 -0400 |
commit | ad792f4f46e12bae58298fc64f5139b99664a773 (patch) | |
tree | 3d20c3a0840b00deb95fe62fdff1bc6e59eb37fe /drivers/media/video/ivtv | |
parent | 3650b0a304663d98a63c68f9020eb1ded477989e (diff) | |
parent | f40aa808bad19a079a0e122e326d6970df141afb (diff) |
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (37 commits)
V4L/DVB (6382): saa7134: fix NULL dereference at suspend time for cards without IR receiver
V4L/DVB (6380): ivtvfb: Removal of the 'osd_compat' module option
V4L/DVB (6379): patch which improves GotView Saa7135 remote control
V4L/DVB (6378b): Updates info about the removal of V4L1 at feature-removal-schedule.txt
V4L/DVB (6378a): Removal of VIDIOC_[G|S]_MPEGCOMP from feature-removal-schedule.txt
V4L/DVB (6378): DiB0700-device: Using 1.10 firmware
V4L/DVB (6357): pvrusb2: Improve encoder chip health tracking
V4L/DVB (6356): "while (!ca->wakeup)" breaks the CAM initialisation
V4L/DVB (6352): ir-kbd-i2c: Missing break statement
V4L/DVB (6350): V4L: possible leak in em28xx_init_isoc
V4L/DVB (6348): ivtv: undo video mute when closing the radio
V4L/DVB (6347): ivtv: fix video mute when radio is used
V4L/DVB (6346): ivtvfb: YUV output size fix when ivtvfb is not loaded
V4L/DVB (6345): ivtvfb: YUV handling of an image which is not visible in the display area
V4L/DVB (6343): ivtvfb: check return value of unregister_framebuffer
V4L/DVB (6342): ivtv: fix circular locking (bug 9037)
V4L/DVB (6341): ivtv: fix resizing MPEG1 streams
V4L/DVB (6340): ivtvfb: screen mode change sometimes goes wrong
V4L/DVB (6339): ivtv: set the video color to black instead of green when capturing from the radio
V4L/DVB (6338): ivtv: fix incorrect EBUSY return
...
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 11 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 8 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 13 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 116 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.h | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-yuv.c | 160 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-yuv.h | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtvfb.c | 92 |
8 files changed, 200 insertions, 202 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index fd7a932e1d33..6d2dd8764f81 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -1003,8 +1003,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
1003 | 1003 | ||
1004 | IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); | 1004 | IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); |
1005 | 1005 | ||
1006 | mutex_lock(&itv->serialize_lock); | ||
1007 | |||
1008 | /* PCI Device Setup */ | 1006 | /* PCI Device Setup */ |
1009 | if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) { | 1007 | if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) { |
1010 | if (retval == -EIO) | 1008 | if (retval == -EIO) |
@@ -1064,7 +1062,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
1064 | IVTV_DEBUG_INFO("activating i2c...\n"); | 1062 | IVTV_DEBUG_INFO("activating i2c...\n"); |
1065 | if (init_ivtv_i2c(itv)) { | 1063 | if (init_ivtv_i2c(itv)) { |
1066 | IVTV_ERR("Could not initialize i2c\n"); | 1064 | IVTV_ERR("Could not initialize i2c\n"); |
1067 | goto free_irq; | 1065 | goto free_io; |
1068 | } | 1066 | } |
1069 | 1067 | ||
1070 | IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active); | 1068 | IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active); |
@@ -1176,7 +1174,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
1176 | IVTV_ERR("Failed to register irq %d\n", retval); | 1174 | IVTV_ERR("Failed to register irq %d\n", retval); |
1177 | goto free_streams; | 1175 | goto free_streams; |
1178 | } | 1176 | } |
1179 | mutex_unlock(&itv->serialize_lock); | 1177 | retval = ivtv_streams_register(itv); |
1178 | if (retval) { | ||
1179 | IVTV_ERR("Error %d registering devices\n", retval); | ||
1180 | goto free_irq; | ||
1181 | } | ||
1180 | IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); | 1182 | IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); |
1181 | return 0; | 1183 | return 0; |
1182 | 1184 | ||
@@ -1195,7 +1197,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
1195 | release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); | 1197 | release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); |
1196 | free_workqueue: | 1198 | free_workqueue: |
1197 | destroy_workqueue(itv->irq_work_queues); | 1199 | destroy_workqueue(itv->irq_work_queues); |
1198 | mutex_unlock(&itv->serialize_lock); | ||
1199 | err: | 1200 | err: |
1200 | if (retval == 0) | 1201 | if (retval == 0) |
1201 | retval = -ENODEV; | 1202 | retval = -ENODEV; |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index da50fa4a72a5..a200a8a95a2d 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -822,6 +822,11 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp) | |||
822 | crystal_freq.flags = 0; | 822 | crystal_freq.flags = 0; |
823 | ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq); | 823 | ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq); |
824 | } | 824 | } |
825 | if (atomic_read(&itv->capturing) > 0) { | ||
826 | /* Undo video mute */ | ||
827 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, | ||
828 | itv->params.video_mute | (itv->params.video_mute_yuv << 8)); | ||
829 | } | ||
825 | /* Done! Unmute and continue. */ | 830 | /* Done! Unmute and continue. */ |
826 | ivtv_unmute(itv); | 831 | ivtv_unmute(itv); |
827 | ivtv_release_stream(s); | 832 | ivtv_release_stream(s); |
@@ -892,6 +897,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
892 | if (atomic_read(&itv->capturing) > 0) { | 897 | if (atomic_read(&itv->capturing) > 0) { |
893 | /* switching to radio while capture is | 898 | /* switching to radio while capture is |
894 | in progress is not polite */ | 899 | in progress is not polite */ |
900 | ivtv_release_stream(s); | ||
895 | kfree(item); | 901 | kfree(item); |
896 | return -EBUSY; | 902 | return -EBUSY; |
897 | } | 903 | } |
@@ -947,7 +953,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) | |||
947 | if (itv == NULL) { | 953 | if (itv == NULL) { |
948 | /* Couldn't find a device registered | 954 | /* Couldn't find a device registered |
949 | on that minor, shouldn't happen! */ | 955 | on that minor, shouldn't happen! */ |
950 | IVTV_WARN("No ivtv device found on minor %d\n", minor); | 956 | printk(KERN_WARNING "No ivtv device found on minor %d\n", minor); |
951 | return -ENXIO; | 957 | return -ENXIO; |
952 | } | 958 | } |
953 | 959 | ||
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 206eee7542db..fd6826f472e3 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -555,6 +555,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, | |||
555 | 555 | ||
556 | /* set window size */ | 556 | /* set window size */ |
557 | if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 557 | if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
558 | struct cx2341x_mpeg_params *p = &itv->params; | ||
558 | int w = fmt->fmt.pix.width; | 559 | int w = fmt->fmt.pix.width; |
559 | int h = fmt->fmt.pix.height; | 560 | int h = fmt->fmt.pix.height; |
560 | 561 | ||
@@ -566,17 +567,19 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, | |||
566 | fmt->fmt.pix.width = w; | 567 | fmt->fmt.pix.width = w; |
567 | fmt->fmt.pix.height = h; | 568 | fmt->fmt.pix.height = h; |
568 | 569 | ||
569 | if (!set_fmt || (itv->params.width == w && itv->params.height == h)) | 570 | if (!set_fmt || (p->width == w && p->height == h)) |
570 | return 0; | 571 | return 0; |
571 | if (atomic_read(&itv->capturing) > 0) | 572 | if (atomic_read(&itv->capturing) > 0) |
572 | return -EBUSY; | 573 | return -EBUSY; |
573 | 574 | ||
574 | itv->params.width = w; | 575 | p->width = w; |
575 | itv->params.height = h; | 576 | p->height = h; |
576 | if (w != 720 || h != (itv->is_50hz ? 576 : 480)) | 577 | if (w != 720 || h != (itv->is_50hz ? 576 : 480)) |
577 | itv->params.video_temporal_filter = 0; | 578 | p->video_temporal_filter = 0; |
578 | else | 579 | else |
579 | itv->params.video_temporal_filter = 8; | 580 | p->video_temporal_filter = 8; |
581 | if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) | ||
582 | fmt->fmt.pix.width /= 2; | ||
580 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); | 583 | itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); |
581 | return ivtv_get_fmt(itv, streamtype, fmt); | 584 | return ivtv_get_fmt(itv, streamtype, fmt); |
582 | } | 585 | } |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index fd135985e70f..aa03e61ef310 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -166,10 +166,9 @@ static void ivtv_stream_init(struct ivtv *itv, int type) | |||
166 | ivtv_queue_init(&s->q_io); | 166 | ivtv_queue_init(&s->q_io); |
167 | } | 167 | } |
168 | 168 | ||
169 | static int ivtv_reg_dev(struct ivtv *itv, int type) | 169 | static int ivtv_prep_dev(struct ivtv *itv, int type) |
170 | { | 170 | { |
171 | struct ivtv_stream *s = &itv->streams[type]; | 171 | struct ivtv_stream *s = &itv->streams[type]; |
172 | int vfl_type = ivtv_stream_info[type].vfl_type; | ||
173 | int minor_offset = ivtv_stream_info[type].minor_offset; | 172 | int minor_offset = ivtv_stream_info[type].minor_offset; |
174 | int minor; | 173 | int minor; |
175 | 174 | ||
@@ -187,15 +186,12 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) | |||
187 | if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | 186 | if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) |
188 | return 0; | 187 | return 0; |
189 | 188 | ||
190 | if (minor_offset >= 0) | 189 | /* card number + user defined offset + device offset */ |
191 | /* card number + user defined offset + device offset */ | 190 | minor = itv->num + ivtv_first_minor + minor_offset; |
192 | minor = itv->num + ivtv_first_minor + minor_offset; | ||
193 | else | ||
194 | minor = -1; | ||
195 | 191 | ||
196 | /* User explicitly selected 0 buffers for these streams, so don't | 192 | /* User explicitly selected 0 buffers for these streams, so don't |
197 | create them. */ | 193 | create them. */ |
198 | if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE && | 194 | if (ivtv_stream_info[type].dma != PCI_DMA_NONE && |
199 | itv->options.kilobytes[type] == 0) { | 195 | itv->options.kilobytes[type] == 0) { |
200 | IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name); | 196 | IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name); |
201 | return 0; | 197 | return 0; |
@@ -223,21 +219,53 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) | |||
223 | s->v4l2dev->fops = ivtv_stream_info[type].fops; | 219 | s->v4l2dev->fops = ivtv_stream_info[type].fops; |
224 | s->v4l2dev->release = video_device_release; | 220 | s->v4l2dev->release = video_device_release; |
225 | 221 | ||
226 | if (minor >= 0) { | 222 | return 0; |
227 | /* Register device. First try the desired minor, then any free one. */ | 223 | } |
228 | if (video_register_device(s->v4l2dev, vfl_type, minor) && | 224 | |
229 | video_register_device(s->v4l2dev, vfl_type, -1)) { | 225 | /* Initialize v4l2 variables and prepare v4l2 devices */ |
230 | IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", | 226 | int ivtv_streams_setup(struct ivtv *itv) |
231 | s->name, minor); | 227 | { |
232 | video_device_release(s->v4l2dev); | 228 | int type; |
233 | s->v4l2dev = NULL; | 229 | |
234 | return -ENOMEM; | 230 | /* Setup V4L2 Devices */ |
235 | } | 231 | for (type = 0; type < IVTV_MAX_STREAMS; type++) { |
232 | /* Prepare device */ | ||
233 | if (ivtv_prep_dev(itv, type)) | ||
234 | break; | ||
235 | |||
236 | if (itv->streams[type].v4l2dev == NULL) | ||
237 | continue; | ||
238 | |||
239 | /* Allocate Stream */ | ||
240 | if (ivtv_stream_alloc(&itv->streams[type])) | ||
241 | break; | ||
236 | } | 242 | } |
237 | else { | 243 | if (type == IVTV_MAX_STREAMS) |
238 | /* Don't register a 'hidden' stream (OSD) */ | ||
239 | IVTV_INFO("Created framebuffer stream for %s\n", s->name); | ||
240 | return 0; | 244 | return 0; |
245 | |||
246 | /* One or more streams could not be initialized. Clean 'em all up. */ | ||
247 | ivtv_streams_cleanup(itv); | ||
248 | return -ENOMEM; | ||
249 | } | ||
250 | |||
251 | static int ivtv_reg_dev(struct ivtv *itv, int type) | ||
252 | { | ||
253 | struct ivtv_stream *s = &itv->streams[type]; | ||
254 | int vfl_type = ivtv_stream_info[type].vfl_type; | ||
255 | int minor; | ||
256 | |||
257 | if (s->v4l2dev == NULL) | ||
258 | return 0; | ||
259 | |||
260 | minor = s->v4l2dev->minor; | ||
261 | /* Register device. First try the desired minor, then any free one. */ | ||
262 | if (video_register_device(s->v4l2dev, vfl_type, minor) && | ||
263 | video_register_device(s->v4l2dev, vfl_type, -1)) { | ||
264 | IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n", | ||
265 | s->name, minor); | ||
266 | video_device_release(s->v4l2dev); | ||
267 | s->v4l2dev = NULL; | ||
268 | return -ENOMEM; | ||
241 | } | 269 | } |
242 | 270 | ||
243 | switch (vfl_type) { | 271 | switch (vfl_type) { |
@@ -262,27 +290,18 @@ static int ivtv_reg_dev(struct ivtv *itv, int type) | |||
262 | return 0; | 290 | return 0; |
263 | } | 291 | } |
264 | 292 | ||
265 | /* Initialize v4l2 variables and register v4l2 devices */ | 293 | /* Register v4l2 devices */ |
266 | int ivtv_streams_setup(struct ivtv *itv) | 294 | int ivtv_streams_register(struct ivtv *itv) |
267 | { | 295 | { |
268 | int type; | 296 | int type; |
297 | int err = 0; | ||
269 | 298 | ||
270 | /* Setup V4L2 Devices */ | 299 | /* Register V4L2 devices */ |
271 | for (type = 0; type < IVTV_MAX_STREAMS; type++) { | 300 | for (type = 0; type < IVTV_MAX_STREAMS; type++) |
272 | /* Register Device */ | 301 | err |= ivtv_reg_dev(itv, type); |
273 | if (ivtv_reg_dev(itv, type)) | ||
274 | break; | ||
275 | |||
276 | if (itv->streams[type].v4l2dev == NULL) | ||
277 | continue; | ||
278 | 302 | ||
279 | /* Allocate Stream */ | 303 | if (err == 0) |
280 | if (ivtv_stream_alloc(&itv->streams[type])) | ||
281 | break; | ||
282 | } | ||
283 | if (type == IVTV_MAX_STREAMS) { | ||
284 | return 0; | 304 | return 0; |
285 | } | ||
286 | 305 | ||
287 | /* One or more streams could not be initialized. Clean 'em all up. */ | 306 | /* One or more streams could not be initialized. Clean 'em all up. */ |
288 | ivtv_streams_cleanup(itv); | 307 | ivtv_streams_cleanup(itv); |
@@ -303,11 +322,8 @@ void ivtv_streams_cleanup(struct ivtv *itv) | |||
303 | continue; | 322 | continue; |
304 | 323 | ||
305 | ivtv_stream_free(&itv->streams[type]); | 324 | ivtv_stream_free(&itv->streams[type]); |
306 | /* Free Device */ | 325 | /* Unregister device */ |
307 | if (vdev->minor == -1) /* 'Hidden' never registered stream (OSD) */ | 326 | video_unregister_device(vdev); |
308 | video_device_release(vdev); | ||
309 | else /* All others, just unregister. */ | ||
310 | video_unregister_device(vdev); | ||
311 | } | 327 | } |
312 | } | 328 | } |
313 | 329 | ||
@@ -425,6 +441,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
425 | { | 441 | { |
426 | u32 data[CX2341X_MBOX_MAX_DATA]; | 442 | u32 data[CX2341X_MBOX_MAX_DATA]; |
427 | struct ivtv *itv = s->itv; | 443 | struct ivtv *itv = s->itv; |
444 | struct cx2341x_mpeg_params *p = &itv->params; | ||
428 | int captype = 0, subtype = 0; | 445 | int captype = 0, subtype = 0; |
429 | int enable_passthrough = 0; | 446 | int enable_passthrough = 0; |
430 | 447 | ||
@@ -445,7 +462,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
445 | } | 462 | } |
446 | itv->mpg_data_received = itv->vbi_data_inserted = 0; | 463 | itv->mpg_data_received = itv->vbi_data_inserted = 0; |
447 | itv->dualwatch_jiffies = jiffies; | 464 | itv->dualwatch_jiffies = jiffies; |
448 | itv->dualwatch_stereo_mode = itv->params.audio_properties & 0x0300; | 465 | itv->dualwatch_stereo_mode = p->audio_properties & 0x0300; |
449 | itv->search_pack_header = 0; | 466 | itv->search_pack_header = 0; |
450 | break; | 467 | break; |
451 | 468 | ||
@@ -477,9 +494,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
477 | s->subtype = subtype; | 494 | s->subtype = subtype; |
478 | s->buffers_stolen = 0; | 495 | s->buffers_stolen = 0; |
479 | 496 | ||
480 | /* mute/unmute video */ | ||
481 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? 1 : 0); | ||
482 | |||
483 | /* Clear Streamoff flags in case left from last capture */ | 497 | /* Clear Streamoff flags in case left from last capture */ |
484 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | 498 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); |
485 | 499 | ||
@@ -536,7 +550,12 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
536 | itv->pgm_info_offset, itv->pgm_info_num); | 550 | itv->pgm_info_offset, itv->pgm_info_num); |
537 | 551 | ||
538 | /* Setup API for Stream */ | 552 | /* Setup API for Stream */ |
539 | cx2341x_update(itv, ivtv_api_func, NULL, &itv->params); | 553 | cx2341x_update(itv, ivtv_api_func, NULL, p); |
554 | |||
555 | /* mute if capturing radio */ | ||
556 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) | ||
557 | ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, | ||
558 | 1 | (p->video_mute_yuv << 8)); | ||
540 | } | 559 | } |
541 | 560 | ||
542 | /* Vsync Setup */ | 561 | /* Vsync Setup */ |
@@ -585,6 +604,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) | |||
585 | { | 604 | { |
586 | u32 data[CX2341X_MBOX_MAX_DATA]; | 605 | u32 data[CX2341X_MBOX_MAX_DATA]; |
587 | struct ivtv *itv = s->itv; | 606 | struct ivtv *itv = s->itv; |
607 | struct cx2341x_mpeg_params *p = &itv->params; | ||
588 | int datatype; | 608 | int datatype; |
589 | 609 | ||
590 | if (s->v4l2dev == NULL) | 610 | if (s->v4l2dev == NULL) |
@@ -623,7 +643,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) | |||
623 | break; | 643 | break; |
624 | } | 644 | } |
625 | if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, | 645 | if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, |
626 | itv->params.width, itv->params.height, itv->params.audio_properties)) { | 646 | p->width, p->height, p->audio_properties)) { |
627 | IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); | 647 | IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); |
628 | } | 648 | } |
629 | return 0; | 649 | return 0; |
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h index 8f5f5b1c7c89..3d76a415fbd8 100644 --- a/drivers/media/video/ivtv/ivtv-streams.h +++ b/drivers/media/video/ivtv/ivtv-streams.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define IVTV_STREAMS_H | 22 | #define IVTV_STREAMS_H |
23 | 23 | ||
24 | int ivtv_streams_setup(struct ivtv *itv); | 24 | int ivtv_streams_setup(struct ivtv *itv); |
25 | int ivtv_streams_register(struct ivtv *itv); | ||
25 | void ivtv_streams_cleanup(struct ivtv *itv); | 26 | void ivtv_streams_cleanup(struct ivtv *itv); |
26 | 27 | ||
27 | /* Capture related */ | 28 | /* Capture related */ |
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index e2288f224ab6..9091c4837bbc 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -710,7 +710,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo | |||
710 | 710 | ||
711 | /* If there's nothing to safe to display, we may as well stop now */ | 711 | /* If there's nothing to safe to display, we may as well stop now */ |
712 | if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { | 712 | if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { |
713 | return 0; | 713 | return IVTV_YUV_UPDATE_INVALID; |
714 | } | 714 | } |
715 | 715 | ||
716 | /* Ensure video remains inside OSD area */ | 716 | /* Ensure video remains inside OSD area */ |
@@ -791,7 +791,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo | |||
791 | 791 | ||
792 | /* Check again. If there's nothing to safe to display, stop now */ | 792 | /* Check again. If there's nothing to safe to display, stop now */ |
793 | if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { | 793 | if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { |
794 | return 0; | 794 | return IVTV_YUV_UPDATE_INVALID; |
795 | } | 795 | } |
796 | 796 | ||
797 | /* Both x offset & width are linked, so they have to be done together */ | 797 | /* Both x offset & width are linked, so they have to be done together */ |
@@ -840,110 +840,118 @@ void ivtv_yuv_work_handler (struct ivtv *itv) | |||
840 | if (!(yuv_update = ivtv_yuv_window_setup (itv, &window))) | 840 | if (!(yuv_update = ivtv_yuv_window_setup (itv, &window))) |
841 | return; | 841 | return; |
842 | 842 | ||
843 | /* Update horizontal settings */ | 843 | if (yuv_update & IVTV_YUV_UPDATE_INVALID) { |
844 | if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL) | 844 | write_reg(0x01008080, 0x2898); |
845 | ivtv_yuv_handle_horizontal(itv, &window); | 845 | } else if (yuv_update) { |
846 | write_reg(0x00108080, 0x2898); | ||
846 | 847 | ||
847 | if (yuv_update & IVTV_YUV_UPDATE_VERTICAL) | 848 | if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL) |
848 | ivtv_yuv_handle_vertical(itv, &window); | 849 | ivtv_yuv_handle_horizontal(itv, &window); |
850 | |||
851 | if (yuv_update & IVTV_YUV_UPDATE_VERTICAL) | ||
852 | ivtv_yuv_handle_vertical(itv, &window); | ||
853 | } | ||
849 | 854 | ||
850 | memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info)); | 855 | memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info)); |
851 | } | 856 | } |
852 | 857 | ||
853 | static void ivtv_yuv_init (struct ivtv *itv) | 858 | static void ivtv_yuv_init (struct ivtv *itv) |
854 | { | 859 | { |
860 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
861 | |||
855 | IVTV_DEBUG_YUV("ivtv_yuv_init\n"); | 862 | IVTV_DEBUG_YUV("ivtv_yuv_init\n"); |
856 | 863 | ||
857 | /* Take a snapshot of the current register settings */ | 864 | /* Take a snapshot of the current register settings */ |
858 | itv->yuv_info.reg_2834 = read_reg(0x02834); | 865 | yi->reg_2834 = read_reg(0x02834); |
859 | itv->yuv_info.reg_2838 = read_reg(0x02838); | 866 | yi->reg_2838 = read_reg(0x02838); |
860 | itv->yuv_info.reg_283c = read_reg(0x0283c); | 867 | yi->reg_283c = read_reg(0x0283c); |
861 | itv->yuv_info.reg_2840 = read_reg(0x02840); | 868 | yi->reg_2840 = read_reg(0x02840); |
862 | itv->yuv_info.reg_2844 = read_reg(0x02844); | 869 | yi->reg_2844 = read_reg(0x02844); |
863 | itv->yuv_info.reg_2848 = read_reg(0x02848); | 870 | yi->reg_2848 = read_reg(0x02848); |
864 | itv->yuv_info.reg_2854 = read_reg(0x02854); | 871 | yi->reg_2854 = read_reg(0x02854); |
865 | itv->yuv_info.reg_285c = read_reg(0x0285c); | 872 | yi->reg_285c = read_reg(0x0285c); |
866 | itv->yuv_info.reg_2864 = read_reg(0x02864); | 873 | yi->reg_2864 = read_reg(0x02864); |
867 | itv->yuv_info.reg_2870 = read_reg(0x02870); | 874 | yi->reg_2870 = read_reg(0x02870); |
868 | itv->yuv_info.reg_2874 = read_reg(0x02874); | 875 | yi->reg_2874 = read_reg(0x02874); |
869 | itv->yuv_info.reg_2898 = read_reg(0x02898); | 876 | yi->reg_2898 = read_reg(0x02898); |
870 | itv->yuv_info.reg_2890 = read_reg(0x02890); | 877 | yi->reg_2890 = read_reg(0x02890); |
871 | 878 | ||
872 | itv->yuv_info.reg_289c = read_reg(0x0289c); | 879 | yi->reg_289c = read_reg(0x0289c); |
873 | itv->yuv_info.reg_2918 = read_reg(0x02918); | 880 | yi->reg_2918 = read_reg(0x02918); |
874 | itv->yuv_info.reg_291c = read_reg(0x0291c); | 881 | yi->reg_291c = read_reg(0x0291c); |
875 | itv->yuv_info.reg_2920 = read_reg(0x02920); | 882 | yi->reg_2920 = read_reg(0x02920); |
876 | itv->yuv_info.reg_2924 = read_reg(0x02924); | 883 | yi->reg_2924 = read_reg(0x02924); |
877 | itv->yuv_info.reg_2928 = read_reg(0x02928); | 884 | yi->reg_2928 = read_reg(0x02928); |
878 | itv->yuv_info.reg_292c = read_reg(0x0292c); | 885 | yi->reg_292c = read_reg(0x0292c); |
879 | itv->yuv_info.reg_2930 = read_reg(0x02930); | 886 | yi->reg_2930 = read_reg(0x02930); |
880 | itv->yuv_info.reg_2934 = read_reg(0x02934); | 887 | yi->reg_2934 = read_reg(0x02934); |
881 | itv->yuv_info.reg_2938 = read_reg(0x02938); | 888 | yi->reg_2938 = read_reg(0x02938); |
882 | itv->yuv_info.reg_293c = read_reg(0x0293c); | 889 | yi->reg_293c = read_reg(0x0293c); |
883 | itv->yuv_info.reg_2940 = read_reg(0x02940); | 890 | yi->reg_2940 = read_reg(0x02940); |
884 | itv->yuv_info.reg_2944 = read_reg(0x02944); | 891 | yi->reg_2944 = read_reg(0x02944); |
885 | itv->yuv_info.reg_2948 = read_reg(0x02948); | 892 | yi->reg_2948 = read_reg(0x02948); |
886 | itv->yuv_info.reg_294c = read_reg(0x0294c); | 893 | yi->reg_294c = read_reg(0x0294c); |
887 | itv->yuv_info.reg_2950 = read_reg(0x02950); | 894 | yi->reg_2950 = read_reg(0x02950); |
888 | itv->yuv_info.reg_2954 = read_reg(0x02954); | 895 | yi->reg_2954 = read_reg(0x02954); |
889 | itv->yuv_info.reg_2958 = read_reg(0x02958); | 896 | yi->reg_2958 = read_reg(0x02958); |
890 | itv->yuv_info.reg_295c = read_reg(0x0295c); | 897 | yi->reg_295c = read_reg(0x0295c); |
891 | itv->yuv_info.reg_2960 = read_reg(0x02960); | 898 | yi->reg_2960 = read_reg(0x02960); |
892 | itv->yuv_info.reg_2964 = read_reg(0x02964); | 899 | yi->reg_2964 = read_reg(0x02964); |
893 | itv->yuv_info.reg_2968 = read_reg(0x02968); | 900 | yi->reg_2968 = read_reg(0x02968); |
894 | itv->yuv_info.reg_296c = read_reg(0x0296c); | 901 | yi->reg_296c = read_reg(0x0296c); |
895 | itv->yuv_info.reg_2970 = read_reg(0x02970); | 902 | yi->reg_2970 = read_reg(0x02970); |
896 | 903 | ||
897 | itv->yuv_info.v_filter_1 = -1; | 904 | yi->v_filter_1 = -1; |
898 | itv->yuv_info.v_filter_2 = -1; | 905 | yi->v_filter_2 = -1; |
899 | itv->yuv_info.h_filter = -1; | 906 | yi->h_filter = -1; |
900 | 907 | ||
901 | /* Set some valid size info */ | 908 | /* Set some valid size info */ |
902 | itv->yuv_info.osd_x_offset = read_reg(0x02a04) & 0x00000FFF; | 909 | yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF; |
903 | itv->yuv_info.osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF; | 910 | yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF; |
904 | 911 | ||
905 | /* Bit 2 of reg 2878 indicates current decoder output format | 912 | /* Bit 2 of reg 2878 indicates current decoder output format |
906 | 0 : NTSC 1 : PAL */ | 913 | 0 : NTSC 1 : PAL */ |
907 | if (read_reg(0x2878) & 4) | 914 | if (read_reg(0x2878) & 4) |
908 | itv->yuv_info.decode_height = 576; | 915 | yi->decode_height = 576; |
909 | else | 916 | else |
910 | itv->yuv_info.decode_height = 480; | 917 | yi->decode_height = 480; |
911 | 918 | ||
912 | /* If no visible size set, assume full size */ | 919 | if (!itv->osd_info) { |
913 | if (!itv->yuv_info.osd_vis_w) | 920 | yi->osd_vis_w = 720 - yi->osd_x_offset; |
914 | itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset; | 921 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; |
915 | |||
916 | if (!itv->yuv_info.osd_vis_h) { | ||
917 | itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset; | ||
918 | } else { | 922 | } else { |
919 | /* If output video standard has changed, requested height may | 923 | /* If no visible size set, assume full size */ |
920 | not be legal */ | 924 | if (!yi->osd_vis_w) |
921 | if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) { | 925 | yi->osd_vis_w = 720 - yi->osd_x_offset; |
922 | IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n", | 926 | |
923 | itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset, | 927 | if (!yi->osd_vis_h) |
924 | itv->yuv_info.decode_height); | 928 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; |
925 | itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset; | 929 | else { |
930 | /* If output video standard has changed, requested height may | ||
931 | not be legal */ | ||
932 | if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) { | ||
933 | IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n", | ||
934 | yi->osd_vis_h + yi->osd_y_offset, | ||
935 | yi->decode_height); | ||
936 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; | ||
937 | } | ||
926 | } | 938 | } |
927 | } | 939 | } |
928 | 940 | ||
929 | /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ | 941 | /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ |
930 | itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL); | 942 | yi->blanking_ptr = kzalloc(720*16, GFP_KERNEL); |
931 | if (itv->yuv_info.blanking_ptr) { | 943 | if (yi->blanking_ptr) |
932 | itv->yuv_info.blanking_dmaptr = pci_map_single(itv->dev, itv->yuv_info.blanking_ptr, 720*16, PCI_DMA_TODEVICE); | 944 | yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); |
933 | } | ||
934 | else { | 945 | else { |
935 | itv->yuv_info.blanking_dmaptr = 0; | 946 | yi->blanking_dmaptr = 0; |
936 | IVTV_DEBUG_WARN ("Failed to allocate yuv blanking buffer\n"); | 947 | IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n"); |
937 | } | 948 | } |
938 | 949 | ||
939 | IVTV_DEBUG_WARN("Enable video output\n"); | ||
940 | write_reg_sync(0x00108080, 0x2898); | ||
941 | |||
942 | /* Enable YUV decoder output */ | 950 | /* Enable YUV decoder output */ |
943 | write_reg_sync(0x01, IVTV_REG_VDM); | 951 | write_reg_sync(0x01, IVTV_REG_VDM); |
944 | 952 | ||
945 | set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags); | 953 | set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags); |
946 | atomic_set(&itv->yuv_info.next_dma_frame,0); | 954 | atomic_set(&yi->next_dma_frame, 0); |
947 | } | 955 | } |
948 | 956 | ||
949 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | 957 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) |
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h index f7215eeca018..3b966f0a204a 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.h +++ b/drivers/media/video/ivtv/ivtv-yuv.h | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #define IVTV_YUV_UPDATE_HORIZONTAL 0x01 | 35 | #define IVTV_YUV_UPDATE_HORIZONTAL 0x01 |
36 | #define IVTV_YUV_UPDATE_VERTICAL 0x02 | 36 | #define IVTV_YUV_UPDATE_VERTICAL 0x02 |
37 | #define IVTV_YUV_UPDATE_INVALID 0x04 | ||
37 | 38 | ||
38 | extern const u32 yuv_offset[4]; | 39 | extern const u32 yuv_offset[4]; |
39 | 40 | ||
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 9684048fe56c..52ffd154a3d8 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c | |||
@@ -55,7 +55,6 @@ | |||
55 | static int ivtvfb_card_id = -1; | 55 | static int ivtvfb_card_id = -1; |
56 | static int ivtvfb_debug = 0; | 56 | static int ivtvfb_debug = 0; |
57 | static int osd_laced; | 57 | static int osd_laced; |
58 | static int osd_compat; | ||
59 | static int osd_depth; | 58 | static int osd_depth; |
60 | static int osd_upper; | 59 | static int osd_upper; |
61 | static int osd_left; | 60 | static int osd_left; |
@@ -65,7 +64,6 @@ static int osd_xres; | |||
65 | module_param(ivtvfb_card_id, int, 0444); | 64 | module_param(ivtvfb_card_id, int, 0444); |
66 | module_param_named(debug,ivtvfb_debug, int, 0644); | 65 | module_param_named(debug,ivtvfb_debug, int, 0644); |
67 | module_param(osd_laced, bool, 0444); | 66 | module_param(osd_laced, bool, 0444); |
68 | module_param(osd_compat, bool, 0444); | ||
69 | module_param(osd_depth, int, 0444); | 67 | module_param(osd_depth, int, 0444); |
70 | module_param(osd_upper, int, 0444); | 68 | module_param(osd_upper, int, 0444); |
71 | module_param(osd_left, int, 0444); | 69 | module_param(osd_left, int, 0444); |
@@ -80,12 +78,6 @@ MODULE_PARM_DESC(debug, | |||
80 | "Debug level (bitmask). Default: errors only\n" | 78 | "Debug level (bitmask). Default: errors only\n" |
81 | "\t\t\t(debug = 3 gives full debugging)"); | 79 | "\t\t\t(debug = 3 gives full debugging)"); |
82 | 80 | ||
83 | MODULE_PARM_DESC(osd_compat, | ||
84 | "Compatibility mode - Display size is locked (use for old X drivers)\n" | ||
85 | "\t\t\t0=off\n" | ||
86 | "\t\t\t1=on\n" | ||
87 | "\t\t\tdefault off"); | ||
88 | |||
89 | /* Why upper, left, xres, yres, depth, laced ? To match terminology used | 81 | /* Why upper, left, xres, yres, depth, laced ? To match terminology used |
90 | by fbset. | 82 | by fbset. |
91 | Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */ | 83 | Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */ |
@@ -166,9 +158,6 @@ struct osd_info { | |||
166 | unsigned long fb_end_aligned_physaddr; | 158 | unsigned long fb_end_aligned_physaddr; |
167 | #endif | 159 | #endif |
168 | 160 | ||
169 | /* Current osd mode */ | ||
170 | int osd_mode; | ||
171 | |||
172 | /* Store the buffer offset */ | 161 | /* Store the buffer offset */ |
173 | int set_osd_coords_x; | 162 | int set_osd_coords_x; |
174 | int set_osd_coords_y; | 163 | int set_osd_coords_y; |
@@ -470,13 +459,11 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | |||
470 | IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); | 459 | IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); |
471 | } | 460 | } |
472 | 461 | ||
473 | /* Change osd mode if needed. | 462 | /* Set video mode. Although rare, the display can become scrambled even |
474 | Although rare, things can go wrong. The extra mode | 463 | if we don't change mode. Always 'bounce' to osd_mode via mode 0 */ |
475 | change seems to help... */ | 464 | if (osd_mode != -1) { |
476 | if (osd_mode != -1 && osd_mode != oi->osd_mode) { | ||
477 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | 465 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); |
478 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode); | 466 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode); |
479 | oi->osd_mode = osd_mode; | ||
480 | } | 467 | } |
481 | 468 | ||
482 | oi->bits_per_pixel = var->bits_per_pixel; | 469 | oi->bits_per_pixel = var->bits_per_pixel; |
@@ -579,14 +566,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) | |||
579 | osd_height_limit = 480; | 566 | osd_height_limit = 480; |
580 | } | 567 | } |
581 | 568 | ||
582 | /* Check the bits per pixel */ | ||
583 | if (osd_compat) { | ||
584 | if (var->bits_per_pixel != 32) { | ||
585 | IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { | 569 | if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { |
591 | var->transp.offset = 24; | 570 | var->transp.offset = 24; |
592 | var->transp.length = 8; | 571 | var->transp.length = 8; |
@@ -638,32 +617,20 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) | |||
638 | } | 617 | } |
639 | 618 | ||
640 | /* Check the resolution */ | 619 | /* Check the resolution */ |
641 | if (osd_compat) { | 620 | if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) { |
642 | if (var->xres != oi->ivtvfb_defined.xres || | 621 | IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n", |
643 | var->yres != oi->ivtvfb_defined.yres || | 622 | var->xres, var->yres); |
644 | var->xres_virtual != oi->ivtvfb_defined.xres_virtual || | 623 | return -EINVAL; |
645 | var->yres_virtual != oi->ivtvfb_defined.yres_virtual) { | ||
646 | IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n", | ||
647 | var->xres, var->yres, var->xres_virtual, var->yres_virtual); | ||
648 | return -EINVAL; | ||
649 | } | ||
650 | } | 624 | } |
651 | else { | ||
652 | if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) { | ||
653 | IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n", | ||
654 | var->xres, var->yres); | ||
655 | return -EINVAL; | ||
656 | } | ||
657 | 625 | ||
658 | /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */ | 626 | /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */ |
659 | if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || | 627 | if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || |
660 | var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || | 628 | var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || |
661 | var->xres_virtual < var->xres || | 629 | var->xres_virtual < var->xres || |
662 | var->yres_virtual < var->yres) { | 630 | var->yres_virtual < var->yres) { |
663 | IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n", | 631 | IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n", |
664 | var->xres_virtual, var->yres_virtual); | 632 | var->xres_virtual, var->yres_virtual); |
665 | return -EINVAL; | 633 | return -EINVAL; |
666 | } | ||
667 | } | 634 | } |
668 | 635 | ||
669 | /* Some extra checks if in 8 bit mode */ | 636 | /* Some extra checks if in 8 bit mode */ |
@@ -877,17 +844,15 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) | |||
877 | 844 | ||
878 | /* Color mode */ | 845 | /* Color mode */ |
879 | 846 | ||
880 | if (osd_compat) osd_depth = 32; | 847 | if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) |
881 | if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8; | 848 | osd_depth = 8; |
882 | oi->bits_per_pixel = osd_depth; | 849 | oi->bits_per_pixel = osd_depth; |
883 | oi->bytes_per_pixel = oi->bits_per_pixel / 8; | 850 | oi->bytes_per_pixel = oi->bits_per_pixel / 8; |
884 | 851 | ||
885 | /* Invalidate current osd mode to force a mode switch later */ | ||
886 | oi->osd_mode = -1; | ||
887 | |||
888 | /* Horizontal size & position */ | 852 | /* Horizontal size & position */ |
889 | 853 | ||
890 | if (osd_xres > 720) osd_xres = 720; | 854 | if (osd_xres > 720) |
855 | osd_xres = 720; | ||
891 | 856 | ||
892 | /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */ | 857 | /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */ |
893 | if (osd_depth == 8) | 858 | if (osd_depth == 8) |
@@ -895,10 +860,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) | |||
895 | else if (osd_depth == 16) | 860 | else if (osd_depth == 16) |
896 | osd_xres &= ~1; | 861 | osd_xres &= ~1; |
897 | 862 | ||
898 | if (osd_xres) | 863 | start_window.width = osd_xres ? osd_xres : 640; |
899 | start_window.width = osd_xres; | ||
900 | else | ||
901 | start_window.width = osd_compat ? 720: 640; | ||
902 | 864 | ||
903 | /* Check horizontal start (osd_left). */ | 865 | /* Check horizontal start (osd_left). */ |
904 | if (osd_left && osd_left + start_window.width > 721) { | 866 | if (osd_left && osd_left + start_window.width > 721) { |
@@ -921,10 +883,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) | |||
921 | if (osd_yres > max_height) | 883 | if (osd_yres > max_height) |
922 | osd_yres = max_height; | 884 | osd_yres = max_height; |
923 | 885 | ||
924 | if (osd_yres) | 886 | start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400; |
925 | start_window.height = osd_yres; | ||
926 | else | ||
927 | start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400); | ||
928 | 887 | ||
929 | /* Check vertical start (osd_upper). */ | 888 | /* Check vertical start (osd_upper). */ |
930 | if (osd_upper + start_window.height > max_height + 1) { | 889 | if (osd_upper + start_window.height > max_height + 1) { |
@@ -1127,10 +1086,6 @@ static int ivtvfb_init_card(struct ivtv *itv) | |||
1127 | /* Enable the osd */ | 1086 | /* Enable the osd */ |
1128 | ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); | 1087 | ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); |
1129 | 1088 | ||
1130 | /* Note if we're running in compatibility mode */ | ||
1131 | if (osd_compat) | ||
1132 | IVTVFB_INFO("Running in compatibility mode. Display resize & mode change disabled\n"); | ||
1133 | |||
1134 | /* Allocate DMA */ | 1089 | /* Allocate DMA */ |
1135 | ivtv_udma_alloc(itv); | 1090 | ivtv_udma_alloc(itv); |
1136 | return 0; | 1091 | return 0; |
@@ -1177,9 +1132,12 @@ static void ivtvfb_cleanup(void) | |||
1177 | for (i = 0; i < ivtv_cards_active; i++) { | 1132 | for (i = 0; i < ivtv_cards_active; i++) { |
1178 | itv = ivtv_cards[i]; | 1133 | itv = ivtv_cards[i]; |
1179 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) { | 1134 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) { |
1135 | if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { | ||
1136 | IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i); | ||
1137 | return; | ||
1138 | } | ||
1180 | IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i); | 1139 | IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i); |
1181 | ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); | 1140 | ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); |
1182 | unregister_framebuffer(&itv->osd_info->ivtvfb_info); | ||
1183 | ivtvfb_release_buffers(itv); | 1141 | ivtvfb_release_buffers(itv); |
1184 | itv->osd_video_pbase = 0; | 1142 | itv->osd_video_pbase = 0; |
1185 | } | 1143 | } |