Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 366850
b: refs/heads/master
c: 79b0c64
h: refs/heads/master
v: v3
  • Loading branch information
Hans Verkuil authored and Mauro Carvalho Chehab committed Mar 25, 2013
1 parent 284fcab commit ea50912
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 820eac0ef8b86f7275acd1f8bccfb0b30f17bbe9
refs/heads/master: 79b0c6400517456935f84f8d46c8bb0cf73f1813
5 changes: 4 additions & 1 deletion trunk/drivers/media/v4l2-core/v4l2-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ EXPORT_SYMBOL(v4l2_ctrl_next);
int v4l2_chip_match_host(const struct v4l2_dbg_match *match)
{
switch (match->type) {
case V4L2_CHIP_MATCH_HOST:
case V4L2_CHIP_MATCH_BRIDGE:
return match->addr == 0;
default:
return 0;
Expand All @@ -254,6 +254,9 @@ int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match
return len && !strncmp(c->driver->driver.name, match->name, len);
case V4L2_CHIP_MATCH_I2C_ADDR:
return c->addr == match->addr;
case V4L2_CHIP_MATCH_SUBDEV_IDX:
case V4L2_CHIP_MATCH_SUBDEV_NAME:
return 1;
default:
return 0;
}
Expand Down
5 changes: 3 additions & 2 deletions trunk/drivers/media/v4l2-core/v4l2-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -591,9 +591,10 @@ static void determine_valid_ioctls(struct video_device *vdev)
SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status);
set_bit(_IOC_NR(VIDIOC_DBG_G_CHIP_NAME), valid_ioctls);
#ifdef CONFIG_VIDEO_ADV_DEBUG
SET_VALID_IOCTL(ops, VIDIOC_DBG_G_REGISTER, vidioc_g_register);
SET_VALID_IOCTL(ops, VIDIOC_DBG_S_REGISTER, vidioc_s_register);
set_bit(_IOC_NR(VIDIOC_DBG_G_REGISTER), valid_ioctls);
set_bit(_IOC_NR(VIDIOC_DBG_S_REGISTER), valid_ioctls);
#endif
SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident);
/* yes, really vidioc_subscribe_event */
Expand Down
115 changes: 111 additions & 4 deletions trunk/drivers/media/v4l2-core/v4l2-ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,8 @@ static void v4l_print_dbg_chip_ident(const void *arg, bool write_only)
const struct v4l2_dbg_chip_ident *p = arg;

pr_cont("type=%u, ", p->match.type);
if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER ||
p->match.type == V4L2_CHIP_MATCH_SUBDEV_NAME)
pr_cont("name=%.*s, ",
(int)sizeof(p->match.name), p->match.name);
else
Expand All @@ -638,12 +639,27 @@ static void v4l_print_dbg_chip_ident(const void *arg, bool write_only)
p->ident, p->revision);
}

static void v4l_print_dbg_chip_name(const void *arg, bool write_only)
{
const struct v4l2_dbg_chip_name *p = arg;

pr_cont("type=%u, ", p->match.type);
if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER ||
p->match.type == V4L2_CHIP_MATCH_SUBDEV_NAME)
pr_cont("name=%.*s, ",
(int)sizeof(p->match.name), p->match.name);
else
pr_cont("addr=%u, ", p->match.addr);
pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
}

static void v4l_print_dbg_register(const void *arg, bool write_only)
{
const struct v4l2_dbg_register *p = arg;

pr_cont("type=%u, ", p->match.type);
if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER ||
p->match.type == V4L2_CHIP_MATCH_SUBDEV_NAME)
pr_cont("name=%.*s, ",
(int)sizeof(p->match.name), p->match.name);
else
Expand Down Expand Up @@ -1775,15 +1791,38 @@ static int v4l_log_status(const struct v4l2_ioctl_ops *ops,
return ret;
}

static bool v4l_dbg_found_match(const struct v4l2_dbg_match *match,
struct v4l2_subdev *sd, int idx)
{
if (match->type == V4L2_CHIP_MATCH_SUBDEV_IDX)
return match->addr == idx;
return !strcmp(match->name, sd->name);
}

static int v4l_dbg_g_register(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
struct v4l2_dbg_register *p = arg;
struct video_device *vfd = video_devdata(file);
struct v4l2_subdev *sd;
int idx = 0;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;
return ops->vidioc_g_register(file, fh, p);
if (p->match.type == V4L2_CHIP_MATCH_SUBDEV_IDX ||
p->match.type == V4L2_CHIP_MATCH_SUBDEV_NAME) {
if (vfd->v4l2_dev == NULL)
return -EINVAL;
v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
if (v4l_dbg_found_match(&p->match, sd, idx++))
return v4l2_subdev_call(sd, core, g_register, p);
}
return -EINVAL;
}
if (ops->vidioc_g_register)
return ops->vidioc_g_register(file, fh, p);
return -EINVAL;
#else
return -ENOTTY;
#endif
Expand All @@ -1794,10 +1833,25 @@ static int v4l_dbg_s_register(const struct v4l2_ioctl_ops *ops,
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
const struct v4l2_dbg_register *p = arg;
struct video_device *vfd = video_devdata(file);
struct v4l2_subdev *sd;
int idx = 0;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;
return ops->vidioc_s_register(file, fh, p);
if (p->match.type == V4L2_CHIP_MATCH_SUBDEV_IDX ||
p->match.type == V4L2_CHIP_MATCH_SUBDEV_NAME) {
if (vfd->v4l2_dev == NULL)
return -EINVAL;
v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
if (v4l_dbg_found_match(&p->match, sd, idx++))
return v4l2_subdev_call(sd, core, s_register, p);
}
return -EINVAL;
}
if (ops->vidioc_s_register)
return ops->vidioc_s_register(file, fh, p);
return -EINVAL;
#else
return -ENOTTY;
#endif
Expand All @@ -1810,9 +1864,61 @@ static int v4l_dbg_g_chip_ident(const struct v4l2_ioctl_ops *ops,

p->ident = V4L2_IDENT_NONE;
p->revision = 0;
if (p->match.type == V4L2_CHIP_MATCH_SUBDEV_NAME ||
p->match.type == V4L2_CHIP_MATCH_SUBDEV_IDX)
return -EINVAL;
return ops->vidioc_g_chip_ident(file, fh, p);
}

static int v4l_dbg_g_chip_name(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct video_device *vfd = video_devdata(file);
struct v4l2_dbg_chip_name *p = arg;
struct v4l2_subdev *sd;
int idx = 0;

switch (p->match.type) {
case V4L2_CHIP_MATCH_BRIDGE:
#ifdef CONFIG_VIDEO_ADV_DEBUG
if (ops->vidioc_s_register)
p->flags |= V4L2_CHIP_FL_WRITABLE;
if (ops->vidioc_g_register)
p->flags |= V4L2_CHIP_FL_READABLE;
#endif
if (ops->vidioc_g_chip_name)
return ops->vidioc_g_chip_name(file, fh, arg);
if (p->match.addr)
return -EINVAL;
if (vfd->v4l2_dev)
strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
else if (vfd->parent)
strlcpy(p->name, vfd->parent->driver->name, sizeof(p->name));
else
strlcpy(p->name, "bridge", sizeof(p->name));
return 0;

case V4L2_CHIP_MATCH_SUBDEV_IDX:
case V4L2_CHIP_MATCH_SUBDEV_NAME:
if (vfd->v4l2_dev == NULL)
break;
v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
if (v4l_dbg_found_match(&p->match, sd, idx++)) {
#ifdef CONFIG_VIDEO_ADV_DEBUG
if (sd->ops->core && sd->ops->core->s_register)
p->flags |= V4L2_CHIP_FL_WRITABLE;
if (sd->ops->core && sd->ops->core->g_register)
p->flags |= V4L2_CHIP_FL_READABLE;
#endif
strlcpy(p->name, sd->name, sizeof(p->name));
return 0;
}
}
break;
}
return -EINVAL;
}

static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
Expand Down Expand Up @@ -2027,6 +2133,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0),
IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)),
IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0),
IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_NAME, v4l_dbg_g_chip_name, v4l_print_dbg_chip_name, INFO_FL_CLEAR(v4l2_dbg_chip_name, match)),
};
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)

Expand Down
3 changes: 3 additions & 0 deletions trunk/include/media/v4l2-ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ struct v4l2_ioctl_ops {
int (*vidioc_g_chip_ident) (struct file *file, void *fh,
struct v4l2_dbg_chip_ident *chip);

int (*vidioc_g_chip_name) (struct file *file, void *fh,
struct v4l2_dbg_chip_name *chip);

int (*vidioc_enum_framesizes) (struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize);

Expand Down
34 changes: 25 additions & 9 deletions trunk/include/uapi/linux/videodev2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1807,10 +1807,13 @@ struct v4l2_event_subscription {

/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */

#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */
#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */
#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */
#define V4L2_CHIP_MATCH_BRIDGE 0 /* Match against chip ID on the bridge (0 for the bridge) */
#define V4L2_CHIP_MATCH_HOST V4L2_CHIP_MATCH_BRIDGE
#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */
#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */
#define V4L2_CHIP_MATCH_SUBDEV_NAME 4 /* Match against subdev name */
#define V4L2_CHIP_MATCH_SUBDEV_IDX 5 /* Match against subdev index */

struct v4l2_dbg_match {
__u32 type; /* Match type */
Expand All @@ -1834,6 +1837,17 @@ struct v4l2_dbg_chip_ident {
__u32 revision; /* chip revision, chip specific */
} __attribute__ ((packed));

#define V4L2_CHIP_FL_READABLE (1 << 0)
#define V4L2_CHIP_FL_WRITABLE (1 << 1)

/* VIDIOC_DBG_G_CHIP_NAME */
struct v4l2_dbg_chip_name {
struct v4l2_dbg_match match;
char name[32];
__u32 flags;
__u32 reserved[8];
} __attribute__ ((packed));

/**
* struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument
* @index: on return, index of the first created buffer
Expand Down Expand Up @@ -1911,25 +1925,23 @@ struct v4l2_create_buffers {
#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls)
#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls)
#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls)
#if 1
#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum)
#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum)
#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx)
#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd)
#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd)
#endif

#if 1
/* Experimental, meant for debugging, testing and internal use.
Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined.
You must be root to use these ioctls. Never use these in applications! */
#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register)

/* Experimental, meant for debugging, testing and internal use.
Never use this ioctl in applications! */
Never use this ioctl in applications!
Note: this ioctl is deprecated in favor of VIDIOC_DBG_G_CHIP_NAME and
will go away in the future. */
#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident)
#endif

#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)

Expand Down Expand Up @@ -1963,6 +1975,10 @@ struct v4l2_create_buffers {
versions. */
#define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band)

/* Experimental, meant for debugging, testing and internal use.
Never use these in applications! */
#define VIDIOC_DBG_G_CHIP_NAME _IOWR('V', 102, struct v4l2_dbg_chip_name)

/* Reminder: when adding new ioctls please add support for them to
drivers/media/video/v4l2-compat-ioctl32.c as well! */

Expand Down

0 comments on commit ea50912

Please sign in to comment.