Commit 432907f7 authored by Mike Isely's avatar Mike Isely Committed by Mauro Carvalho Chehab

V4L/DVB (8900): pvrusb2: Implement cropping pass through

This builds upon the previous pvrusb2 change to more formally
implement full cropping support.  This enables access from the
driver's V4L interface, and enables access to full capabilities from
sysfs as well.  Note that this is only effective when in analog mode.
It also will only work when the underlying digitizer's driver (saa7115
or cx25840 depending on the hardware) also implements the appropriate
functions.
Signed-off-by: default avatarMike Isely <isely@pobox.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 0b7c2c95
......@@ -308,6 +308,10 @@ struct pvr2_hdw {
struct v4l2_tuner tuner_signal_info;
int tuner_signal_stale;
/* Cropping capability info */
struct v4l2_cropcap cropcap_info;
int cropcap_stale;
/* Video standard handling */
v4l2_std_id std_mask_eeprom; // Hardware supported selections
v4l2_std_id std_mask_avail; // Which standards we may select from
......@@ -320,7 +324,6 @@ struct pvr2_hdw {
struct pvr2_ctl_info std_info_cur;
struct v4l2_standard *std_defs;
const char **std_enum_names;
struct v4l2_cropcap cropcap;
// Generated string names, one per actual V4L2 standard
const char *std_mask_ptrs[32];
......
This diff is collapsed.
......@@ -40,6 +40,12 @@
#define PVR2_CID_CROPT 10
#define PVR2_CID_CROPW 11
#define PVR2_CID_CROPH 12
#define PVR2_CID_CROPCAPPAN 13
#define PVR2_CID_CROPCAPPAD 14
#define PVR2_CID_CROPCAPBL 15
#define PVR2_CID_CROPCAPBT 16
#define PVR2_CID_CROPCAPBW 17
#define PVR2_CID_CROPCAPBH 18
/* Legal values for the INPUT state variable */
#define PVR2_CVAL_INPUT_TV 0
......@@ -174,6 +180,9 @@ void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *);
/* Return information about the tuner */
int pvr2_hdw_get_tuner_status(struct pvr2_hdw *,struct v4l2_tuner *);
/* Return information about cropping capabilities */
int pvr2_hdw_get_cropcap(struct pvr2_hdw *, struct v4l2_cropcap *);
/* Query device and see if it thinks it is on a high-speed USB link */
int pvr2_hdw_is_hsm(struct pvr2_hdw *);
......
......@@ -37,6 +37,7 @@ static void set_standard(struct pvr2_hdw *hdw)
pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
}
hdw->tuner_signal_stale = !0;
hdw->cropcap_stale = !0;
}
......@@ -235,34 +236,20 @@ const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = {
static void set_crop(struct pvr2_hdw *hdw)
{
struct v4l2_cropcap cap;
struct v4l2_crop crop;
int stat;
memset(&cap, 0, sizeof cap);
cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
stat = pvr2_i2c_core_cmd(hdw, VIDIOC_CROPCAP, &cap);
hdw->cropcap = cap;
memset(&crop, 0, sizeof crop);
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cap.defrect;
crop.c.left += hdw->cropl_val;
crop.c.top += hdw->cropt_val;
crop.c.left = hdw->cropl_val;
crop.c.top = hdw->cropt_val;
crop.c.height = hdw->croph_val;
crop.c.width = hdw->cropw_val;
pvr2_trace(PVR2_TRACE_CHIPS,
"i2c v4l2 set_crop stat=%d cap=%d:%d:%d:%d"
" crop=%d:%d:%d:%d", stat, cap.bounds.width,
cap.bounds.height, cap.bounds.left, cap.bounds.top,
"i2c v4l2 set_crop crop=%d:%d:%d:%d",
crop.c.width, crop.c.height, crop.c.left, crop.c.top);
if (stat >= 0) {
/* This comment is present purely to keep
checkpatch.pl quiet */
pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop);
}
pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop);
}
static int check_crop(struct pvr2_hdw *hdw)
......@@ -312,7 +299,19 @@ void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp)
{
pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&cp->hdw->tuner_signal_info);
int stat;
struct pvr2_hdw *hdw = cp->hdw;
if (hdw->cropcap_stale) {
hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP,
&hdw->cropcap_info);
if (stat == 0) {
/* Check was successful, so the data is no
longer considered stale. */
hdw->cropcap_stale = 0;
}
}
pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info);
}
......
......@@ -891,6 +891,7 @@ static int pvr2_i2c_attach_inform(struct i2c_client *client)
INIT_LIST_HEAD(&cp->list);
cp->client = client;
mutex_lock(&hdw->i2c_list_lock); do {
hdw->cropcap_stale = !0;
list_add_tail(&cp->list,&hdw->i2c_clients);
hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT;
} while (0); mutex_unlock(&hdw->i2c_list_lock);
......@@ -905,6 +906,7 @@ static int pvr2_i2c_detach_inform(struct i2c_client *client)
unsigned long amask = 0;
int foundfl = 0;
mutex_lock(&hdw->i2c_list_lock); do {
hdw->cropcap_stale = !0;
list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
if (cp->client == client) {
trace_i2c("pvr2_i2c_detach"
......
......@@ -755,6 +755,92 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file,
break;
}
case VIDIOC_CROPCAP:
{
struct v4l2_cropcap *cap = (struct v4l2_cropcap *)arg;
if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = -EINVAL;
break;
}
ret = pvr2_hdw_get_cropcap(hdw, cap);
cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */
break;
}
case VIDIOC_G_CROP:
{
struct v4l2_crop *crop = (struct v4l2_crop *)arg;
int val = 0;
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = -EINVAL;
break;
}
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val);
if (ret != 0) {
ret = -EINVAL;
break;
}
crop->c.left = val;
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val);
if (ret != 0) {
ret = -EINVAL;
break;
}
crop->c.top = val;
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val);
if (ret != 0) {
ret = -EINVAL;
break;
}
crop->c.width = val;
ret = pvr2_ctrl_get_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val);
if (ret != 0) {
ret = -EINVAL;
break;
}
crop->c.height = val;
}
case VIDIOC_S_CROP:
{
struct v4l2_crop *crop = (struct v4l2_crop *)arg;
struct v4l2_cropcap cap;
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = -EINVAL;
break;
}
cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = pvr2_ctrl_set_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
crop->c.left);
if (ret != 0) {
ret = -EINVAL;
break;
}
ret = pvr2_ctrl_set_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT),
crop->c.top);
if (ret != 0) {
ret = -EINVAL;
break;
}
ret = pvr2_ctrl_set_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW),
crop->c.width);
if (ret != 0) {
ret = -EINVAL;
break;
}
ret = pvr2_ctrl_set_value(
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH),
crop->c.height);
if (ret != 0) {
ret = -EINVAL;
break;
}
}
case VIDIOC_LOG_STATUS:
{
pvr2_hdw_trigger_module_log(hdw);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment