All of lore.kernel.org
 help / color / mirror / Atom feed
* [REVIEW PATCH 0/3] Control header fix and convert tvaudio/mt9v011 to the controlfw
@ 2013-01-24  7:51 Hans Verkuil
  2013-01-24  7:51 ` [REVIEW PATCH 1/3] Move DV-class control IDs from videodev2.h to v4l2-controls.h Hans Verkuil
  0 siblings, 1 reply; 5+ messages in thread
From: Hans Verkuil @ 2013-01-24  7:51 UTC (permalink / raw)
  To: linux-media; +Cc: Devin Heitmueller

The first patch moves the DV control IDs to their proper place in
v4l2-controls.h. I suspect the patch splitting off the control IDs to
a separate header and adding the new DV controls crossed one another.

The other two patches convert tvaudio and mt9v011 to the controls
framework: this is needed to make em28xx work correctly for devices
using those subdev drivers. Without this the controls defined in those
drivers won't show up.

Regards,

	Hans


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

* [REVIEW PATCH 1/3] Move DV-class control IDs from videodev2.h to v4l2-controls.h
  2013-01-24  7:51 [REVIEW PATCH 0/3] Control header fix and convert tvaudio/mt9v011 to the controlfw Hans Verkuil
@ 2013-01-24  7:51 ` Hans Verkuil
  2013-01-24  7:51   ` [REVIEW PATCH 2/3] tvaudio: convert to the control framework Hans Verkuil
  2013-01-24  7:51   ` [REVIEW PATCH 3/3] mt9v011: " Hans Verkuil
  0 siblings, 2 replies; 5+ messages in thread
From: Hans Verkuil @ 2013-01-24  7:51 UTC (permalink / raw)
  To: linux-media; +Cc: Devin Heitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

When the control IDs were split off from videodev2.h to v4l2-controls.h
these new Digital Video controls were forgotten (the two patches may
have crossed one another).

Move these controls to their proper place in v4l2-controls.h.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 include/uapi/linux/v4l2-controls.h |   24 ++++++++++++++++++++++++
 include/uapi/linux/videodev2.h     |   22 ----------------------
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 4dc0822..0bece06 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -778,6 +778,7 @@ enum v4l2_jpeg_chroma_subsampling {
 #define	V4L2_JPEG_ACTIVE_MARKER_DQT		(1 << 17)
 #define	V4L2_JPEG_ACTIVE_MARKER_DHT		(1 << 18)
 
+
 /* Image source controls */
 #define V4L2_CID_IMAGE_SOURCE_CLASS_BASE	(V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900)
 #define V4L2_CID_IMAGE_SOURCE_CLASS		(V4L2_CTRL_CLASS_IMAGE_SOURCE | 1)
@@ -796,4 +797,27 @@ enum v4l2_jpeg_chroma_subsampling {
 #define V4L2_CID_PIXEL_RATE			(V4L2_CID_IMAGE_PROC_CLASS_BASE + 2)
 #define V4L2_CID_TEST_PATTERN			(V4L2_CID_IMAGE_PROC_CLASS_BASE + 3)
 
+
+/*  DV-class control IDs defined by V4L2 */
+#define V4L2_CID_DV_CLASS_BASE			(V4L2_CTRL_CLASS_DV | 0x900)
+#define V4L2_CID_DV_CLASS			(V4L2_CTRL_CLASS_DV | 1)
+
+#define	V4L2_CID_DV_TX_HOTPLUG			(V4L2_CID_DV_CLASS_BASE + 1)
+#define	V4L2_CID_DV_TX_RXSENSE			(V4L2_CID_DV_CLASS_BASE + 2)
+#define	V4L2_CID_DV_TX_EDID_PRESENT		(V4L2_CID_DV_CLASS_BASE + 3)
+#define	V4L2_CID_DV_TX_MODE			(V4L2_CID_DV_CLASS_BASE + 4)
+enum v4l2_dv_tx_mode {
+	V4L2_DV_TX_MODE_DVI_D	= 0,
+	V4L2_DV_TX_MODE_HDMI	= 1,
+};
+#define V4L2_CID_DV_TX_RGB_RANGE		(V4L2_CID_DV_CLASS_BASE + 5)
+enum v4l2_dv_rgb_range {
+	V4L2_DV_RGB_RANGE_AUTO	  = 0,
+	V4L2_DV_RGB_RANGE_LIMITED = 1,
+	V4L2_DV_RGB_RANGE_FULL	  = 2,
+};
+
+#define	V4L2_CID_DV_RX_POWER_PRESENT		(V4L2_CID_DV_CLASS_BASE + 100)
+#define V4L2_CID_DV_RX_RGB_RANGE		(V4L2_CID_DV_CLASS_BASE + 101)
+
 #endif
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 94cbe26..132a9c5 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1354,28 +1354,6 @@ struct v4l2_querymenu {
 #define V4L2_CID_PRIVATE_BASE		0x08000000
 
 
-/*  DV-class control IDs defined by V4L2 */
-#define V4L2_CID_DV_CLASS_BASE			(V4L2_CTRL_CLASS_DV | 0x900)
-#define V4L2_CID_DV_CLASS			(V4L2_CTRL_CLASS_DV | 1)
-
-#define	V4L2_CID_DV_TX_HOTPLUG			(V4L2_CID_DV_CLASS_BASE + 1)
-#define	V4L2_CID_DV_TX_RXSENSE			(V4L2_CID_DV_CLASS_BASE + 2)
-#define	V4L2_CID_DV_TX_EDID_PRESENT		(V4L2_CID_DV_CLASS_BASE + 3)
-#define	V4L2_CID_DV_TX_MODE			(V4L2_CID_DV_CLASS_BASE + 4)
-enum v4l2_dv_tx_mode {
-	V4L2_DV_TX_MODE_DVI_D	= 0,
-	V4L2_DV_TX_MODE_HDMI	= 1,
-};
-#define V4L2_CID_DV_TX_RGB_RANGE		(V4L2_CID_DV_CLASS_BASE + 5)
-enum v4l2_dv_rgb_range {
-	V4L2_DV_RGB_RANGE_AUTO	  = 0,
-	V4L2_DV_RGB_RANGE_LIMITED = 1,
-	V4L2_DV_RGB_RANGE_FULL	  = 2,
-};
-
-#define	V4L2_CID_DV_RX_POWER_PRESENT		(V4L2_CID_DV_CLASS_BASE + 100)
-#define V4L2_CID_DV_RX_RGB_RANGE		(V4L2_CID_DV_CLASS_BASE + 101)
-
 /*
  *	T U N I N G
  */
-- 
1.7.10.4


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

* [REVIEW PATCH 2/3] tvaudio: convert to the control framework.
  2013-01-24  7:51 ` [REVIEW PATCH 1/3] Move DV-class control IDs from videodev2.h to v4l2-controls.h Hans Verkuil
@ 2013-01-24  7:51   ` Hans Verkuil
  2013-01-24  7:51   ` [REVIEW PATCH 3/3] mt9v011: " Hans Verkuil
  1 sibling, 0 replies; 5+ messages in thread
From: Hans Verkuil @ 2013-01-24  7:51 UTC (permalink / raw)
  To: linux-media; +Cc: Devin Heitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/tvaudio.c |  224 +++++++++++++++----------------------------
 1 file changed, 75 insertions(+), 149 deletions(-)

diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c
index 3b24d3f..00a1ca8 100644
--- a/drivers/media/i2c/tvaudio.c
+++ b/drivers/media/i2c/tvaudio.c
@@ -39,6 +39,7 @@
 #include <media/tvaudio.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
 
 #include <media/i2c-addr.h>
 
@@ -91,13 +92,13 @@ struct CHIPDESC {
 	audiocmd   init;
 
 	/* which register has which value */
-	int    leftreg,rightreg,treblereg,bassreg;
+	int    leftreg, rightreg, treblereg, bassreg;
 
-	/* initialize with (defaults to 65535/65535/32768/32768 */
-	int    leftinit,rightinit,trebleinit,bassinit;
+	/* initialize with (defaults to 65535/32768/32768 */
+	int    volinit, trebleinit, bassinit;
 
 	/* functions to convert the values (v4l -> chip) */
-	getvalue volfunc,treblefunc,bassfunc;
+	getvalue volfunc, treblefunc, bassfunc;
 
 	/* get/set mode */
 	getrxsubchans	getrxsubchans;
@@ -113,6 +114,12 @@ struct CHIPDESC {
 /* current state of the chip */
 struct CHIPSTATE {
 	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
+	struct {
+		/* volume/balance cluster */
+		struct v4l2_ctrl *volume;
+		struct v4l2_ctrl *balance;
+	};
 
 	/* chip-specific description - should point to
 	   an entry at CHIPDESC table */
@@ -122,7 +129,7 @@ struct CHIPSTATE {
 	audiocmd   shadow;
 
 	/* current settings */
-	__u16 left, right, treble, bass, muted;
+	u16 muted;
 	int prevmode;
 	int radio;
 	int input;
@@ -138,6 +145,11 @@ static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd)
 	return container_of(sd, struct CHIPSTATE, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+	return &container_of(ctrl->handler, struct CHIPSTATE, hdl)->sd;
+}
+
 
 /* ---------------------------------------------------------------------- */
 /* i2c I/O functions                                                      */
@@ -1523,8 +1535,7 @@ static struct CHIPDESC chiplist[] = {
 		.rightreg   = TDA9875_MVR,
 		.bassreg    = TDA9875_MBA,
 		.treblereg  = TDA9875_MTR,
-		.leftinit   = 58880,
-		.rightinit  = 58880,
+		.volinit    = 58880,
 	},
 	{
 		.name       = "tda9850",
@@ -1679,121 +1690,39 @@ static struct CHIPDESC chiplist[] = {
 
 /* ---------------------------------------------------------------------- */
 
-static int tvaudio_g_ctrl(struct v4l2_subdev *sd,
-			    struct v4l2_control *ctrl)
+static int tvaudio_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+	struct v4l2_subdev *sd = to_sd(ctrl);
 	struct CHIPSTATE *chip = to_state(sd);
 	struct CHIPDESC *desc = chip->desc;
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		if (!(desc->flags & CHIP_HAS_INPUTSEL))
-			break;
-		ctrl->value=chip->muted;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		if (!(desc->flags & CHIP_HAS_VOLUME))
-			break;
-		ctrl->value = max(chip->left,chip->right);
-		return 0;
-	case V4L2_CID_AUDIO_BALANCE:
-	{
-		int volume;
-		if (!(desc->flags & CHIP_HAS_VOLUME))
-			break;
-		volume = max(chip->left,chip->right);
-		if (volume)
-			ctrl->value=(32768*min(chip->left,chip->right))/volume;
-		else
-			ctrl->value=32768;
-		return 0;
-	}
-	case V4L2_CID_AUDIO_BASS:
-		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
-			break;
-		ctrl->value = chip->bass;
-		return 0;
-	case V4L2_CID_AUDIO_TREBLE:
-		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
-			break;
-		ctrl->value = chip->treble;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int tvaudio_s_ctrl(struct v4l2_subdev *sd,
-			    struct v4l2_control *ctrl)
-{
-	struct CHIPSTATE *chip = to_state(sd);
-	struct CHIPDESC *desc = chip->desc;
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (!(desc->flags & CHIP_HAS_INPUTSEL))
-			break;
-
-		if (ctrl->value < 0 || ctrl->value >= 2)
-			return -ERANGE;
-		chip->muted = ctrl->value;
+		chip->muted = ctrl->val;
 		if (chip->muted)
 			chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask);
 		else
 			chip_write_masked(chip,desc->inputreg,
 					desc->inputmap[chip->input],desc->inputmask);
 		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-	{
-		int volume,balance;
-
-		if (!(desc->flags & CHIP_HAS_VOLUME))
-			break;
-
-		volume = max(chip->left,chip->right);
-		if (volume)
-			balance=(32768*min(chip->left,chip->right))/volume;
-		else
-			balance=32768;
-
-		volume=ctrl->value;
-		chip->left = (min(65536 - balance,32768) * volume) / 32768;
-		chip->right = (min(balance,volume *(__u16)32768)) / 32768;
-
-		chip_write(chip,desc->leftreg,desc->volfunc(chip->left));
-		chip_write(chip,desc->rightreg,desc->volfunc(chip->right));
-
-		return 0;
-	}
-	case V4L2_CID_AUDIO_BALANCE:
-	{
-		int volume, balance;
+	case V4L2_CID_AUDIO_VOLUME: {
+		u32 volume, balance;
+		u32 left, right;
 
-		if (!(desc->flags & CHIP_HAS_VOLUME))
-			break;
-
-		volume = max(chip->left, chip->right);
-		balance = ctrl->value;
-		chip->left = (min(65536 - balance, 32768) * volume) / 32768;
-		chip->right = (min(balance, volume * (__u16)32768)) / 32768;
-
-		chip_write(chip, desc->leftreg, desc->volfunc(chip->left));
-		chip_write(chip, desc->rightreg, desc->volfunc(chip->right));
+		volume = chip->volume->val;
+		balance = chip->balance->val;
+		left = (min(65536U - balance, 32768U) * volume) / 32768U;
+		right = (min(balance, 32768U) * volume) / 32768U;
 
+		chip_write(chip, desc->leftreg, desc->volfunc(left));
+		chip_write(chip, desc->rightreg, desc->volfunc(right));
 		return 0;
 	}
 	case V4L2_CID_AUDIO_BASS:
-		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
-			break;
-		chip->bass = ctrl->value;
-		chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
-
+		chip_write(chip, desc->bassreg, desc->bassfunc(ctrl->val));
 		return 0;
 	case V4L2_CID_AUDIO_TREBLE:
-		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
-			break;
-		chip->treble = ctrl->value;
-		chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
-
+		chip_write(chip, desc->treblereg, desc->treblefunc(ctrl->val));
 		return 0;
 	}
 	return -EINVAL;
@@ -1812,35 +1741,6 @@ static int tvaudio_s_radio(struct v4l2_subdev *sd)
 	return 0;
 }
 
-static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-	struct CHIPSTATE *chip = to_state(sd);
-	struct CHIPDESC *desc = chip->desc;
-
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (desc->flags & CHIP_HAS_INPUTSEL)
-			return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
-		break;
-	case V4L2_CID_AUDIO_VOLUME:
-		if (desc->flags & CHIP_HAS_VOLUME)
-			return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
-		break;
-	case V4L2_CID_AUDIO_BALANCE:
-		if (desc->flags & CHIP_HAS_VOLUME)
-			return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
-		break;
-	case V4L2_CID_AUDIO_BASS:
-	case V4L2_CID_AUDIO_TREBLE:
-		if (desc->flags & CHIP_HAS_BASSTREBLE)
-			return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
-		break;
-	default:
-		break;
-	}
-	return -EINVAL;
-}
-
 static int tvaudio_s_routing(struct v4l2_subdev *sd,
 			     u32 input, u32 output, u32 config)
 {
@@ -1946,11 +1846,19 @@ static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
 
 /* ----------------------------------------------------------------------- */
 
+static const struct v4l2_ctrl_ops tvaudio_ctrl_ops = {
+	.s_ctrl = tvaudio_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
 	.g_chip_ident = tvaudio_g_chip_ident,
-	.queryctrl = tvaudio_queryctrl,
-	.g_ctrl = tvaudio_g_ctrl,
-	.s_ctrl = tvaudio_s_ctrl,
+	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+	.g_ctrl = v4l2_subdev_g_ctrl,
+	.s_ctrl = v4l2_subdev_s_ctrl,
+	.queryctrl = v4l2_subdev_queryctrl,
+	.querymenu = v4l2_subdev_querymenu,
 	.s_std = tvaudio_s_std,
 };
 
@@ -2035,6 +1943,10 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
 	else
 		chip_cmd(chip, "init", &desc->init);
 
+	v4l2_ctrl_handler_init(&chip->hdl, 5);
+	if (desc->flags & CHIP_HAS_INPUTSEL)
+		v4l2_ctrl_new_std(&chip->hdl, &tvaudio_ctrl_ops,
+			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
 	if (desc->flags & CHIP_HAS_VOLUME) {
 		if (!desc->volfunc) {
 			/* This shouldn't be happen. Warn user, but keep working
@@ -2043,12 +1955,14 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
 			v4l2_info(sd, "volume callback undefined!\n");
 			desc->flags &= ~CHIP_HAS_VOLUME;
 		} else {
-			chip->left  = desc->leftinit  ? desc->leftinit  : 65535;
-			chip->right = desc->rightinit ? desc->rightinit : 65535;
-			chip_write(chip, desc->leftreg,
-				   desc->volfunc(chip->left));
-			chip_write(chip, desc->rightreg,
-				   desc->volfunc(chip->right));
+			chip->volume = v4l2_ctrl_new_std(&chip->hdl,
+				&tvaudio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
+				0, 65535, 65535 / 100,
+				desc->volinit ? desc->volinit : 65535);
+			chip->balance = v4l2_ctrl_new_std(&chip->hdl,
+				&tvaudio_ctrl_ops, V4L2_CID_AUDIO_BALANCE,
+				0, 65535, 65535 / 100, 32768);
+			v4l2_ctrl_cluster(2, &chip->volume);
 		}
 	}
 	if (desc->flags & CHIP_HAS_BASSTREBLE) {
@@ -2059,17 +1973,28 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
 			v4l2_info(sd, "bass/treble callbacks undefined!\n");
 			desc->flags &= ~CHIP_HAS_BASSTREBLE;
 		} else {
-			chip->treble = desc->trebleinit ?
-						desc->trebleinit : 32768;
-			chip->bass   = desc->bassinit   ?
-						desc->bassinit   : 32768;
-			chip_write(chip, desc->bassreg,
-				   desc->bassfunc(chip->bass));
-			chip_write(chip, desc->treblereg,
-				   desc->treblefunc(chip->treble));
+			v4l2_ctrl_new_std(&chip->hdl,
+				&tvaudio_ctrl_ops, V4L2_CID_AUDIO_BASS,
+				0, 65535, 65535 / 100,
+				desc->bassinit ? desc->bassinit : 32768);
+			v4l2_ctrl_new_std(&chip->hdl,
+				&tvaudio_ctrl_ops, V4L2_CID_AUDIO_TREBLE,
+				0, 65535, 65535 / 100,
+				desc->trebleinit ? desc->trebleinit : 32768);
 		}
 	}
 
+	sd->ctrl_handler = &chip->hdl;
+	if (chip->hdl.error) {
+		int err = chip->hdl.error;
+
+		v4l2_ctrl_handler_free(&chip->hdl);
+		kfree(chip);
+		return err;
+	}
+	/* set controls to the default values */
+	v4l2_ctrl_handler_setup(&chip->hdl);
+
 	chip->thread = NULL;
 	init_timer(&chip->wt);
 	if (desc->flags & CHIP_NEED_CHECKMODE) {
@@ -2105,6 +2030,7 @@ static int tvaudio_remove(struct i2c_client *client)
 	}
 
 	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&chip->hdl);
 	kfree(chip);
 	return 0;
 }
-- 
1.7.10.4


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

* [REVIEW PATCH 3/3] mt9v011: convert to the control framework.
  2013-01-24  7:51 ` [REVIEW PATCH 1/3] Move DV-class control IDs from videodev2.h to v4l2-controls.h Hans Verkuil
  2013-01-24  7:51   ` [REVIEW PATCH 2/3] tvaudio: convert to the control framework Hans Verkuil
@ 2013-01-24  7:51   ` Hans Verkuil
  2013-01-25 16:56     ` Frank Schäfer
  1 sibling, 1 reply; 5+ messages in thread
From: Hans Verkuil @ 2013-01-24  7:51 UTC (permalink / raw)
  To: linux-media; +Cc: Devin Heitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/mt9v011.c |  223 +++++++++++++------------------------------
 1 file changed, 67 insertions(+), 156 deletions(-)

diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 6bf01ad..73b7688 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -13,6 +13,7 @@
 #include <asm/div64.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
 #include <media/mt9v011.h>
 
 MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
@@ -48,68 +49,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
 #define MT9V011_VERSION			0x8232
 #define MT9V011_REV_B_VERSION		0x8243
 
-/* supported controls */
-static struct v4l2_queryctrl mt9v011_qctrl[] = {
-	{
-		.id = V4L2_CID_GAIN,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Gain",
-		.minimum = 0,
-		.maximum = (1 << 12) - 1 - 0x0020,
-		.step = 1,
-		.default_value = 0x0020,
-		.flags = 0,
-	}, {
-		.id = V4L2_CID_EXPOSURE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Exposure",
-		.minimum = 0,
-		.maximum = 2047,
-		.step = 1,
-		.default_value = 0x01fc,
-		.flags = 0,
-	}, {
-		.id = V4L2_CID_RED_BALANCE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Red Balance",
-		.minimum = -1 << 9,
-		.maximum = (1 << 9) - 1,
-		.step = 1,
-		.default_value = 0,
-		.flags = 0,
-	}, {
-		.id = V4L2_CID_BLUE_BALANCE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Blue Balance",
-		.minimum = -1 << 9,
-		.maximum = (1 << 9) - 1,
-		.step = 1,
-		.default_value = 0,
-		.flags = 0,
-	}, {
-		.id      = V4L2_CID_HFLIP,
-		.type    = V4L2_CTRL_TYPE_BOOLEAN,
-		.name    = "Mirror",
-		.minimum = 0,
-		.maximum = 1,
-		.step    = 1,
-		.default_value = 0,
-		.flags = 0,
-	}, {
-		.id      = V4L2_CID_VFLIP,
-		.type    = V4L2_CTRL_TYPE_BOOLEAN,
-		.name    = "Vflip",
-		.minimum = 0,
-		.maximum = 1,
-		.step    = 1,
-		.default_value = 0,
-		.flags = 0,
-	}, {
-	}
-};
-
 struct mt9v011 {
 	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler ctrls;
 	unsigned width, height;
 	unsigned xtal;
 	unsigned hflip:1;
@@ -381,99 +323,6 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
 	set_read_mode(sd);
 
 	return 0;
-};
-
-static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-	struct mt9v011 *core = to_mt9v011(sd);
-
-	v4l2_dbg(1, debug, sd, "g_ctrl called\n");
-
-	switch (ctrl->id) {
-	case V4L2_CID_GAIN:
-		ctrl->value = core->global_gain;
-		return 0;
-	case V4L2_CID_EXPOSURE:
-		ctrl->value = core->exposure;
-		return 0;
-	case V4L2_CID_RED_BALANCE:
-		ctrl->value = core->red_bal;
-		return 0;
-	case V4L2_CID_BLUE_BALANCE:
-		ctrl->value = core->blue_bal;
-		return 0;
-	case V4L2_CID_HFLIP:
-		ctrl->value = core->hflip ? 1 : 0;
-		return 0;
-	case V4L2_CID_VFLIP:
-		ctrl->value = core->vflip ? 1 : 0;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-	int i;
-
-	v4l2_dbg(1, debug, sd, "queryctrl called\n");
-
-	for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++)
-		if (qc->id && qc->id == mt9v011_qctrl[i].id) {
-			memcpy(qc, &(mt9v011_qctrl[i]),
-			       sizeof(*qc));
-			return 0;
-		}
-
-	return -EINVAL;
-}
-
-
-static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-	struct mt9v011 *core = to_mt9v011(sd);
-	u8 i, n;
-	n = ARRAY_SIZE(mt9v011_qctrl);
-
-	for (i = 0; i < n; i++) {
-		if (ctrl->id != mt9v011_qctrl[i].id)
-			continue;
-		if (ctrl->value < mt9v011_qctrl[i].minimum ||
-		    ctrl->value > mt9v011_qctrl[i].maximum)
-			return -ERANGE;
-		v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
-					ctrl->id, ctrl->value);
-		break;
-	}
-
-	switch (ctrl->id) {
-	case V4L2_CID_GAIN:
-		core->global_gain = ctrl->value;
-		break;
-	case V4L2_CID_EXPOSURE:
-		core->exposure = ctrl->value;
-		break;
-	case V4L2_CID_RED_BALANCE:
-		core->red_bal = ctrl->value;
-		break;
-	case V4L2_CID_BLUE_BALANCE:
-		core->blue_bal = ctrl->value;
-		break;
-	case V4L2_CID_HFLIP:
-		core->hflip = ctrl->value;
-		set_read_mode(sd);
-		return 0;
-	case V4L2_CID_VFLIP:
-		core->vflip = ctrl->value;
-		set_read_mode(sd);
-		return 0;
-	default:
-		return -EINVAL;
-	}
-
-	set_balance(sd);
-
-	return 0;
 }
 
 static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
@@ -599,10 +448,46 @@ static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
 					  version);
 }
 
-static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
-	.queryctrl = mt9v011_queryctrl,
-	.g_ctrl = mt9v011_g_ctrl,
+static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct mt9v011 *core =
+		container_of(ctrl->handler, struct mt9v011, ctrls);
+	struct v4l2_subdev *sd = &core->sd;
+
+	switch (ctrl->id) {
+	case V4L2_CID_GAIN:
+		core->global_gain = ctrl->val;
+		break;
+	case V4L2_CID_EXPOSURE:
+		core->exposure = ctrl->val;
+		break;
+	case V4L2_CID_RED_BALANCE:
+		core->red_bal = ctrl->val;
+		break;
+	case V4L2_CID_BLUE_BALANCE:
+		core->blue_bal = ctrl->val;
+		break;
+	case V4L2_CID_HFLIP:
+		core->hflip = ctrl->val;
+		set_read_mode(sd);
+		return 0;
+	case V4L2_CID_VFLIP:
+		core->vflip = ctrl->val;
+		set_read_mode(sd);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+
+	set_balance(sd);
+	return 0;
+}
+
+static struct v4l2_ctrl_ops mt9v011_ctrl_ops = {
 	.s_ctrl = mt9v011_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
 	.reset = mt9v011_reset,
 	.g_chip_ident = mt9v011_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -658,6 +543,30 @@ static int mt9v011_probe(struct i2c_client *c,
 		return -EINVAL;
 	}
 
+	v4l2_ctrl_handler_init(&core->ctrls, 5);
+	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+			  V4L2_CID_GAIN, 0, (1 << 12) - 1 - 0x20, 1, 0x20);
+	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+			  V4L2_CID_EXPOSURE, 0, 2047, 1, 0x01fc);
+	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+			  V4L2_CID_RED_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0);
+	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+			  V4L2_CID_BLUE_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0);
+	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+			  V4L2_CID_HFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+			  V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+	if (core->ctrls.error) {
+		int ret = core->ctrls.error;
+
+		v4l2_err(sd, "control initialization error %d\n", ret);
+		v4l2_ctrl_handler_free(&core->ctrls);
+		kfree(core);
+		return ret;
+	}
+	core->sd.ctrl_handler = &core->ctrls;
+
 	core->global_gain = 0x0024;
 	core->exposure = 0x01fc;
 	core->width  = 640;
@@ -681,12 +590,14 @@ static int mt9v011_probe(struct i2c_client *c,
 static int mt9v011_remove(struct i2c_client *c)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(c);
+	struct mt9v011 *core = to_mt9v011(sd);
 
 	v4l2_dbg(1, debug, sd,
 		"mt9v011.c: removing mt9v011 adapter on address 0x%x\n",
 		c->addr << 1);
 
 	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&core->ctrls);
 	kfree(to_mt9v011(sd));
 	return 0;
 }
-- 
1.7.10.4


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

* Re: [REVIEW PATCH 3/3] mt9v011: convert to the control framework.
  2013-01-24  7:51   ` [REVIEW PATCH 3/3] mt9v011: " Hans Verkuil
@ 2013-01-25 16:56     ` Frank Schäfer
  0 siblings, 0 replies; 5+ messages in thread
From: Frank Schäfer @ 2013-01-25 16:56 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, Devin Heitmueller, Hans Verkuil

Am 24.01.2013 08:51, schrieb Hans Verkuil:
> From: Hans Verkuil <hans.verkuil@cisco.com>
>
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/media/i2c/mt9v011.c |  223 +++++++++++++------------------------------
>  1 file changed, 67 insertions(+), 156 deletions(-)
>
> diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
> index 6bf01ad..73b7688 100644
> --- a/drivers/media/i2c/mt9v011.c
> +++ b/drivers/media/i2c/mt9v011.c
> @@ -13,6 +13,7 @@
>  #include <asm/div64.h>
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-chip-ident.h>
> +#include <media/v4l2-ctrls.h>
>  #include <media/mt9v011.h>
>  
>  MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
> @@ -48,68 +49,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
>  #define MT9V011_VERSION			0x8232
>  #define MT9V011_REV_B_VERSION		0x8243
>  
> -/* supported controls */
> -static struct v4l2_queryctrl mt9v011_qctrl[] = {
> -	{
> -		.id = V4L2_CID_GAIN,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "Gain",
> -		.minimum = 0,
> -		.maximum = (1 << 12) - 1 - 0x0020,
> -		.step = 1,
> -		.default_value = 0x0020,
> -		.flags = 0,
> -	}, {
> -		.id = V4L2_CID_EXPOSURE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "Exposure",
> -		.minimum = 0,
> -		.maximum = 2047,
> -		.step = 1,
> -		.default_value = 0x01fc,
> -		.flags = 0,
> -	}, {
> -		.id = V4L2_CID_RED_BALANCE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "Red Balance",
> -		.minimum = -1 << 9,
> -		.maximum = (1 << 9) - 1,
> -		.step = 1,
> -		.default_value = 0,
> -		.flags = 0,
> -	}, {
> -		.id = V4L2_CID_BLUE_BALANCE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "Blue Balance",
> -		.minimum = -1 << 9,
> -		.maximum = (1 << 9) - 1,
> -		.step = 1,
> -		.default_value = 0,
> -		.flags = 0,
> -	}, {
> -		.id      = V4L2_CID_HFLIP,
> -		.type    = V4L2_CTRL_TYPE_BOOLEAN,
> -		.name    = "Mirror",
> -		.minimum = 0,
> -		.maximum = 1,
> -		.step    = 1,
> -		.default_value = 0,
> -		.flags = 0,
> -	}, {
> -		.id      = V4L2_CID_VFLIP,
> -		.type    = V4L2_CTRL_TYPE_BOOLEAN,
> -		.name    = "Vflip",
> -		.minimum = 0,
> -		.maximum = 1,
> -		.step    = 1,
> -		.default_value = 0,
> -		.flags = 0,
> -	}, {
> -	}
> -};
> -
>  struct mt9v011 {
>  	struct v4l2_subdev sd;
> +	struct v4l2_ctrl_handler ctrls;
>  	unsigned width, height;
>  	unsigned xtal;
>  	unsigned hflip:1;
> @@ -381,99 +323,6 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
>  	set_read_mode(sd);
>  
>  	return 0;
> -};
> -
> -static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
> -{
> -	struct mt9v011 *core = to_mt9v011(sd);
> -
> -	v4l2_dbg(1, debug, sd, "g_ctrl called\n");
> -
> -	switch (ctrl->id) {
> -	case V4L2_CID_GAIN:
> -		ctrl->value = core->global_gain;
> -		return 0;
> -	case V4L2_CID_EXPOSURE:
> -		ctrl->value = core->exposure;
> -		return 0;
> -	case V4L2_CID_RED_BALANCE:
> -		ctrl->value = core->red_bal;
> -		return 0;
> -	case V4L2_CID_BLUE_BALANCE:
> -		ctrl->value = core->blue_bal;
> -		return 0;
> -	case V4L2_CID_HFLIP:
> -		ctrl->value = core->hflip ? 1 : 0;
> -		return 0;
> -	case V4L2_CID_VFLIP:
> -		ctrl->value = core->vflip ? 1 : 0;
> -		return 0;
> -	}
> -	return -EINVAL;
> -}
> -
> -static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
> -{
> -	int i;
> -
> -	v4l2_dbg(1, debug, sd, "queryctrl called\n");
> -
> -	for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++)
> -		if (qc->id && qc->id == mt9v011_qctrl[i].id) {
> -			memcpy(qc, &(mt9v011_qctrl[i]),
> -			       sizeof(*qc));
> -			return 0;
> -		}
> -
> -	return -EINVAL;
> -}
> -
> -
> -static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
> -{
> -	struct mt9v011 *core = to_mt9v011(sd);
> -	u8 i, n;
> -	n = ARRAY_SIZE(mt9v011_qctrl);
> -
> -	for (i = 0; i < n; i++) {
> -		if (ctrl->id != mt9v011_qctrl[i].id)
> -			continue;
> -		if (ctrl->value < mt9v011_qctrl[i].minimum ||
> -		    ctrl->value > mt9v011_qctrl[i].maximum)
> -			return -ERANGE;
> -		v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
> -					ctrl->id, ctrl->value);
> -		break;
> -	}
> -
> -	switch (ctrl->id) {
> -	case V4L2_CID_GAIN:
> -		core->global_gain = ctrl->value;
> -		break;
> -	case V4L2_CID_EXPOSURE:
> -		core->exposure = ctrl->value;
> -		break;
> -	case V4L2_CID_RED_BALANCE:
> -		core->red_bal = ctrl->value;
> -		break;
> -	case V4L2_CID_BLUE_BALANCE:
> -		core->blue_bal = ctrl->value;
> -		break;
> -	case V4L2_CID_HFLIP:
> -		core->hflip = ctrl->value;
> -		set_read_mode(sd);
> -		return 0;
> -	case V4L2_CID_VFLIP:
> -		core->vflip = ctrl->value;
> -		set_read_mode(sd);
> -		return 0;
> -	default:
> -		return -EINVAL;
> -	}
> -
> -	set_balance(sd);
> -
> -	return 0;
>  }
>  
>  static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
> @@ -599,10 +448,46 @@ static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
>  					  version);
>  }
>  
> -static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
> -	.queryctrl = mt9v011_queryctrl,
> -	.g_ctrl = mt9v011_g_ctrl,
> +static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct mt9v011 *core =
> +		container_of(ctrl->handler, struct mt9v011, ctrls);
> +	struct v4l2_subdev *sd = &core->sd;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_GAIN:
> +		core->global_gain = ctrl->val;
> +		break;
> +	case V4L2_CID_EXPOSURE:
> +		core->exposure = ctrl->val;
> +		break;
> +	case V4L2_CID_RED_BALANCE:
> +		core->red_bal = ctrl->val;
> +		break;
> +	case V4L2_CID_BLUE_BALANCE:
> +		core->blue_bal = ctrl->val;
> +		break;
> +	case V4L2_CID_HFLIP:
> +		core->hflip = ctrl->val;
> +		set_read_mode(sd);
> +		return 0;
> +	case V4L2_CID_VFLIP:
> +		core->vflip = ctrl->val;
> +		set_read_mode(sd);
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	set_balance(sd);
> +	return 0;
> +}
> +
> +static struct v4l2_ctrl_ops mt9v011_ctrl_ops = {
>  	.s_ctrl = mt9v011_s_ctrl,
> +};
> +
> +static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
>  	.reset = mt9v011_reset,
>  	.g_chip_ident = mt9v011_g_chip_ident,
>  #ifdef CONFIG_VIDEO_ADV_DEBUG
> @@ -658,6 +543,30 @@ static int mt9v011_probe(struct i2c_client *c,
>  		return -EINVAL;
>  	}
>  
> +	v4l2_ctrl_handler_init(&core->ctrls, 5);
> +	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
> +			  V4L2_CID_GAIN, 0, (1 << 12) - 1 - 0x20, 1, 0x20);
> +	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
> +			  V4L2_CID_EXPOSURE, 0, 2047, 1, 0x01fc);
> +	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
> +			  V4L2_CID_RED_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0);
> +	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
> +			  V4L2_CID_BLUE_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0);
> +	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
> +			  V4L2_CID_HFLIP, 0, 1, 1, 0);
> +	v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
> +			  V4L2_CID_VFLIP, 0, 1, 1, 0);
> +
> +	if (core->ctrls.error) {
> +		int ret = core->ctrls.error;
> +
> +		v4l2_err(sd, "control initialization error %d\n", ret);
> +		v4l2_ctrl_handler_free(&core->ctrls);
> +		kfree(core);
> +		return ret;
> +	}
> +	core->sd.ctrl_handler = &core->ctrls;
> +
>  	core->global_gain = 0x0024;
>  	core->exposure = 0x01fc;
>  	core->width  = 640;
> @@ -681,12 +590,14 @@ static int mt9v011_probe(struct i2c_client *c,
>  static int mt9v011_remove(struct i2c_client *c)
>  {
>  	struct v4l2_subdev *sd = i2c_get_clientdata(c);
> +	struct mt9v011 *core = to_mt9v011(sd);
>  
>  	v4l2_dbg(1, debug, sd,
>  		"mt9v011.c: removing mt9v011 adapter on address 0x%x\n",
>  		c->addr << 1);
>  
>  	v4l2_device_unregister_subdev(sd);
> +	v4l2_ctrl_handler_free(&core->ctrls);
>  	kfree(to_mt9v011(sd));
>  	return 0;
>  }

Tested-by: Frank Schäfer <fschaefer.oss@googlemail.com>

Fixes the em28xx regression (no image control with "Silvercrest 1.3MPix
webcam") in the media-tree.

Regards,
Frank


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

end of thread, other threads:[~2013-01-25 16:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-24  7:51 [REVIEW PATCH 0/3] Control header fix and convert tvaudio/mt9v011 to the controlfw Hans Verkuil
2013-01-24  7:51 ` [REVIEW PATCH 1/3] Move DV-class control IDs from videodev2.h to v4l2-controls.h Hans Verkuil
2013-01-24  7:51   ` [REVIEW PATCH 2/3] tvaudio: convert to the control framework Hans Verkuil
2013-01-24  7:51   ` [REVIEW PATCH 3/3] mt9v011: " Hans Verkuil
2013-01-25 16:56     ` Frank Schäfer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.