diff options
author | Sakari Ailus <sakari.ailus@iki.fi> | 2012-03-15 17:01:39 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-13 15:26:05 -0400 |
commit | 41a33a00e82a897f973a98355e43e78efaa292e1 (patch) | |
tree | d54095dbea104a5394470617d8252e0bd53f90a9 /drivers/media/i2c | |
parent | 03d5285b8b320994b57b610553cf2b019186b5ba (diff) |
[media] mt9v032: Provide pixel rate control
Provide pixel rate control calculated from external clock and horizontal
binning factor.
Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r-- | drivers/media/i2c/mt9v032.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index 4ba4884c016e..2203a6f52e48 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c | |||
@@ -122,6 +122,7 @@ struct mt9v032 { | |||
122 | struct v4l2_mbus_framefmt format; | 122 | struct v4l2_mbus_framefmt format; |
123 | struct v4l2_rect crop; | 123 | struct v4l2_rect crop; |
124 | 124 | ||
125 | struct v4l2_ctrl *pixel_rate; | ||
125 | struct v4l2_ctrl_handler ctrls; | 126 | struct v4l2_ctrl_handler ctrls; |
126 | 127 | ||
127 | struct mutex power_lock; | 128 | struct mutex power_lock; |
@@ -187,13 +188,15 @@ mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable) | |||
187 | return 0; | 188 | return 0; |
188 | } | 189 | } |
189 | 190 | ||
191 | #define EXT_CLK 25000000 | ||
192 | |||
190 | static int mt9v032_power_on(struct mt9v032 *mt9v032) | 193 | static int mt9v032_power_on(struct mt9v032 *mt9v032) |
191 | { | 194 | { |
192 | struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); | 195 | struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); |
193 | int ret; | 196 | int ret; |
194 | 197 | ||
195 | if (mt9v032->pdata->set_clock) { | 198 | if (mt9v032->pdata->set_clock) { |
196 | mt9v032->pdata->set_clock(&mt9v032->subdev, 25000000); | 199 | mt9v032->pdata->set_clock(&mt9v032->subdev, EXT_CLK); |
197 | udelay(1); | 200 | udelay(1); |
198 | } | 201 | } |
199 | 202 | ||
@@ -365,6 +368,17 @@ static int mt9v032_get_format(struct v4l2_subdev *subdev, | |||
365 | return 0; | 368 | return 0; |
366 | } | 369 | } |
367 | 370 | ||
371 | static void mt9v032_configure_pixel_rate(struct mt9v032 *mt9v032, | ||
372 | unsigned int hratio) | ||
373 | { | ||
374 | struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); | ||
375 | int ret; | ||
376 | |||
377 | ret = v4l2_ctrl_s_ctrl_int64(mt9v032->pixel_rate, EXT_CLK / hratio); | ||
378 | if (ret < 0) | ||
379 | dev_warn(&client->dev, "failed to set pixel rate (%d)\n", ret); | ||
380 | } | ||
381 | |||
368 | static int mt9v032_set_format(struct v4l2_subdev *subdev, | 382 | static int mt9v032_set_format(struct v4l2_subdev *subdev, |
369 | struct v4l2_subdev_fh *fh, | 383 | struct v4l2_subdev_fh *fh, |
370 | struct v4l2_subdev_format *format) | 384 | struct v4l2_subdev_format *format) |
@@ -395,6 +409,8 @@ static int mt9v032_set_format(struct v4l2_subdev *subdev, | |||
395 | format->which); | 409 | format->which); |
396 | __format->width = __crop->width / hratio; | 410 | __format->width = __crop->width / hratio; |
397 | __format->height = __crop->height / vratio; | 411 | __format->height = __crop->height / vratio; |
412 | if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) | ||
413 | mt9v032_configure_pixel_rate(mt9v032, hratio); | ||
398 | 414 | ||
399 | format->format = *__format; | 415 | format->format = *__format; |
400 | 416 | ||
@@ -450,6 +466,8 @@ static int mt9v032_set_crop(struct v4l2_subdev *subdev, | |||
450 | crop->which); | 466 | crop->which); |
451 | __format->width = rect.width; | 467 | __format->width = rect.width; |
452 | __format->height = rect.height; | 468 | __format->height = rect.height; |
469 | if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) | ||
470 | mt9v032_configure_pixel_rate(mt9v032, 1); | ||
453 | } | 471 | } |
454 | 472 | ||
455 | *__crop = rect; | 473 | *__crop = rect; |
@@ -598,6 +616,8 @@ static int mt9v032_registered(struct v4l2_subdev *subdev) | |||
598 | dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n", | 616 | dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n", |
599 | client->addr); | 617 | client->addr); |
600 | 618 | ||
619 | mt9v032_configure_pixel_rate(mt9v032, 1); | ||
620 | |||
601 | return ret; | 621 | return ret; |
602 | } | 622 | } |
603 | 623 | ||
@@ -681,7 +701,7 @@ static int mt9v032_probe(struct i2c_client *client, | |||
681 | mutex_init(&mt9v032->power_lock); | 701 | mutex_init(&mt9v032->power_lock); |
682 | mt9v032->pdata = client->dev.platform_data; | 702 | mt9v032->pdata = client->dev.platform_data; |
683 | 703 | ||
684 | v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 4); | 704 | v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 5); |
685 | 705 | ||
686 | v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, | 706 | v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, |
687 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | 707 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); |
@@ -695,6 +715,9 @@ static int mt9v032_probe(struct i2c_client *client, | |||
695 | V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN, | 715 | V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN, |
696 | MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1, | 716 | MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1, |
697 | MT9V032_TOTAL_SHUTTER_WIDTH_DEF); | 717 | MT9V032_TOTAL_SHUTTER_WIDTH_DEF); |
718 | mt9v032->pixel_rate = | ||
719 | v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, | ||
720 | V4L2_CID_PIXEL_RATE, 0, 0, 1, 0); | ||
698 | 721 | ||
699 | for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i) | 722 | for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i) |
700 | v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL); | 723 | v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL); |