aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/mt9v032.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-07-26 07:02:50 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-09-13 15:29:07 -0400
commite9a50e4c2dd8ca871c20480e49125ef67da84722 (patch)
treed9cc020b0479d2de5a9abbccb2ffe0990bef4481 /drivers/media/i2c/mt9v032.c
parent41a33a00e82a897f973a98355e43e78efaa292e1 (diff)
[media] mt9v032: Provide link frequency control
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/i2c/mt9v032.c')
-rw-r--r--drivers/media/i2c/mt9v032.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 2203a6f52e48..bf591b891a74 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -29,6 +29,8 @@
29#define MT9V032_PIXEL_ARRAY_HEIGHT 492 29#define MT9V032_PIXEL_ARRAY_HEIGHT 492
30#define MT9V032_PIXEL_ARRAY_WIDTH 782 30#define MT9V032_PIXEL_ARRAY_WIDTH 782
31 31
32#define MT9V032_SYSCLK_FREQ_DEF 26600000
33
32#define MT9V032_CHIP_VERSION 0x00 34#define MT9V032_CHIP_VERSION 0x00
33#define MT9V032_CHIP_ID_REV1 0x1311 35#define MT9V032_CHIP_ID_REV1 0x1311
34#define MT9V032_CHIP_ID_REV3 0x1313 36#define MT9V032_CHIP_ID_REV3 0x1313
@@ -122,13 +124,18 @@ struct mt9v032 {
122 struct v4l2_mbus_framefmt format; 124 struct v4l2_mbus_framefmt format;
123 struct v4l2_rect crop; 125 struct v4l2_rect crop;
124 126
125 struct v4l2_ctrl *pixel_rate;
126 struct v4l2_ctrl_handler ctrls; 127 struct v4l2_ctrl_handler ctrls;
128 struct {
129 struct v4l2_ctrl *link_freq;
130 struct v4l2_ctrl *pixel_rate;
131 };
127 132
128 struct mutex power_lock; 133 struct mutex power_lock;
129 int power_count; 134 int power_count;
130 135
131 struct mt9v032_platform_data *pdata; 136 struct mt9v032_platform_data *pdata;
137
138 u32 sysclk;
132 u16 chip_control; 139 u16 chip_control;
133 u16 aec_agc; 140 u16 aec_agc;
134}; 141};
@@ -196,7 +203,7 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
196 int ret; 203 int ret;
197 204
198 if (mt9v032->pdata->set_clock) { 205 if (mt9v032->pdata->set_clock) {
199 mt9v032->pdata->set_clock(&mt9v032->subdev, EXT_CLK); 206 mt9v032->pdata->set_clock(&mt9v032->subdev, mt9v032->sysclk);
200 udelay(1); 207 udelay(1);
201 } 208 }
202 209
@@ -374,7 +381,8 @@ static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032,
374 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); 381 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
375 int ret; 382 int ret;
376 383
377 ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate, EXT_CLK / hratio); 384 ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate,
385 mt9v032->sysclk / hratio);
378 if (ret < 0) 386 if (ret < 0)
379 dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret); 387 dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret);
380} 388}
@@ -487,6 +495,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
487 struct mt9v032 *mt9v032 = 495 struct mt9v032 *mt9v032 =
488 container_of(ctrl->handler, struct mt9v032, ctrls); 496 container_of(ctrl->handler, struct mt9v032, ctrls);
489 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); 497 struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
498 u32 freq;
490 u16 data; 499 u16 data;
491 500
492 switch (ctrl->id) { 501 switch (ctrl->id) {
@@ -505,6 +514,16 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
505 return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH, 514 return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
506 ctrl->val); 515 ctrl->val);
507 516
517 case V4L2_CID_PIXEL_RATE:
518 case V4L2_CID_LINK_FREQ:
519 if (mt9v032->link_freq == NULL)
520 break;
521
522 freq = mt9v032->pdata->link_freqs[mt9v032->link_freq->val];
523 mt9v032->pixel_rate->val64 = freq;
524 mt9v032->sysclk = freq;
525 break;
526
508 case V4L2_CID_TEST_PATTERN: 527 case V4L2_CID_TEST_PATTERN:
509 switch (ctrl->val) { 528 switch (ctrl->val) {
510 case 0: 529 case 0:
@@ -683,6 +702,7 @@ static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
683static int mt9v032_probe(struct i2c_client *client, 702static int mt9v032_probe(struct i2c_client *client,
684 const struct i2c_device_id *did) 703 const struct i2c_device_id *did)
685{ 704{
705 struct mt9v032_platform_data *pdata = client->dev.platform_data;
686 struct mt9v032 *mt9v032; 706 struct mt9v032 *mt9v032;
687 unsigned int i; 707 unsigned int i;
688 int ret; 708 int ret;
@@ -699,9 +719,9 @@ static int mt9v032_probe(struct i2c_client *client,
699 return -ENOMEM; 719 return -ENOMEM;
700 720
701 mutex_init(&mt9v032->power_lock); 721 mutex_init(&mt9v032->power_lock);
702 mt9v032->pdata = client->dev.platform_data; 722 mt9v032->pdata = pdata;
703 723
704 v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 5); 724 v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 6);
705 725
706 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 726 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
707 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 727 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
@@ -715,10 +735,27 @@ static int mt9v032_probe(struct i2c_client *client,
715 V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN, 735 V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
716 MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1, 736 MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
717 MT9V032_TOTAL_SHUTTER_WIDTH_DEF); 737 MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
738
718 mt9v032->pixel_rate = 739 mt9v032->pixel_rate =
719 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, 740 v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
720 V4L2_CID_PIXEL_RATE, 0, 0, 1, 0); 741 V4L2_CID_PIXEL_RATE, 0, 0, 1, 0);
721 742
743 if (pdata && pdata->link_freqs) {
744 unsigned int def = 0;
745
746 for (i = 0; pdata->link_freqs[i]; ++i) {
747 if (pdata->link_freqs[i] == pdata->link_def_freq)
748 def = i;
749 }
750
751 mt9v032->link_freq =
752 v4l2_ctrl_new_int_menu(&mt9v032->ctrls,
753 &mt9v032_ctrl_ops,
754 V4L2_CID_LINK_FREQ, i - 1, def,
755 pdata->link_freqs);
756 v4l2_ctrl_cluster(2, &mt9v032->link_freq);
757 }
758
722 for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i) 759 for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i)
723 v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL); 760 v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL);
724 761
@@ -740,6 +777,7 @@ static int mt9v032_probe(struct i2c_client *client,
740 mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB; 777 mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
741 778
742 mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE; 779 mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
780 mt9v032->sysclk = MT9V032_SYSCLK_FREQ_DEF;
743 781
744 v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops); 782 v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
745 mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops; 783 mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;