summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-firmware.c11
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-driver.c5
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-driver.h2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-firmware.c8
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-ioctl.c36
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-irq.c25
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-yuv.c32
-rw-r--r--linux/drivers/media/video/tveeprom.c134
8 files changed, 64 insertions, 189 deletions
diff --git a/linux/drivers/media/video/cx25840/cx25840-firmware.c b/linux/drivers/media/video/cx25840/cx25840-firmware.c
index 56f992087..d283ef2d1 100644
--- a/linux/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/linux/drivers/media/video/cx25840/cx25840-firmware.c
@@ -88,11 +88,9 @@ static int check_fw_load(struct i2c_client *client, int size)
return 0;
}
-static int fw_write(struct i2c_client *client, u8 * data, int size)
+static int fw_write(struct i2c_client *client, u8 *data, int size)
{
- int sent;
-
- if ((sent = i2c_master_send(client, data, size)) < size) {
+ if (i2c_master_send(client, data, size) < size) {
v4l_err(client, "firmware load i2c failure\n");
return -ENOSYS;
}
@@ -105,7 +103,7 @@ int cx25840_loadfw(struct i2c_client *client)
struct cx25840_state *state = i2c_get_clientdata(client);
const struct firmware *fw = NULL;
u8 buffer[4], *ptr;
- int size, send, retval;
+ int size, retval;
if (state->is_cx23885)
firmware = FWFILE_CX23885;
@@ -133,8 +131,7 @@ int cx25840_loadfw(struct i2c_client *client)
while (size > 0) {
ptr[0] = 0x08;
ptr[1] = 0x02;
- send = size > (FWSEND - 2) ? FWSEND : size + 2;
- retval = fw_write(client, ptr, send);
+ retval = fw_write(client, ptr, min(FWSEND, size + 2));
if (retval < 0) {
release_firmware(fw);
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c
index b6c145752..56ae17af3 100644
--- a/linux/drivers/media/video/ivtv/ivtv-driver.c
+++ b/linux/drivers/media/video/ivtv/ivtv-driver.c
@@ -54,7 +54,6 @@
#include "ivtv-vbi.h"
#include "ivtv-routing.h"
#include "ivtv-gpio.h"
-#include "ivtv-yuv.h"
#include <media/tveeprom.h>
#include <media/saa7115.h>
@@ -713,6 +712,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
itv->yuv_info.lace_mode = ivtv_yuv_mode;
itv->yuv_info.lace_threshold = ivtv_yuv_threshold;
itv->yuv_info.max_frames_buffered = 3;
+ itv->yuv_info.track_osd = 1;
return 0;
}
@@ -1057,9 +1057,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
goto free_io;
}
- /* Check yuv output filter table */
- if (itv->has_cx23415) ivtv_yuv_filter_check(itv);
-
ivtv_gpio_init(itv);
/* active i2c */
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h
index ab8ba6fb4..ba8763f62 100644
--- a/linux/drivers/media/video/ivtv/ivtv-driver.h
+++ b/linux/drivers/media/video/ivtv/ivtv-driver.h
@@ -463,6 +463,8 @@ struct yuv_playback_info
int v_filter_2;
int h_filter;
+ u8 track_osd; /* Should yuv output track the OSD size & position */
+
u32 osd_x_offset;
u32 osd_y_offset;
diff --git a/linux/drivers/media/video/ivtv/ivtv-firmware.c b/linux/drivers/media/video/ivtv/ivtv-firmware.c
index 425eb1063..6dba55b7e 100644
--- a/linux/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/linux/drivers/media/video/ivtv/ivtv-firmware.c
@@ -22,6 +22,7 @@
#include "ivtv-driver.h"
#include "ivtv-mailbox.h"
#include "ivtv-firmware.h"
+#include "ivtv-yuv.h"
#include <linux/firmware.h>
#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
@@ -225,11 +226,14 @@ int ivtv_firmware_init(struct ivtv *itv)
return 0;
itv->dec_mbox.mbox = ivtv_search_mailbox(itv->dec_mem, IVTV_DECODER_SIZE);
- if (itv->dec_mbox.mbox == NULL)
+ if (itv->dec_mbox.mbox == NULL) {
IVTV_ERR("Decoder mailbox not found\n");
- else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) {
+ } else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) {
IVTV_ERR("Decoder firmware dead!\n");
itv->dec_mbox.mbox = NULL;
+ } else {
+ /* Firmware okay, so check yuv output filter table */
+ ivtv_yuv_filter_check(itv);
}
return itv->dec_mbox.mbox ? 0 : -ENODEV;
}
diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
index 87a83b8e3..873296394 100644
--- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -718,6 +718,7 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
{
struct ivtv_open_id *id = NULL;
+ struct yuv_playback_info *yi = &itv->yuv_info;
u32 data[CX2341X_MBOX_MAX_DATA];
int streamtype = 0;
@@ -833,8 +834,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
case VIDIOC_CROPCAP: {
struct v4l2_cropcap *cropcap = arg;
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
cropcap->bounds.top = cropcap->bounds.left = 0;
cropcap->bounds.width = 720;
@@ -843,8 +843,14 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
} else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- cropcap->bounds.width = itv->yuv_info.osd_full_w;
- cropcap->bounds.height = itv->yuv_info.osd_full_h;
+ if (yi->track_osd) {
+ cropcap->bounds.width = yi->osd_full_w;
+ cropcap->bounds.height = yi->osd_full_h;
+ } else {
+ cropcap->bounds.width = 720;
+ cropcap->bounds.height =
+ itv->is_out_50hz ? 576 : 480;
+ }
cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
} else {
@@ -862,7 +868,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- itv->yuv_info.main_rect = crop->c;
+ yi->main_rect = crop->c;
return 0;
} else {
if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
@@ -873,9 +879,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
}
return -EINVAL;
}
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
+ return -EINVAL;
}
case VIDIOC_G_CROP: {
@@ -884,14 +888,12 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
- crop->c = itv->yuv_info.main_rect;
+ crop->c = yi->main_rect;
else
crop->c = itv->main_rect;
return 0;
}
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
+ return -EINVAL;
}
case VIDIOC_ENUM_FMT: {
@@ -1076,11 +1078,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
itv->main_rect.height = itv->params.height;
ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
720, itv->main_rect.height, 0, 0);
- itv->yuv_info.main_rect = itv->main_rect;
+ yi->main_rect = itv->main_rect;
if (!itv->osd_info) {
- itv->yuv_info.osd_full_w = 720;
- itv->yuv_info.osd_full_h =
- itv->is_out_50hz ? 576 : 480;
+ yi->osd_full_w = 720;
+ yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
}
}
break;
@@ -1284,6 +1285,8 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
else
fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
}
+ if (yi->track_osd)
+ fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
break;
}
@@ -1297,6 +1300,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
(fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
ivtv_set_osd_alpha(itv);
+ yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
break;
}
diff --git a/linux/drivers/media/video/ivtv/ivtv-irq.c b/linux/drivers/media/video/ivtv/ivtv-irq.c
index 46a5cbc62..0e417d860 100644
--- a/linux/drivers/media/video/ivtv/ivtv-irq.c
+++ b/linux/drivers/media/video/ivtv/ivtv-irq.c
@@ -390,6 +390,8 @@ static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s)
ivtv_stream_sync_for_device(s);
write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR);
write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
+ itv->dma_timer.expires = jiffies + msecs_to_jiffies(100);
+ add_timer(&itv->dma_timer);
}
static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
@@ -404,6 +406,8 @@ static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
ivtv_stream_sync_for_device(s);
write_reg(s->sg_handle, IVTV_REG_DECDMAADDR);
write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
+ itv->dma_timer.expires = jiffies + msecs_to_jiffies(100);
+ add_timer(&itv->dma_timer);
}
/* start the encoder DMA */
@@ -465,8 +469,6 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
ivtv_dma_enc_start_xfer(s);
set_bit(IVTV_F_I_DMA, &itv->i_flags);
itv->cur_dma_stream = s->type;
- itv->dma_timer.expires = jiffies + msecs_to_jiffies(100);
- add_timer(&itv->dma_timer);
}
}
@@ -487,8 +489,6 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s)
ivtv_dma_dec_start_xfer(s);
set_bit(IVTV_F_I_DMA, &itv->i_flags);
itv->cur_dma_stream = s->type;
- itv->dma_timer.expires = jiffies + msecs_to_jiffies(100);
- add_timer(&itv->dma_timer);
}
static void ivtv_irq_dma_read(struct ivtv *itv)
@@ -498,10 +498,11 @@ static void ivtv_irq_dma_read(struct ivtv *itv)
int hw_stream_type = 0;
IVTV_DEBUG_HI_IRQ("DEC DMA READ\n");
- if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0) {
- del_timer(&itv->dma_timer);
+
+ del_timer(&itv->dma_timer);
+
+ if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0)
return;
- }
if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
s = &itv->streams[itv->cur_dma_stream];
@@ -549,7 +550,6 @@ static void ivtv_irq_dma_read(struct ivtv *itv)
}
wake_up(&s->waitq);
}
- del_timer(&itv->dma_timer);
clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
clear_bit(IVTV_F_I_DMA, &itv->i_flags);
itv->cur_dma_stream = -1;
@@ -563,10 +563,12 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
- if (itv->cur_dma_stream < 0) {
- del_timer(&itv->dma_timer);
+
+ del_timer(&itv->dma_timer);
+
+ if (itv->cur_dma_stream < 0)
return;
- }
+
s = &itv->streams[itv->cur_dma_stream];
ivtv_stream_sync_for_cpu(s);
@@ -591,7 +593,6 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
ivtv_dma_enc_start_xfer(s);
return;
}
- del_timer(&itv->dma_timer);
clear_bit(IVTV_F_I_DMA, &itv->i_flags);
itv->cur_dma_stream = -1;
dma_post(s);
diff --git a/linux/drivers/media/video/ivtv/ivtv-yuv.c b/linux/drivers/media/video/ivtv/ivtv-yuv.c
index 8fdd67cef..393d917cd 100644
--- a/linux/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/linux/drivers/media/video/ivtv/ivtv-yuv.c
@@ -718,9 +718,11 @@ static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
f->src_w -= (osd_scale * osd_crop) >> 16;
}
- /* The OSD can be moved. Track to it */
- f->dst_x += itv->yuv_info.osd_x_offset;
- f->dst_y += itv->yuv_info.osd_y_offset;
+ if (itv->yuv_info.track_osd) {
+ /* The OSD can be moved. Track to it */
+ f->dst_x += itv->yuv_info.osd_x_offset;
+ f->dst_y += itv->yuv_info.osd_y_offset;
+ }
/* Width & height for both src & dst must be even.
Same for coordinates. */
@@ -792,11 +794,19 @@ void ivtv_yuv_work_handler(struct ivtv *itv)
IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame);
f = yi->new_frame_info[frame];
- /* Update the osd pan info */
- f.pan_x = yi->osd_x_pan;
- f.pan_y = yi->osd_y_pan;
- f.vis_w = yi->osd_vis_w;
- f.vis_h = yi->osd_vis_h;
+ if (yi->track_osd) {
+ /* Snapshot the osd pan info */
+ f.pan_x = yi->osd_x_pan;
+ f.pan_y = yi->osd_y_pan;
+ f.vis_w = yi->osd_vis_w;
+ f.vis_h = yi->osd_vis_h;
+ } else {
+ /* Not tracking the osd, so assume full screen */
+ f.pan_x = 0;
+ f.pan_y = 0;
+ f.vis_w = 720;
+ f.vis_h = yi->decode_height;
+ }
/* Calculate the display window coordinates. Exit if nothing left */
if (!(yuv_update = ivtv_yuv_window_setup(itv, &f)))
@@ -965,12 +975,6 @@ static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
/* Are we going to offset the Y plane */
nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0;
- /* Snapshot the osd pan info */
- nf->pan_x = yi->osd_x_pan;
- nf->pan_y = yi->osd_y_pan;
- nf->vis_w = yi->osd_vis_w;
- nf->vis_h = yi->osd_vis_h;
-
nf->update = 0;
nf->interlaced_y = 0;
nf->interlaced_uv = 0;
diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c
index 9b95d2f28..81a85035f 100644
--- a/linux/drivers/media/video/tveeprom.c
+++ b/linux/drivers/media/video/tveeprom.c
@@ -749,140 +749,6 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
}
EXPORT_SYMBOL(tveeprom_read);
-/* ----------------------------------------------------------------------- */
-/* needed for ivtv.sf.net at the moment. Should go away in the long */
-/* run, just call the exported tveeprom_* directly, there is no point in */
-/* using the indirect way via i2c_driver->command() */
-
-static unsigned short normal_i2c[] = {
- 0xa0 >> 1,
- I2C_CLIENT_END,
-};
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
-#endif
-
-I2C_CLIENT_INSMOD;
-
-static struct i2c_driver i2c_driver_tveeprom;
-
-static int
-tveeprom_command(struct i2c_client *client,
- unsigned int cmd,
- void *arg)
-{
- struct tveeprom eeprom;
- u32 *eeprom_props = arg;
- u8 *buf;
-
- switch (cmd) {
- case 0:
- buf = kzalloc(256, GFP_KERNEL);
- tveeprom_read(client, buf, 256);
- tveeprom_hauppauge_analog(client, &eeprom, buf);
- kfree(buf);
- eeprom_props[0] = eeprom.tuner_type;
- eeprom_props[1] = eeprom.tuner_formats;
- eeprom_props[2] = eeprom.model;
- eeprom_props[3] = eeprom.revision;
- eeprom_props[4] = eeprom.has_radio;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
-static int
-tveeprom_detect_client(struct i2c_adapter *adapter,
- int address,
- int kind)
-#else
-static int
-tveeprom_detect_client(struct i2c_adapter *adapter,
- int address,
- unsigned short flags,
- int kind)
-#endif
-{
- struct i2c_client *client;
-
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (NULL == client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_tveeprom;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15)
- client->flags = I2C_CLIENT_ALLOW_USE;
-#endif
- snprintf(client->name, sizeof(client->name), "tveeprom");
- i2c_attach_client(client);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
- MOD_INC_USE_COUNT;
-#endif
- return 0;
-}
-
-static int
-tveeprom_attach_adapter(struct i2c_adapter *adapter)
-{
-#ifdef I2C_CLASS_TV_ANALOG
- if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
- if (adapter->id == I2C_HW_B_BT848)
-#endif
- return i2c_probe(adapter, &addr_data, tveeprom_detect_client);
- return 0;
-}
-
-static int
-tveeprom_detach_client(struct i2c_client *client)
-{
- int err;
-
- err = i2c_detach_client(client);
- if (err < 0)
- return err;
- kfree(client);
- return 0;
-}
-
-static struct i2c_driver i2c_driver_tveeprom = {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15)
- .owner = THIS_MODULE,
-#endif
-#endif
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15)
- .name = "tveeprom",
- .flags = I2C_DF_NOTIFY,
-#else
- .driver = {
- .name = "tveeprom",
- },
-#endif
- .id = I2C_DRIVERID_TVEEPROM,
- .attach_adapter = tveeprom_attach_adapter,
- .detach_client = tveeprom_detach_client,
- .command = tveeprom_command,
-};
-
-static int __init tveeprom_init(void)
-{
- return i2c_add_driver(&i2c_driver_tveeprom);
-}
-
-static void __exit tveeprom_exit(void)
-{
- i2c_del_driver(&i2c_driver_tveeprom);
-}
-
-module_init(tveeprom_init);
-module_exit(tveeprom_exit);
-
/*
* Local variables:
* c-basic-offset: 8