[media] vpif_cap/disp: Add support for DV presets
- Added functions to set/get/query/enum DV presets for vpif_caputre and vpif_display. - The format specification table is extended with all the DV formats supported by TVP7002. Signed-off-by: Mats Randgaard <mats.randgaard@cisco.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Manjunath Hadli <manjunath.hadli@ti.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
aa44440635
commit
40c8bcea6b
@ -46,6 +46,133 @@ void __iomem *vpif_base;
|
|||||||
* The table must include all presets from supported subdevices.
|
* The table must include all presets from supported subdevices.
|
||||||
*/
|
*/
|
||||||
const struct vpif_channel_config_params ch_params[] = {
|
const struct vpif_channel_config_params ch_params[] = {
|
||||||
|
/* HDTV formats */
|
||||||
|
{
|
||||||
|
.name = "480p59_94",
|
||||||
|
.width = 720,
|
||||||
|
.height = 480,
|
||||||
|
.frm_fmt = 1,
|
||||||
|
.ycmux_mode = 0,
|
||||||
|
.eav2sav = 138-8,
|
||||||
|
.sav2eav = 720,
|
||||||
|
.l1 = 1,
|
||||||
|
.l3 = 43,
|
||||||
|
.l5 = 523,
|
||||||
|
.vsize = 525,
|
||||||
|
.capture_format = 0,
|
||||||
|
.vbi_supported = 0,
|
||||||
|
.hd_sd = 1,
|
||||||
|
.dv_preset = V4L2_DV_480P59_94,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "576p50",
|
||||||
|
.width = 720,
|
||||||
|
.height = 576,
|
||||||
|
.frm_fmt = 1,
|
||||||
|
.ycmux_mode = 0,
|
||||||
|
.eav2sav = 144-8,
|
||||||
|
.sav2eav = 720,
|
||||||
|
.l1 = 1,
|
||||||
|
.l3 = 45,
|
||||||
|
.l5 = 621,
|
||||||
|
.vsize = 625,
|
||||||
|
.capture_format = 0,
|
||||||
|
.vbi_supported = 0,
|
||||||
|
.hd_sd = 1,
|
||||||
|
.dv_preset = V4L2_DV_576P50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "720p50",
|
||||||
|
.width = 1280,
|
||||||
|
.height = 720,
|
||||||
|
.frm_fmt = 1,
|
||||||
|
.ycmux_mode = 0,
|
||||||
|
.eav2sav = 700-8,
|
||||||
|
.sav2eav = 1280,
|
||||||
|
.l1 = 1,
|
||||||
|
.l3 = 26,
|
||||||
|
.l5 = 746,
|
||||||
|
.vsize = 750,
|
||||||
|
.capture_format = 0,
|
||||||
|
.vbi_supported = 0,
|
||||||
|
.hd_sd = 1,
|
||||||
|
.dv_preset = V4L2_DV_720P50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "720p60",
|
||||||
|
.width = 1280,
|
||||||
|
.height = 720,
|
||||||
|
.frm_fmt = 1,
|
||||||
|
.ycmux_mode = 0,
|
||||||
|
.eav2sav = 370 - 8,
|
||||||
|
.sav2eav = 1280,
|
||||||
|
.l1 = 1,
|
||||||
|
.l3 = 26,
|
||||||
|
.l5 = 746,
|
||||||
|
.vsize = 750,
|
||||||
|
.capture_format = 0,
|
||||||
|
.vbi_supported = 0,
|
||||||
|
.hd_sd = 1,
|
||||||
|
.dv_preset = V4L2_DV_720P60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "1080I50",
|
||||||
|
.width = 1920,
|
||||||
|
.height = 1080,
|
||||||
|
.frm_fmt = 0,
|
||||||
|
.ycmux_mode = 0,
|
||||||
|
.eav2sav = 720 - 8,
|
||||||
|
.sav2eav = 1920,
|
||||||
|
.l1 = 1,
|
||||||
|
.l3 = 21,
|
||||||
|
.l5 = 561,
|
||||||
|
.l7 = 563,
|
||||||
|
.l9 = 584,
|
||||||
|
.l11 = 1124,
|
||||||
|
.vsize = 1125,
|
||||||
|
.capture_format = 0,
|
||||||
|
.vbi_supported = 0,
|
||||||
|
.hd_sd = 1,
|
||||||
|
.dv_preset = V4L2_DV_1080I50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "1080I60",
|
||||||
|
.width = 1920,
|
||||||
|
.height = 1080,
|
||||||
|
.frm_fmt = 0,
|
||||||
|
.ycmux_mode = 0,
|
||||||
|
.eav2sav = 280 - 8,
|
||||||
|
.sav2eav = 1920,
|
||||||
|
.l1 = 1,
|
||||||
|
.l3 = 21,
|
||||||
|
.l5 = 561,
|
||||||
|
.l7 = 563,
|
||||||
|
.l9 = 584,
|
||||||
|
.l11 = 1124,
|
||||||
|
.vsize = 1125,
|
||||||
|
.capture_format = 0,
|
||||||
|
.vbi_supported = 0,
|
||||||
|
.hd_sd = 1,
|
||||||
|
.dv_preset = V4L2_DV_1080I60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "1080p60",
|
||||||
|
.width = 1920,
|
||||||
|
.height = 1080,
|
||||||
|
.frm_fmt = 1,
|
||||||
|
.ycmux_mode = 0,
|
||||||
|
.eav2sav = 280 - 8,
|
||||||
|
.sav2eav = 1920,
|
||||||
|
.l1 = 1,
|
||||||
|
.l3 = 42,
|
||||||
|
.l5 = 1122,
|
||||||
|
.vsize = 1125,
|
||||||
|
.capture_format = 0,
|
||||||
|
.vbi_supported = 0,
|
||||||
|
.hd_sd = 1,
|
||||||
|
.dv_preset = V4L2_DV_1080P60,
|
||||||
|
},
|
||||||
|
|
||||||
/* SDTV formats */
|
/* SDTV formats */
|
||||||
{
|
{
|
||||||
.name = "NTSC_M",
|
.name = "NTSC_M",
|
||||||
|
@ -591,6 +591,7 @@ struct vpif_channel_config_params {
|
|||||||
* supports capturing vbi or not */
|
* supports capturing vbi or not */
|
||||||
u8 hd_sd;
|
u8 hd_sd;
|
||||||
v4l2_std_id stdid;
|
v4l2_std_id stdid;
|
||||||
|
u32 dv_preset; /* HDTV format */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const unsigned int vpif_ch_params_count;
|
extern const unsigned int vpif_ch_params_count;
|
||||||
|
@ -432,9 +432,18 @@ static int vpif_update_std_info(struct channel_obj *ch)
|
|||||||
|
|
||||||
for (index = 0; index < vpif_ch_params_count; index++) {
|
for (index = 0; index < vpif_ch_params_count; index++) {
|
||||||
config = &ch_params[index];
|
config = &ch_params[index];
|
||||||
if (config->stdid & vid_ch->stdid) {
|
if (config->hd_sd == 0) {
|
||||||
memcpy(std_info, config, sizeof(*config));
|
vpif_dbg(2, debug, "SD format\n");
|
||||||
break;
|
if (config->stdid & vid_ch->stdid) {
|
||||||
|
memcpy(std_info, config, sizeof(*config));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vpif_dbg(2, debug, "HD format\n");
|
||||||
|
if (config->dv_preset == vid_ch->dv_preset) {
|
||||||
|
memcpy(std_info, config, sizeof(*config));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1442,6 +1451,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
|
|||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
ch->video.stdid = *std_id;
|
ch->video.stdid = *std_id;
|
||||||
|
ch->video.dv_preset = V4L2_DV_INVALID;
|
||||||
|
|
||||||
/* Get the information about the standard */
|
/* Get the information about the standard */
|
||||||
if (vpif_update_std_info(ch)) {
|
if (vpif_update_std_info(ch)) {
|
||||||
@ -1794,6 +1804,110 @@ static int vpif_cropcap(struct file *file, void *priv,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
|
||||||
|
* @file: file ptr
|
||||||
|
* @priv: file handle
|
||||||
|
* @preset: input preset
|
||||||
|
*/
|
||||||
|
static int vpif_enum_dv_presets(struct file *file, void *priv,
|
||||||
|
struct v4l2_dv_enum_preset *preset)
|
||||||
|
{
|
||||||
|
struct vpif_fh *fh = priv;
|
||||||
|
struct channel_obj *ch = fh->channel;
|
||||||
|
|
||||||
|
return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
|
||||||
|
video, enum_dv_presets, preset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vpif_query_dv_presets() - QUERY_DV_PRESET handler
|
||||||
|
* @file: file ptr
|
||||||
|
* @priv: file handle
|
||||||
|
* @preset: input preset
|
||||||
|
*/
|
||||||
|
static int vpif_query_dv_preset(struct file *file, void *priv,
|
||||||
|
struct v4l2_dv_preset *preset)
|
||||||
|
{
|
||||||
|
struct vpif_fh *fh = priv;
|
||||||
|
struct channel_obj *ch = fh->channel;
|
||||||
|
|
||||||
|
return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
|
||||||
|
video, query_dv_preset, preset);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* vpif_s_dv_presets() - S_DV_PRESETS handler
|
||||||
|
* @file: file ptr
|
||||||
|
* @priv: file handle
|
||||||
|
* @preset: input preset
|
||||||
|
*/
|
||||||
|
static int vpif_s_dv_preset(struct file *file, void *priv,
|
||||||
|
struct v4l2_dv_preset *preset)
|
||||||
|
{
|
||||||
|
struct vpif_fh *fh = priv;
|
||||||
|
struct channel_obj *ch = fh->channel;
|
||||||
|
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (common->started) {
|
||||||
|
vpif_dbg(1, debug, "streaming in progress\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
|
||||||
|
(VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
|
||||||
|
if (!fh->initialized) {
|
||||||
|
vpif_dbg(1, debug, "Channel Busy\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = v4l2_prio_check(&ch->prio, fh->prio);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
fh->initialized = 1;
|
||||||
|
|
||||||
|
/* Call encoder subdevice function to set the standard */
|
||||||
|
if (mutex_lock_interruptible(&common->lock))
|
||||||
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
|
ch->video.dv_preset = preset->preset;
|
||||||
|
ch->video.stdid = V4L2_STD_UNKNOWN;
|
||||||
|
|
||||||
|
/* Get the information about the standard */
|
||||||
|
if (vpif_update_std_info(ch)) {
|
||||||
|
vpif_dbg(1, debug, "Error getting the standard info\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
} else {
|
||||||
|
/* Configure the default format information */
|
||||||
|
vpif_config_format(ch);
|
||||||
|
|
||||||
|
ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
|
||||||
|
video, s_dv_preset, preset);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&common->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* vpif_g_dv_presets() - G_DV_PRESETS handler
|
||||||
|
* @file: file ptr
|
||||||
|
* @priv: file handle
|
||||||
|
* @preset: input preset
|
||||||
|
*/
|
||||||
|
static int vpif_g_dv_preset(struct file *file, void *priv,
|
||||||
|
struct v4l2_dv_preset *preset)
|
||||||
|
{
|
||||||
|
struct vpif_fh *fh = priv;
|
||||||
|
struct channel_obj *ch = fh->channel;
|
||||||
|
|
||||||
|
preset->preset = ch->video.dv_preset;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vpif_g_chip_ident() - Identify the chip
|
* vpif_g_chip_ident() - Identify the chip
|
||||||
* @file: file ptr
|
* @file: file ptr
|
||||||
@ -1892,6 +2006,10 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
|
|||||||
.vidioc_streamon = vpif_streamon,
|
.vidioc_streamon = vpif_streamon,
|
||||||
.vidioc_streamoff = vpif_streamoff,
|
.vidioc_streamoff = vpif_streamoff,
|
||||||
.vidioc_cropcap = vpif_cropcap,
|
.vidioc_cropcap = vpif_cropcap,
|
||||||
|
.vidioc_enum_dv_presets = vpif_enum_dv_presets,
|
||||||
|
.vidioc_s_dv_preset = vpif_s_dv_preset,
|
||||||
|
.vidioc_g_dv_preset = vpif_g_dv_preset,
|
||||||
|
.vidioc_query_dv_preset = vpif_query_dv_preset,
|
||||||
.vidioc_g_chip_ident = vpif_g_chip_ident,
|
.vidioc_g_chip_ident = vpif_g_chip_ident,
|
||||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||||
.vidioc_g_register = vpif_dbg_g_register,
|
.vidioc_g_register = vpif_dbg_g_register,
|
||||||
|
@ -59,6 +59,7 @@ struct video_obj {
|
|||||||
enum v4l2_field buf_field;
|
enum v4l2_field buf_field;
|
||||||
/* Currently selected or default standard */
|
/* Currently selected or default standard */
|
||||||
v4l2_std_id stdid;
|
v4l2_std_id stdid;
|
||||||
|
u32 dv_preset;
|
||||||
/* This is to track the last input that is passed to application */
|
/* This is to track the last input that is passed to application */
|
||||||
u32 input_idx;
|
u32 input_idx;
|
||||||
};
|
};
|
||||||
|
@ -373,15 +373,23 @@ static int vpif_get_std_info(struct channel_obj *ch)
|
|||||||
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
std_info->stdid = vid_ch->stdid;
|
if (!vid_ch->stdid && !vid_ch->dv_preset)
|
||||||
if (!std_info->stdid)
|
return -EINVAL;
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (index = 0; index < vpif_ch_params_count; index++) {
|
for (index = 0; index < vpif_ch_params_count; index++) {
|
||||||
config = &ch_params[index];
|
config = &ch_params[index];
|
||||||
if (config->stdid & std_info->stdid) {
|
if (config->hd_sd == 0) {
|
||||||
memcpy(std_info, config, sizeof(*config));
|
vpif_dbg(2, debug, "SD format\n");
|
||||||
break;
|
if (config->stdid & vid_ch->stdid) {
|
||||||
|
memcpy(std_info, config, sizeof(*config));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vpif_dbg(2, debug, "HD format\n");
|
||||||
|
if (config->dv_preset == vid_ch->dv_preset) {
|
||||||
|
memcpy(std_info, config, sizeof(*config));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1305,6 +1313,88 @@ static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
|
|||||||
return v4l2_prio_change(&ch->prio, &fh->prio, p);
|
return v4l2_prio_change(&ch->prio, &fh->prio, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
|
||||||
|
* @file: file ptr
|
||||||
|
* @priv: file handle
|
||||||
|
* @preset: input preset
|
||||||
|
*/
|
||||||
|
static int vpif_enum_dv_presets(struct file *file, void *priv,
|
||||||
|
struct v4l2_dv_enum_preset *preset)
|
||||||
|
{
|
||||||
|
struct vpif_fh *fh = priv;
|
||||||
|
struct channel_obj *ch = fh->channel;
|
||||||
|
struct video_obj *vid_ch = &ch->video;
|
||||||
|
|
||||||
|
return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
|
||||||
|
video, enum_dv_presets, preset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vpif_s_dv_presets() - S_DV_PRESETS handler
|
||||||
|
* @file: file ptr
|
||||||
|
* @priv: file handle
|
||||||
|
* @preset: input preset
|
||||||
|
*/
|
||||||
|
static int vpif_s_dv_preset(struct file *file, void *priv,
|
||||||
|
struct v4l2_dv_preset *preset)
|
||||||
|
{
|
||||||
|
struct vpif_fh *fh = priv;
|
||||||
|
struct channel_obj *ch = fh->channel;
|
||||||
|
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
|
||||||
|
struct video_obj *vid_ch = &ch->video;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (common->started) {
|
||||||
|
vpif_dbg(1, debug, "streaming in progress\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = v4l2_prio_check(&ch->prio, fh->prio);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
fh->initialized = 1;
|
||||||
|
|
||||||
|
/* Call encoder subdevice function to set the standard */
|
||||||
|
if (mutex_lock_interruptible(&common->lock))
|
||||||
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
|
ch->video.dv_preset = preset->preset;
|
||||||
|
ch->video.stdid = V4L2_STD_UNKNOWN;
|
||||||
|
|
||||||
|
/* Get the information about the standard */
|
||||||
|
if (vpif_get_std_info(ch)) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
vpif_dbg(1, debug, "Error getting the standard info\n");
|
||||||
|
} else {
|
||||||
|
/* Configure the default format information */
|
||||||
|
vpif_config_format(ch);
|
||||||
|
|
||||||
|
ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
|
||||||
|
video, s_dv_preset, preset);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&common->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* vpif_g_dv_presets() - G_DV_PRESETS handler
|
||||||
|
* @file: file ptr
|
||||||
|
* @priv: file handle
|
||||||
|
* @preset: input preset
|
||||||
|
*/
|
||||||
|
static int vpif_g_dv_preset(struct file *file, void *priv,
|
||||||
|
struct v4l2_dv_preset *preset)
|
||||||
|
{
|
||||||
|
struct vpif_fh *fh = priv;
|
||||||
|
struct channel_obj *ch = fh->channel;
|
||||||
|
|
||||||
|
preset->preset = ch->video.dv_preset;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vpif_g_chip_ident() - Identify the chip
|
* vpif_g_chip_ident() - Identify the chip
|
||||||
@ -1405,6 +1495,9 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
|
|||||||
.vidioc_s_output = vpif_s_output,
|
.vidioc_s_output = vpif_s_output,
|
||||||
.vidioc_g_output = vpif_g_output,
|
.vidioc_g_output = vpif_g_output,
|
||||||
.vidioc_cropcap = vpif_cropcap,
|
.vidioc_cropcap = vpif_cropcap,
|
||||||
|
.vidioc_enum_dv_presets = vpif_enum_dv_presets,
|
||||||
|
.vidioc_s_dv_preset = vpif_s_dv_preset,
|
||||||
|
.vidioc_g_dv_preset = vpif_g_dv_preset,
|
||||||
.vidioc_g_chip_ident = vpif_g_chip_ident,
|
.vidioc_g_chip_ident = vpif_g_chip_ident,
|
||||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||||
.vidioc_g_register = vpif_dbg_g_register,
|
.vidioc_g_register = vpif_dbg_g_register,
|
||||||
|
@ -67,6 +67,7 @@ struct video_obj {
|
|||||||
* most recent displayed frame only */
|
* most recent displayed frame only */
|
||||||
v4l2_std_id stdid; /* Currently selected or default
|
v4l2_std_id stdid; /* Currently selected or default
|
||||||
* standard */
|
* standard */
|
||||||
|
u32 dv_preset;
|
||||||
u32 output_id; /* Current output id */
|
u32 output_id; /* Current output id */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user