aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManjunath Hadli <manjunath.hadli@ti.com>2013-03-08 02:13:35 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-21 13:06:29 -0400
commit5b38b0f88d28bd1b492fe225b6d401b2e51fd8cc (patch)
treece88ef5cd4722ec09ea96268cdbdf5f029972c0c
parente64171b97b88a1adf297d429826fdbb9e232ab53 (diff)
[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>
-rw-r--r--drivers/media/i2c/tvp514x.c163
1 files changed, 154 insertions, 9 deletions
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index aa94ebc2d755..ab8f3fee7e94 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -12,6 +12,7 @@
12 * Hardik Shah <hardik.shah@ti.com> 12 * Hardik Shah <hardik.shah@ti.com>
13 * Manjunath Hadli <mrh@ti.com> 13 * Manjunath Hadli <mrh@ti.com>
14 * Karicheri Muralidharan <m-karicheri2@ti.com> 14 * Karicheri Muralidharan <m-karicheri2@ti.com>
15 * Prabhakar Lad <prabhakar.lad@ti.com>
15 * 16 *
16 * This package is free software; you can redistribute it and/or modify 17 * This package is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as 18 * it under the terms of the GNU General Public License version 2 as
@@ -33,6 +34,7 @@
33#include <linux/delay.h> 34#include <linux/delay.h>
34#include <linux/videodev2.h> 35#include <linux/videodev2.h>
35#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/v4l2-mediabus.h>
36 38
37#include <media/v4l2-device.h> 39#include <media/v4l2-device.h>
38#include <media/v4l2-common.h> 40#include <media/v4l2-common.h>
@@ -40,12 +42,10 @@
40#include <media/v4l2-chip-ident.h> 42#include <media/v4l2-chip-ident.h>
41#include <media/v4l2-ctrls.h> 43#include <media/v4l2-ctrls.h>
42#include <media/tvp514x.h> 44#include <media/tvp514x.h>
45#include <media/media-entity.h>
43 46
44#include "tvp514x_regs.h" 47#include "tvp514x_regs.h"
45 48
46/* Module Name */
47#define TVP514X_MODULE_NAME "tvp514x"
48
49/* Private macros for TVP */ 49/* Private macros for TVP */
50#define I2C_RETRY_COUNT (5) 50#define I2C_RETRY_COUNT (5)
51#define LOCK_RETRY_COUNT (5) 51#define LOCK_RETRY_COUNT (5)
@@ -91,6 +91,9 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
91 * @pdata: Board specific 91 * @pdata: Board specific
92 * @ver: Chip version 92 * @ver: Chip version
93 * @streaming: TVP5146/47 decoder streaming - enabled or disabled. 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 * @current_std: Current standard 97 * @current_std: Current standard
95 * @num_stds: Number of standards 98 * @num_stds: Number of standards
96 * @std_list: Standards list 99 * @std_list: Standards list
@@ -106,12 +109,20 @@ struct tvp514x_decoder {
106 int ver; 109 int ver;
107 int streaming; 110 int streaming;
108 111
112 struct v4l2_pix_format pix;
113 int num_fmts;
114 const struct v4l2_fmtdesc *fmt_list;
115
109 enum tvp514x_std current_std; 116 enum tvp514x_std current_std;
110 int num_stds; 117 int num_stds;
111 const struct tvp514x_std_info *std_list; 118 const struct tvp514x_std_info *std_list;
112 /* Input and Output Routing parameters */ 119 /* Input and Output Routing parameters */
113 u32 input; 120 u32 input;
114 u32 output; 121 u32 output;
122
123 /* mc related members */
124 struct media_pad pad;
125 struct v4l2_mbus_framefmt format;
115}; 126};
116 127
117/* TVP514x default register values */ 128/* TVP514x default register values */
@@ -200,6 +211,21 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = {
200}; 211};
201 212
202/** 213/**
214 * List of image formats supported by TVP5146/47 decoder
215 * Currently we are using 8 bit mode only, but can be
216 * extended to 10/20 bit mode.
217 */
218static const struct v4l2_fmtdesc tvp514x_fmt_list[] = {
219 {
220 .index = 0,
221 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
222 .flags = 0,
223 .description = "8-bit UYVY 4:2:2 Format",
224 .pixelformat = V4L2_PIX_FMT_UYVY,
225 },
226};
227
228/**
203 * Supported standards - 229 * Supported standards -
204 * 230 *
205 * Currently supports two standards only, need to add support for rest of the 231 * Currently supports two standards only, need to add support for rest of the
@@ -733,7 +759,7 @@ tvp514x_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
733} 759}
734 760
735/** 761/**
736 * tvp514x_mbus_fmt_cap() - V4L2 decoder interface handler for try/s/g_mbus_fmt 762 * tvp514x_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt
737 * @sd: pointer to standard V4L2 sub-device structure 763 * @sd: pointer to standard V4L2 sub-device structure
738 * @f: pointer to the mediabus format structure 764 * @f: pointer to the mediabus format structure
739 * 765 *
@@ -751,12 +777,11 @@ tvp514x_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
751 /* Calculate height and width based on current standard */ 777 /* Calculate height and width based on current standard */
752 current_std = decoder->current_std; 778 current_std = decoder->current_std;
753 779
754 f->code = V4L2_MBUS_FMT_YUYV10_2X10; 780 f->code = V4L2_MBUS_FMT_YUYV8_2X8;
755 f->width = decoder->std_list[current_std].width; 781 f->width = decoder->std_list[current_std].width;
756 f->height = decoder->std_list[current_std].height; 782 f->height = decoder->std_list[current_std].height;
757 f->field = V4L2_FIELD_INTERLACED; 783 f->field = V4L2_FIELD_INTERLACED;
758 f->colorspace = V4L2_COLORSPACE_SMPTE170M; 784 f->colorspace = V4L2_COLORSPACE_SMPTE170M;
759
760 v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d\n", 785 v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d\n",
761 f->width, f->height); 786 f->width, f->height);
762 return 0; 787 return 0;
@@ -892,6 +917,88 @@ static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = {
892 .s_ctrl = tvp514x_s_ctrl, 917 .s_ctrl = tvp514x_s_ctrl,
893}; 918};
894 919
920/**
921 * tvp514x_enum_mbus_code() - V4L2 decoder interface handler for enum_mbus_code
922 * @sd: pointer to standard V4L2 sub-device structure
923 * @fh: file handle
924 * @code: pointer to v4l2_subdev_mbus_code_enum structure
925 *
926 * Enumertaes mbus codes supported
927 */
928static int tvp514x_enum_mbus_code(struct v4l2_subdev *sd,
929 struct v4l2_subdev_fh *fh,
930 struct v4l2_subdev_mbus_code_enum *code)
931{
932 u32 pad = code->pad;
933 u32 index = code->index;
934
935 memset(code, 0, sizeof(*code));
936 code->index = index;
937 code->pad = pad;
938
939 if (index != 0)
940 return -EINVAL;
941
942 code->code = V4L2_MBUS_FMT_YUYV8_2X8;
943
944 return 0;
945}
946
947/**
948 * tvp514x_get_pad_format() - V4L2 decoder interface handler for get pad format
949 * @sd: pointer to standard V4L2 sub-device structure
950 * @fh: file handle
951 * @format: pointer to v4l2_subdev_format structure
952 *
953 * Retrieves pad format which is active or tried based on requirement
954 */
955static int tvp514x_get_pad_format(struct v4l2_subdev *sd,
956 struct v4l2_subdev_fh *fh,
957 struct v4l2_subdev_format *format)
958{
959 struct tvp514x_decoder *decoder = to_decoder(sd);
960 __u32 which = format->which;
961
962 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
963 format->format = decoder->format;
964 return 0;
965 }
966
967 format->format.code = V4L2_MBUS_FMT_YUYV8_2X8;
968 format->format.width = tvp514x_std_list[decoder->current_std].width;
969 format->format.height = tvp514x_std_list[decoder->current_std].height;
970 format->format.colorspace = V4L2_COLORSPACE_SMPTE170M;
971 format->format.field = V4L2_FIELD_INTERLACED;
972
973 return 0;
974}
975
976/**
977 * tvp514x_set_pad_format() - V4L2 decoder interface handler for set pad format
978 * @sd: pointer to standard V4L2 sub-device structure
979 * @fh: file handle
980 * @format: pointer to v4l2_subdev_format structure
981 *
982 * Set pad format for the output pad
983 */
984static int tvp514x_set_pad_format(struct v4l2_subdev *sd,
985 struct v4l2_subdev_fh *fh,
986 struct v4l2_subdev_format *fmt)
987{
988 struct tvp514x_decoder *decoder = to_decoder(sd);
989
990 if (fmt->format.field != V4L2_FIELD_INTERLACED ||
991 fmt->format.code != V4L2_MBUS_FMT_YUYV8_2X8 ||
992 fmt->format.colorspace != V4L2_COLORSPACE_SMPTE170M ||
993 fmt->format.width != tvp514x_std_list[decoder->current_std].width ||
994 fmt->format.height != tvp514x_std_list[decoder->current_std].height)
995 return -EINVAL;
996
997 decoder->format = fmt->format;
998
999 return 0;
1000}
1001
895static const struct v4l2_subdev_core_ops tvp514x_core_ops = { 1002static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
896 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, 1003 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
897 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, 1004 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
@@ -915,13 +1022,33 @@ static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
915 .s_stream = tvp514x_s_stream, 1022 .s_stream = tvp514x_s_stream,
916}; 1023};
917 1024
1025static const struct v4l2_subdev_pad_ops tvp514x_pad_ops = {
1026 .enum_mbus_code = tvp514x_enum_mbus_code,
1027 .get_fmt = tvp514x_get_pad_format,
1028 .set_fmt = tvp514x_set_pad_format,
1029};
1030
918static const struct v4l2_subdev_ops tvp514x_ops = { 1031static const struct v4l2_subdev_ops tvp514x_ops = {
919 .core = &tvp514x_core_ops, 1032 .core = &tvp514x_core_ops,
920 .video = &tvp514x_video_ops, 1033 .video = &tvp514x_video_ops,
1034 .pad = &tvp514x_pad_ops,
921}; 1035};
922 1036
923static struct tvp514x_decoder tvp514x_dev = { 1037static struct tvp514x_decoder tvp514x_dev = {
924 .streaming = 0, 1038 .streaming = 0,
1039 .fmt_list = tvp514x_fmt_list,
1040 .num_fmts = ARRAY_SIZE(tvp514x_fmt_list),
1041 .pix = {
1042 /* Default to NTSC 8-bit YUV 422 */
1043 .width = NTSC_NUM_ACTIVE_PIXELS,
1044 .height = NTSC_NUM_ACTIVE_LINES,
1045 .pixelformat = V4L2_PIX_FMT_UYVY,
1046 .field = V4L2_FIELD_INTERLACED,
1047 .bytesperline = NTSC_NUM_ACTIVE_PIXELS * 2,
1048 .sizeimage = NTSC_NUM_ACTIVE_PIXELS * 2 *
1049 NTSC_NUM_ACTIVE_LINES,
1050 .colorspace = V4L2_COLORSPACE_SMPTE170M,
1051 },
925 .current_std = STD_NTSC_MJ, 1052 .current_std = STD_NTSC_MJ,
926 .std_list = tvp514x_std_list, 1053 .std_list = tvp514x_std_list,
927 .num_stds = ARRAY_SIZE(tvp514x_std_list), 1054 .num_stds = ARRAY_SIZE(tvp514x_std_list),
@@ -941,6 +1068,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
941{ 1068{
942 struct tvp514x_decoder *decoder; 1069 struct tvp514x_decoder *decoder;
943 struct v4l2_subdev *sd; 1070 struct v4l2_subdev *sd;
1071 int ret;
944 1072
945 /* Check if the adapter supports the needed features */ 1073 /* Check if the adapter supports the needed features */
946 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1074 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -981,7 +1109,21 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
981 /* Register with V4L2 layer as slave device */ 1109 /* Register with V4L2 layer as slave device */
982 sd = &decoder->sd; 1110 sd = &decoder->sd;
983 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops); 1111 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
984 1112 strlcpy(sd->name, TVP514X_MODULE_NAME, sizeof(sd->name));
1113
1114#if defined(CONFIG_MEDIA_CONTROLLER)
1115 decoder->pad.flags = MEDIA_PAD_FL_SOURCE;
1116 decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1117 decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
1118
1119 ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad, 0);
1120 if (ret < 0) {
1121 v4l2_err(sd, "%s decoder driver failed to register !!\n",
1122 sd->name);
1123 kfree(decoder);
1124 return ret;
1125 }
1126#endif
985 v4l2_ctrl_handler_init(&decoder->hdl, 5); 1127 v4l2_ctrl_handler_init(&decoder->hdl, 5);
986 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops, 1128 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
987 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); 1129 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
@@ -995,10 +1137,10 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
995 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 1137 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
996 sd->ctrl_handler = &decoder->hdl; 1138 sd->ctrl_handler = &decoder->hdl;
997 if (decoder->hdl.error) { 1139 if (decoder->hdl.error) {
998 int err = decoder->hdl.error; 1140 ret = decoder->hdl.error;
999 1141
1000 v4l2_ctrl_handler_free(&decoder->hdl); 1142 v4l2_ctrl_handler_free(&decoder->hdl);
1001 return err; 1143 return ret;
1002 } 1144 }
1003 v4l2_ctrl_handler_setup(&decoder->hdl); 1145 v4l2_ctrl_handler_setup(&decoder->hdl);
1004 1146
@@ -1021,6 +1163,9 @@ static int tvp514x_remove(struct i2c_client *client)
1021 struct tvp514x_decoder *decoder = to_decoder(sd); 1163 struct tvp514x_decoder *decoder = to_decoder(sd);
1022 1164
1023 v4l2_device_unregister_subdev(sd); 1165 v4l2_device_unregister_subdev(sd);
1166#if defined(CONFIG_MEDIA_CONTROLLER)
1167 media_entity_cleanup(&decoder->sd.entity);
1168#endif
1024 v4l2_ctrl_handler_free(&decoder->hdl); 1169 v4l2_ctrl_handler_free(&decoder->hdl);
1025 return 0; 1170 return 0;
1026} 1171}