Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] media: tvp514x: enable TVP514X for media controller based usage

add support for TVP514x as a media entity and support for
pad operations. The decoder supports 1 output pad.
The default format code was V4L2_MBUS_FMT_YUYV10_2X10
changed it to V4L2_MBUS_FMT_UYVY8_2X8.

Signed-off-by: Manjunath Hadli <manjunath.hadli@ti.com>
Signed-off-by: Lad, Prabhakar <prabhakar.lad@ti.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Manjunath Hadli and committed by
Mauro Carvalho Chehab
5b38b0f8 e64171b9

+153 -8
+153 -8
drivers/media/i2c/tvp514x.c
··· 12 12 * Hardik Shah <hardik.shah@ti.com> 13 13 * Manjunath Hadli <mrh@ti.com> 14 14 * Karicheri Muralidharan <m-karicheri2@ti.com> 15 + * Prabhakar Lad <prabhakar.lad@ti.com> 15 16 * 16 17 * This package is free software; you can redistribute it and/or modify 17 18 * it under the terms of the GNU General Public License version 2 as ··· 34 33 #include <linux/delay.h> 35 34 #include <linux/videodev2.h> 36 35 #include <linux/module.h> 36 + #include <linux/v4l2-mediabus.h> 37 37 38 38 #include <media/v4l2-device.h> 39 39 #include <media/v4l2-common.h> ··· 42 40 #include <media/v4l2-chip-ident.h> 43 41 #include <media/v4l2-ctrls.h> 44 42 #include <media/tvp514x.h> 43 + #include <media/media-entity.h> 45 44 46 45 #include "tvp514x_regs.h" 47 - 48 - /* Module Name */ 49 - #define TVP514X_MODULE_NAME "tvp514x" 50 46 51 47 /* Private macros for TVP */ 52 48 #define I2C_RETRY_COUNT (5) ··· 91 91 * @pdata: Board specific 92 92 * @ver: Chip version 93 93 * @streaming: TVP5146/47 decoder streaming - enabled or disabled. 94 + * @pix: Current pixel format 95 + * @num_fmts: Number of formats 96 + * @fmt_list: Format list 94 97 * @current_std: Current standard 95 98 * @num_stds: Number of standards 96 99 * @std_list: Standards list ··· 109 106 int ver; 110 107 int streaming; 111 108 109 + struct v4l2_pix_format pix; 110 + int num_fmts; 111 + const struct v4l2_fmtdesc *fmt_list; 112 + 112 113 enum tvp514x_std current_std; 113 114 int num_stds; 114 115 const struct tvp514x_std_info *std_list; 115 116 /* Input and Output Routing parameters */ 116 117 u32 input; 117 118 u32 output; 119 + 120 + /* mc related members */ 121 + struct media_pad pad; 122 + struct v4l2_mbus_framefmt format; 118 123 }; 119 124 120 125 /* TVP514x default register values */ ··· 208 197 /* Clear status */ 209 198 {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01}, 210 199 {TOK_TERM, 0, 0}, 200 + }; 201 + 202 + /** 203 + * List of image formats supported by TVP5146/47 decoder 204 + * Currently we are using 8 bit mode only, but can be 205 + * extended to 10/20 bit mode. 206 + */ 207 + static const struct v4l2_fmtdesc tvp514x_fmt_list[] = { 208 + { 209 + .index = 0, 210 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 211 + .flags = 0, 212 + .description = "8-bit UYVY 4:2:2 Format", 213 + .pixelformat = V4L2_PIX_FMT_UYVY, 214 + }, 211 215 }; 212 216 213 217 /** ··· 759 733 } 760 734 761 735 /** 762 - * tvp514x_mbus_fmt_cap() - V4L2 decoder interface handler for try/s/g_mbus_fmt 736 + * tvp514x_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt 763 737 * @sd: pointer to standard V4L2 sub-device structure 764 738 * @f: pointer to the mediabus format structure 765 739 * ··· 777 751 /* Calculate height and width based on current standard */ 778 752 current_std = decoder->current_std; 779 753 780 - f->code = V4L2_MBUS_FMT_YUYV10_2X10; 754 + f->code = V4L2_MBUS_FMT_YUYV8_2X8; 781 755 f->width = decoder->std_list[current_std].width; 782 756 f->height = decoder->std_list[current_std].height; 783 757 f->field = V4L2_FIELD_INTERLACED; 784 758 f->colorspace = V4L2_COLORSPACE_SMPTE170M; 785 - 786 759 v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d\n", 787 760 f->width, f->height); 788 761 return 0; ··· 917 892 .s_ctrl = tvp514x_s_ctrl, 918 893 }; 919 894 895 + /** 896 + * tvp514x_enum_mbus_code() - V4L2 decoder interface handler for enum_mbus_code 897 + * @sd: pointer to standard V4L2 sub-device structure 898 + * @fh: file handle 899 + * @code: pointer to v4l2_subdev_mbus_code_enum structure 900 + * 901 + * Enumertaes mbus codes supported 902 + */ 903 + static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd, 904 + struct v4l2_subdev_fh *fh, 905 + struct v4l2_subdev_mbus_code_enum *code) 906 + { 907 + u32 pad = code->pad; 908 + u32 index = code->index; 909 + 910 + memset(code, 0, sizeof(*code)); 911 + code->index = index; 912 + code->pad = pad; 913 + 914 + if (index != 0) 915 + return -EINVAL; 916 + 917 + code->code = V4L2_MBUS_FMT_YUYV8_2X8; 918 + 919 + return 0; 920 + } 921 + 922 + /** 923 + * tvp514x_get_pad_format() - V4L2 decoder interface handler for get pad format 924 + * @sd: pointer to standard V4L2 sub-device structure 925 + * @fh: file handle 926 + * @format: pointer to v4l2_subdev_format structure 927 + * 928 + * Retrieves pad format which is active or tried based on requirement 929 + */ 930 + static int tvp514x_get_pad_format(struct v4l2_subdev *sd, 931 + struct v4l2_subdev_fh *fh, 932 + struct v4l2_subdev_format *format) 933 + { 934 + struct tvp514x_decoder *decoder = to_decoder(sd); 935 + __u32 which = format->which; 936 + 937 + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { 938 + format->format = decoder->format; 939 + return 0; 940 + } 941 + 942 + format->format.code = V4L2_MBUS_FMT_YUYV8_2X8; 943 + format->format.width = tvp514x_std_list[decoder->current_std].width; 944 + format->format.height = tvp514x_std_list[decoder->current_std].height; 945 + format->format.colorspace = V4L2_COLORSPACE_SMPTE170M; 946 + format->format.field = V4L2_FIELD_INTERLACED; 947 + 948 + return 0; 949 + } 950 + 951 + /** 952 + * tvp514x_set_pad_format() - V4L2 decoder interface handler for set pad format 953 + * @sd: pointer to standard V4L2 sub-device structure 954 + * @fh: file handle 955 + * @format: pointer to v4l2_subdev_format structure 956 + * 957 + * Set pad format for the output pad 958 + */ 959 + static int tvp514x_set_pad_format(struct v4l2_subdev *sd, 960 + struct v4l2_subdev_fh *fh, 961 + struct v4l2_subdev_format *fmt) 962 + { 963 + struct tvp514x_decoder *decoder = to_decoder(sd); 964 + 965 + if (fmt->format.field != V4L2_FIELD_INTERLACED || 966 + fmt->format.code != V4L2_MBUS_FMT_YUYV8_2X8 || 967 + fmt->format.colorspace != V4L2_COLORSPACE_SMPTE170M || 968 + fmt->format.width != tvp514x_std_list[decoder->current_std].width || 969 + fmt->format.height != tvp514x_std_list[decoder->current_std].height) 970 + return -EINVAL; 971 + 972 + decoder->format = fmt->format; 973 + 974 + return 0; 975 + } 976 + 920 977 static const struct v4l2_subdev_core_ops tvp514x_core_ops = { 921 978 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, 922 979 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, ··· 1022 915 .s_stream = tvp514x_s_stream, 1023 916 }; 1024 917 918 + static const struct v4l2_subdev_pad_ops tvp514x_pad_ops = { 919 + .enum_mbus_code = tvp514x_enum_mbus_code, 920 + .get_fmt = tvp514x_get_pad_format, 921 + .set_fmt = tvp514x_set_pad_format, 922 + }; 923 + 1025 924 static const struct v4l2_subdev_ops tvp514x_ops = { 1026 925 .core = &tvp514x_core_ops, 1027 926 .video = &tvp514x_video_ops, 927 + .pad = &tvp514x_pad_ops, 1028 928 }; 1029 929 1030 930 static struct tvp514x_decoder tvp514x_dev = { 1031 931 .streaming = 0, 932 + .fmt_list = tvp514x_fmt_list, 933 + .num_fmts = ARRAY_SIZE(tvp514x_fmt_list), 934 + .pix = { 935 + /* Default to NTSC 8-bit YUV 422 */ 936 + .width = NTSC_NUM_ACTIVE_PIXELS, 937 + .height = NTSC_NUM_ACTIVE_LINES, 938 + .pixelformat = V4L2_PIX_FMT_UYVY, 939 + .field = V4L2_FIELD_INTERLACED, 940 + .bytesperline = NTSC_NUM_ACTIVE_PIXELS * 2, 941 + .sizeimage = NTSC_NUM_ACTIVE_PIXELS * 2 * 942 + NTSC_NUM_ACTIVE_LINES, 943 + .colorspace = V4L2_COLORSPACE_SMPTE170M, 944 + }, 1032 945 .current_std = STD_NTSC_MJ, 1033 946 .std_list = tvp514x_std_list, 1034 947 .num_stds = ARRAY_SIZE(tvp514x_std_list), ··· 1068 941 { 1069 942 struct tvp514x_decoder *decoder; 1070 943 struct v4l2_subdev *sd; 944 + int ret; 1071 945 1072 946 /* Check if the adapter supports the needed features */ 1073 947 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ··· 1109 981 /* Register with V4L2 layer as slave device */ 1110 982 sd = &decoder->sd; 1111 983 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops); 984 + strlcpy(sd->name, TVP514X_MODULE_NAME, sizeof(sd->name)); 1112 985 986 + #if defined(CONFIG_MEDIA_CONTROLLER) 987 + decoder->pad.flags = MEDIA_PAD_FL_SOURCE; 988 + decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 989 + decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; 990 + 991 + ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad, 0); 992 + if (ret < 0) { 993 + v4l2_err(sd, "%s decoder driver failed to register !!\n", 994 + sd->name); 995 + kfree(decoder); 996 + return ret; 997 + } 998 + #endif 1113 999 v4l2_ctrl_handler_init(&decoder->hdl, 5); 1114 1000 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops, 1115 1001 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); ··· 1137 995 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 1138 996 sd->ctrl_handler = &decoder->hdl; 1139 997 if (decoder->hdl.error) { 1140 - int err = decoder->hdl.error; 998 + ret = decoder->hdl.error; 1141 999 1142 1000 v4l2_ctrl_handler_free(&decoder->hdl); 1143 - return err; 1001 + return ret; 1144 1002 } 1145 1003 v4l2_ctrl_handler_setup(&decoder->hdl); 1146 1004 ··· 1163 1021 struct tvp514x_decoder *decoder = to_decoder(sd); 1164 1022 1165 1023 v4l2_device_unregister_subdev(sd); 1024 + #if defined(CONFIG_MEDIA_CONTROLLER) 1025 + media_entity_cleanup(&decoder->sd.entity); 1026 + #endif 1166 1027 v4l2_ctrl_handler_free(&decoder->hdl); 1167 1028 return 0; 1168 1029 }