diff options
-rw-r--r-- | drivers/media/i2c/tvp7002.c | 96 | ||||
-rw-r--r-- | include/media/tvp7002.h | 2 |
2 files changed, 93 insertions, 5 deletions
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 027809cca5f5..270e6997cc76 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c | |||
@@ -424,6 +424,7 @@ struct tvp7002 { | |||
424 | int streaming; | 424 | int streaming; |
425 | 425 | ||
426 | const struct tvp7002_timings_definition *current_timings; | 426 | const struct tvp7002_timings_definition *current_timings; |
427 | struct media_pad pad; | ||
427 | }; | 428 | }; |
428 | 429 | ||
429 | /* | 430 | /* |
@@ -880,6 +881,65 @@ static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = { | |||
880 | .s_ctrl = tvp7002_s_ctrl, | 881 | .s_ctrl = tvp7002_s_ctrl, |
881 | }; | 882 | }; |
882 | 883 | ||
884 | /* | ||
885 | * tvp7002_enum_mbus_code() - Enum supported digital video format on pad | ||
886 | * @sd: pointer to standard V4L2 sub-device structure | ||
887 | * @fh: file handle for the subdev | ||
888 | * @code: pointer to subdev enum mbus code struct | ||
889 | * | ||
890 | * Enumerate supported digital video formats for pad. | ||
891 | */ | ||
892 | static int | ||
893 | tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | ||
894 | struct v4l2_subdev_mbus_code_enum *code) | ||
895 | { | ||
896 | /* Check requested format index is within range */ | ||
897 | if (code->index != 0) | ||
898 | return -EINVAL; | ||
899 | |||
900 | code->code = V4L2_MBUS_FMT_YUYV10_1X20; | ||
901 | |||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | /* | ||
906 | * tvp7002_get_pad_format() - get video format on pad | ||
907 | * @sd: pointer to standard V4L2 sub-device structure | ||
908 | * @fh: file handle for the subdev | ||
909 | * @fmt: pointer to subdev format struct | ||
910 | * | ||
911 | * get video format for pad. | ||
912 | */ | ||
913 | static int | ||
914 | tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | ||
915 | struct v4l2_subdev_format *fmt) | ||
916 | { | ||
917 | struct tvp7002 *tvp7002 = to_tvp7002(sd); | ||
918 | |||
919 | fmt->format.code = V4L2_MBUS_FMT_YUYV10_1X20; | ||
920 | fmt->format.width = tvp7002->current_timings->timings.bt.width; | ||
921 | fmt->format.height = tvp7002->current_timings->timings.bt.height; | ||
922 | fmt->format.field = tvp7002->current_timings->scanmode; | ||
923 | fmt->format.colorspace = tvp7002->current_timings->color_space; | ||
924 | |||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | /* | ||
929 | * tvp7002_set_pad_format() - set video format on pad | ||
930 | * @sd: pointer to standard V4L2 sub-device structure | ||
931 | * @fh: file handle for the subdev | ||
932 | * @fmt: pointer to subdev format struct | ||
933 | * | ||
934 | * set video format for pad. | ||
935 | */ | ||
936 | static int | ||
937 | tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | ||
938 | struct v4l2_subdev_format *fmt) | ||
939 | { | ||
940 | return tvp7002_get_pad_format(sd, fh, fmt); | ||
941 | } | ||
942 | |||
883 | /* V4L2 core operation handlers */ | 943 | /* V4L2 core operation handlers */ |
884 | static const struct v4l2_subdev_core_ops tvp7002_core_ops = { | 944 | static const struct v4l2_subdev_core_ops tvp7002_core_ops = { |
885 | .g_chip_ident = tvp7002_g_chip_ident, | 945 | .g_chip_ident = tvp7002_g_chip_ident, |
@@ -910,10 +970,18 @@ static const struct v4l2_subdev_video_ops tvp7002_video_ops = { | |||
910 | .enum_mbus_fmt = tvp7002_enum_mbus_fmt, | 970 | .enum_mbus_fmt = tvp7002_enum_mbus_fmt, |
911 | }; | 971 | }; |
912 | 972 | ||
973 | /* media pad related operation handlers */ | ||
974 | static const struct v4l2_subdev_pad_ops tvp7002_pad_ops = { | ||
975 | .enum_mbus_code = tvp7002_enum_mbus_code, | ||
976 | .get_fmt = tvp7002_get_pad_format, | ||
977 | .set_fmt = tvp7002_set_pad_format, | ||
978 | }; | ||
979 | |||
913 | /* V4L2 top level operation handlers */ | 980 | /* V4L2 top level operation handlers */ |
914 | static const struct v4l2_subdev_ops tvp7002_ops = { | 981 | static const struct v4l2_subdev_ops tvp7002_ops = { |
915 | .core = &tvp7002_core_ops, | 982 | .core = &tvp7002_core_ops, |
916 | .video = &tvp7002_video_ops, | 983 | .video = &tvp7002_video_ops, |
984 | .pad = &tvp7002_pad_ops, | ||
917 | }; | 985 | }; |
918 | 986 | ||
919 | /* | 987 | /* |
@@ -993,19 +1061,35 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) | |||
993 | timings = device->current_timings->timings; | 1061 | timings = device->current_timings->timings; |
994 | error = tvp7002_s_dv_timings(sd, &timings); | 1062 | error = tvp7002_s_dv_timings(sd, &timings); |
995 | 1063 | ||
1064 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1065 | strlcpy(sd->name, TVP7002_MODULE_NAME, sizeof(sd->name)); | ||
1066 | device->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
1067 | device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
1068 | device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; | ||
1069 | |||
1070 | error = media_entity_init(&device->sd.entity, 1, &device->pad, 0); | ||
1071 | if (error < 0) | ||
1072 | return error; | ||
1073 | #endif | ||
1074 | |||
996 | v4l2_ctrl_handler_init(&device->hdl, 1); | 1075 | v4l2_ctrl_handler_init(&device->hdl, 1); |
997 | v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops, | 1076 | v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops, |
998 | V4L2_CID_GAIN, 0, 255, 1, 0); | 1077 | V4L2_CID_GAIN, 0, 255, 1, 0); |
999 | sd->ctrl_handler = &device->hdl; | 1078 | sd->ctrl_handler = &device->hdl; |
1000 | if (device->hdl.error) { | 1079 | if (device->hdl.error) { |
1001 | int err = device->hdl.error; | 1080 | error = device->hdl.error; |
1002 | 1081 | goto error; | |
1003 | v4l2_ctrl_handler_free(&device->hdl); | ||
1004 | return err; | ||
1005 | } | 1082 | } |
1006 | v4l2_ctrl_handler_setup(&device->hdl); | 1083 | v4l2_ctrl_handler_setup(&device->hdl); |
1007 | 1084 | ||
1008 | return 0; | 1085 | return 0; |
1086 | |||
1087 | error: | ||
1088 | v4l2_ctrl_handler_free(&device->hdl); | ||
1089 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1090 | media_entity_cleanup(&device->sd.entity); | ||
1091 | #endif | ||
1092 | return error; | ||
1009 | } | 1093 | } |
1010 | 1094 | ||
1011 | /* | 1095 | /* |
@@ -1022,7 +1106,9 @@ static int tvp7002_remove(struct i2c_client *c) | |||
1022 | 1106 | ||
1023 | v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter" | 1107 | v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter" |
1024 | "on address 0x%x\n", c->addr); | 1108 | "on address 0x%x\n", c->addr); |
1025 | 1109 | #if defined(CONFIG_MEDIA_CONTROLLER) | |
1110 | media_entity_cleanup(&device->sd.entity); | ||
1111 | #endif | ||
1026 | v4l2_device_unregister_subdev(sd); | 1112 | v4l2_device_unregister_subdev(sd); |
1027 | v4l2_ctrl_handler_free(&device->hdl); | 1113 | v4l2_ctrl_handler_free(&device->hdl); |
1028 | return 0; | 1114 | return 0; |
diff --git a/include/media/tvp7002.h b/include/media/tvp7002.h index ee4353459ef5..7123048408d6 100644 --- a/include/media/tvp7002.h +++ b/include/media/tvp7002.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #ifndef _TVP7002_H_ | 26 | #ifndef _TVP7002_H_ |
27 | #define _TVP7002_H_ | 27 | #define _TVP7002_H_ |
28 | 28 | ||
29 | #define TVP7002_MODULE_NAME "tvp7002" | ||
30 | |||
29 | /* Platform-dependent data | 31 | /* Platform-dependent data |
30 | * | 32 | * |
31 | * clk_polarity: | 33 | * clk_polarity: |