aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/mt9v011.c
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-09-07 04:42:15 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-05 15:02:49 -0500
commitea01a83d5c88a3e0bb124ec4b3abf3aefcf0d719 (patch)
treeea64349f3dc44692457d54305adea592281888f5 /drivers/media/i2c/mt9v011.c
parent28718152e0a78085297ec7705f53869e41d1ae73 (diff)
[media] mt9v011: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Tested-by: Frank Schäfer <fschaefer.oss@googlemail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/i2c/mt9v011.c')
-rw-r--r--drivers/media/i2c/mt9v011.c223
1 files changed, 67 insertions, 156 deletions
diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 6bf01ad62765..73b7688cbebd 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -13,6 +13,7 @@
13#include <asm/div64.h> 13#include <asm/div64.h>
14#include <media/v4l2-device.h> 14#include <media/v4l2-device.h>
15#include <media/v4l2-chip-ident.h> 15#include <media/v4l2-chip-ident.h>
16#include <media/v4l2-ctrls.h>
16#include <media/mt9v011.h> 17#include <media/mt9v011.h>
17 18
18MODULE_DESCRIPTION("Micron mt9v011 sensor driver"); 19MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
@@ -48,68 +49,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
48#define MT9V011_VERSION 0x8232 49#define MT9V011_VERSION 0x8232
49#define MT9V011_REV_B_VERSION 0x8243 50#define MT9V011_REV_B_VERSION 0x8243
50 51
51/* supported controls */
52static struct v4l2_queryctrl mt9v011_qctrl[] = {
53 {
54 .id = V4L2_CID_GAIN,
55 .type = V4L2_CTRL_TYPE_INTEGER,
56 .name = "Gain",
57 .minimum = 0,
58 .maximum = (1 << 12) - 1 - 0x0020,
59 .step = 1,
60 .default_value = 0x0020,
61 .flags = 0,
62 }, {
63 .id = V4L2_CID_EXPOSURE,
64 .type = V4L2_CTRL_TYPE_INTEGER,
65 .name = "Exposure",
66 .minimum = 0,
67 .maximum = 2047,
68 .step = 1,
69 .default_value = 0x01fc,
70 .flags = 0,
71 }, {
72 .id = V4L2_CID_RED_BALANCE,
73 .type = V4L2_CTRL_TYPE_INTEGER,
74 .name = "Red Balance",
75 .minimum = -1 << 9,
76 .maximum = (1 << 9) - 1,
77 .step = 1,
78 .default_value = 0,
79 .flags = 0,
80 }, {
81 .id = V4L2_CID_BLUE_BALANCE,
82 .type = V4L2_CTRL_TYPE_INTEGER,
83 .name = "Blue Balance",
84 .minimum = -1 << 9,
85 .maximum = (1 << 9) - 1,
86 .step = 1,
87 .default_value = 0,
88 .flags = 0,
89 }, {
90 .id = V4L2_CID_HFLIP,
91 .type = V4L2_CTRL_TYPE_BOOLEAN,
92 .name = "Mirror",
93 .minimum = 0,
94 .maximum = 1,
95 .step = 1,
96 .default_value = 0,
97 .flags = 0,
98 }, {
99 .id = V4L2_CID_VFLIP,
100 .type = V4L2_CTRL_TYPE_BOOLEAN,
101 .name = "Vflip",
102 .minimum = 0,
103 .maximum = 1,
104 .step = 1,
105 .default_value = 0,
106 .flags = 0,
107 }, {
108 }
109};
110
111struct mt9v011 { 52struct mt9v011 {
112 struct v4l2_subdev sd; 53 struct v4l2_subdev sd;
54 struct v4l2_ctrl_handler ctrls;
113 unsigned width, height; 55 unsigned width, height;
114 unsigned xtal; 56 unsigned xtal;
115 unsigned hflip:1; 57 unsigned hflip:1;
@@ -381,99 +323,6 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
381 set_read_mode(sd); 323 set_read_mode(sd);
382 324
383 return 0; 325 return 0;
384};
385
386static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
387{
388 struct mt9v011 *core = to_mt9v011(sd);
389
390 v4l2_dbg(1, debug, sd, "g_ctrl called\n");
391
392 switch (ctrl->id) {
393 case V4L2_CID_GAIN:
394 ctrl->value = core->global_gain;
395 return 0;
396 case V4L2_CID_EXPOSURE:
397 ctrl->value = core->exposure;
398 return 0;
399 case V4L2_CID_RED_BALANCE:
400 ctrl->value = core->red_bal;
401 return 0;
402 case V4L2_CID_BLUE_BALANCE:
403 ctrl->value = core->blue_bal;
404 return 0;
405 case V4L2_CID_HFLIP:
406 ctrl->value = core->hflip ? 1 : 0;
407 return 0;
408 case V4L2_CID_VFLIP:
409 ctrl->value = core->vflip ? 1 : 0;
410 return 0;
411 }
412 return -EINVAL;
413}
414
415static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
416{
417 int i;
418
419 v4l2_dbg(1, debug, sd, "queryctrl called\n");
420
421 for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++)
422 if (qc->id && qc->id == mt9v011_qctrl[i].id) {
423 memcpy(qc, &(mt9v011_qctrl[i]),
424 sizeof(*qc));
425 return 0;
426 }
427
428 return -EINVAL;
429}
430
431
432static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
433{
434 struct mt9v011 *core = to_mt9v011(sd);
435 u8 i, n;
436 n = ARRAY_SIZE(mt9v011_qctrl);
437
438 for (i = 0; i < n; i++) {
439 if (ctrl->id != mt9v011_qctrl[i].id)
440 continue;
441 if (ctrl->value < mt9v011_qctrl[i].minimum ||
442 ctrl->value > mt9v011_qctrl[i].maximum)
443 return -ERANGE;
444 v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
445 ctrl->id, ctrl->value);
446 break;
447 }
448
449 switch (ctrl->id) {
450 case V4L2_CID_GAIN:
451 core->global_gain = ctrl->value;
452 break;
453 case V4L2_CID_EXPOSURE:
454 core->exposure = ctrl->value;
455 break;
456 case V4L2_CID_RED_BALANCE:
457 core->red_bal = ctrl->value;
458 break;
459 case V4L2_CID_BLUE_BALANCE:
460 core->blue_bal = ctrl->value;
461 break;
462 case V4L2_CID_HFLIP:
463 core->hflip = ctrl->value;
464 set_read_mode(sd);
465 return 0;
466 case V4L2_CID_VFLIP:
467 core->vflip = ctrl->value;
468 set_read_mode(sd);
469 return 0;
470 default:
471 return -EINVAL;
472 }
473
474 set_balance(sd);
475
476 return 0;
477} 326}
478 327
479static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index, 328static 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,
599 version); 448 version);
600} 449}
601 450
602static const struct v4l2_subdev_core_ops mt9v011_core_ops = { 451static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl)
603 .queryctrl = mt9v011_queryctrl, 452{
604 .g_ctrl = mt9v011_g_ctrl, 453 struct mt9v011 *core =
454 container_of(ctrl->handler, struct mt9v011, ctrls);
455 struct v4l2_subdev *sd = &core->sd;
456
457 switch (ctrl->id) {
458 case V4L2_CID_GAIN:
459 core->global_gain = ctrl->val;
460 break;
461 case V4L2_CID_EXPOSURE:
462 core->exposure = ctrl->val;
463 break;
464 case V4L2_CID_RED_BALANCE:
465 core->red_bal = ctrl->val;
466 break;
467 case V4L2_CID_BLUE_BALANCE:
468 core->blue_bal = ctrl->val;
469 break;
470 case V4L2_CID_HFLIP:
471 core->hflip = ctrl->val;
472 set_read_mode(sd);
473 return 0;
474 case V4L2_CID_VFLIP:
475 core->vflip = ctrl->val;
476 set_read_mode(sd);
477 return 0;
478 default:
479 return -EINVAL;
480 }
481
482 set_balance(sd);
483 return 0;
484}
485
486static struct v4l2_ctrl_ops mt9v011_ctrl_ops = {
605 .s_ctrl = mt9v011_s_ctrl, 487 .s_ctrl = mt9v011_s_ctrl,
488};
489
490static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
606 .reset = mt9v011_reset, 491 .reset = mt9v011_reset,
607 .g_chip_ident = mt9v011_g_chip_ident, 492 .g_chip_ident = mt9v011_g_chip_ident,
608#ifdef CONFIG_VIDEO_ADV_DEBUG 493#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -658,6 +543,30 @@ static int mt9v011_probe(struct i2c_client *c,
658 return -EINVAL; 543 return -EINVAL;
659 } 544 }
660 545
546 v4l2_ctrl_handler_init(&core->ctrls, 5);
547 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
548 V4L2_CID_GAIN, 0, (1 << 12) - 1 - 0x20, 1, 0x20);
549 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
550 V4L2_CID_EXPOSURE, 0, 2047, 1, 0x01fc);
551 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
552 V4L2_CID_RED_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0);
553 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
554 V4L2_CID_BLUE_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0);
555 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
556 V4L2_CID_HFLIP, 0, 1, 1, 0);
557 v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
558 V4L2_CID_VFLIP, 0, 1, 1, 0);
559
560 if (core->ctrls.error) {
561 int ret = core->ctrls.error;
562
563 v4l2_err(sd, "control initialization error %d\n", ret);
564 v4l2_ctrl_handler_free(&core->ctrls);
565 kfree(core);
566 return ret;
567 }
568 core->sd.ctrl_handler = &core->ctrls;
569
661 core->global_gain = 0x0024; 570 core->global_gain = 0x0024;
662 core->exposure = 0x01fc; 571 core->exposure = 0x01fc;
663 core->width = 640; 572 core->width = 640;
@@ -681,12 +590,14 @@ static int mt9v011_probe(struct i2c_client *c,
681static int mt9v011_remove(struct i2c_client *c) 590static int mt9v011_remove(struct i2c_client *c)
682{ 591{
683 struct v4l2_subdev *sd = i2c_get_clientdata(c); 592 struct v4l2_subdev *sd = i2c_get_clientdata(c);
593 struct mt9v011 *core = to_mt9v011(sd);
684 594
685 v4l2_dbg(1, debug, sd, 595 v4l2_dbg(1, debug, sd,
686 "mt9v011.c: removing mt9v011 adapter on address 0x%x\n", 596 "mt9v011.c: removing mt9v011 adapter on address 0x%x\n",
687 c->addr << 1); 597 c->addr << 1);
688 598
689 v4l2_device_unregister_subdev(sd); 599 v4l2_device_unregister_subdev(sd);
600 v4l2_ctrl_handler_free(&core->ctrls);
690 kfree(to_mt9v011(sd)); 601 kfree(to_mt9v011(sd));
691 return 0; 602 return 0;
692} 603}