[media] ivtv: implement new decoder controls
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
77bd4c0ff1
commit
debf80014f
@@ -21,6 +21,7 @@
|
|||||||
#include "ivtv-driver.h"
|
#include "ivtv-driver.h"
|
||||||
#include "ivtv-ioctl.h"
|
#include "ivtv-ioctl.h"
|
||||||
#include "ivtv-controls.h"
|
#include "ivtv-controls.h"
|
||||||
|
#include "ivtv-mailbox.h"
|
||||||
|
|
||||||
static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
|
static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
|
||||||
{
|
{
|
||||||
@@ -99,3 +100,64 @@ struct cx2341x_handler_ops ivtv_cxhdl_ops = {
|
|||||||
.s_video_encoding = ivtv_s_video_encoding,
|
.s_video_encoding = ivtv_s_video_encoding,
|
||||||
.s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt,
|
.s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame)
|
||||||
|
{
|
||||||
|
u32 data[CX2341X_MBOX_MAX_DATA];
|
||||||
|
|
||||||
|
if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
|
||||||
|
*pts = (s64)((u64)itv->last_dec_timing[2] << 32) |
|
||||||
|
(u64)itv->last_dec_timing[1];
|
||||||
|
*frame = itv->last_dec_timing[0];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*pts = 0;
|
||||||
|
*frame = 0;
|
||||||
|
if (atomic_read(&itv->decoding)) {
|
||||||
|
if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
|
||||||
|
IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
|
||||||
|
set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
|
||||||
|
*pts = (s64)((u64) data[2] << 32) | (u64) data[1];
|
||||||
|
*frame = data[0];
|
||||||
|
/*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ivtv_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||||
|
{
|
||||||
|
struct ivtv *itv = container_of(ctrl->handler, struct ivtv, hdl_out);
|
||||||
|
|
||||||
|
switch (ctrl->id) {
|
||||||
|
/* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME
|
||||||
|
control cluster */
|
||||||
|
case V4L2_CID_MPEG_VIDEO_DEC_PTS:
|
||||||
|
return ivtv_g_pts_frame(itv, &itv->ctrl_pts->val64,
|
||||||
|
&itv->ctrl_frame->val64);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ivtv_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||||
|
{
|
||||||
|
struct ivtv *itv = container_of(ctrl->handler, struct ivtv, hdl_out);
|
||||||
|
|
||||||
|
switch (ctrl->id) {
|
||||||
|
/* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK
|
||||||
|
control cluster */
|
||||||
|
case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
|
||||||
|
itv->audio_stereo_mode = itv->ctrl_audio_playback->val - 1;
|
||||||
|
itv->audio_bilingual_mode = itv->ctrl_audio_multilingual_playback->val - 1;
|
||||||
|
ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct v4l2_ctrl_ops ivtv_hdl_out_ops = {
|
||||||
|
.s_ctrl = ivtv_s_ctrl,
|
||||||
|
.g_volatile_ctrl = ivtv_g_volatile_ctrl,
|
||||||
|
};
|
||||||
|
@@ -22,5 +22,7 @@
|
|||||||
#define IVTV_CONTROLS_H
|
#define IVTV_CONTROLS_H
|
||||||
|
|
||||||
extern struct cx2341x_handler_ops ivtv_cxhdl_ops;
|
extern struct cx2341x_handler_ops ivtv_cxhdl_ops;
|
||||||
|
extern const struct v4l2_ctrl_ops ivtv_hdl_out_ops;
|
||||||
|
int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -744,8 +744,6 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
|
|||||||
|
|
||||||
itv->cur_dma_stream = -1;
|
itv->cur_dma_stream = -1;
|
||||||
itv->cur_pio_stream = -1;
|
itv->cur_pio_stream = -1;
|
||||||
itv->audio_stereo_mode = AUDIO_STEREO;
|
|
||||||
itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
|
|
||||||
|
|
||||||
/* Ctrls */
|
/* Ctrls */
|
||||||
itv->speed = 1000;
|
itv->speed = 1000;
|
||||||
@@ -1200,6 +1198,32 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
|
|||||||
itv->tuner_std = itv->std;
|
itv->tuner_std = itv->std;
|
||||||
|
|
||||||
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
|
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
|
||||||
|
v4l2_ctrl_handler_init(&itv->hdl_out, 50);
|
||||||
|
itv->ctrl_pts = v4l2_ctrl_new_std(&itv->hdl_out, &ivtv_hdl_out_ops,
|
||||||
|
V4L2_CID_MPEG_VIDEO_DEC_PTS, 0, 0, 1, 0);
|
||||||
|
itv->ctrl_frame = v4l2_ctrl_new_std(&itv->hdl_out, &ivtv_hdl_out_ops,
|
||||||
|
V4L2_CID_MPEG_VIDEO_DEC_FRAME, 0, 0x7fffffff, 1, 0);
|
||||||
|
/* Note: V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO is not supported,
|
||||||
|
mask that menu item. */
|
||||||
|
itv->ctrl_audio_playback =
|
||||||
|
v4l2_ctrl_new_std_menu(&itv->hdl_out, &ivtv_hdl_out_ops,
|
||||||
|
V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK,
|
||||||
|
V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
|
||||||
|
1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
|
||||||
|
V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO);
|
||||||
|
itv->ctrl_audio_multilingual_playback =
|
||||||
|
v4l2_ctrl_new_std_menu(&itv->hdl_out, &ivtv_hdl_out_ops,
|
||||||
|
V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK,
|
||||||
|
V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
|
||||||
|
1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
|
||||||
|
V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT);
|
||||||
|
v4l2_ctrl_add_handler(&itv->hdl_out, &itv->cxhdl.hdl);
|
||||||
|
if (itv->hdl_out.error) {
|
||||||
|
retval = itv->hdl_out.error;
|
||||||
|
goto free_i2c;
|
||||||
|
}
|
||||||
|
v4l2_ctrl_cluster(2, &itv->ctrl_pts);
|
||||||
|
v4l2_ctrl_cluster(2, &itv->ctrl_audio_playback);
|
||||||
ivtv_call_all(itv, video, s_std_output, itv->std);
|
ivtv_call_all(itv, video, s_std_output, itv->std);
|
||||||
/* Turn off the output signal. The mpeg decoder is not yet
|
/* Turn off the output signal. The mpeg decoder is not yet
|
||||||
active so without this you would get a green image until the
|
active so without this you would get a green image until the
|
||||||
@@ -1236,6 +1260,9 @@ free_streams:
|
|||||||
free_irq:
|
free_irq:
|
||||||
free_irq(itv->pdev->irq, (void *)itv);
|
free_irq(itv->pdev->irq, (void *)itv);
|
||||||
free_i2c:
|
free_i2c:
|
||||||
|
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
|
||||||
|
v4l2_ctrl_handler_free(&itv->hdl_out);
|
||||||
|
v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
|
||||||
exit_ivtv_i2c(itv);
|
exit_ivtv_i2c(itv);
|
||||||
free_io:
|
free_io:
|
||||||
ivtv_iounmap(itv);
|
ivtv_iounmap(itv);
|
||||||
@@ -1391,6 +1418,10 @@ static void ivtv_remove(struct pci_dev *pdev)
|
|||||||
ivtv_streams_cleanup(itv, 1);
|
ivtv_streams_cleanup(itv, 1);
|
||||||
ivtv_udma_free(itv);
|
ivtv_udma_free(itv);
|
||||||
|
|
||||||
|
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
|
||||||
|
v4l2_ctrl_handler_free(&itv->hdl_out);
|
||||||
|
v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
|
||||||
|
|
||||||
exit_ivtv_i2c(itv);
|
exit_ivtv_i2c(itv);
|
||||||
|
|
||||||
free_irq(itv->pdev->irq, (void *)itv);
|
free_irq(itv->pdev->irq, (void *)itv);
|
||||||
|
@@ -631,6 +631,17 @@ struct ivtv {
|
|||||||
|
|
||||||
struct v4l2_device v4l2_dev;
|
struct v4l2_device v4l2_dev;
|
||||||
struct cx2341x_handler cxhdl;
|
struct cx2341x_handler cxhdl;
|
||||||
|
struct {
|
||||||
|
/* PTS/Frame count control cluster */
|
||||||
|
struct v4l2_ctrl *ctrl_pts;
|
||||||
|
struct v4l2_ctrl *ctrl_frame;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
/* Audio Playback control cluster */
|
||||||
|
struct v4l2_ctrl *ctrl_audio_playback;
|
||||||
|
struct v4l2_ctrl *ctrl_audio_multilingual_playback;
|
||||||
|
};
|
||||||
|
struct v4l2_ctrl_handler hdl_out;
|
||||||
struct v4l2_ctrl_handler hdl_gpio;
|
struct v4l2_ctrl_handler hdl_gpio;
|
||||||
struct v4l2_subdev sd_gpio; /* GPIO sub-device */
|
struct v4l2_subdev sd_gpio; /* GPIO sub-device */
|
||||||
u16 instance;
|
u16 instance;
|
||||||
@@ -650,7 +661,6 @@ struct ivtv {
|
|||||||
u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */
|
u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */
|
||||||
u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */
|
u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */
|
||||||
|
|
||||||
|
|
||||||
/* Locking */
|
/* Locking */
|
||||||
spinlock_t lock; /* lock access to this struct */
|
spinlock_t lock; /* lock access to this struct */
|
||||||
struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
|
struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
|
||||||
|
@@ -1510,13 +1510,6 @@ static int ivtv_log_status(struct file *file, void *fh)
|
|||||||
"YUV Frames",
|
"YUV Frames",
|
||||||
"Passthrough",
|
"Passthrough",
|
||||||
};
|
};
|
||||||
static const char * const audio_modes[5] = {
|
|
||||||
"Stereo",
|
|
||||||
"Left",
|
|
||||||
"Right",
|
|
||||||
"Mono",
|
|
||||||
"Swapped"
|
|
||||||
};
|
|
||||||
static const char * const alpha_mode[4] = {
|
static const char * const alpha_mode[4] = {
|
||||||
"None",
|
"None",
|
||||||
"Global",
|
"Global",
|
||||||
@@ -1545,9 +1538,6 @@ static int ivtv_log_status(struct file *file, void *fh)
|
|||||||
ivtv_get_output(itv, itv->active_output, &vidout);
|
ivtv_get_output(itv, itv->active_output, &vidout);
|
||||||
ivtv_get_audio_output(itv, 0, &audout);
|
ivtv_get_audio_output(itv, 0, &audout);
|
||||||
IVTV_INFO("Video Output: %s\n", vidout.name);
|
IVTV_INFO("Video Output: %s\n", vidout.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)
|
if (mode < 0 || mode > OUT_PASSTHROUGH)
|
||||||
mode = OUT_NONE;
|
mode = OUT_NONE;
|
||||||
IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
|
IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
|
||||||
@@ -1560,7 +1550,10 @@ static int ivtv_log_status(struct file *file, void *fh)
|
|||||||
}
|
}
|
||||||
IVTV_INFO("Tuner: %s\n",
|
IVTV_INFO("Tuner: %s\n",
|
||||||
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
|
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
|
||||||
v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
|
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
|
||||||
|
v4l2_ctrl_handler_log_status(&itv->hdl_out, itv->v4l2_dev.name);
|
||||||
|
else
|
||||||
|
v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.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++) {
|
for (i = 0; i < IVTV_MAX_STREAMS; i++) {
|
||||||
struct ivtv_stream *s = &itv->streams[i];
|
struct ivtv_stream *s = &itv->streams[i];
|
||||||
@@ -1633,8 +1626,8 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case VIDEO_GET_PTS: {
|
case VIDEO_GET_PTS: {
|
||||||
u32 data[CX2341X_MBOX_MAX_DATA];
|
s64 *pts = arg;
|
||||||
u64 *pts = arg;
|
s64 frame;
|
||||||
|
|
||||||
IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
|
IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
|
||||||
if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
|
if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
|
||||||
@@ -1643,29 +1636,12 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
|
|||||||
}
|
}
|
||||||
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
|
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
return ivtv_g_pts_frame(itv, pts, &frame);
|
||||||
if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
|
|
||||||
*pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
|
|
||||||
(u64)itv->last_dec_timing[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*pts = 0;
|
|
||||||
if (atomic_read(&itv->decoding)) {
|
|
||||||
if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
|
|
||||||
IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
|
|
||||||
set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
|
|
||||||
*pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
|
|
||||||
/*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDEO_GET_FRAME_COUNT: {
|
case VIDEO_GET_FRAME_COUNT: {
|
||||||
u32 data[CX2341X_MBOX_MAX_DATA];
|
s64 *frame = arg;
|
||||||
u64 *frame = arg;
|
s64 pts;
|
||||||
|
|
||||||
IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
|
IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
|
||||||
if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
|
if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
|
||||||
@@ -1674,22 +1650,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
|
|||||||
}
|
}
|
||||||
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
|
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
return ivtv_g_pts_frame(itv, &pts, frame);
|
||||||
if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
|
|
||||||
*frame = itv->last_dec_timing[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*frame = 0;
|
|
||||||
if (atomic_read(&itv->decoding)) {
|
|
||||||
if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
|
|
||||||
IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
|
|
||||||
set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
|
|
||||||
*frame = data[0];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case VIDEO_PLAY: {
|
case VIDEO_PLAY: {
|
||||||
@@ -1804,17 +1765,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
|
|||||||
IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
|
IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
|
||||||
if (iarg > AUDIO_STEREO_SWAPPED)
|
if (iarg > AUDIO_STEREO_SWAPPED)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
itv->audio_stereo_mode = iarg;
|
return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg);
|
||||||
ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case AUDIO_BILINGUAL_CHANNEL_SELECT:
|
case AUDIO_BILINGUAL_CHANNEL_SELECT:
|
||||||
IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
|
IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
|
||||||
if (iarg > AUDIO_STEREO_SWAPPED)
|
if (iarg > AUDIO_STEREO_SWAPPED)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
itv->audio_bilingual_mode = iarg;
|
return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg);
|
||||||
ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@@ -223,7 +223,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
|
|||||||
|
|
||||||
s->vdev->num = num;
|
s->vdev->num = num;
|
||||||
s->vdev->v4l2_dev = &itv->v4l2_dev;
|
s->vdev->v4l2_dev = &itv->v4l2_dev;
|
||||||
s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
|
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
|
||||||
|
s->vdev->ctrl_handler = &itv->hdl_out;
|
||||||
|
else
|
||||||
|
s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
|
||||||
s->vdev->fops = ivtv_stream_info[type].fops;
|
s->vdev->fops = ivtv_stream_info[type].fops;
|
||||||
s->vdev->release = video_device_release;
|
s->vdev->release = video_device_release;
|
||||||
s->vdev->tvnorms = V4L2_STD_ALL;
|
s->vdev->tvnorms = V4L2_STD_ALL;
|
||||||
|
Reference in New Issue
Block a user