p->ident, p->revision);
}
-static void v4l_print_dbg_register(const void *arg, bool write_only)
+static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
{
- const struct v4l2_dbg_register *p = arg;
+ const struct v4l2_dbg_chip_info *p = arg;
pr_cont("type=%u, ", p->match.type);
if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
(int)sizeof(p->match.name), p->match.name);
else
pr_cont("addr=%u, ", p->match.addr);
- pr_cont("reg=0x%llx, val=0x%llx\n",
- p->reg, p->val);
-}
-
-static void v4l_print_dv_enum_presets(const void *arg, bool write_only)
-{
- const struct v4l2_dv_enum_preset *p = arg;
-
- pr_cont("index=%u, preset=%u, name=%.*s, width=%u, height=%u\n",
- p->index, p->preset,
- (int)sizeof(p->name), p->name, p->width, p->height);
+ pr_cont("name=%.*s\n", (int)sizeof(p->name), p->name);
}
-static void v4l_print_dv_preset(const void *arg, bool write_only)
+static void v4l_print_dbg_register(const void *arg, bool write_only)
{
- const struct v4l2_dv_preset *p = arg;
+ const struct v4l2_dbg_register *p = arg;
- pr_cont("preset=%u\n", p->preset);
+ pr_cont("type=%u, ", p->match.type);
+ if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
+ pr_cont("name=%.*s, ",
+ (int)sizeof(p->match.name), p->match.name);
+ else
+ pr_cont("addr=%u, ", p->match.addr);
+ pr_cont("reg=0x%llx, val=0x%llx\n",
+ p->reg, p->val);
}
static void v4l_print_dv_timings(const void *arg, bool write_only)
struct v4l2_input *p = arg;
/*
- * We set the flags for CAP_PRESETS, CAP_DV_TIMINGS &
+ * We set the flags for CAP_DV_TIMINGS &
* CAP_STD here based on ioctl handler provided by the
* driver. If the driver doesn't support these
* for a specific input, it must override these flags.
*/
if (is_valid_ioctl(vfd, VIDIOC_S_STD))
p->capabilities |= V4L2_IN_CAP_STD;
- if (is_valid_ioctl(vfd, VIDIOC_S_DV_PRESET))
- p->capabilities |= V4L2_IN_CAP_PRESETS;
- if (is_valid_ioctl(vfd, VIDIOC_S_DV_TIMINGS))
- p->capabilities |= V4L2_IN_CAP_DV_TIMINGS;
return ops->vidioc_enum_input(file, fh, p);
}
struct v4l2_output *p = arg;
/*
- * We set the flags for CAP_PRESETS, CAP_DV_TIMINGS &
+ * We set the flags for CAP_DV_TIMINGS &
* CAP_STD here based on ioctl handler provided by the
* driver. If the driver doesn't support these
* for a specific output, it must override these flags.
*/
if (is_valid_ioctl(vfd, VIDIOC_S_STD))
p->capabilities |= V4L2_OUT_CAP_STD;
- if (is_valid_ioctl(vfd, VIDIOC_S_DV_PRESET))
- p->capabilities |= V4L2_OUT_CAP_PRESETS;
- if (is_valid_ioctl(vfd, VIDIOC_S_DV_TIMINGS))
- p->capabilities |= V4L2_OUT_CAP_DV_TIMINGS;
return ops->vidioc_enum_output(file, fh, p);
}
{
#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) {
+ if (vfd->v4l2_dev == NULL)
+ return -EINVAL;
+ v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
+ if (p->match.addr == 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
{
#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) {
+ if (vfd->v4l2_dev == NULL)
+ return -EINVAL;
+ v4l2_device_for_each_subdev(sd, vfd->v4l2_dev)
+ if (p->match.addr == 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
p->ident = V4L2_IDENT_NONE;
p->revision = 0;
+ if (p->match.type == V4L2_CHIP_MATCH_SUBDEV)
+ return -EINVAL;
return ops->vidioc_g_chip_ident(file, fh, p);
}
+static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
+ struct file *file, void *fh, void *arg)
+{
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ struct video_device *vfd = video_devdata(file);
+ struct v4l2_dbg_chip_info *p = arg;
+ struct v4l2_subdev *sd;
+ int idx = 0;
+
+ switch (p->match.type) {
+ case V4L2_CHIP_MATCH_BRIDGE:
+ if (ops->vidioc_s_register)
+ p->flags |= V4L2_CHIP_FL_WRITABLE;
+ if (ops->vidioc_g_register)
+ p->flags |= V4L2_CHIP_FL_READABLE;
+ 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));
+ if (ops->vidioc_g_chip_info)
+ return ops->vidioc_g_chip_info(file, fh, arg);
+ if (p->match.addr)
+ return -EINVAL;
+ return 0;
+
+ case V4L2_CHIP_MATCH_SUBDEV:
+ if (vfd->v4l2_dev == NULL)
+ break;
+ v4l2_device_for_each_subdev(sd, vfd->v4l2_dev) {
+ if (p->match.addr != idx++)
+ continue;
+ 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;
+ strlcpy(p->name, sd->name, sizeof(p->name));
+ return 0;
+ }
+ break;
+ }
+ return -EINVAL;
+#else
+ return -ENOTTY;
+#endif
+}
+
static int v4l_dqevent(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_IDENT, v4l_dbg_g_chip_ident, v4l_print_dbg_chip_ident, 0),
IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets, v4l_print_dv_enum_presets, 0),
- IOCTL_INFO_STD(VIDIOC_S_DV_PRESET, vidioc_s_dv_preset, v4l_print_dv_preset, INFO_FL_PRIO),
- IOCTL_INFO_STD(VIDIOC_G_DV_PRESET, vidioc_g_dv_preset, v4l_print_dv_preset, 0),
- IOCTL_INFO_STD(VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset, v4l_print_dv_preset, 0),
IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO),
IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
IOCTL_INFO_FNC(VIDIOC_DQEVENT, v4l_dqevent, v4l_print_event, 0),
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_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)),
};
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)