public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] [media] tvp5150: convert register access to regmap
@ 2015-11-18 16:55 Lucas Stach
  2015-11-18 16:55 ` [PATCH 2/9] [media] tvp5150: add userspace subdev API Lucas Stach
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

Regmap provides built in debugging, caching and provides dedicated accessors
for bit manipulations in registers, which make the following changes a lot
simpler.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c | 194 ++++++++++++++++++++++++++++++--------------
 1 file changed, 133 insertions(+), 61 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 3c5fb2509c47..a7495d2856c3 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -10,6 +10,7 @@
 #include <linux/videodev2.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/regmap.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
 #include <media/tvp5150.h>
@@ -37,6 +38,7 @@ struct tvp5150 {
 	struct v4l2_subdev sd;
 	struct v4l2_ctrl_handler hdl;
 	struct v4l2_rect rect;
+	struct regmap *regmap;
 
 	v4l2_std_id norm;	/* Current set standard */
 	u32 input;
@@ -56,30 +58,14 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
 
 static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
 {
-	struct i2c_client *c = v4l2_get_subdevdata(sd);
-	int rc;
-
-	rc = i2c_smbus_read_byte_data(c, addr);
-	if (rc < 0) {
-		v4l2_err(sd, "i2c i/o error: rc == %d\n", rc);
-		return rc;
-	}
-
-	v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, rc);
-
-	return rc;
-}
+	struct tvp5150 *decoder = to_tvp5150(sd);
+	int ret, val;
 
-static inline void tvp5150_write(struct v4l2_subdev *sd, unsigned char addr,
-				 unsigned char value)
-{
-	struct i2c_client *c = v4l2_get_subdevdata(sd);
-	int rc;
+	ret = regmap_read(decoder->regmap, addr, &val);
+	if (ret < 0)
+		return ret;
 
-	v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", addr, value);
-	rc = i2c_smbus_write_byte_data(c, addr, value);
-	if (rc < 0)
-		v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d\n", rc);
+	return val;
 }
 
 static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init,
@@ -266,8 +252,8 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd)
 			decoder->input, decoder->output,
 			input, opmode);
 
-	tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
-	tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);
+	regmap_write(decoder->regmap, TVP5150_OP_MODE_CTL, opmode);
+	regmap_write(decoder->regmap, TVP5150_VD_IN_SRC_SEL_1, input);
 
 	/* Svideo should enable YCrCb output and disable GPCL output
 	 * For Composite and TV, it should be the reverse
@@ -282,7 +268,7 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd)
 		val = (val & ~0x40) | 0x10;
 	else
 		val = (val & ~0x10) | 0x40;
-	tvp5150_write(sd, TVP5150_MISC_CTL, val);
+	regmap_write(decoder->regmap, TVP5150_MISC_CTL, val);
 };
 
 struct i2c_reg_value {
@@ -553,8 +539,10 @@ static struct i2c_vbi_ram_value vbi_ram_default[] =
 static int tvp5150_write_inittab(struct v4l2_subdev *sd,
 				const struct i2c_reg_value *regs)
 {
+	struct tvp5150 *decoder = to_tvp5150(sd);
+
 	while (regs->reg != 0xff) {
-		tvp5150_write(sd, regs->reg, regs->value);
+		regmap_write(decoder->regmap, regs->reg, regs->value);
 		regs++;
 	}
 	return 0;
@@ -563,22 +551,24 @@ static int tvp5150_write_inittab(struct v4l2_subdev *sd,
 static int tvp5150_vdp_init(struct v4l2_subdev *sd,
 				const struct i2c_vbi_ram_value *regs)
 {
+	struct tvp5150 *decoder = to_tvp5150(sd);
+	struct regmap *map = decoder->regmap;
 	unsigned int i;
 
 	/* Disable Full Field */
-	tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
+	regmap_write(map, TVP5150_FULL_FIELD_ENA, 0);
 
 	/* Before programming, Line mode should be at 0xff */
 	for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++)
-		tvp5150_write(sd, i, 0xff);
+		regmap_write(map, i, 0xff);
 
 	/* Load Ram Table */
 	while (regs->reg != (u16)-1) {
-		tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
-		tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
+		regmap_write(map, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8);
+		regmap_write(map, TVP5150_CONF_RAM_ADDR_LOW, regs->reg);
 
 		for (i = 0; i < 16; i++)
-			tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
+			regmap_write(map, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]);
 
 		regs++;
 	}
@@ -658,11 +648,11 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd,
 	reg=((line-6)<<1)+TVP5150_LINE_MODE_INI;
 
 	if (fields&1) {
-		tvp5150_write(sd, reg, type);
+		regmap_write(decoder->regmap, reg, type);
 	}
 
 	if (fields&2) {
-		tvp5150_write(sd, reg+1, type);
+		regmap_write(decoder->regmap, reg+1, type);
 	}
 
 	return type;
@@ -731,7 +721,7 @@ static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
 	}
 
 	v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt);
-	tvp5150_write(sd, TVP5150_VIDEO_STD, fmt);
+	regmap_write(decoder->regmap, TVP5150_VIDEO_STD, fmt);
 	return 0;
 }
 
@@ -777,20 +767,20 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 
 static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	struct v4l2_subdev *sd = to_sd(ctrl);
+	struct tvp5150 *decoder = to_tvp5150(to_sd(ctrl));
 
 	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
-		tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->val);
+		regmap_write(decoder->regmap, TVP5150_BRIGHT_CTL, ctrl->val);
 		return 0;
 	case V4L2_CID_CONTRAST:
-		tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->val);
+		regmap_write(decoder->regmap, TVP5150_CONTRAST_CTL, ctrl->val);
 		return 0;
 	case V4L2_CID_SATURATION:
-		tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->val);
+		regmap_write(decoder->regmap, TVP5150_SATURATION_CTL, ctrl->val);
 		return 0;
 	case V4L2_CID_HUE:
-		tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val);
+		regmap_write(decoder->regmap, TVP5150_HUE_CTL, ctrl->val);
 		return 0;
 	}
 	return -EINVAL;
@@ -890,17 +880,17 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
 			      hmax - TVP5150_MAX_CROP_TOP - rect.top,
 			      hmax - rect.top);
 
-	tvp5150_write(sd, TVP5150_VERT_BLANKING_START, rect.top);
-	tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP,
+	regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START, rect.top);
+	regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP,
 		      rect.top + rect.height - hmax);
-	tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_MSB,
+	regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_MSB,
 		      rect.left >> TVP5150_CROP_SHIFT);
-	tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_LSB,
+	regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_LSB,
 		      rect.left | (1 << TVP5150_CROP_SHIFT));
-	tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_MSB,
+	regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_MSB,
 		      (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >>
 		      TVP5150_CROP_SHIFT);
-	tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_LSB,
+	regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_LSB,
 		      rect.left + rect.width - TVP5150_MAX_CROP_LEFT);
 
 	decoder->rect = rect;
@@ -965,22 +955,25 @@ static int tvp5150_s_routing(struct v4l2_subdev *sd,
 
 static int tvp5150_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
 {
+	struct tvp5150 *decoder = to_tvp5150(sd);
+
 	/* this is for capturing 36 raw vbi lines
 	   if there's a way to cut off the beginning 2 vbi lines
 	   with the tvp5150 then the vbi line count could be lowered
 	   to 17 lines/field again, although I couldn't find a register
 	   which could do that cropping */
 	if (fmt->sample_format == V4L2_PIX_FMT_GREY)
-		tvp5150_write(sd, TVP5150_LUMA_PROC_CTL_1, 0x70);
+		regmap_write(decoder->regmap, TVP5150_LUMA_PROC_CTL_1, 0x70);
 	if (fmt->count[0] == 18 && fmt->count[1] == 18) {
-		tvp5150_write(sd, TVP5150_VERT_BLANKING_START, 0x00);
-		tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 0x01);
+		regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START, 0x00);
+		regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP, 0x01);
 	}
 	return 0;
 }
 
 static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi)
 {
+	struct tvp5150 *decoder = to_tvp5150(sd);
 	int i;
 
 	if (svbi->service_set != 0) {
@@ -991,17 +984,17 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f
 				       svbi->service_lines[0][i], 0xf0, i, 3);
 		}
 		/* Enables FIFO */
-		tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1);
+		regmap_write(decoder->regmap, TVP5150_FIFO_OUT_CTRL, 1);
 	} else {
 		/* Disables FIFO*/
-		tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 0);
+		regmap_write(decoder->regmap, TVP5150_FIFO_OUT_CTRL, 0);
 
 		/* Disable Full Field */
-		tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0);
+		regmap_write(decoder->regmap, TVP5150_FULL_FIELD_ENA, 0);
 
 		/* Disable Line modes */
 		for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++)
-			tvp5150_write(sd, i, 0xff);
+			regmap_write(decoder->regmap, i, 0xff);
 	}
 	return 0;
 }
@@ -1039,7 +1032,9 @@ static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
 
 static int tvp5150_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff);
+	struct tvp5150 *decoder = to_tvp5150(sd);
+
+	regmap_write(decoder->regmap, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
@@ -1105,13 +1100,87 @@ static const struct v4l2_subdev_ops tvp5150_ops = {
 			I2C Client & Driver
  ****************************************************************************/
 
+static const struct regmap_range tvp5150_readable_ranges[] = {
+	{
+		.range_min = TVP5150_VD_IN_SRC_SEL_1,
+		.range_max = TVP5150_AUTOSW_MSK,
+	}, {
+		.range_min = TVP5150_COLOR_KIL_THSH_CTL,
+		.range_max = TVP5150_CONF_SHARED_PIN,
+	}, {
+		.range_min = TVP5150_ACT_VD_CROP_ST_MSB,
+		.range_max = TVP5150_HORIZ_SYNC_START,
+	}, {
+		.range_min = TVP5150_VERT_BLANKING_START,
+		.range_max = TVP5150_INTT_CONFIG_REG_B,
+	}, {
+		.range_min = TVP5150_VIDEO_STD,
+		.range_max = TVP5150_VIDEO_STD,
+	}, {
+		.range_min = TVP5150_CB_GAIN_FACT,
+		.range_max = TVP5150_REV_SELECT,
+	}, {
+		.range_min = TVP5150_MSB_DEV_ID,
+		.range_max = TVP5150_STATUS_REG_5,
+	}, {
+		.range_min = TVP5150_CC_DATA_INI,
+		.range_max = TVP5150_TELETEXT_FIL_ENA,
+	}, {
+		.range_min = TVP5150_INT_STATUS_REG_A,
+		.range_max = TVP5150_FIFO_OUT_CTRL,
+	}, {
+		.range_min = TVP5150_FULL_FIELD_ENA,
+		.range_max = TVP5150_FULL_FIELD_MODE_REG,
+	},
+};
+
+bool tvp5150_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TVP5150_VERT_LN_COUNT_MSB:
+	case TVP5150_VERT_LN_COUNT_LSB:
+	case TVP5150_INT_STATUS_REG_A:
+	case TVP5150_INT_STATUS_REG_B:
+	case TVP5150_INT_ACTIVE_REG_B:
+	case TVP5150_STATUS_REG_1:
+	case TVP5150_STATUS_REG_2:
+	case TVP5150_STATUS_REG_3:
+	case TVP5150_STATUS_REG_4:
+	case TVP5150_STATUS_REG_5:
+	/* CC, WSS, VPS, VITC data? */
+	case TVP5150_VBI_FIFO_READ_DATA:
+	case TVP5150_VDP_STATUS_REG:
+	case TVP5150_FIFO_WORD_COUNT:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_access_table tvp5150_readable_table = {
+	.yes_ranges = tvp5150_readable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(tvp5150_readable_ranges),
+};
+
+static struct regmap_config tvp5150_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0xff,
+
+	.cache_type = REGCACHE_RBTREE,
+
+	.rd_table = &tvp5150_readable_table,
+	.volatile_reg = tvp5150_volatile_reg,
+};
+
 static int tvp5150_probe(struct i2c_client *c,
 			 const struct i2c_device_id *id)
 {
 	struct tvp5150 *core;
 	struct v4l2_subdev *sd;
-	int tvp5150_id[4];
-	int i, res;
+	struct regmap *map;
+	u8 tvp5150_id[4];
+	int res;
 
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(c->adapter,
@@ -1121,6 +1190,10 @@ static int tvp5150_probe(struct i2c_client *c,
 	core = devm_kzalloc(&c->dev, sizeof(*core), GFP_KERNEL);
 	if (!core)
 		return -ENOMEM;
+	map = devm_regmap_init_i2c(c, &tvp5150_config);
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+	core->regmap = map;
 	sd = &core->sd;
 	v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
 
@@ -1128,11 +1201,10 @@ static int tvp5150_probe(struct i2c_client *c,
 	 * Read consequent registers - TVP5150_MSB_DEV_ID, TVP5150_LSB_DEV_ID,
 	 * TVP5150_ROM_MAJOR_VER, TVP5150_ROM_MINOR_VER 
 	 */
-	for (i = 0; i < 4; i++) {
-		res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
-		if (res < 0)
-			return res;
-		tvp5150_id[i] = res;
+	res = regmap_bulk_read(map, TVP5150_MSB_DEV_ID, tvp5150_id, 4);
+	if (res < 0) {
+		dev_err(&c->dev, "reading ID registers failed: %d\n", res);
+		return res;
 	}
 
 	v4l_info(c, "chip found @ 0x%02x (%s)\n",
@@ -1143,7 +1215,7 @@ static int tvp5150_probe(struct i2c_client *c,
 			  tvp5150_id[0], tvp5150_id[1]);
 
 		/* ITU-T BT.656.4 timing */
-		tvp5150_write(sd, TVP5150_REV_SELECT, 0);
+		regmap_write(map, TVP5150_REV_SELECT, 0);
 	} else {
 		/* Is TVP5150A */
 		if (tvp5150_id[2] == 3 || tvp5150_id[3] == 0x21) {
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/9] [media] tvp5150: add userspace subdev API
  2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
@ 2015-11-18 16:55 ` Lucas Stach
  2015-11-18 17:06   ` kbuild test robot
  2015-11-18 17:08   ` kbuild test robot
  2015-11-18 16:55 ` [PATCH 3/9] [media] tvp5150: determine BT.656 or YUV 4:2:2 mode from device tree Lucas Stach
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

This patch adds userspace V4L2 subdevice API support.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c | 259 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 200 insertions(+), 59 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index a7495d2856c3..8670b478dcd6 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -36,7 +36,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
 
 struct tvp5150 {
 	struct v4l2_subdev sd;
+	struct media_pad pad;
 	struct v4l2_ctrl_handler hdl;
+	struct v4l2_mbus_framefmt format;
 	struct v4l2_rect rect;
 	struct regmap *regmap;
 
@@ -819,38 +821,68 @@ static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
-		struct v4l2_subdev_pad_config *cfg,
-		struct v4l2_subdev_format *format)
+static void tvp5150_try_crop(struct tvp5150 *decoder, struct v4l2_rect *rect,
+			       v4l2_std_id std)
 {
-	struct v4l2_mbus_framefmt *f;
-	struct tvp5150 *decoder = to_tvp5150(sd);
+	unsigned int hmax;
 
-	if (!format || format->pad)
-		return -EINVAL;
+	/* Clamp the crop rectangle boundaries to tvp5150 limits */
+	rect->left = clamp(rect->left, 0, TVP5150_MAX_CROP_LEFT);
+	rect->width = clamp(rect->width,
+			    TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect->left,
+			    TVP5150_H_MAX - rect->left);
+	rect->top = clamp(rect->top, 0, TVP5150_MAX_CROP_TOP);
 
-	f = &format->format;
+	/* tvp5150 has some special limits */
+	rect->left = clamp(rect->left, 0, TVP5150_MAX_CROP_LEFT);
+	rect->width = clamp_t(unsigned int, rect->width,
+			      TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect->left,
+			      TVP5150_H_MAX - rect->left);
+	rect->top = clamp(rect->top, 0, TVP5150_MAX_CROP_TOP);
 
-	tvp5150_reset(sd, 0);
+	/* Calculate height based on current standard */
+	if (std & V4L2_STD_525_60)
+		hmax = TVP5150_V_MAX_525_60;
+	else
+		hmax = TVP5150_V_MAX_OTHERS;
 
-	f->width = decoder->rect.width;
-	f->height = decoder->rect.height;
+	rect->height = clamp(rect->height,
+			     hmax - TVP5150_MAX_CROP_TOP - rect->top,
+			     hmax - rect->top);
+}
 
-	f->code = MEDIA_BUS_FMT_UYVY8_2X8;
-	f->field = V4L2_FIELD_SEQ_TB;
-	f->colorspace = V4L2_COLORSPACE_SMPTE170M;
+static void tvp5150_set_crop(struct tvp5150 *decoder, struct v4l2_rect *rect,
+			       v4l2_std_id std)
+{
+	struct regmap *map = decoder->regmap;
+	unsigned int hmax;
 
-	v4l2_dbg(1, debug, sd, "width = %d, height = %d\n", f->width,
-			f->height);
-	return 0;
+	if (std & V4L2_STD_525_60)
+		hmax = TVP5150_V_MAX_525_60;
+	else
+		hmax = TVP5150_V_MAX_OTHERS;
+
+	regmap_write(map, TVP5150_VERT_BLANKING_START, rect->top);
+	regmap_write(map, TVP5150_VERT_BLANKING_STOP,
+		     rect->top + rect->height - hmax);
+	regmap_write(map, TVP5150_ACT_VD_CROP_ST_MSB,
+		     rect->left >> TVP5150_CROP_SHIFT);
+	regmap_write(map, TVP5150_ACT_VD_CROP_ST_LSB,
+		     rect->left | (1 << TVP5150_CROP_SHIFT));
+	regmap_write(map, TVP5150_ACT_VD_CROP_STP_MSB,
+		     (rect->left + rect->width - TVP5150_MAX_CROP_LEFT) >>
+		     TVP5150_CROP_SHIFT);
+	regmap_write(map, TVP5150_ACT_VD_CROP_STP_LSB,
+		     rect->left + rect->width - TVP5150_MAX_CROP_LEFT);
+
+	decoder->rect = *rect;
 }
 
 static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
 {
-	struct v4l2_rect rect = a->c;
 	struct tvp5150 *decoder = to_tvp5150(sd);
+	struct v4l2_rect rect = a->c;
 	v4l2_std_id std;
-	unsigned int hmax;
 
 	v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n",
 		__func__, rect.left, rect.top, rect.width, rect.height);
@@ -858,42 +890,13 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	/* tvp5150 has some special limits */
-	rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT);
-	rect.width = clamp_t(unsigned int, rect.width,
-			     TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left,
-			     TVP5150_H_MAX - rect.left);
-	rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP);
-
-	/* Calculate height based on current standard */
 	if (decoder->norm == V4L2_STD_ALL)
 		std = tvp5150_read_std(sd);
 	else
 		std = decoder->norm;
 
-	if (std & V4L2_STD_525_60)
-		hmax = TVP5150_V_MAX_525_60;
-	else
-		hmax = TVP5150_V_MAX_OTHERS;
-
-	rect.height = clamp_t(unsigned int, rect.height,
-			      hmax - TVP5150_MAX_CROP_TOP - rect.top,
-			      hmax - rect.top);
-
-	regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START, rect.top);
-	regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP,
-		      rect.top + rect.height - hmax);
-	regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_MSB,
-		      rect.left >> TVP5150_CROP_SHIFT);
-	regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_LSB,
-		      rect.left | (1 << TVP5150_CROP_SHIFT));
-	regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_MSB,
-		      (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >>
-		      TVP5150_CROP_SHIFT);
-	regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_LSB,
-		      rect.left + rect.width - TVP5150_MAX_CROP_LEFT);
-
-	decoder->rect = rect;
+	tvp5150_try_crop(decoder, &rect, std);
+	tvp5150_set_crop(decoder, &rect, std);
 
 	return 0;
 }
@@ -1049,6 +1052,138 @@ static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 
 /* ----------------------------------------------------------------------- */
 
+static struct v4l2_mbus_framefmt *
+tvp5150_get_pad_format(struct tvp5150 *decoder, struct v4l2_subdev *sd,
+			 struct v4l2_subdev_pad_config *cfg, unsigned int pad,
+			 enum v4l2_subdev_format_whence which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_format(sd, cfg, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &decoder->format;
+	default:
+		return NULL;
+	}
+}
+
+static struct v4l2_rect *
+tvp5150_get_pad_crop(struct tvp5150 *decoder, struct v4l2_subdev *sd,
+		       struct v4l2_subdev_pad_config *cfg, unsigned int pad,
+		       enum v4l2_subdev_format_whence which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_crop(sd, cfg, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &decoder->rect;
+	default:
+		return NULL;
+	}
+}
+
+static int tvp5150_enum_frame_size(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct tvp5150 *decoder = to_tvp5150(sd);
+	v4l2_std_id std;
+
+	if (fse->index > 0 || fse->code != MEDIA_BUS_FMT_UYVY8_2X8)
+		return -EINVAL;
+
+	fse->min_width = TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT;
+	fse->max_width = TVP5150_H_MAX;
+
+	/* Calculate height based on current standard */
+	if (decoder->norm == V4L2_STD_ALL)
+		std = tvp5150_read_std(sd);
+	else
+		std = decoder->norm;
+
+	if (std & V4L2_STD_525_60) {
+		fse->min_height = TVP5150_V_MAX_525_60 - TVP5150_MAX_CROP_TOP;
+		fse->max_height = TVP5150_V_MAX_525_60;
+	} else {
+		fse->min_height = TVP5150_V_MAX_OTHERS - TVP5150_MAX_CROP_TOP;
+		fse->max_height = TVP5150_V_MAX_OTHERS;
+	}
+
+	return 0;
+}
+
+static int tvp5150_get_format(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_pad_config *cfg,
+			      struct v4l2_subdev_format *format)
+{
+	struct tvp5150 *decoder = to_tvp5150(sd);
+
+	format->format = *tvp5150_get_pad_format(decoder, sd, cfg,
+						   format->pad, format->which);
+	return 0;
+}
+
+static int tvp5150_set_format(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_pad_config *cfg,
+			      struct v4l2_subdev_format *format)
+{
+	struct tvp5150 *decoder = to_tvp5150(sd);
+	struct v4l2_mbus_framefmt *mbus_format;
+	struct v4l2_rect *crop;
+
+	crop = tvp5150_get_pad_crop(decoder, sd, cfg, format->pad,
+					format->which);
+	mbus_format = tvp5150_get_pad_format(decoder, sd, cfg, format->pad,
+					    format->which);
+	mbus_format->width = crop->width;
+	mbus_format->height = crop->height;
+
+	format->format = *mbus_format;
+
+	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+		tvp5150_reset(sd, 0);
+
+	v4l2_dbg(1, debug, sd, "width = %d, height = %d\n", mbus_format->width,
+			mbus_format->height);
+
+	return 0;
+}
+
+static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop,
+				struct v4l2_mbus_framefmt *format)
+{
+	crop->left = 0;
+	crop->width = TVP5150_H_MAX;
+	crop->top = 0;
+	if (std & V4L2_STD_525_60)
+		crop->height = TVP5150_V_MAX_525_60;
+	else
+		crop->height = TVP5150_V_MAX_OTHERS;
+
+	format->width = crop->width;
+	format->height = crop->height;
+	format->code = MEDIA_BUS_FMT_UYVY8_2X8;
+	format->field = V4L2_FIELD_SEQ_TB;
+	format->colorspace = V4L2_COLORSPACE_SMPTE170M;
+}
+
+static int tvp5150_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct tvp5150 *decoder = to_tvp5150(sd);
+	v4l2_std_id std;
+
+	if (decoder->norm == V4L2_STD_ALL)
+		std = tvp5150_read_std(sd);
+	else
+		std = decoder->norm;
+
+	tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
+				 v4l2_subdev_get_try_format(fh, 0));
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
 static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
 	.s_ctrl = tvp5150_s_ctrl,
 };
@@ -1083,8 +1218,9 @@ static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
 
 static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = {
 	.enum_mbus_code = tvp5150_enum_mbus_code,
-	.set_fmt = tvp5150_fill_fmt,
-	.get_fmt = tvp5150_fill_fmt,
+	.enum_frame_size = tvp5150_enum_frame_size,
+	.get_fmt = tvp5150_get_format,
+	.set_fmt = tvp5150_set_format,
 };
 
 static const struct v4l2_subdev_ops tvp5150_ops = {
@@ -1095,6 +1231,9 @@ static const struct v4l2_subdev_ops tvp5150_ops = {
 	.pad = &tvp5150_pad_ops,
 };
 
+static const struct v4l2_subdev_internal_ops tvp5150_internal_ops = {
+	.open = tvp5150_open,
+};
 
 /****************************************************************************
 			I2C Client & Driver
@@ -1196,6 +1335,13 @@ static int tvp5150_probe(struct i2c_client *c,
 	core->regmap = map;
 	sd = &core->sd;
 	v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
+	sd->internal_ops = &tvp5150_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
+	core->pad.flags = MEDIA_PAD_FL_SOURCE;
+	res = media_entity_init(&sd->entity, 1, &core->pad, 0);
+	if (res < 0)
+		return res;
 
 	/* 
 	 * Read consequent registers - TVP5150_MSB_DEV_ID, TVP5150_LSB_DEV_ID,
@@ -1250,14 +1396,9 @@ static int tvp5150_probe(struct i2c_client *c,
 	v4l2_ctrl_handler_setup(&core->hdl);
 
 	/* Default is no cropping */
-	core->rect.top = 0;
-	if (tvp5150_read_std(sd) & V4L2_STD_525_60)
-		core->rect.height = TVP5150_V_MAX_525_60;
-	else
-		core->rect.height = TVP5150_V_MAX_OTHERS;
-	core->rect.left = 0;
-	core->rect.width = TVP5150_H_MAX;
+	tvp5150_set_default(tvp5150_read_std(sd), &core->rect, &core->format);
 
+	sd->dev = &c->dev;
 	res = v4l2_async_register_subdev(sd);
 	if (res < 0)
 		goto err;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/9] [media] tvp5150: determine BT.656 or YUV 4:2:2 mode from device tree
  2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
  2015-11-18 16:55 ` [PATCH 2/9] [media] tvp5150: add userspace subdev API Lucas Stach
@ 2015-11-18 16:55 ` Lucas Stach
  2015-11-18 16:55 ` [PATCH 4/9] [media] tvp5150: fix standard autodetection Lucas Stach
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

By looking at the endpoint flags, it can be determined whether the link
should be of V4L2_MBUS_PARALLEL or V4L2_MBUS_BT656 type. Disable the
dedicated HSYNC/VSYNC outputs in BT.656 mode.

For devices that are not instantiated through DT the current behavior
is preserved.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 8670b478dcd6..21cde350e385 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -11,10 +11,12 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
+#include <linux/of_graph.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
 #include <media/tvp5150.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-of.h>
 
 #include "tvp5150_reg.h"
 
@@ -38,6 +40,7 @@ struct tvp5150 {
 	struct v4l2_subdev sd;
 	struct media_pad pad;
 	struct v4l2_ctrl_handler hdl;
+	enum v4l2_mbus_type bus_type;
 	struct v4l2_mbus_framefmt format;
 	struct v4l2_rect rect;
 	struct regmap *regmap;
@@ -424,8 +427,6 @@ static const struct i2c_reg_value tvp5150_init_enable[] = {
 		TVP5150_MISC_CTL, 0x6f
 	},{	/* Activates video std autodetection for all standards */
 		TVP5150_AUTOSW_MSK, 0x0
-	},{	/* Default format: 0x47. For 4:2:2: 0x40 */
-		TVP5150_DATA_RATE_SEL, 0x47
 	},{
 		TVP5150_CHROMA_PROC_CTL_1, 0x0c
 	},{
@@ -760,6 +761,25 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 	/* Initializes TVP5150 to stream enabled values */
 	tvp5150_write_inittab(sd, tvp5150_init_enable);
 
+	switch (decoder->bus_type) {
+	case V4L2_MBUS_BT656:
+		/* 8-bit ITU BT.656 */
+		regmap_update_bits(decoder->regmap, TVP5150_DATA_RATE_SEL,
+				   0x7, 0x7);
+		/* disable HSYNC, VSYNC/PALI, AVID, and FID/GLCO */
+		regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, 0x4, 0x0);
+		break;
+	case V4L2_MBUS_PARALLEL:
+		/* 8-bit YUV 4:2:2 */
+		regmap_update_bits(decoder->regmap, TVP5150_DATA_RATE_SEL,
+				   0x7, 0x0);
+		/* enable HSYNC, VSYNC/PALI, AVID, and FID/GLCO */
+		regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, 0x4, 0x4);
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	/* Initialize image preferences */
 	v4l2_ctrl_handler_setup(&decoder->hdl);
 
@@ -1315,6 +1335,8 @@ static struct regmap_config tvp5150_config = {
 static int tvp5150_probe(struct i2c_client *c,
 			 const struct i2c_device_id *id)
 {
+	struct v4l2_of_endpoint bus_cfg;
+	struct device_node *endpoint;
 	struct tvp5150 *core;
 	struct v4l2_subdev *sd;
 	struct regmap *map;
@@ -1375,6 +1397,14 @@ static int tvp5150_probe(struct i2c_client *c,
 		}
 	}
 
+	endpoint = of_graph_get_next_endpoint(c->dev.of_node, NULL);
+	if (endpoint) {
+		v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+		core->bus_type = bus_cfg.bus_type;
+	} else {
+		core->bus_type = V4L2_MBUS_BT656;
+	}
+
 	core->norm = V4L2_STD_ALL;	/* Default is autodetect */
 	core->input = TVP5150_COMPOSITE1;
 	core->enable = 1;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/9] [media] tvp5150: fix standard autodetection
  2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
  2015-11-18 16:55 ` [PATCH 2/9] [media] tvp5150: add userspace subdev API Lucas Stach
  2015-11-18 16:55 ` [PATCH 3/9] [media] tvp5150: determine BT.656 or YUV 4:2:2 mode from device tree Lucas Stach
@ 2015-11-18 16:55 ` Lucas Stach
  2015-11-18 16:55 ` [PATCH 5/9] [media] tvp5150: split reset/enable routine Lucas Stach
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

Make sure to not overwrite decoder->norm when setting the standard
in hardware, but only when instructed by V4L2 API calls.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c | 56 +++++++++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 25 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 21cde350e385..b943b9cc24c8 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -703,8 +703,6 @@ static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
 	struct tvp5150 *decoder = to_tvp5150(sd);
 	int fmt = 0;
 
-	decoder->norm = std;
-
 	/* First tests should be against specific std */
 
 	if (std == V4L2_STD_NTSC_443) {
@@ -741,13 +739,37 @@ static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 	else
 		decoder->rect.height = TVP5150_V_MAX_OTHERS;
 
+	decoder->norm = std;
 
 	return tvp5150_set_std(sd, std);
 }
 
+static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
+{
+	int val = tvp5150_read(sd, TVP5150_STATUS_REG_5);
+
+	switch (val & 0x0F) {
+	case 0x01:
+		return V4L2_STD_NTSC;
+	case 0x03:
+		return V4L2_STD_PAL;
+	case 0x05:
+		return V4L2_STD_PAL_M;
+	case 0x07:
+		return V4L2_STD_PAL_N | V4L2_STD_PAL_Nc;
+	case 0x09:
+		return V4L2_STD_NTSC_443;
+	case 0xb:
+		return V4L2_STD_SECAM;
+	default:
+		return V4L2_STD_UNKNOWN;
+	}
+}
+
 static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 {
 	struct tvp5150 *decoder = to_tvp5150(sd);
+	v4l2_std_id std;
 
 	/* Initializes TVP5150 to its default values */
 	tvp5150_write_inittab(sd, tvp5150_init_default);
@@ -783,7 +805,13 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 	/* Initialize image preferences */
 	v4l2_ctrl_handler_setup(&decoder->hdl);
 
-	tvp5150_set_std(sd, decoder->norm);
+	if (decoder->norm == V4L2_STD_ALL)
+		std = tvp5150_read_std(sd);
+	else
+		std = decoder->norm;
+
+	/* Disable autoswitch mode */
+	tvp5150_set_std(sd, std);
 	return 0;
 };
 
@@ -808,28 +836,6 @@ static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
 	return -EINVAL;
 }
 
-static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
-{
-	int val = tvp5150_read(sd, TVP5150_STATUS_REG_5);
-
-	switch (val & 0x0F) {
-	case 0x01:
-		return V4L2_STD_NTSC;
-	case 0x03:
-		return V4L2_STD_PAL;
-	case 0x05:
-		return V4L2_STD_PAL_M;
-	case 0x07:
-		return V4L2_STD_PAL_N | V4L2_STD_PAL_Nc;
-	case 0x09:
-		return V4L2_STD_NTSC_443;
-	case 0xb:
-		return V4L2_STD_SECAM;
-	default:
-		return V4L2_STD_UNKNOWN;
-	}
-}
-
 static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd,
 		struct v4l2_subdev_pad_config *cfg,
 		struct v4l2_subdev_mbus_code_enum *code)
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/9] [media] tvp5150: split reset/enable routine
  2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
                   ` (2 preceding siblings ...)
  2015-11-18 16:55 ` [PATCH 4/9] [media] tvp5150: fix standard autodetection Lucas Stach
@ 2015-11-18 16:55 ` Lucas Stach
  2015-11-18 16:55 ` [PATCH 6/9] [media] tvp5150: trigger autodetection on subdev open to reset cropping Lucas Stach
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

To trigger standard autodetection only the reset part of the routine
is necessary. Split this out to make it callable on its own.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index b943b9cc24c8..b6328353404f 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -768,9 +768,6 @@ static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
 
 static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 {
-	struct tvp5150 *decoder = to_tvp5150(sd);
-	v4l2_std_id std;
-
 	/* Initializes TVP5150 to its default values */
 	tvp5150_write_inittab(sd, tvp5150_init_default);
 
@@ -780,6 +777,14 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 	/* Selects decoder input */
 	tvp5150_selmux(sd);
 
+	return 0;
+}
+
+static int tvp5150_enable(struct v4l2_subdev *sd)
+{
+	struct tvp5150 *decoder = to_tvp5150(sd);
+	v4l2_std_id std;
+
 	/* Initializes TVP5150 to stream enabled values */
 	tvp5150_write_inittab(sd, tvp5150_init_enable);
 
@@ -844,6 +849,7 @@ static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd,
 		return -EINVAL;
 
 	code->code = MEDIA_BUS_FMT_UYVY8_2X8;
+
 	return 0;
 }
 
@@ -1166,8 +1172,10 @@ static int tvp5150_set_format(struct v4l2_subdev *sd,
 
 	format->format = *mbus_format;
 
-	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
 		tvp5150_reset(sd, 0);
+		tvp5150_enable(sd);
+	}
 
 	v4l2_dbg(1, debug, sd, "width = %d, height = %d\n", mbus_format->width,
 			mbus_format->height);
@@ -1431,6 +1439,7 @@ static int tvp5150_probe(struct i2c_client *c,
 	}
 	v4l2_ctrl_handler_setup(&core->hdl);
 
+	tvp5150_reset(sd, 0);
 	/* Default is no cropping */
 	tvp5150_set_default(tvp5150_read_std(sd), &core->rect, &core->format);
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/9] [media] tvp5150: trigger autodetection on subdev open to reset cropping
  2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
                   ` (3 preceding siblings ...)
  2015-11-18 16:55 ` [PATCH 5/9] [media] tvp5150: split reset/enable routine Lucas Stach
@ 2015-11-18 16:55 ` Lucas Stach
  2015-11-18 16:55 ` [PATCH 7/9] [media] tvp5150: remove pin configuration from initialization tables Lucas Stach
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

If cropping isn't set explicitly by userspace, reset it to the maximum
possible rectangle in subdevice open if a standard change is detected.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index b6328353404f..791572737ee3 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -46,6 +46,7 @@ struct tvp5150 {
 	struct regmap *regmap;
 
 	v4l2_std_id norm;	/* Current set standard */
+	v4l2_std_id detected_norm;
 	u32 input;
 	u32 output;
 	int enable;
@@ -1206,13 +1207,19 @@ static int tvp5150_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 	struct tvp5150 *decoder = to_tvp5150(sd);
 	v4l2_std_id std;
 
-	if (decoder->norm == V4L2_STD_ALL)
+	if (decoder->norm == V4L2_STD_ALL) {
 		std = tvp5150_read_std(sd);
-	else
-		std = decoder->norm;
+		if (std != decoder->detected_norm) {
+			decoder->detected_norm = std;
+
+			if (std & V4L2_STD_525_60)
+				decoder->rect.height = TVP5150_V_MAX_525_60;
+			else
+				decoder->rect.height = TVP5150_V_MAX_OTHERS;
+			decoder->format.height = decoder->rect.height;
+		}
+	}
 
-	tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
-				 v4l2_subdev_get_try_format(fh, 0));
 	return 0;
 }
 
@@ -1420,6 +1427,7 @@ static int tvp5150_probe(struct i2c_client *c,
 	}
 
 	core->norm = V4L2_STD_ALL;	/* Default is autodetect */
+	core->detected_norm = V4L2_STD_UNKNOWN;
 	core->input = TVP5150_COMPOSITE1;
 	core->enable = 1;
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/9] [media] tvp5150: remove pin configuration from initialization tables
  2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
                   ` (4 preceding siblings ...)
  2015-11-18 16:55 ` [PATCH 6/9] [media] tvp5150: trigger autodetection on subdev open to reset cropping Lucas Stach
@ 2015-11-18 16:55 ` Lucas Stach
  2015-11-18 16:55 ` [PATCH 8/9] [media] tvp5150: Add sync lock interrupt handling Lucas Stach
  2015-11-18 16:55 ` [PATCH 9/9] [media] tvp5150: disable output while signal not locked Lucas Stach
  7 siblings, 0 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

To allow optional interrupt support, we want to configure the pin settings
dynamically. Move those register accesses out of the static initialization
tables.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c     | 19 +++++++------------
 drivers/media/i2c/tvp5150_reg.h |  1 +
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 791572737ee3..abea26eb6fe0 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -323,9 +323,6 @@ static const struct i2c_reg_value tvp5150_init_default[] = {
 	{ /* 0x0e */
 		TVP5150_LUMA_PROC_CTL_3,0x00
 	},
-	{ /* 0x0f */
-		TVP5150_CONF_SHARED_PIN,0x08
-	},
 	{ /* 0x11 */
 		TVP5150_ACT_VD_CROP_ST_MSB,0x00
 	},
@@ -362,9 +359,6 @@ static const struct i2c_reg_value tvp5150_init_default[] = {
 	{ /* 0x1d */
 		TVP5150_INT_ENABLE_REG_B,0x00
 	},
-	{ /* 0x1e */
-		TVP5150_INTT_CONFIG_REG_B,0x00
-	},
 	{ /* 0x28 */
 		TVP5150_VIDEO_STD,0x00
 	},
@@ -383,9 +377,6 @@ static const struct i2c_reg_value tvp5150_init_default[] = {
 	{ /* 0xc1 */
 		TVP5150_INT_ENABLE_REG_A,0x00
 	},
-	{ /* 0xc2 */
-		TVP5150_INT_CONF,0x04
-	},
 	{ /* 0xc8 */
 		TVP5150_FIFO_INT_THRESHOLD,0x80
 	},
@@ -420,9 +411,7 @@ static const struct i2c_reg_value tvp5150_init_default[] = {
 
 /* Default values as sugested at TVP5150AM1 datasheet */
 static const struct i2c_reg_value tvp5150_init_enable[] = {
-	{
-		TVP5150_CONF_SHARED_PIN, 2
-	},{	/* Automatic offset and AGC enabled */
+	{	/* Automatic offset and AGC enabled */
 		TVP5150_ANAL_CHL_CTL, 0x15
 	},{	/* Activate YCrCb output 0x9 or 0xd ? */
 		TVP5150_MISC_CTL, 0x6f
@@ -772,6 +761,12 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 	/* Initializes TVP5150 to its default values */
 	tvp5150_write_inittab(sd, tvp5150_init_default);
 
+	/* Configure pins: FID, VSYNC, GPCL/VBLK, SCLK */
+	regmap_write(map, TVP5150_CONF_SHARED_PIN, 0x2);
+	/* Keep interrupt polarity active low */
+	regmap_write(map, TVP5150_INT_CONF, TVP5150_VDPOE);
+	regmap_write(map, TVP5150_INTT_CONFIG_REG_B, 0x0);
+
 	/* Initializes VDP registers */
 	tvp5150_vdp_init(sd, vbi_ram_default);
 
diff --git a/drivers/media/i2c/tvp5150_reg.h b/drivers/media/i2c/tvp5150_reg.h
index 25a994944918..fc3bcb26413a 100644
--- a/drivers/media/i2c/tvp5150_reg.h
+++ b/drivers/media/i2c/tvp5150_reg.h
@@ -117,6 +117,7 @@
 #define TVP5150_INT_STATUS_REG_A    0xc0 /* Interrupt status register A */
 #define TVP5150_INT_ENABLE_REG_A    0xc1 /* Interrupt enable register A */
 #define TVP5150_INT_CONF            0xc2 /* Interrupt configuration */
+#define   TVP5150_VDPOE             BIT(2)
 #define TVP5150_VDP_CONF_RAM_DATA   0xc3 /* VDP configuration RAM data */
 #define TVP5150_CONF_RAM_ADDR_LOW   0xc4 /* Configuration RAM address low byte */
 #define TVP5150_CONF_RAM_ADDR_HIGH  0xc5 /* Configuration RAM address high byte */
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 8/9] [media] tvp5150: Add sync lock interrupt handling
  2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
                   ` (5 preceding siblings ...)
  2015-11-18 16:55 ` [PATCH 7/9] [media] tvp5150: remove pin configuration from initialization tables Lucas Stach
@ 2015-11-18 16:55 ` Lucas Stach
  2015-11-18 16:55 ` [PATCH 9/9] [media] tvp5150: disable output while signal not locked Lucas Stach
  7 siblings, 0 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

This patch adds an optional interrupt handler to handle the sync
lock interrupt and sync lock status.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c     | 103 ++++++++++++++++++++++++++++++++++++++--
 drivers/media/i2c/tvp5150_reg.h |   2 +
 2 files changed, 100 insertions(+), 5 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index abea26eb6fe0..9e006bf36e67 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/delay.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
 #include <linux/of_graph.h>
@@ -44,12 +45,14 @@ struct tvp5150 {
 	struct v4l2_mbus_framefmt format;
 	struct v4l2_rect rect;
 	struct regmap *regmap;
+	int irq;
 
 	v4l2_std_id norm;	/* Current set standard */
 	v4l2_std_id detected_norm;
 	u32 input;
 	u32 output;
 	int enable;
+	bool lock;
 };
 
 static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
@@ -716,6 +719,15 @@ static int tvp5150_set_std(struct v4l2_subdev *sd, v4l2_std_id std)
 	return 0;
 }
 
+static int tvp5150_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	struct tvp5150 *decoder = to_tvp5150(sd);
+
+	*std = decoder->norm;
+
+	return 0;
+}
+
 static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 {
 	struct tvp5150 *decoder = to_tvp5150(sd);
@@ -758,14 +770,25 @@ static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd)
 
 static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 {
+	struct tvp5150 *decoder = to_tvp5150(sd);
+	struct regmap *map = decoder->regmap;
+
 	/* Initializes TVP5150 to its default values */
 	tvp5150_write_inittab(sd, tvp5150_init_default);
 
-	/* Configure pins: FID, VSYNC, GPCL/VBLK, SCLK */
-	regmap_write(map, TVP5150_CONF_SHARED_PIN, 0x2);
-	/* Keep interrupt polarity active low */
-	regmap_write(map, TVP5150_INT_CONF, TVP5150_VDPOE);
-	regmap_write(map, TVP5150_INTT_CONFIG_REG_B, 0x0);
+	if (decoder->irq) {
+		/* Configure pins: FID, VSYNC, INTREQ, SCLK */
+		regmap_write(map, TVP5150_CONF_SHARED_PIN, 0x0);
+		/* Set interrupt polarity to active high */
+		regmap_write(map, TVP5150_INT_CONF, TVP5150_VDPOE | 0x1);
+		regmap_write(map, TVP5150_INTT_CONFIG_REG_B, 0x1);
+	} else {
+		/* Configure pins: FID, VSYNC, GPCL/VBLK, SCLK */
+		regmap_write(map, TVP5150_CONF_SHARED_PIN, 0x2);
+		/* Keep interrupt polarity active low */
+		regmap_write(map, TVP5150_INT_CONF, TVP5150_VDPOE);
+		regmap_write(map, TVP5150_INTT_CONFIG_REG_B, 0x0);
+	}
 
 	/* Initializes VDP registers */
 	tvp5150_vdp_init(sd, vbi_ram_default);
@@ -776,6 +799,33 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
 	return 0;
 }
 
+static irqreturn_t tvp5150_isr(int irq, void *dev_id)
+{
+	struct tvp5150 *decoder = dev_id;
+	struct regmap *map = decoder->regmap;
+	unsigned int active = 0, status = 0;
+
+	regmap_read(map, TVP5150_INT_STATUS_REG_A, &status);
+	if (status) {
+		regmap_write(map, TVP5150_INT_STATUS_REG_A, status);
+
+		if (status & TVP5150_INT_A_LOCK)
+			decoder->lock = !!(status & TVP5150_INT_A_LOCK_STATUS);
+
+		return IRQ_HANDLED;
+	}
+
+	regmap_read(map, TVP5150_INT_ACTIVE_REG_B, &active);
+	if (active) {
+		status = 0;
+		regmap_read(map, TVP5150_INT_STATUS_REG_B, &status);
+		if (status)
+			regmap_write(map, TVP5150_INT_RESET_REG_B, status);
+	}
+
+	return IRQ_HANDLED;
+}
+
 static int tvp5150_enable(struct v4l2_subdev *sd)
 {
 	struct tvp5150 *decoder = to_tvp5150(sd);
@@ -939,6 +989,35 @@ static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 	return 0;
 }
 
+static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
+
+	if (enable) {
+		/* Enable YUV(OUT7:0), clock */
+		regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, 0xd,
+			(decoder->bus_type == V4L2_MBUS_BT656) ? 0x9 : 0xd);
+		if (decoder->irq) {
+			/* Enable lock interrupt */
+			regmap_update_bits(decoder->regmap,
+					   TVP5150_INT_ENABLE_REG_A,
+					   TVP5150_INT_A_LOCK,
+					   TVP5150_INT_A_LOCK);
+		}
+	} else {
+		/* Disable YUV(OUT7:0), SYNC, clock */
+		regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, 0xd, 0x0);
+		if (decoder->irq) {
+			/* Disable lock interrupt */
+			regmap_update_bits(decoder->regmap,
+					   TVP5150_INT_ENABLE_REG_A,
+					   TVP5150_INT_A_LOCK, 0);
+		}
+	}
+
+	return 0;
+}
+
 static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 {
 	struct tvp5150 *decoder = to_tvp5150(sd);
@@ -1239,9 +1318,11 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = {
 
 static const struct v4l2_subdev_video_ops tvp5150_video_ops = {
 	.s_std = tvp5150_s_std,
+	.g_std = tvp5150_g_std,
 	.s_routing = tvp5150_s_routing,
 	.s_crop = tvp5150_s_crop,
 	.g_crop = tvp5150_g_crop,
+	.s_stream = tvp5150_s_stream,
 	.cropcap = tvp5150_cropcap,
 };
 
@@ -1442,7 +1523,19 @@ static int tvp5150_probe(struct i2c_client *c,
 	}
 	v4l2_ctrl_handler_setup(&core->hdl);
 
+	core->irq = c->irq;
 	tvp5150_reset(sd, 0);
+
+	if (c->irq) {
+		res = devm_request_threaded_irq(&c->dev, c->irq, NULL,
+				tvp5150_isr, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+				"tvp5150", core);
+		if (res)
+			return res;
+	} else {
+		core->lock = true;
+	}
+
 	/* Default is no cropping */
 	tvp5150_set_default(tvp5150_read_std(sd), &core->rect, &core->format);
 
diff --git a/drivers/media/i2c/tvp5150_reg.h b/drivers/media/i2c/tvp5150_reg.h
index fc3bcb26413a..282a8a852e45 100644
--- a/drivers/media/i2c/tvp5150_reg.h
+++ b/drivers/media/i2c/tvp5150_reg.h
@@ -115,6 +115,8 @@
 #define TVP5150_TELETEXT_FIL_ENA    0xbb /* Teletext filter enable */
 /* Reserved	BCh-BFh */
 #define TVP5150_INT_STATUS_REG_A    0xc0 /* Interrupt status register A */
+#define   TVP5150_INT_A_LOCK_STATUS BIT(7)
+#define   TVP5150_INT_A_LOCK        BIT(6)
 #define TVP5150_INT_ENABLE_REG_A    0xc1 /* Interrupt enable register A */
 #define TVP5150_INT_CONF            0xc2 /* Interrupt configuration */
 #define   TVP5150_VDPOE             BIT(2)
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 9/9] [media] tvp5150: disable output while signal not locked
  2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
                   ` (6 preceding siblings ...)
  2015-11-18 16:55 ` [PATCH 8/9] [media] tvp5150: Add sync lock interrupt handling Lucas Stach
@ 2015-11-18 16:55 ` Lucas Stach
  7 siblings, 0 replies; 13+ messages in thread
From: Lucas Stach @ 2015-11-18 16:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, linux-media; +Cc: kernel, patchwork-lst

From: Philipp Zabel <p.zabel@pengutronix.de>

To avoid short frames on stream start, keep output pins at high impedance
while we are not properly locked onto the input signal.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/i2c/tvp5150.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 9e006bf36e67..9d03496d0af4 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -51,6 +51,7 @@ struct tvp5150 {
 	v4l2_std_id detected_norm;
 	u32 input;
 	u32 output;
+	u32 oe;
 	int enable;
 	bool lock;
 };
@@ -809,8 +810,11 @@ static irqreturn_t tvp5150_isr(int irq, void *dev_id)
 	if (status) {
 		regmap_write(map, TVP5150_INT_STATUS_REG_A, status);
 
-		if (status & TVP5150_INT_A_LOCK)
+		if (status & TVP5150_INT_A_LOCK) {
 			decoder->lock = !!(status & TVP5150_INT_A_LOCK_STATUS);
+			regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL,
+					   0xd, decoder->lock ? decoder->oe : 0);
+		}
 
 		return IRQ_HANDLED;
 	}
@@ -841,6 +845,7 @@ static int tvp5150_enable(struct v4l2_subdev *sd)
 				   0x7, 0x7);
 		/* disable HSYNC, VSYNC/PALI, AVID, and FID/GLCO */
 		regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, 0x4, 0x0);
+		decoder->oe = 0x9;
 		break;
 	case V4L2_MBUS_PARALLEL:
 		/* 8-bit YUV 4:2:2 */
@@ -848,6 +853,7 @@ static int tvp5150_enable(struct v4l2_subdev *sd)
 				   0x7, 0x0);
 		/* enable HSYNC, VSYNC/PALI, AVID, and FID/GLCO */
 		regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, 0x4, 0x4);
+		decoder->oe = 0xd;
 		break;
 	default:
 		return -EINVAL;
@@ -994,9 +1000,9 @@ static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)
 	struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd);
 
 	if (enable) {
-		/* Enable YUV(OUT7:0), clock */
+		/* Enable YUV(OUT7:0), (SYNC), clock signal, if locked */
 		regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, 0xd,
-			(decoder->bus_type == V4L2_MBUS_BT656) ? 0x9 : 0xd);
+				   decoder->lock ? decoder->oe : 0);
 		if (decoder->irq) {
 			/* Enable lock interrupt */
 			regmap_update_bits(decoder->regmap,
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/9] [media] tvp5150: add userspace subdev API
  2015-11-18 16:55 ` [PATCH 2/9] [media] tvp5150: add userspace subdev API Lucas Stach
@ 2015-11-18 17:06   ` kbuild test robot
  2015-11-19  8:59     ` Lucas Stach
  2015-11-18 17:08   ` kbuild test robot
  1 sibling, 1 reply; 13+ messages in thread
From: kbuild test robot @ 2015-11-18 17:06 UTC (permalink / raw)
  To: Lucas Stach
  Cc: kbuild-all, Mauro Carvalho Chehab, linux-media, kernel,
	patchwork-lst

[-- Attachment #1: Type: text/plain, Size: 7200 bytes --]

Hi Philipp,

[auto build test ERROR on: v4.4-rc1]
[also build test ERROR on: next-20151118]
[cannot apply to: linuxtv-media/master]

url:    https://github.com/0day-ci/linux/commits/Lucas-Stach/tvp5150-convert-register-access-to-regmap/20151119-005732
config: x86_64-randconfig-x018-11181928 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   drivers/media/i2c/tvp5150.c: In function 'tvp5150_get_pad_format':
>> drivers/media/i2c/tvp5150.c:1062:10: error: implicit declaration of function 'v4l2_subdev_get_try_format' [-Werror=implicit-function-declaration]
      return v4l2_subdev_get_try_format(sd, cfg, pad);
             ^
>> drivers/media/i2c/tvp5150.c:1062:10: warning: return makes pointer from integer without a cast [-Wint-conversion]
   drivers/media/i2c/tvp5150.c: In function 'tvp5150_get_pad_crop':
>> drivers/media/i2c/tvp5150.c:1077:10: error: implicit declaration of function 'v4l2_subdev_get_try_crop' [-Werror=implicit-function-declaration]
      return v4l2_subdev_get_try_crop(sd, cfg, pad);
             ^
   drivers/media/i2c/tvp5150.c:1077:10: warning: return makes pointer from integer without a cast [-Wint-conversion]
   drivers/media/i2c/tvp5150.c: In function 'tvp5150_open':
>> drivers/media/i2c/tvp5150.c:1180:27: warning: passing argument 2 of 'tvp5150_set_default' makes pointer from integer without a cast [-Wint-conversion]
     tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
                              ^
   drivers/media/i2c/tvp5150.c:1152:13: note: expected 'struct v4l2_rect *' but argument is of type 'int'
    static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop,
                ^
   drivers/media/i2c/tvp5150.c:1181:6: warning: passing argument 3 of 'tvp5150_set_default' makes pointer from integer without a cast [-Wint-conversion]
         v4l2_subdev_get_try_format(fh, 0));
         ^
   drivers/media/i2c/tvp5150.c:1152:13: note: expected 'struct v4l2_mbus_framefmt *' but argument is of type 'int'
    static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop,
                ^
   drivers/media/i2c/tvp5150.c: In function 'tvp5150_probe':
>> drivers/media/i2c/tvp5150.c:1340:4: error: 'struct v4l2_subdev' has no member named 'entity'
     sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
       ^
   drivers/media/i2c/tvp5150.c:1342:29: error: 'struct v4l2_subdev' has no member named 'entity'
     res = media_entity_init(&sd->entity, 1, &core->pad, 0);
                                ^
   cc1: some warnings being treated as errors

vim +/v4l2_subdev_get_try_format +1062 drivers/media/i2c/tvp5150.c

  1056	tvp5150_get_pad_format(struct tvp5150 *decoder, struct v4l2_subdev *sd,
  1057				 struct v4l2_subdev_pad_config *cfg, unsigned int pad,
  1058				 enum v4l2_subdev_format_whence which)
  1059	{
  1060		switch (which) {
  1061		case V4L2_SUBDEV_FORMAT_TRY:
> 1062			return v4l2_subdev_get_try_format(sd, cfg, pad);
  1063		case V4L2_SUBDEV_FORMAT_ACTIVE:
  1064			return &decoder->format;
  1065		default:
  1066			return NULL;
  1067		}
  1068	}
  1069	
  1070	static struct v4l2_rect *
  1071	tvp5150_get_pad_crop(struct tvp5150 *decoder, struct v4l2_subdev *sd,
  1072			       struct v4l2_subdev_pad_config *cfg, unsigned int pad,
  1073			       enum v4l2_subdev_format_whence which)
  1074	{
  1075		switch (which) {
  1076		case V4L2_SUBDEV_FORMAT_TRY:
> 1077			return v4l2_subdev_get_try_crop(sd, cfg, pad);
  1078		case V4L2_SUBDEV_FORMAT_ACTIVE:
  1079			return &decoder->rect;
  1080		default:
  1081			return NULL;
  1082		}
  1083	}
  1084	
  1085	static int tvp5150_enum_frame_size(struct v4l2_subdev *sd,
  1086					   struct v4l2_subdev_pad_config *cfg,
  1087					   struct v4l2_subdev_frame_size_enum *fse)
  1088	{
  1089		struct tvp5150 *decoder = to_tvp5150(sd);
  1090		v4l2_std_id std;
  1091	
  1092		if (fse->index > 0 || fse->code != MEDIA_BUS_FMT_UYVY8_2X8)
  1093			return -EINVAL;
  1094	
  1095		fse->min_width = TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT;
  1096		fse->max_width = TVP5150_H_MAX;
  1097	
  1098		/* Calculate height based on current standard */
  1099		if (decoder->norm == V4L2_STD_ALL)
  1100			std = tvp5150_read_std(sd);
  1101		else
  1102			std = decoder->norm;
  1103	
  1104		if (std & V4L2_STD_525_60) {
  1105			fse->min_height = TVP5150_V_MAX_525_60 - TVP5150_MAX_CROP_TOP;
  1106			fse->max_height = TVP5150_V_MAX_525_60;
  1107		} else {
  1108			fse->min_height = TVP5150_V_MAX_OTHERS - TVP5150_MAX_CROP_TOP;
  1109			fse->max_height = TVP5150_V_MAX_OTHERS;
  1110		}
  1111	
  1112		return 0;
  1113	}
  1114	
  1115	static int tvp5150_get_format(struct v4l2_subdev *sd,
  1116				      struct v4l2_subdev_pad_config *cfg,
  1117				      struct v4l2_subdev_format *format)
  1118	{
  1119		struct tvp5150 *decoder = to_tvp5150(sd);
  1120	
  1121		format->format = *tvp5150_get_pad_format(decoder, sd, cfg,
  1122							   format->pad, format->which);
  1123		return 0;
  1124	}
  1125	
  1126	static int tvp5150_set_format(struct v4l2_subdev *sd,
  1127				      struct v4l2_subdev_pad_config *cfg,
  1128				      struct v4l2_subdev_format *format)
  1129	{
  1130		struct tvp5150 *decoder = to_tvp5150(sd);
  1131		struct v4l2_mbus_framefmt *mbus_format;
  1132		struct v4l2_rect *crop;
  1133	
  1134		crop = tvp5150_get_pad_crop(decoder, sd, cfg, format->pad,
  1135						format->which);
  1136		mbus_format = tvp5150_get_pad_format(decoder, sd, cfg, format->pad,
  1137						    format->which);
  1138		mbus_format->width = crop->width;
  1139		mbus_format->height = crop->height;
  1140	
  1141		format->format = *mbus_format;
  1142	
  1143		if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
  1144			tvp5150_reset(sd, 0);
  1145	
  1146		v4l2_dbg(1, debug, sd, "width = %d, height = %d\n", mbus_format->width,
  1147				mbus_format->height);
  1148	
  1149		return 0;
  1150	}
  1151	
  1152	static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop,
  1153					struct v4l2_mbus_framefmt *format)
  1154	{
  1155		crop->left = 0;
  1156		crop->width = TVP5150_H_MAX;
  1157		crop->top = 0;
  1158		if (std & V4L2_STD_525_60)
  1159			crop->height = TVP5150_V_MAX_525_60;
  1160		else
  1161			crop->height = TVP5150_V_MAX_OTHERS;
  1162	
  1163		format->width = crop->width;
  1164		format->height = crop->height;
  1165		format->code = MEDIA_BUS_FMT_UYVY8_2X8;
  1166		format->field = V4L2_FIELD_SEQ_TB;
  1167		format->colorspace = V4L2_COLORSPACE_SMPTE170M;
  1168	}
  1169	
  1170	static int tvp5150_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
  1171	{
  1172		struct tvp5150 *decoder = to_tvp5150(sd);
  1173		v4l2_std_id std;
  1174	
  1175		if (decoder->norm == V4L2_STD_ALL)
  1176			std = tvp5150_read_std(sd);
  1177		else
  1178			std = decoder->norm;
  1179	
> 1180		tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
> 1181					 v4l2_subdev_get_try_format(fh, 0));
  1182		return 0;
  1183	}
  1184	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 24879 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/9] [media] tvp5150: add userspace subdev API
  2015-11-18 16:55 ` [PATCH 2/9] [media] tvp5150: add userspace subdev API Lucas Stach
  2015-11-18 17:06   ` kbuild test robot
@ 2015-11-18 17:08   ` kbuild test robot
  1 sibling, 0 replies; 13+ messages in thread
From: kbuild test robot @ 2015-11-18 17:08 UTC (permalink / raw)
  To: Lucas Stach
  Cc: kbuild-all, Mauro Carvalho Chehab, linux-media, kernel,
	patchwork-lst

[-- Attachment #1: Type: text/plain, Size: 4026 bytes --]

Hi Philipp,

[auto build test ERROR on: v4.4-rc1]
[also build test ERROR on: next-20151118]
[cannot apply to: linuxtv-media/master]

url:    https://github.com/0day-ci/linux/commits/Lucas-Stach/tvp5150-convert-register-access-to-regmap/20151119-005732
config: x86_64-randconfig-x017-11181928 (attached as .config)
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

Note: the linux-review/Lucas-Stach/tvp5150-convert-register-access-to-regmap/20151119-005732 HEAD bda9ffd30fce12dfa1b1964094311ae5dd780461 builds fine.
      It only hurts bisectibility.

All error/warnings (new ones prefixed by >>):

   drivers/media/i2c/tvp5150.c: In function 'tvp5150_open':
>> drivers/media/i2c/tvp5150.c:1180:52: warning: passing argument 1 of 'v4l2_subdev_get_try_crop' from incompatible pointer type [-Wincompatible-pointer-types]
     tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
                                                       ^
   In file included from include/media/v4l2-device.h:25:0,
                    from drivers/media/i2c/tvp5150.c:15:
   include/media/v4l2-subdev.h:769:37: note: expected 'struct v4l2_subdev *' but argument is of type 'struct v4l2_subdev_fh *'
    __V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, v4l2_subdev_get_try_crop, try_crop)
                                        ^
   include/media/v4l2-subdev.h:760:2: note: in definition of macro '__V4L2_SUBDEV_MK_GET_TRY'
     fun_name(struct v4l2_subdev *sd,    \
     ^
>> drivers/media/i2c/tvp5150.c:1180:27: error: too few arguments to function 'v4l2_subdev_get_try_crop'
     tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
                              ^
   In file included from include/media/v4l2-device.h:25:0,
                    from drivers/media/i2c/tvp5150.c:15:
   include/media/v4l2-subdev.h:769:37: note: declared here
    __V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, v4l2_subdev_get_try_crop, try_crop)
                                        ^
   include/media/v4l2-subdev.h:760:2: note: in definition of macro '__V4L2_SUBDEV_MK_GET_TRY'
     fun_name(struct v4l2_subdev *sd,    \
     ^
>> drivers/media/i2c/tvp5150.c:1181:33: warning: passing argument 1 of 'v4l2_subdev_get_try_format' from incompatible pointer type [-Wincompatible-pointer-types]
         v4l2_subdev_get_try_format(fh, 0));
                                    ^
   In file included from include/media/v4l2-device.h:25:0,
                    from drivers/media/i2c/tvp5150.c:15:
   include/media/v4l2-subdev.h:768:46: note: expected 'struct v4l2_subdev *' but argument is of type 'struct v4l2_subdev_fh *'
    __V4L2_SUBDEV_MK_GET_TRY(v4l2_mbus_framefmt, v4l2_subdev_get_try_format, try_fmt)
                                                 ^
   include/media/v4l2-subdev.h:760:2: note: in definition of macro '__V4L2_SUBDEV_MK_GET_TRY'
     fun_name(struct v4l2_subdev *sd,    \
     ^
>> drivers/media/i2c/tvp5150.c:1181:6: error: too few arguments to function 'v4l2_subdev_get_try_format'
         v4l2_subdev_get_try_format(fh, 0));
         ^
   In file included from include/media/v4l2-device.h:25:0,
                    from drivers/media/i2c/tvp5150.c:15:
   include/media/v4l2-subdev.h:768:46: note: declared here
    __V4L2_SUBDEV_MK_GET_TRY(v4l2_mbus_framefmt, v4l2_subdev_get_try_format, try_fmt)
                                                 ^
   include/media/v4l2-subdev.h:760:2: note: in definition of macro '__V4L2_SUBDEV_MK_GET_TRY'
     fun_name(struct v4l2_subdev *sd,    \
     ^

vim +/v4l2_subdev_get_try_crop +1180 drivers/media/i2c/tvp5150.c

  1174	
  1175		if (decoder->norm == V4L2_STD_ALL)
  1176			std = tvp5150_read_std(sd);
  1177		else
  1178			std = decoder->norm;
  1179	
> 1180		tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
> 1181					 v4l2_subdev_get_try_format(fh, 0));
  1182		return 0;
  1183	}
  1184	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 25439 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/9] [media] tvp5150: add userspace subdev API
  2015-11-18 17:06   ` kbuild test robot
@ 2015-11-19  8:59     ` Lucas Stach
  2015-11-19  9:27       ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 13+ messages in thread
From: Lucas Stach @ 2015-11-19  8:59 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linux-media, kernel, patchwork-lst, kbuild test robot

Am Donnerstag, den 19.11.2015, 01:06 +0800 schrieb kbuild test robot:
> Hi Philipp,
> 
> [auto build test ERROR on: v4.4-rc1]
> [also build test ERROR on: next-20151118]
> [cannot apply to: linuxtv-media/master]
> 
> url:    https://github.com/0day-ci/linux/commits/Lucas-Stach/tvp5150-convert-register-access-to-regmap/20151119-005732
> config: x86_64-randconfig-x018-11181928 (attached as .config)
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
> 
> All error/warnings (new ones prefixed by >>):
> 
>    drivers/media/i2c/tvp5150.c: In function 'tvp5150_get_pad_format':
> >> drivers/media/i2c/tvp5150.c:1062:10: error: implicit declaration of function 'v4l2_subdev_get_try_format' [-Werror=implicit-function-declaration]
>       return v4l2_subdev_get_try_format(sd, cfg, pad);
>              ^
> >> drivers/media/i2c/tvp5150.c:1062:10: warning: return makes pointer from integer without a cast [-Wint-conversion]
>    drivers/media/i2c/tvp5150.c: In function 'tvp5150_get_pad_crop':
> >> drivers/media/i2c/tvp5150.c:1077:10: error: implicit declaration of function 'v4l2_subdev_get_try_crop' [-Werror=implicit-function-declaration]
>       return v4l2_subdev_get_try_crop(sd, cfg, pad);
>              ^
>    drivers/media/i2c/tvp5150.c:1077:10: warning: return makes pointer from integer without a cast [-Wint-conversion]
>    drivers/media/i2c/tvp5150.c: In function 'tvp5150_open':
> >> drivers/media/i2c/tvp5150.c:1180:27: warning: passing argument 2 of 'tvp5150_set_default' makes pointer from integer without a cast [-Wint-conversion]
>      tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
>                               ^
>    drivers/media/i2c/tvp5150.c:1152:13: note: expected 'struct v4l2_rect *' but argument is of type 'int'
>     static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop,
>                 ^
>    drivers/media/i2c/tvp5150.c:1181:6: warning: passing argument 3 of 'tvp5150_set_default' makes pointer from integer without a cast [-Wint-conversion]
>          v4l2_subdev_get_try_format(fh, 0));
>          ^
>    drivers/media/i2c/tvp5150.c:1152:13: note: expected 'struct v4l2_mbus_framefmt *' but argument is of type 'int'
>     static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop,
>                 ^
>    drivers/media/i2c/tvp5150.c: In function 'tvp5150_probe':
> >> drivers/media/i2c/tvp5150.c:1340:4: error: 'struct v4l2_subdev' has no member named 'entity'
>      sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
>        ^
>    drivers/media/i2c/tvp5150.c:1342:29: error: 'struct v4l2_subdev' has no member named 'entity'
>      res = media_entity_init(&sd->entity, 1, &core->pad, 0);
>                                 ^
>    cc1: some warnings being treated as errors

Ok, this is just a missing depends on VIDEO_V4L2_SUBDEV_API. I'll wait
for other feedback before resending with that fixed.

Regards,
Lucas

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/9] [media] tvp5150: add userspace subdev API
  2015-11-19  8:59     ` Lucas Stach
@ 2015-11-19  9:27       ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 13+ messages in thread
From: Mauro Carvalho Chehab @ 2015-11-19  9:27 UTC (permalink / raw)
  To: Lucas Stach; +Cc: linux-media, kernel, patchwork-lst, kbuild test robot

Em Thu, 19 Nov 2015 09:59:15 +0100
Lucas Stach <l.stach@pengutronix.de> escreveu:

> Am Donnerstag, den 19.11.2015, 01:06 +0800 schrieb kbuild test robot:
> > Hi Philipp,
> > 
> > [auto build test ERROR on: v4.4-rc1]
> > [also build test ERROR on: next-20151118]
> > [cannot apply to: linuxtv-media/master]
> > 
> > url:    https://github.com/0day-ci/linux/commits/Lucas-Stach/tvp5150-convert-register-access-to-regmap/20151119-005732
> > config: x86_64-randconfig-x018-11181928 (attached as .config)
> > reproduce:
> >         # save the attached .config to linux build tree
> >         make ARCH=x86_64 
> > 
> > All error/warnings (new ones prefixed by >>):
> > 
> >    drivers/media/i2c/tvp5150.c: In function 'tvp5150_get_pad_format':
> > >> drivers/media/i2c/tvp5150.c:1062:10: error: implicit declaration of function 'v4l2_subdev_get_try_format' [-Werror=implicit-function-declaration]
> >       return v4l2_subdev_get_try_format(sd, cfg, pad);
> >              ^
> > >> drivers/media/i2c/tvp5150.c:1062:10: warning: return makes pointer from integer without a cast [-Wint-conversion]
> >    drivers/media/i2c/tvp5150.c: In function 'tvp5150_get_pad_crop':
> > >> drivers/media/i2c/tvp5150.c:1077:10: error: implicit declaration of function 'v4l2_subdev_get_try_crop' [-Werror=implicit-function-declaration]
> >       return v4l2_subdev_get_try_crop(sd, cfg, pad);
> >              ^
> >    drivers/media/i2c/tvp5150.c:1077:10: warning: return makes pointer from integer without a cast [-Wint-conversion]
> >    drivers/media/i2c/tvp5150.c: In function 'tvp5150_open':
> > >> drivers/media/i2c/tvp5150.c:1180:27: warning: passing argument 2 of 'tvp5150_set_default' makes pointer from integer without a cast [-Wint-conversion]
> >      tvp5150_set_default(std, v4l2_subdev_get_try_crop(fh, 0),
> >                               ^
> >    drivers/media/i2c/tvp5150.c:1152:13: note: expected 'struct v4l2_rect *' but argument is of type 'int'
> >     static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop,
> >                 ^
> >    drivers/media/i2c/tvp5150.c:1181:6: warning: passing argument 3 of 'tvp5150_set_default' makes pointer from integer without a cast [-Wint-conversion]
> >          v4l2_subdev_get_try_format(fh, 0));
> >          ^
> >    drivers/media/i2c/tvp5150.c:1152:13: note: expected 'struct v4l2_mbus_framefmt *' but argument is of type 'int'
> >     static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop,
> >                 ^
> >    drivers/media/i2c/tvp5150.c: In function 'tvp5150_probe':
> > >> drivers/media/i2c/tvp5150.c:1340:4: error: 'struct v4l2_subdev' has no member named 'entity'
> >      sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
> >        ^
> >    drivers/media/i2c/tvp5150.c:1342:29: error: 'struct v4l2_subdev' has no member named 'entity'
> >      res = media_entity_init(&sd->entity, 1, &core->pad, 0);
> >                                 ^
> >    cc1: some warnings being treated as errors
> 
> Ok, this is just a missing depends on VIDEO_V4L2_SUBDEV_API. I'll wait
> for other feedback before resending with that fixed.

Lucas,

Please notice that tvp5150 is used by drivers that doesn't need nor
want VIDEO_V4L2_SUBDEV_API. So, you should be sure that the driver
will compile fine without subdev API, and will keep working properly
for those devices, no matter if subdev API was compiled or not.

Regards,
Mauro

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-11-19  9:27 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-18 16:55 [PATCH 1/9] [media] tvp5150: convert register access to regmap Lucas Stach
2015-11-18 16:55 ` [PATCH 2/9] [media] tvp5150: add userspace subdev API Lucas Stach
2015-11-18 17:06   ` kbuild test robot
2015-11-19  8:59     ` Lucas Stach
2015-11-19  9:27       ` Mauro Carvalho Chehab
2015-11-18 17:08   ` kbuild test robot
2015-11-18 16:55 ` [PATCH 3/9] [media] tvp5150: determine BT.656 or YUV 4:2:2 mode from device tree Lucas Stach
2015-11-18 16:55 ` [PATCH 4/9] [media] tvp5150: fix standard autodetection Lucas Stach
2015-11-18 16:55 ` [PATCH 5/9] [media] tvp5150: split reset/enable routine Lucas Stach
2015-11-18 16:55 ` [PATCH 6/9] [media] tvp5150: trigger autodetection on subdev open to reset cropping Lucas Stach
2015-11-18 16:55 ` [PATCH 7/9] [media] tvp5150: remove pin configuration from initialization tables Lucas Stach
2015-11-18 16:55 ` [PATCH 8/9] [media] tvp5150: Add sync lock interrupt handling Lucas Stach
2015-11-18 16:55 ` [PATCH 9/9] [media] tvp5150: disable output while signal not locked Lucas Stach

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox