summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/ivtv/ivtv-ioctl.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-08-20 11:10:31 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-08-20 11:10:31 -0300
commit638acf07e1921e20c61cd6fa47effac3dd17960b (patch)
tree25d9ef804621434a97f1c710f8013b64713712f5 /linux/drivers/media/video/ivtv/ivtv-ioctl.c
parent231c6131d555f40b849f0e7332b9f90a2568145a (diff)
parente9f3de679c696aca2da479114ffac7389e0196e1 (diff)
downloadmediapointer-dvb-s2-638acf07e1921e20c61cd6fa47effac3dd17960b.tar.gz
mediapointer-dvb-s2-638acf07e1921e20c61cd6fa47effac3dd17960b.tar.bz2
merge: http://linuxtv.org/hg/~tap/v4l-dvb
From: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media/video/ivtv/ivtv-ioctl.c')
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-ioctl.c95
1 files changed, 80 insertions, 15 deletions
diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
index 7d1a5e434..1e8d288b9 100644
--- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -912,6 +912,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
IVTV_DEBUG_INFO("Input unchanged\n");
break;
}
+ if (atomic_read(&itv->capturing) > 0) {
+ return -EBUSY;
+ }
IVTV_DEBUG_INFO("Changing input from %d to %d\n",
itv->active_input, inp);
@@ -1140,12 +1143,14 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
memset(&enc->raw, 0, sizeof(enc->raw));
switch (enc->cmd) {
case V4L2_ENC_CMD_START:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
enc->flags = 0;
if (try)
return 0;
return ivtv_start_capture(id);
case V4L2_ENC_CMD_STOP:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
if (try)
return 0;
@@ -1153,6 +1158,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return 0;
case V4L2_ENC_CMD_PAUSE:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
enc->flags = 0;
if (try)
return 0;
@@ -1165,6 +1171,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
break;
case V4L2_ENC_CMD_RESUME:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
enc->flags = 0;
if (try)
return 0;
@@ -1176,6 +1183,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
ivtv_unmute(itv);
break;
default:
+ IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
return -EINVAL;
}
break;
@@ -1214,9 +1222,19 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
break;
}
+ case VIDIOC_OVERLAY: {
+ int *on = arg;
+
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+ return -EINVAL;
+ ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0);
+ break;
+ }
+
case VIDIOC_LOG_STATUS:
{
int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
+ u32 data[CX2341X_MBOX_MAX_DATA];
struct v4l2_input vidin;
struct v4l2_audio audin;
int i;
@@ -1231,8 +1249,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
ivtv_get_input(itv, itv->active_input, &vidin);
ivtv_get_audio_input(itv, itv->audio_input, &audin);
- IVTV_INFO("Video Input: %s\n", vidin.name);
- IVTV_INFO("Audio Input: %s\n", audin.name);
+ IVTV_INFO("Video Input: %s\n", vidin.name);
+ IVTV_INFO("Audio Input: %s%s\n", audin.name,
+ (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
if (has_output) {
struct v4l2_output vidout;
struct v4l2_audioout audout;
@@ -1244,19 +1263,49 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
"YUV Frames",
"Passthrough",
};
+ static const char * const audio_modes[] = {
+ "Stereo",
+ "Left",
+ "Right",
+ "Mono",
+ "Swapped"
+ };
+ static const char * const alpha_mode[] = {
+ "None",
+ "Global",
+ "Local",
+ "Global and Local"
+ };
+ static const char * const pixel_format[] = {
+ "Indexed",
+ "RGB 5:6:5",
+ "ARGB 1:5:5:5",
+ "ARGB 1:4:4:4",
+ "ARGB 8:8:8:8",
+ "5",
+ "6",
+ "7",
+ };
ivtv_get_output(itv, itv->active_output, &vidout);
ivtv_get_audio_output(itv, 0, &audout);
IVTV_INFO("Video Output: %s\n", vidout.name);
- IVTV_INFO("Audio Output: %s\n", audout.name);
+ IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
+ audio_modes[itv->audio_stereo_mode],
+ audio_modes[itv->audio_bilingual_mode]);
if (mode < 0 || mode > OUT_PASSTHROUGH)
mode = OUT_NONE;
- IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
+ IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
+ ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
+ IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
+ data[0] & 1 ? "On" : "Off",
+ alpha_mode[(data[0] >> 1) & 0x3],
+ pixel_format[(data[0] >> 3) & 0x7]);
}
- IVTV_INFO("Tuner: %s\n",
+ IVTV_INFO("Tuner: %s\n",
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
cx2341x_log_status(&itv->params, itv->name);
- IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
+ IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
for (i = 0; i < IVTV_MAX_STREAMS; i++) {
struct ivtv_stream *s = &itv->streams[i];
@@ -1266,7 +1315,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
(s->buffers - s->q_free.buffers) * 100 / s->buffers,
(s->buffers * s->buf_size) / 1024, s->buffers);
}
- IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
+ IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
break;
}
@@ -1410,9 +1459,9 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
int try = (cmd == VIDEO_TRY_COMMAND);
if (try)
- IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND\n");
+ IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
else
- IVTV_DEBUG_IOCTL("VIDEO_COMMAND\n");
+ IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
return ivtv_video_command(itv, id, vc, try);
}
@@ -1443,11 +1492,15 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
return 0;
if (nonblocking)
return -EAGAIN;
- /* wait for event */
+ /* Wait for event. Note that serialize_lock is locked,
+ so to allow other processes to access the driver while
+ we are waiting unlock first and later lock again. */
+ mutex_unlock(&itv->serialize_lock);
prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
schedule();
finish_wait(&itv->event_waitq, &wait);
+ mutex_lock(&itv->serialize_lock);
if (signal_pending(current)) {
/* return if a signal was received */
IVTV_DEBUG_INFO("User stopped wait for event\n");
@@ -1484,6 +1537,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
case VIDIOC_S_AUDOUT:
case VIDIOC_S_EXT_CTRLS:
case VIDIOC_S_FBUF:
+ case VIDIOC_OVERLAY:
ret = v4l2_prio_check(&itv->prio, &id->prio);
if (ret)
return ret;
@@ -1537,6 +1591,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
case VIDIOC_TRY_ENCODER_CMD:
case VIDIOC_G_FBUF:
case VIDIOC_S_FBUF:
+ case VIDIOC_OVERLAY:
if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
v4l_printk_ioctl(cmd);
@@ -1577,12 +1632,9 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
return 0;
}
-int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
+static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
- struct ivtv *itv = id->itv;
-
/* Filter dvb ioctls that cannot be handled by video_usercopy */
switch (cmd) {
case VIDEO_SELECT_SOURCE:
@@ -1617,3 +1669,16 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
}
return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
}
+
+int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
+ struct ivtv *itv = id->itv;
+ int res;
+
+ mutex_lock(&itv->serialize_lock);
+ res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg);
+ mutex_unlock(&itv->serialize_lock);
+ return res;
+}