Commit dd519bb3 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] v4l2: add VIDIOC_G/S_EDID support to the v4l2 core

Support this ioctl as part of the v4l2 core. Use the new ioctl
name and struct v4l2_edid type in the existing core code.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Acked-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 254a4777
...@@ -740,7 +740,7 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u ...@@ -740,7 +740,7 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
return 0; return 0;
} }
struct v4l2_subdev_edid32 { struct v4l2_edid32 {
__u32 pad; __u32 pad;
__u32 start_block; __u32 start_block;
__u32 blocks; __u32 blocks;
...@@ -748,11 +748,11 @@ struct v4l2_subdev_edid32 { ...@@ -748,11 +748,11 @@ struct v4l2_subdev_edid32 {
compat_caddr_t edid; compat_caddr_t edid;
}; };
static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subdev_edid32 __user *up) static int get_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
{ {
u32 tmp; u32 tmp;
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_subdev_edid32)) || if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_edid32)) ||
get_user(kp->pad, &up->pad) || get_user(kp->pad, &up->pad) ||
get_user(kp->start_block, &up->start_block) || get_user(kp->start_block, &up->start_block) ||
get_user(kp->blocks, &up->blocks) || get_user(kp->blocks, &up->blocks) ||
...@@ -763,11 +763,11 @@ static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde ...@@ -763,11 +763,11 @@ static int get_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde
return 0; return 0;
} }
static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subdev_edid32 __user *up) static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
{ {
u32 tmp = (u32)((unsigned long)kp->edid); u32 tmp = (u32)((unsigned long)kp->edid);
if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_subdev_edid32)) || if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_edid32)) ||
put_user(kp->pad, &up->pad) || put_user(kp->pad, &up->pad) ||
put_user(kp->start_block, &up->start_block) || put_user(kp->start_block, &up->start_block) ||
put_user(kp->blocks, &up->blocks) || put_user(kp->blocks, &up->blocks) ||
...@@ -787,8 +787,8 @@ static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde ...@@ -787,8 +787,8 @@ static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde
#define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32) #define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32)
#define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32) #define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32)
#define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32) #define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
#define VIDIOC_SUBDEV_G_EDID32 _IOWR('V', 40, struct v4l2_subdev_edid32) #define VIDIOC_G_EDID32 _IOWR('V', 40, struct v4l2_edid32)
#define VIDIOC_SUBDEV_S_EDID32 _IOWR('V', 41, struct v4l2_subdev_edid32) #define VIDIOC_S_EDID32 _IOWR('V', 41, struct v4l2_edid32)
#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) #define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
#define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32) #define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32)
#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
...@@ -816,7 +816,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar ...@@ -816,7 +816,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
struct v4l2_ext_controls v2ecs; struct v4l2_ext_controls v2ecs;
struct v4l2_event v2ev; struct v4l2_event v2ev;
struct v4l2_create_buffers v2crt; struct v4l2_create_buffers v2crt;
struct v4l2_subdev_edid v2edid; struct v4l2_edid v2edid;
unsigned long vx; unsigned long vx;
int vi; int vi;
} karg; } karg;
...@@ -849,8 +849,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar ...@@ -849,8 +849,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break; case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break; case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
case VIDIOC_SUBDEV_G_EDID32: cmd = VIDIOC_SUBDEV_G_EDID; break; case VIDIOC_G_EDID32: cmd = VIDIOC_G_EDID; break;
case VIDIOC_SUBDEV_S_EDID32: cmd = VIDIOC_SUBDEV_S_EDID; break; case VIDIOC_S_EDID32: cmd = VIDIOC_S_EDID; break;
} }
switch (cmd) { switch (cmd) {
...@@ -868,9 +868,9 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar ...@@ -868,9 +868,9 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
compatible_arg = 0; compatible_arg = 0;
break; break;
case VIDIOC_SUBDEV_G_EDID: case VIDIOC_G_EDID:
case VIDIOC_SUBDEV_S_EDID: case VIDIOC_S_EDID:
err = get_v4l2_subdev_edid32(&karg.v2edid, up); err = get_v4l2_edid32(&karg.v2edid, up);
compatible_arg = 0; compatible_arg = 0;
break; break;
...@@ -966,9 +966,9 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar ...@@ -966,9 +966,9 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
err = put_v4l2_event32(&karg.v2ev, up); err = put_v4l2_event32(&karg.v2ev, up);
break; break;
case VIDIOC_SUBDEV_G_EDID: case VIDIOC_G_EDID:
case VIDIOC_SUBDEV_S_EDID: case VIDIOC_S_EDID:
err = put_v4l2_subdev_edid32(&karg.v2edid, up); err = put_v4l2_edid32(&karg.v2edid, up);
break; break;
case VIDIOC_G_FMT: case VIDIOC_G_FMT:
......
...@@ -701,6 +701,7 @@ static void determine_valid_ioctls(struct video_device *vdev) ...@@ -701,6 +701,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio); SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio);
SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio); SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio);
SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings);
SET_VALID_IOCTL(ops, VIDIOC_S_EDID, vidioc_s_edid);
} }
if (is_tx) { if (is_tx) {
SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output); SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output);
...@@ -726,6 +727,7 @@ static void determine_valid_ioctls(struct video_device *vdev) ...@@ -726,6 +727,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings);
SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings);
SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap); SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap);
SET_VALID_IOCTL(ops, VIDIOC_G_EDID, vidioc_g_edid);
} }
if (is_tx && (is_radio || is_sdr)) { if (is_tx && (is_radio || is_sdr)) {
/* radio transmitter only ioctls */ /* radio transmitter only ioctls */
......
...@@ -844,6 +844,14 @@ static void v4l_print_freq_band(const void *arg, bool write_only) ...@@ -844,6 +844,14 @@ static void v4l_print_freq_band(const void *arg, bool write_only)
p->rangehigh, p->modulation); p->rangehigh, p->modulation);
} }
static void v4l_print_edid(const void *arg, bool write_only)
{
const struct v4l2_edid *p = arg;
pr_cont("pad=%u, start_block=%u, blocks=%u\n",
p->pad, p->start_block, p->blocks);
}
static void v4l_print_u32(const void *arg, bool write_only) static void v4l_print_u32(const void *arg, bool write_only)
{ {
pr_cont("value=%u\n", *(const u32 *)arg); pr_cont("value=%u\n", *(const u32 *)arg);
...@@ -2062,6 +2070,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { ...@@ -2062,6 +2070,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)),
IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0), IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0),
IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, INFO_FL_CLEAR(v4l2_edid, edid)),
IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_edid, edid)),
IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0), IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0),
IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
...@@ -2274,9 +2284,9 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, ...@@ -2274,9 +2284,9 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
break; break;
} }
case VIDIOC_SUBDEV_G_EDID: case VIDIOC_G_EDID:
case VIDIOC_SUBDEV_S_EDID: { case VIDIOC_S_EDID: {
struct v4l2_subdev_edid *edid = parg; struct v4l2_edid *edid = parg;
if (edid->blocks) { if (edid->blocks) {
if (edid->blocks > 256) { if (edid->blocks > 256) {
......
...@@ -349,10 +349,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) ...@@ -349,10 +349,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
sd, pad, set_selection, subdev_fh, sel); sd, pad, set_selection, subdev_fh, sel);
} }
case VIDIOC_SUBDEV_G_EDID: case VIDIOC_G_EDID:
return v4l2_subdev_call(sd, pad, get_edid, arg); return v4l2_subdev_call(sd, pad, get_edid, arg);
case VIDIOC_SUBDEV_S_EDID: case VIDIOC_S_EDID:
return v4l2_subdev_call(sd, pad, set_edid, arg); return v4l2_subdev_call(sd, pad, set_edid, arg);
#endif #endif
default: default:
......
...@@ -273,6 +273,8 @@ struct v4l2_ioctl_ops { ...@@ -273,6 +273,8 @@ struct v4l2_ioctl_ops {
struct v4l2_enum_dv_timings *timings); struct v4l2_enum_dv_timings *timings);
int (*vidioc_dv_timings_cap) (struct file *file, void *fh, int (*vidioc_dv_timings_cap) (struct file *file, void *fh,
struct v4l2_dv_timings_cap *cap); struct v4l2_dv_timings_cap *cap);
int (*vidioc_g_edid) (struct file *file, void *fh, struct v4l2_edid *edid);
int (*vidioc_s_edid) (struct file *file, void *fh, struct v4l2_edid *edid);
int (*vidioc_subscribe_event) (struct v4l2_fh *fh, int (*vidioc_subscribe_event) (struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub); const struct v4l2_event_subscription *sub);
......
...@@ -507,8 +507,8 @@ struct v4l2_subdev_pad_ops { ...@@ -507,8 +507,8 @@ struct v4l2_subdev_pad_ops {
struct v4l2_subdev_selection *sel); struct v4l2_subdev_selection *sel);
int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_subdev_selection *sel); struct v4l2_subdev_selection *sel);
int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid); int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid); int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid);
#ifdef CONFIG_MEDIA_CONTROLLER #ifdef CONFIG_MEDIA_CONTROLLER
int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link, int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link,
struct v4l2_subdev_format *source_fmt, struct v4l2_subdev_format *source_fmt,
......
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