aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2011-09-07 05:08:51 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-03 16:28:54 -0400
commit41efcd7a6862951fd13c0e950ef05b865d7488a8 (patch)
tree468aa97160eeb208d96c8f5d4f1feed2abab4f22 /drivers/media
parentaf8425c54beb3c32cbb503a379132b3975535289 (diff)
[media] mt9t031: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> [g.liakhovetski@gmx.de: simplified pointer arithmetic] Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/mt9t031.c252
1 files changed, 86 insertions, 166 deletions
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 25fb833f6f2..7ce37990a44 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -19,6 +19,7 @@
19#include <media/soc_mediabus.h> 19#include <media/soc_mediabus.h>
20#include <media/v4l2-chip-ident.h> 20#include <media/v4l2-chip-ident.h>
21#include <media/v4l2-subdev.h> 21#include <media/v4l2-subdev.h>
22#include <media/v4l2-ctrls.h>
22 23
23/* 24/*
24 * mt9t031 i2c address 0x5d 25 * mt9t031 i2c address 0x5d
@@ -60,14 +61,18 @@
60 61
61struct mt9t031 { 62struct mt9t031 {
62 struct v4l2_subdev subdev; 63 struct v4l2_subdev subdev;
64 struct v4l2_ctrl_handler hdl;
65 struct {
66 /* exposure/auto-exposure cluster */
67 struct v4l2_ctrl *autoexposure;
68 struct v4l2_ctrl *exposure;
69 };
63 struct v4l2_rect rect; /* Sensor window */ 70 struct v4l2_rect rect; /* Sensor window */
64 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ 71 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
65 u16 xskip; 72 u16 xskip;
66 u16 yskip; 73 u16 yskip;
67 unsigned int gain; 74 unsigned int total_h;
68 unsigned short y_skip_top; /* Lines to skip at the top */ 75 unsigned short y_skip_top; /* Lines to skip at the top */
69 unsigned int exposure;
70 unsigned char autoexposure;
71}; 76};
72 77
73static struct mt9t031 *to_mt9t031(const struct i2c_client *client) 78static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
@@ -175,69 +180,6 @@ static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
175 return 0; 180 return 0;
176} 181}
177 182
178enum {
179 MT9T031_CTRL_VFLIP,
180 MT9T031_CTRL_HFLIP,
181 MT9T031_CTRL_GAIN,
182 MT9T031_CTRL_EXPOSURE,
183 MT9T031_CTRL_EXPOSURE_AUTO,
184};
185
186static const struct v4l2_queryctrl mt9t031_controls[] = {
187 [MT9T031_CTRL_VFLIP] = {
188 .id = V4L2_CID_VFLIP,
189 .type = V4L2_CTRL_TYPE_BOOLEAN,
190 .name = "Flip Vertically",
191 .minimum = 0,
192 .maximum = 1,
193 .step = 1,
194 .default_value = 0,
195 },
196 [MT9T031_CTRL_HFLIP] = {
197 .id = V4L2_CID_HFLIP,
198 .type = V4L2_CTRL_TYPE_BOOLEAN,
199 .name = "Flip Horizontally",
200 .minimum = 0,
201 .maximum = 1,
202 .step = 1,
203 .default_value = 0,
204 },
205 [MT9T031_CTRL_GAIN] = {
206 .id = V4L2_CID_GAIN,
207 .type = V4L2_CTRL_TYPE_INTEGER,
208 .name = "Gain",
209 .minimum = 0,
210 .maximum = 127,
211 .step = 1,
212 .default_value = 64,
213 .flags = V4L2_CTRL_FLAG_SLIDER,
214 },
215 [MT9T031_CTRL_EXPOSURE] = {
216 .id = V4L2_CID_EXPOSURE,
217 .type = V4L2_CTRL_TYPE_INTEGER,
218 .name = "Exposure",
219 .minimum = 1,
220 .maximum = 255,
221 .step = 1,
222 .default_value = 255,
223 .flags = V4L2_CTRL_FLAG_SLIDER,
224 },
225 [MT9T031_CTRL_EXPOSURE_AUTO] = {
226 .id = V4L2_CID_EXPOSURE_AUTO,
227 .type = V4L2_CTRL_TYPE_BOOLEAN,
228 .name = "Automatic Exposure",
229 .minimum = 0,
230 .maximum = 1,
231 .step = 1,
232 .default_value = 1,
233 }
234};
235
236static struct soc_camera_ops mt9t031_ops = {
237 .controls = mt9t031_controls,
238 .num_controls = ARRAY_SIZE(mt9t031_controls),
239};
240
241/* target must be _even_ */ 183/* target must be _even_ */
242static u16 mt9t031_skip(s32 *source, s32 target, s32 max) 184static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
243{ 185{
@@ -334,17 +276,10 @@ static int mt9t031_set_params(struct i2c_client *client,
334 if (ret >= 0) 276 if (ret >= 0)
335 ret = reg_write(client, MT9T031_WINDOW_HEIGHT, 277 ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
336 rect->height + mt9t031->y_skip_top - 1); 278 rect->height + mt9t031->y_skip_top - 1);
337 if (ret >= 0 && mt9t031->autoexposure) { 279 if (ret >= 0 && v4l2_ctrl_g_ctrl(mt9t031->autoexposure) == V4L2_EXPOSURE_AUTO) {
338 unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank; 280 mt9t031->total_h = rect->height + mt9t031->y_skip_top + vblank;
339 ret = set_shutter(client, total_h); 281
340 if (ret >= 0) { 282 ret = set_shutter(client, mt9t031->total_h);
341 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
342 const struct v4l2_queryctrl *qctrl =
343 &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
344 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
345 (qctrl->maximum - qctrl->minimum)) /
346 shutter_max + qctrl->minimum;
347 }
348 } 283 }
349 284
350 /* Re-enable register update, commit all changes */ 285 /* Re-enable register update, commit all changes */
@@ -513,71 +448,57 @@ static int mt9t031_s_register(struct v4l2_subdev *sd,
513} 448}
514#endif 449#endif
515 450
516static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 451static int mt9t031_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
517{ 452{
518 struct i2c_client *client = v4l2_get_subdevdata(sd); 453 struct mt9t031 *mt9t031 = container_of(ctrl->handler,
519 struct mt9t031 *mt9t031 = to_mt9t031(client); 454 struct mt9t031, hdl);
520 int data; 455 const u32 shutter_max = MT9T031_MAX_HEIGHT + MT9T031_VERTICAL_BLANK;
456 s32 min, max;
521 457
522 switch (ctrl->id) { 458 switch (ctrl->id) {
523 case V4L2_CID_VFLIP:
524 data = reg_read(client, MT9T031_READ_MODE_2);
525 if (data < 0)
526 return -EIO;
527 ctrl->value = !!(data & 0x8000);
528 break;
529 case V4L2_CID_HFLIP:
530 data = reg_read(client, MT9T031_READ_MODE_2);
531 if (data < 0)
532 return -EIO;
533 ctrl->value = !!(data & 0x4000);
534 break;
535 case V4L2_CID_EXPOSURE_AUTO: 459 case V4L2_CID_EXPOSURE_AUTO:
536 ctrl->value = mt9t031->autoexposure; 460 min = mt9t031->exposure->minimum;
537 break; 461 max = mt9t031->exposure->maximum;
538 case V4L2_CID_GAIN: 462 mt9t031->exposure->val =
539 ctrl->value = mt9t031->gain; 463 (shutter_max / 2 + (mt9t031->total_h - 1) * (max - min))
540 break; 464 / shutter_max + min;
541 case V4L2_CID_EXPOSURE:
542 ctrl->value = mt9t031->exposure;
543 break; 465 break;
544 } 466 }
545 return 0; 467 return 0;
546} 468}
547 469
548static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 470static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
549{ 471{
472 struct mt9t031 *mt9t031 = container_of(ctrl->handler,
473 struct mt9t031, hdl);
474 struct v4l2_subdev *sd = &mt9t031->subdev;
550 struct i2c_client *client = v4l2_get_subdevdata(sd); 475 struct i2c_client *client = v4l2_get_subdevdata(sd);
551 struct mt9t031 *mt9t031 = to_mt9t031(client); 476 struct v4l2_ctrl *exp = mt9t031->exposure;
552 const struct v4l2_queryctrl *qctrl;
553 int data; 477 int data;
554 478
555 switch (ctrl->id) { 479 switch (ctrl->id) {
556 case V4L2_CID_VFLIP: 480 case V4L2_CID_VFLIP:
557 if (ctrl->value) 481 if (ctrl->val)
558 data = reg_set(client, MT9T031_READ_MODE_2, 0x8000); 482 data = reg_set(client, MT9T031_READ_MODE_2, 0x8000);
559 else 483 else
560 data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000); 484 data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000);
561 if (data < 0) 485 if (data < 0)
562 return -EIO; 486 return -EIO;
563 break; 487 return 0;
564 case V4L2_CID_HFLIP: 488 case V4L2_CID_HFLIP:
565 if (ctrl->value) 489 if (ctrl->val)
566 data = reg_set(client, MT9T031_READ_MODE_2, 0x4000); 490 data = reg_set(client, MT9T031_READ_MODE_2, 0x4000);
567 else 491 else
568 data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000); 492 data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000);
569 if (data < 0) 493 if (data < 0)
570 return -EIO; 494 return -EIO;
571 break; 495 return 0;
572 case V4L2_CID_GAIN: 496 case V4L2_CID_GAIN:
573 qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN];
574 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
575 return -EINVAL;
576 /* See Datasheet Table 7, Gain settings. */ 497 /* See Datasheet Table 7, Gain settings. */
577 if (ctrl->value <= qctrl->default_value) { 498 if (ctrl->val <= ctrl->default_value) {
578 /* Pack it into 0..1 step 0.125, register values 0..8 */ 499 /* Pack it into 0..1 step 0.125, register values 0..8 */
579 unsigned long range = qctrl->default_value - qctrl->minimum; 500 unsigned long range = ctrl->default_value - ctrl->minimum;
580 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 501 data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
581 502
582 dev_dbg(&client->dev, "Setting gain %d\n", data); 503 dev_dbg(&client->dev, "Setting gain %d\n", data);
583 data = reg_write(client, MT9T031_GLOBAL_GAIN, data); 504 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
@@ -586,9 +507,9 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
586 } else { 507 } else {
587 /* Pack it into 1.125..128 variable step, register values 9..0x7860 */ 508 /* Pack it into 1.125..128 variable step, register values 9..0x7860 */
588 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ 509 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
589 unsigned long range = qctrl->maximum - qctrl->default_value - 1; 510 unsigned long range = ctrl->maximum - ctrl->default_value - 1;
590 /* calculated gain: map 65..127 to 9..1024 step 0.125 */ 511 /* calculated gain: map 65..127 to 9..1024 step 0.125 */
591 unsigned long gain = ((ctrl->value - qctrl->default_value - 1) * 512 unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
592 1015 + range / 2) / range + 9; 513 1015 + range / 2) / range + 9;
593 514
594 if (gain <= 32) /* calculated gain 9..32 -> 9..32 */ 515 if (gain <= 32) /* calculated gain 9..32 -> 9..32 */
@@ -605,19 +526,13 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
605 if (data < 0) 526 if (data < 0)
606 return -EIO; 527 return -EIO;
607 } 528 }
529 return 0;
608 530
609 /* Success */ 531 case V4L2_CID_EXPOSURE_AUTO:
610 mt9t031->gain = ctrl->value; 532 if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
611 break; 533 unsigned int range = exp->maximum - exp->minimum;
612 case V4L2_CID_EXPOSURE: 534 unsigned int shutter = ((exp->val - exp->minimum) * 1048 +
613 qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; 535 range / 2) / range + 1;
614 /* mt9t031 has maximum == default */
615 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
616 return -EINVAL;
617 else {
618 const unsigned long range = qctrl->maximum - qctrl->minimum;
619 const u32 shutter = ((ctrl->value - qctrl->minimum) * 1048 +
620 range / 2) / range + 1;
621 u32 old; 536 u32 old;
622 537
623 get_shutter(client, &old); 538 get_shutter(client, &old);
@@ -625,27 +540,15 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
625 old, shutter); 540 old, shutter);
626 if (set_shutter(client, shutter) < 0) 541 if (set_shutter(client, shutter) < 0)
627 return -EIO; 542 return -EIO;
628 mt9t031->exposure = ctrl->value; 543 } else {
629 mt9t031->autoexposure = 0;
630 }
631 break;
632 case V4L2_CID_EXPOSURE_AUTO:
633 if (ctrl->value) {
634 const u16 vblank = MT9T031_VERTICAL_BLANK; 544 const u16 vblank = MT9T031_VERTICAL_BLANK;
635 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 545 mt9t031->total_h = mt9t031->rect.height +
636 unsigned int total_h = mt9t031->rect.height +
637 mt9t031->y_skip_top + vblank; 546 mt9t031->y_skip_top + vblank;
638 547
639 if (set_shutter(client, total_h) < 0) 548 if (set_shutter(client, mt9t031->total_h) < 0)
640 return -EIO; 549 return -EIO;
641 qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; 550 }
642 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * 551 return 0;
643 (qctrl->maximum - qctrl->minimum)) /
644 shutter_max + qctrl->minimum;
645 mt9t031->autoexposure = 1;
646 } else
647 mt9t031->autoexposure = 0;
648 break;
649 default: 552 default:
650 return -EINVAL; 553 return -EINVAL;
651 } 554 }
@@ -735,15 +638,12 @@ static int mt9t031_video_probe(struct i2c_client *client)
735 dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data); 638 dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data);
736 639
737 ret = mt9t031_idle(client); 640 ret = mt9t031_idle(client);
738 if (ret < 0) 641 if (ret < 0) {
739 dev_err(&client->dev, "Failed to initialise the camera\n"); 642 dev_err(&client->dev, "Failed to initialise the camera\n");
740 else 643 } else {
741 vdev->dev.type = &mt9t031_dev_type; 644 vdev->dev.type = &mt9t031_dev_type;
742 645 v4l2_ctrl_handler_setup(&mt9t031->hdl);
743 /* mt9t031_idle() has reset the chip to default. */ 646 }
744 mt9t031->exposure = 255;
745 mt9t031->gain = 64;
746
747 return ret; 647 return ret;
748} 648}
749 649
@@ -757,9 +657,12 @@ static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
757 return 0; 657 return 0;
758} 658}
759 659
660static const struct v4l2_ctrl_ops mt9t031_ctrl_ops = {
661 .g_volatile_ctrl = mt9t031_g_volatile_ctrl,
662 .s_ctrl = mt9t031_s_ctrl,
663};
664
760static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { 665static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
761 .g_ctrl = mt9t031_g_ctrl,
762 .s_ctrl = mt9t031_s_ctrl,
763 .g_chip_ident = mt9t031_g_chip_ident, 666 .g_chip_ident = mt9t031_g_chip_ident,
764#ifdef CONFIG_VIDEO_ADV_DEBUG 667#ifdef CONFIG_VIDEO_ADV_DEBUG
765 .g_register = mt9t031_g_register, 668 .g_register = mt9t031_g_register,
@@ -844,8 +747,6 @@ static int mt9t031_probe(struct i2c_client *client,
844 dev_err(&client->dev, "MT9T031 driver needs platform data\n"); 747 dev_err(&client->dev, "MT9T031 driver needs platform data\n");
845 return -EINVAL; 748 return -EINVAL;
846 } 749 }
847
848 icd->ops = &mt9t031_ops;
849 } 750 }
850 751
851 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { 752 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -859,6 +760,33 @@ static int mt9t031_probe(struct i2c_client *client,
859 return -ENOMEM; 760 return -ENOMEM;
860 761
861 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); 762 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
763 v4l2_ctrl_handler_init(&mt9t031->hdl, 5);
764 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
765 V4L2_CID_VFLIP, 0, 1, 1, 0);
766 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
767 V4L2_CID_HFLIP, 0, 1, 1, 0);
768 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
769 V4L2_CID_GAIN, 0, 127, 1, 64);
770
771 /*
772 * Simulated autoexposure. If enabled, we calculate shutter width
773 * ourselves in the driver based on vertical blanking and frame width
774 */
775 mt9t031->autoexposure = v4l2_ctrl_new_std_menu(&mt9t031->hdl,
776 &mt9t031_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
777 V4L2_EXPOSURE_AUTO);
778 mt9t031->exposure = v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
779 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
780
781 mt9t031->subdev.ctrl_handler = &mt9t031->hdl;
782 if (mt9t031->hdl.error) {
783 int err = mt9t031->hdl.error;
784
785 kfree(mt9t031);
786 return err;
787 }
788 v4l2_ctrl_auto_cluster(2, &mt9t031->autoexposure,
789 V4L2_EXPOSURE_MANUAL, true);
862 790
863 mt9t031->y_skip_top = 0; 791 mt9t031->y_skip_top = 0;
864 mt9t031->rect.left = MT9T031_COLUMN_SKIP; 792 mt9t031->rect.left = MT9T031_COLUMN_SKIP;
@@ -866,12 +794,6 @@ static int mt9t031_probe(struct i2c_client *client,
866 mt9t031->rect.width = MT9T031_MAX_WIDTH; 794 mt9t031->rect.width = MT9T031_MAX_WIDTH;
867 mt9t031->rect.height = MT9T031_MAX_HEIGHT; 795 mt9t031->rect.height = MT9T031_MAX_HEIGHT;
868 796
869 /*
870 * Simulated autoexposure. If enabled, we calculate shutter width
871 * ourselves in the driver based on vertical blanking and frame width
872 */
873 mt9t031->autoexposure = 1;
874
875 mt9t031->xskip = 1; 797 mt9t031->xskip = 1;
876 mt9t031->yskip = 1; 798 mt9t031->yskip = 1;
877 799
@@ -882,8 +804,7 @@ static int mt9t031_probe(struct i2c_client *client,
882 mt9t031_disable(client); 804 mt9t031_disable(client);
883 805
884 if (ret) { 806 if (ret) {
885 if (icd) 807 v4l2_ctrl_handler_free(&mt9t031->hdl);
886 icd->ops = NULL;
887 kfree(mt9t031); 808 kfree(mt9t031);
888 } 809 }
889 810
@@ -893,10 +814,9 @@ static int mt9t031_probe(struct i2c_client *client,
893static int mt9t031_remove(struct i2c_client *client) 814static int mt9t031_remove(struct i2c_client *client)
894{ 815{
895 struct mt9t031 *mt9t031 = to_mt9t031(client); 816 struct mt9t031 *mt9t031 = to_mt9t031(client);
896 struct soc_camera_device *icd = client->dev.platform_data;
897 817
898 if (icd) 818 v4l2_device_unregister_subdev(&mt9t031->subdev);
899 icd->ops = NULL; 819 v4l2_ctrl_handler_free(&mt9t031->hdl);
900 kfree(mt9t031); 820 kfree(mt9t031);
901 821
902 return 0; 822 return 0;