diff mbox

[v2] mt9v032: Provide link frequency control

Message ID 1343807974-4038-1-git-send-email-laurent.pinchart@ideasonboard.com (mailing list archive)
State New, archived
Headers show

Commit Message

Laurent Pinchart Aug. 1, 2012, 7:59 a.m. UTC
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/video/mt9v032.c |   48 ++++++++++++++++++++++++++++++++++++----
 include/media/mt9v032.h       |    3 ++
 2 files changed, 46 insertions(+), 5 deletions(-)

Changes compared to v1:

- Assign pixel_rate->val64 instead of pixel_rate->cur.val

Comments

Sakari Ailus Aug. 13, 2012, 2:20 p.m. UTC | #1
Hi Laurent,

Laurent Pinchart wrote:
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  drivers/media/video/mt9v032.c |   48 ++++++++++++++++++++++++++++++++++++----
>  include/media/mt9v032.h       |    3 ++
>  2 files changed, 46 insertions(+), 5 deletions(-)

Acked-by: Sakari Ailus <sakari.ailus@iki.fi>

I ack this with the assumption that the issues I've brought up previously in
conjunction with the first version of this patch will be fixed, but it
doesn't need to be done right now.

Regards,
diff mbox

Patch

diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c
index 2203a6f..bf591b8 100644
--- a/drivers/media/video/mt9v032.c
+++ b/drivers/media/video/mt9v032.c
@@ -29,6 +29,8 @@ 
 #define MT9V032_PIXEL_ARRAY_HEIGHT			492
 #define MT9V032_PIXEL_ARRAY_WIDTH			782
 
+#define MT9V032_SYSCLK_FREQ_DEF				26600000
+
 #define MT9V032_CHIP_VERSION				0x00
 #define		MT9V032_CHIP_ID_REV1			0x1311
 #define		MT9V032_CHIP_ID_REV3			0x1313
@@ -122,13 +124,18 @@  struct mt9v032 {
 	struct v4l2_mbus_framefmt format;
 	struct v4l2_rect crop;
 
-	struct v4l2_ctrl *pixel_rate;
 	struct v4l2_ctrl_handler ctrls;
+	struct {
+		struct v4l2_ctrl *link_freq;
+		struct v4l2_ctrl *pixel_rate;
+	};
 
 	struct mutex power_lock;
 	int power_count;
 
 	struct mt9v032_platform_data *pdata;
+
+	u32 sysclk;
 	u16 chip_control;
 	u16 aec_agc;
 };
@@ -196,7 +203,7 @@  static int mt9v032_power_on(struct mt9v032 *mt9v032)
 	int ret;
 
 	if (mt9v032->pdata->set_clock) {
-		mt9v032->pdata->set_clock(&mt9v032->subdev, EXT_CLK);
+		mt9v032->pdata->set_clock(&mt9v032->subdev, mt9v032->sysclk);
 		udelay(1);
 	}
 
@@ -374,7 +381,8 @@  static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032,
 	struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
 	int ret;
 
-	ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate, EXT_CLK / hratio);
+	ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate,
+				     mt9v032->sysclk / hratio);
 	if (ret < 0)
 		dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret);
 }
@@ -487,6 +495,7 @@  static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
 	struct mt9v032 *mt9v032 =
 			container_of(ctrl->handler, struct mt9v032, ctrls);
 	struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+	u32 freq;
 	u16 data;
 
 	switch (ctrl->id) {
@@ -505,6 +514,16 @@  static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
 		return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
 				     ctrl->val);
 
+	case V4L2_CID_PIXEL_RATE:
+	case V4L2_CID_LINK_FREQ:
+		if (mt9v032->link_freq == NULL)
+			break;
+
+		freq = mt9v032->pdata->link_freqs[mt9v032->link_freq->val];
+		mt9v032->pixel_rate->val64 = freq;
+		mt9v032->sysclk = freq;
+		break;
+
 	case V4L2_CID_TEST_PATTERN:
 		switch (ctrl->val) {
 		case 0:
@@ -683,6 +702,7 @@  static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
 static int mt9v032_probe(struct i2c_client *client,
 		const struct i2c_device_id *did)
 {
+	struct mt9v032_platform_data *pdata = client->dev.platform_data;
 	struct mt9v032 *mt9v032;
 	unsigned int i;
 	int ret;
@@ -699,9 +719,9 @@  static int mt9v032_probe(struct i2c_client *client,
 		return -ENOMEM;
 
 	mutex_init(&mt9v032->power_lock);
-	mt9v032->pdata = client->dev.platform_data;
+	mt9v032->pdata = pdata;
 
-	v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 5);
+	v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 6);
 
 	v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
 			  V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
@@ -715,10 +735,27 @@  static int mt9v032_probe(struct i2c_client *client,
 			  V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
 			  MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
 			  MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
+
 	mt9v032->pixel_rate =
 		v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
 				  V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
 
+	if (pdata && pdata->link_freqs) {
+		unsigned int def = 0;
+
+		for (i = 0; pdata->link_freqs[i]; ++i) {
+			if (pdata->link_freqs[i] == pdata->link_def_freq)
+				def = i;
+		}
+
+		mt9v032->link_freq =
+			v4l2_ctrl_new_int_menu(&mt9v032->ctrls,
+					       &mt9v032_ctrl_ops,
+					       V4L2_CID_LINK_FREQ, i - 1, def,
+					       pdata->link_freqs);
+		v4l2_ctrl_cluster(2, &mt9v032->link_freq);
+	}
+
 	for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i)
 		v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL);
 
@@ -740,6 +777,7 @@  static int mt9v032_probe(struct i2c_client *client,
 	mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
 
 	mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
+	mt9v032->sysclk = MT9V032_SYSCLK_FREQ_DEF;
 
 	v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
 	mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;
diff --git a/include/media/mt9v032.h b/include/media/mt9v032.h
index 5e27f9b..78fd39e 100644
--- a/include/media/mt9v032.h
+++ b/include/media/mt9v032.h
@@ -7,6 +7,9 @@  struct mt9v032_platform_data {
 	unsigned int clk_pol:1;
 
 	void (*set_clock)(struct v4l2_subdev *subdev, unsigned int rate);
+
+	const s64 *link_freqs;
+	s64 link_def_freq;
 };
 
 #endif