aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c89
-rw-r--r--drivers/media/video/cx88/cx88.h1
2 files changed, 70 insertions, 20 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index f802b565356..7ce37f46b75 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -536,6 +536,9 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
dprintk(1,"Initialize codec\n");
retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
if (retval < 0) {
+
+ dev->mpeg_active = 0;
+
/* ping was not successful, reset and upload firmware */
cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
msleep(1);
@@ -572,38 +575,80 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
blackbird_codec_settings(dev);
msleep(1);
- /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */
blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
BLACKBIRD_FIELD1_SAA7115,
BLACKBIRD_FIELD2_SAA7115
);
- /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */
blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- /* initialize the video input */
- blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
-
msleep(1);
+ return 0;
+}
+
+static int blackbird_start_codec(struct file *file, void *priv)
+{
+ struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
+ struct cx88_core *core = dev->core;
+ /* start capturing to the host interface */
+ u32 reg;
+
+ int i;
+ int lastchange = -1;
+ int lastval = 0;
+
+ for (i=0; (i < 10) && (i < (lastchange + 4)); i++)
+ {
+ reg = cx_read(AUD_STATUS);
+
+ dprintk(1,"AUD_STATUS:%dL: 0x%x\n", i, reg);
+ if ((reg & 0x0F) != lastval)
+ {
+ lastval = reg & 0x0F;
+ lastchange = i;
+ }
+ msleep(100);
+ }
+
+ /* unmute audio source */
+ cx_clear(AUD_VOL_CTL, (1 << 6));
blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
msleep(1);
blackbird_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
msleep(1);
+ blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0);
+
+ /* initialize the video input */
+ blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
+
/* start capturing to the host interface */
- /* blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, 0, 0x13); */
blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
BLACKBIRD_MPEG_CAPTURE,
BLACKBIRD_RAW_BITS_NONE
);
msleep(10);
- blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0);
+ dev->mpeg_active = 1;
+ return 0;
+}
+
+static int blackbird_stop_codec(struct cx8802_dev *dev)
+{
+ struct cx88_core *core = dev->core;
+
+ blackbird_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
+ BLACKBIRD_END_NOW,
+ BLACKBIRD_MPEG_CAPTURE,
+ BLACKBIRD_RAW_BITS_NONE
+ );
+ /* mute audio source */
+ cx_set(AUD_VOL_CTL, (1 << 6));
+
+ dev->mpeg_active = 0;
return 0;
}
@@ -833,6 +878,10 @@ static int vidioc_s_ext_ctrls (struct file *file, void *priv,
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
+
+ if (dev->mpeg_active)
+ blackbird_stop_codec(dev);
+
p = dev->params;
err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
if (!err) {
@@ -864,10 +913,9 @@ static int vidioc_s_frequency (struct file *file, void *priv,
struct cx8802_dev *dev = fh->dev;
struct cx88_core *core = dev->core;
- blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
- BLACKBIRD_END_NOW,
- BLACKBIRD_MPEG_CAPTURE,
- BLACKBIRD_RAW_BITS_NONE);
+ if (dev->mpeg_active)
+ blackbird_stop_codec(dev);
+
cx88_set_freq (core,f);
blackbird_initialize_codec(dev);
cx88_set_scale(dev->core, dev->width, dev->height,
@@ -1073,15 +1121,11 @@ static int mpeg_open(struct inode *inode, struct file *file)
static int mpeg_release(struct inode *inode, struct file *file)
{
struct cx8802_fh *fh = file->private_data;
- struct cx8802_dev *dev = NULL;
+ struct cx8802_dev *dev = fh->dev;
struct cx8802_driver *drv = NULL;
- /* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */
- blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
- BLACKBIRD_END_NOW,
- BLACKBIRD_MPEG_CAPTURE,
- BLACKBIRD_RAW_BITS_NONE
- );
+ if (dev->mpeg_active)
+ blackbird_stop_codec(dev);
cx8802_cancel_buffers(fh->dev);
/* stop mpeg capture */
@@ -1107,6 +1151,10 @@ static ssize_t
mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
struct cx8802_fh *fh = file->private_data;
+ struct cx8802_dev *dev = fh->dev;
+
+ if (!dev->mpeg_active)
+ blackbird_start_codec(file, fh);
return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
file->f_flags & O_NONBLOCK);
@@ -1282,6 +1330,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
core->name);
host_setup(dev->core);
+ blackbird_initialize_codec(dev);
blackbird_register_video(dev);
/* initial device configuration: needed ? */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index bb1036a5c6c..f10d432eb3e 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -461,6 +461,7 @@ struct cx8802_dev {
u32 mailbox;
int width;
int height;
+ unsigned char mpeg_active; /* nonzero if mpeg encoder is active */
/* mpeg params */
struct cx2341x_mpeg_params params;