diff options
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r-- | drivers/media/i2c/cx25840/cx25840-core.c | 2 | ||||
-rw-r--r-- | drivers/media/i2c/m5mols/m5mols.h | 10 | ||||
-rw-r--r-- | drivers/media/i2c/m5mols/m5mols_capture.c | 3 | ||||
-rw-r--r-- | drivers/media/i2c/m5mols/m5mols_core.c | 47 | ||||
-rw-r--r-- | drivers/media/i2c/m5mols/m5mols_reg.h | 1 | ||||
-rw-r--r-- | drivers/media/i2c/mt9p031.c | 19 | ||||
-rw-r--r-- | drivers/media/i2c/mt9t001.c | 22 | ||||
-rw-r--r-- | drivers/media/i2c/mt9v032.c | 54 | ||||
-rw-r--r-- | drivers/media/i2c/soc_camera/ov2640.c | 5 | ||||
-rw-r--r-- | drivers/media/i2c/ths7303.c | 106 | ||||
-rw-r--r-- | drivers/media/i2c/tvp514x.c | 77 |
11 files changed, 218 insertions, 128 deletions
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index d8eac3e30a7e..2cee69e34184 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c | |||
@@ -599,7 +599,7 @@ static void cx23885_initialize(struct i2c_client *client) | |||
599 | cx25840_write4(client, 0x114, 0x01bf0c9e); | 599 | cx25840_write4(client, 0x114, 0x01bf0c9e); |
600 | cx25840_write4(client, 0x110, 0x000a030c); | 600 | cx25840_write4(client, 0x110, 0x000a030c); |
601 | break; | 601 | break; |
602 | }; | 602 | } |
603 | 603 | ||
604 | /* ADC2 input select */ | 604 | /* ADC2 input select */ |
605 | cx25840_write(client, 0x102, 0x10); | 605 | cx25840_write(client, 0x102, 0x10); |
diff --git a/drivers/media/i2c/m5mols/m5mols.h b/drivers/media/i2c/m5mols/m5mols.h index 86c815be348c..90a6c520f115 100644 --- a/drivers/media/i2c/m5mols/m5mols.h +++ b/drivers/media/i2c/m5mols/m5mols.h | |||
@@ -16,9 +16,17 @@ | |||
16 | #ifndef M5MOLS_H | 16 | #ifndef M5MOLS_H |
17 | #define M5MOLS_H | 17 | #define M5MOLS_H |
18 | 18 | ||
19 | #include <linux/sizes.h> | ||
19 | #include <media/v4l2-subdev.h> | 20 | #include <media/v4l2-subdev.h> |
20 | #include "m5mols_reg.h" | 21 | #include "m5mols_reg.h" |
21 | 22 | ||
23 | |||
24 | /* An amount of data transmitted in addition to the value | ||
25 | * determined by CAPP_JPEG_SIZE_MAX register. | ||
26 | */ | ||
27 | #define M5MOLS_JPEG_TAGS_SIZE 0x20000 | ||
28 | #define M5MOLS_MAIN_JPEG_SIZE_MAX (5 * SZ_1M) | ||
29 | |||
22 | extern int m5mols_debug; | 30 | extern int m5mols_debug; |
23 | 31 | ||
24 | enum m5mols_restype { | 32 | enum m5mols_restype { |
@@ -67,12 +75,14 @@ struct m5mols_exif { | |||
67 | /** | 75 | /** |
68 | * struct m5mols_capture - Structure for the capture capability | 76 | * struct m5mols_capture - Structure for the capture capability |
69 | * @exif: EXIF information | 77 | * @exif: EXIF information |
78 | * @buf_size: internal JPEG frame buffer size, in bytes | ||
70 | * @main: size in bytes of the main image | 79 | * @main: size in bytes of the main image |
71 | * @thumb: size in bytes of the thumb image, if it was accompanied | 80 | * @thumb: size in bytes of the thumb image, if it was accompanied |
72 | * @total: total size in bytes of the produced image | 81 | * @total: total size in bytes of the produced image |
73 | */ | 82 | */ |
74 | struct m5mols_capture { | 83 | struct m5mols_capture { |
75 | struct m5mols_exif exif; | 84 | struct m5mols_exif exif; |
85 | unsigned int buf_size; | ||
76 | u32 main; | 86 | u32 main; |
77 | u32 thumb; | 87 | u32 thumb; |
78 | u32 total; | 88 | u32 total; |
diff --git a/drivers/media/i2c/m5mols/m5mols_capture.c b/drivers/media/i2c/m5mols/m5mols_capture.c index cb243bd278ce..ab34ccedf31e 100644 --- a/drivers/media/i2c/m5mols/m5mols_capture.c +++ b/drivers/media/i2c/m5mols/m5mols_capture.c | |||
@@ -105,6 +105,7 @@ static int m5mols_capture_info(struct m5mols_info *info) | |||
105 | 105 | ||
106 | int m5mols_start_capture(struct m5mols_info *info) | 106 | int m5mols_start_capture(struct m5mols_info *info) |
107 | { | 107 | { |
108 | unsigned int framesize = info->cap.buf_size - M5MOLS_JPEG_TAGS_SIZE; | ||
108 | struct v4l2_subdev *sd = &info->sd; | 109 | struct v4l2_subdev *sd = &info->sd; |
109 | int ret; | 110 | int ret; |
110 | 111 | ||
@@ -121,6 +122,8 @@ int m5mols_start_capture(struct m5mols_info *info) | |||
121 | if (!ret) | 122 | if (!ret) |
122 | ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution); | 123 | ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution); |
123 | if (!ret) | 124 | if (!ret) |
125 | ret = m5mols_write(sd, CAPP_JPEG_SIZE_MAX, framesize); | ||
126 | if (!ret) | ||
124 | ret = m5mols_set_mode(info, REG_CAPTURE); | 127 | ret = m5mols_set_mode(info, REG_CAPTURE); |
125 | if (!ret) | 128 | if (!ret) |
126 | /* Wait until a frame is captured to ISP internal memory */ | 129 | /* Wait until a frame is captured to ISP internal memory */ |
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 2f490ef26c38..8131d651de9e 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c | |||
@@ -599,6 +599,51 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
599 | return ret; | 599 | return ret; |
600 | } | 600 | } |
601 | 601 | ||
602 | static int m5mols_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, | ||
603 | struct v4l2_mbus_frame_desc *fd) | ||
604 | { | ||
605 | struct m5mols_info *info = to_m5mols(sd); | ||
606 | |||
607 | if (pad != 0 || fd == NULL) | ||
608 | return -EINVAL; | ||
609 | |||
610 | mutex_lock(&info->lock); | ||
611 | /* | ||
612 | * .get_frame_desc is only used for compressed formats, | ||
613 | * thus we always return the capture frame parameters here. | ||
614 | */ | ||
615 | fd->entry[0].length = info->cap.buf_size; | ||
616 | fd->entry[0].pixelcode = info->ffmt[M5MOLS_RESTYPE_CAPTURE].code; | ||
617 | mutex_unlock(&info->lock); | ||
618 | |||
619 | fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX; | ||
620 | fd->num_entries = 1; | ||
621 | |||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static int m5mols_set_frame_desc(struct v4l2_subdev *sd, unsigned int pad, | ||
626 | struct v4l2_mbus_frame_desc *fd) | ||
627 | { | ||
628 | struct m5mols_info *info = to_m5mols(sd); | ||
629 | struct v4l2_mbus_framefmt *mf = &info->ffmt[M5MOLS_RESTYPE_CAPTURE]; | ||
630 | |||
631 | if (pad != 0 || fd == NULL) | ||
632 | return -EINVAL; | ||
633 | |||
634 | fd->entry[0].flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX; | ||
635 | fd->num_entries = 1; | ||
636 | fd->entry[0].length = clamp_t(u32, fd->entry[0].length, | ||
637 | mf->width * mf->height, | ||
638 | M5MOLS_MAIN_JPEG_SIZE_MAX); | ||
639 | mutex_lock(&info->lock); | ||
640 | info->cap.buf_size = fd->entry[0].length; | ||
641 | mutex_unlock(&info->lock); | ||
642 | |||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | |||
602 | static int m5mols_enum_mbus_code(struct v4l2_subdev *sd, | 647 | static int m5mols_enum_mbus_code(struct v4l2_subdev *sd, |
603 | struct v4l2_subdev_fh *fh, | 648 | struct v4l2_subdev_fh *fh, |
604 | struct v4l2_subdev_mbus_code_enum *code) | 649 | struct v4l2_subdev_mbus_code_enum *code) |
@@ -615,6 +660,8 @@ static struct v4l2_subdev_pad_ops m5mols_pad_ops = { | |||
615 | .enum_mbus_code = m5mols_enum_mbus_code, | 660 | .enum_mbus_code = m5mols_enum_mbus_code, |
616 | .get_fmt = m5mols_get_fmt, | 661 | .get_fmt = m5mols_get_fmt, |
617 | .set_fmt = m5mols_set_fmt, | 662 | .set_fmt = m5mols_set_fmt, |
663 | .get_frame_desc = m5mols_get_frame_desc, | ||
664 | .set_frame_desc = m5mols_set_frame_desc, | ||
618 | }; | 665 | }; |
619 | 666 | ||
620 | /** | 667 | /** |
diff --git a/drivers/media/i2c/m5mols/m5mols_reg.h b/drivers/media/i2c/m5mols/m5mols_reg.h index 14d4be72aeff..58d8027508df 100644 --- a/drivers/media/i2c/m5mols/m5mols_reg.h +++ b/drivers/media/i2c/m5mols/m5mols_reg.h | |||
@@ -310,6 +310,7 @@ | |||
310 | #define REG_JPEG 0x10 | 310 | #define REG_JPEG 0x10 |
311 | 311 | ||
312 | #define CAPP_MAIN_IMAGE_SIZE I2C_REG(CAT_CAPT_PARM, 0x01, 1) | 312 | #define CAPP_MAIN_IMAGE_SIZE I2C_REG(CAT_CAPT_PARM, 0x01, 1) |
313 | #define CAPP_JPEG_SIZE_MAX I2C_REG(CAT_CAPT_PARM, 0x0f, 4) | ||
313 | #define CAPP_JPEG_RATIO I2C_REG(CAT_CAPT_PARM, 0x17, 1) | 314 | #define CAPP_JPEG_RATIO I2C_REG(CAT_CAPT_PARM, 0x17, 1) |
314 | 315 | ||
315 | #define CAPP_MCC_MODE I2C_REG(CAT_CAPT_PARM, 0x1d, 1) | 316 | #define CAPP_MCC_MODE I2C_REG(CAT_CAPT_PARM, 0x1d, 1) |
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 2c0f4077c491..e32833262d32 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c | |||
@@ -574,7 +574,6 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev, | |||
574 | * V4L2 subdev control operations | 574 | * V4L2 subdev control operations |
575 | */ | 575 | */ |
576 | 576 | ||
577 | #define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001) | ||
578 | #define V4L2_CID_BLC_AUTO (V4L2_CID_USER_BASE | 0x1002) | 577 | #define V4L2_CID_BLC_AUTO (V4L2_CID_USER_BASE | 0x1002) |
579 | #define V4L2_CID_BLC_TARGET_LEVEL (V4L2_CID_USER_BASE | 0x1003) | 578 | #define V4L2_CID_BLC_TARGET_LEVEL (V4L2_CID_USER_BASE | 0x1003) |
580 | #define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004) | 579 | #define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004) |
@@ -740,18 +739,6 @@ static const char * const mt9p031_test_pattern_menu[] = { | |||
740 | static const struct v4l2_ctrl_config mt9p031_ctrls[] = { | 739 | static const struct v4l2_ctrl_config mt9p031_ctrls[] = { |
741 | { | 740 | { |
742 | .ops = &mt9p031_ctrl_ops, | 741 | .ops = &mt9p031_ctrl_ops, |
743 | .id = V4L2_CID_TEST_PATTERN, | ||
744 | .type = V4L2_CTRL_TYPE_MENU, | ||
745 | .name = "Test Pattern", | ||
746 | .min = 0, | ||
747 | .max = ARRAY_SIZE(mt9p031_test_pattern_menu) - 1, | ||
748 | .step = 0, | ||
749 | .def = 0, | ||
750 | .flags = 0, | ||
751 | .menu_skip_mask = 0, | ||
752 | .qmenu = mt9p031_test_pattern_menu, | ||
753 | }, { | ||
754 | .ops = &mt9p031_ctrl_ops, | ||
755 | .id = V4L2_CID_BLC_AUTO, | 742 | .id = V4L2_CID_BLC_AUTO, |
756 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 743 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
757 | .name = "BLC, Auto", | 744 | .name = "BLC, Auto", |
@@ -950,7 +937,7 @@ static int mt9p031_probe(struct i2c_client *client, | |||
950 | mt9p031->model = did->driver_data; | 937 | mt9p031->model = did->driver_data; |
951 | mt9p031->reset = -1; | 938 | mt9p031->reset = -1; |
952 | 939 | ||
953 | v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 5); | 940 | v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6); |
954 | 941 | ||
955 | v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, | 942 | v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, |
956 | V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN, | 943 | V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN, |
@@ -966,6 +953,10 @@ static int mt9p031_probe(struct i2c_client *client, | |||
966 | v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, | 953 | v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops, |
967 | V4L2_CID_PIXEL_RATE, pdata->target_freq, | 954 | V4L2_CID_PIXEL_RATE, pdata->target_freq, |
968 | pdata->target_freq, 1, pdata->target_freq); | 955 | pdata->target_freq, 1, pdata->target_freq); |
956 | v4l2_ctrl_new_std_menu_items(&mt9p031->ctrls, &mt9p031_ctrl_ops, | ||
957 | V4L2_CID_TEST_PATTERN, | ||
958 | ARRAY_SIZE(mt9p031_test_pattern_menu) - 1, 0, | ||
959 | 0, mt9p031_test_pattern_menu); | ||
969 | 960 | ||
970 | for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i) | 961 | for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i) |
971 | v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL); | 962 | v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL); |
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c index 6d343adf891d..2e189d8b71bb 100644 --- a/drivers/media/i2c/mt9t001.c +++ b/drivers/media/i2c/mt9t001.c | |||
@@ -371,7 +371,7 @@ static int mt9t001_set_crop(struct v4l2_subdev *subdev, | |||
371 | * V4L2 subdev control operations | 371 | * V4L2 subdev control operations |
372 | */ | 372 | */ |
373 | 373 | ||
374 | #define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001) | 374 | #define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001) |
375 | #define V4L2_CID_BLACK_LEVEL_AUTO (V4L2_CID_USER_BASE | 0x1002) | 375 | #define V4L2_CID_BLACK_LEVEL_AUTO (V4L2_CID_USER_BASE | 0x1002) |
376 | #define V4L2_CID_BLACK_LEVEL_OFFSET (V4L2_CID_USER_BASE | 0x1003) | 376 | #define V4L2_CID_BLACK_LEVEL_OFFSET (V4L2_CID_USER_BASE | 0x1003) |
377 | #define V4L2_CID_BLACK_LEVEL_CALIBRATE (V4L2_CID_USER_BASE | 0x1004) | 377 | #define V4L2_CID_BLACK_LEVEL_CALIBRATE (V4L2_CID_USER_BASE | 0x1004) |
@@ -487,12 +487,11 @@ static int mt9t001_s_ctrl(struct v4l2_ctrl *ctrl) | |||
487 | ctrl->val >> 16); | 487 | ctrl->val >> 16); |
488 | 488 | ||
489 | case V4L2_CID_TEST_PATTERN: | 489 | case V4L2_CID_TEST_PATTERN: |
490 | ret = mt9t001_set_output_control(mt9t001, | 490 | return mt9t001_set_output_control(mt9t001, |
491 | ctrl->val ? 0 : MT9T001_OUTPUT_CONTROL_TEST_DATA, | 491 | ctrl->val ? 0 : MT9T001_OUTPUT_CONTROL_TEST_DATA, |
492 | ctrl->val ? MT9T001_OUTPUT_CONTROL_TEST_DATA : 0); | 492 | ctrl->val ? MT9T001_OUTPUT_CONTROL_TEST_DATA : 0); |
493 | if (ret < 0) | ||
494 | return ret; | ||
495 | 493 | ||
494 | case V4L2_CID_TEST_PATTERN_COLOR: | ||
496 | return mt9t001_write(client, MT9T001_TEST_DATA, ctrl->val << 2); | 495 | return mt9t001_write(client, MT9T001_TEST_DATA, ctrl->val << 2); |
497 | 496 | ||
498 | case V4L2_CID_BLACK_LEVEL_AUTO: | 497 | case V4L2_CID_BLACK_LEVEL_AUTO: |
@@ -533,12 +532,17 @@ static struct v4l2_ctrl_ops mt9t001_ctrl_ops = { | |||
533 | .s_ctrl = mt9t001_s_ctrl, | 532 | .s_ctrl = mt9t001_s_ctrl, |
534 | }; | 533 | }; |
535 | 534 | ||
535 | static const char * const mt9t001_test_pattern_menu[] = { | ||
536 | "Disabled", | ||
537 | "Enabled", | ||
538 | }; | ||
539 | |||
536 | static const struct v4l2_ctrl_config mt9t001_ctrls[] = { | 540 | static const struct v4l2_ctrl_config mt9t001_ctrls[] = { |
537 | { | 541 | { |
538 | .ops = &mt9t001_ctrl_ops, | 542 | .ops = &mt9t001_ctrl_ops, |
539 | .id = V4L2_CID_TEST_PATTERN, | 543 | .id = V4L2_CID_TEST_PATTERN_COLOR, |
540 | .type = V4L2_CTRL_TYPE_INTEGER, | 544 | .type = V4L2_CTRL_TYPE_INTEGER, |
541 | .name = "Test pattern", | 545 | .name = "Test Pattern Color", |
542 | .min = 0, | 546 | .min = 0, |
543 | .max = 1023, | 547 | .max = 1023, |
544 | .step = 1, | 548 | .step = 1, |
@@ -741,7 +745,7 @@ static int mt9t001_probe(struct i2c_client *client, | |||
741 | return -ENOMEM; | 745 | return -ENOMEM; |
742 | 746 | ||
743 | v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) + | 747 | v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) + |
744 | ARRAY_SIZE(mt9t001_gains) + 3); | 748 | ARRAY_SIZE(mt9t001_gains) + 4); |
745 | 749 | ||
746 | v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, | 750 | v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, |
747 | V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN, | 751 | V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN, |
@@ -752,6 +756,10 @@ static int mt9t001_probe(struct i2c_client *client, | |||
752 | v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, | 756 | v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops, |
753 | V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk, | 757 | V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk, |
754 | 1, pdata->ext_clk); | 758 | 1, pdata->ext_clk); |
759 | v4l2_ctrl_new_std_menu_items(&mt9t001->ctrls, &mt9t001_ctrl_ops, | ||
760 | V4L2_CID_TEST_PATTERN, | ||
761 | ARRAY_SIZE(mt9t001_test_pattern_menu) - 1, 0, | ||
762 | 0, mt9t001_test_pattern_menu); | ||
755 | 763 | ||
756 | for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i) | 764 | for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i) |
757 | v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL); | 765 | v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL); |
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index e2177405dad2..3f356cb28256 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c | |||
@@ -141,6 +141,10 @@ struct mt9v032 { | |||
141 | u16 chip_control; | 141 | u16 chip_control; |
142 | u16 aec_agc; | 142 | u16 aec_agc; |
143 | u16 hblank; | 143 | u16 hblank; |
144 | struct { | ||
145 | struct v4l2_ctrl *test_pattern; | ||
146 | struct v4l2_ctrl *test_pattern_color; | ||
147 | }; | ||
144 | }; | 148 | }; |
145 | 149 | ||
146 | static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd) | 150 | static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd) |
@@ -500,7 +504,7 @@ static int mt9v032_set_crop(struct v4l2_subdev *subdev, | |||
500 | * V4L2 subdev control operations | 504 | * V4L2 subdev control operations |
501 | */ | 505 | */ |
502 | 506 | ||
503 | #define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001) | 507 | #define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001) |
504 | 508 | ||
505 | static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl) | 509 | static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl) |
506 | { | 510 | { |
@@ -545,7 +549,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl) | |||
545 | break; | 549 | break; |
546 | 550 | ||
547 | case V4L2_CID_TEST_PATTERN: | 551 | case V4L2_CID_TEST_PATTERN: |
548 | switch (ctrl->val) { | 552 | switch (mt9v032->test_pattern->val) { |
549 | case 0: | 553 | case 0: |
550 | data = 0; | 554 | data = 0; |
551 | break; | 555 | break; |
@@ -562,13 +566,13 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl) | |||
562 | | MT9V032_TEST_PATTERN_ENABLE; | 566 | | MT9V032_TEST_PATTERN_ENABLE; |
563 | break; | 567 | break; |
564 | default: | 568 | default: |
565 | data = (ctrl->val << MT9V032_TEST_PATTERN_DATA_SHIFT) | 569 | data = (mt9v032->test_pattern_color->val << |
570 | MT9V032_TEST_PATTERN_DATA_SHIFT) | ||
566 | | MT9V032_TEST_PATTERN_USE_DATA | 571 | | MT9V032_TEST_PATTERN_USE_DATA |
567 | | MT9V032_TEST_PATTERN_ENABLE | 572 | | MT9V032_TEST_PATTERN_ENABLE |
568 | | MT9V032_TEST_PATTERN_FLIP; | 573 | | MT9V032_TEST_PATTERN_FLIP; |
569 | break; | 574 | break; |
570 | } | 575 | } |
571 | |||
572 | return mt9v032_write(client, MT9V032_TEST_PATTERN, data); | 576 | return mt9v032_write(client, MT9V032_TEST_PATTERN, data); |
573 | } | 577 | } |
574 | 578 | ||
@@ -579,18 +583,24 @@ static struct v4l2_ctrl_ops mt9v032_ctrl_ops = { | |||
579 | .s_ctrl = mt9v032_s_ctrl, | 583 | .s_ctrl = mt9v032_s_ctrl, |
580 | }; | 584 | }; |
581 | 585 | ||
582 | static const struct v4l2_ctrl_config mt9v032_ctrls[] = { | 586 | static const char * const mt9v032_test_pattern_menu[] = { |
583 | { | 587 | "Disabled", |
584 | .ops = &mt9v032_ctrl_ops, | 588 | "Gray Vertical Shade", |
585 | .id = V4L2_CID_TEST_PATTERN, | 589 | "Gray Horizontal Shade", |
586 | .type = V4L2_CTRL_TYPE_INTEGER, | 590 | "Gray Diagonal Shade", |
587 | .name = "Test pattern", | 591 | "Plain", |
588 | .min = 0, | 592 | }; |
589 | .max = 1023, | 593 | |
590 | .step = 1, | 594 | static const struct v4l2_ctrl_config mt9v032_test_pattern_color = { |
591 | .def = 0, | 595 | .ops = &mt9v032_ctrl_ops, |
592 | .flags = 0, | 596 | .id = V4L2_CID_TEST_PATTERN_COLOR, |
593 | } | 597 | .type = V4L2_CTRL_TYPE_INTEGER, |
598 | .name = "Test Pattern Color", | ||
599 | .min = 0, | ||
600 | .max = 1023, | ||
601 | .step = 1, | ||
602 | .def = 0, | ||
603 | .flags = 0, | ||
594 | }; | 604 | }; |
595 | 605 | ||
596 | /* ----------------------------------------------------------------------------- | 606 | /* ----------------------------------------------------------------------------- |
@@ -741,7 +751,7 @@ static int mt9v032_probe(struct i2c_client *client, | |||
741 | mutex_init(&mt9v032->power_lock); | 751 | mutex_init(&mt9v032->power_lock); |
742 | mt9v032->pdata = pdata; | 752 | mt9v032->pdata = pdata; |
743 | 753 | ||
744 | v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 8); | 754 | v4l2_ctrl_handler_init(&mt9v032->ctrls, 10); |
745 | 755 | ||
746 | v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, | 756 | v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, |
747 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | 757 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); |
@@ -763,6 +773,14 @@ static int mt9v032_probe(struct i2c_client *client, | |||
763 | V4L2_CID_VBLANK, MT9V032_VERTICAL_BLANKING_MIN, | 773 | V4L2_CID_VBLANK, MT9V032_VERTICAL_BLANKING_MIN, |
764 | MT9V032_VERTICAL_BLANKING_MAX, 1, | 774 | MT9V032_VERTICAL_BLANKING_MAX, 1, |
765 | MT9V032_VERTICAL_BLANKING_DEF); | 775 | MT9V032_VERTICAL_BLANKING_DEF); |
776 | mt9v032->test_pattern = v4l2_ctrl_new_std_menu_items(&mt9v032->ctrls, | ||
777 | &mt9v032_ctrl_ops, V4L2_CID_TEST_PATTERN, | ||
778 | ARRAY_SIZE(mt9v032_test_pattern_menu) - 1, 0, 0, | ||
779 | mt9v032_test_pattern_menu); | ||
780 | mt9v032->test_pattern_color = v4l2_ctrl_new_custom(&mt9v032->ctrls, | ||
781 | &mt9v032_test_pattern_color, NULL); | ||
782 | |||
783 | v4l2_ctrl_cluster(2, &mt9v032->test_pattern); | ||
766 | 784 | ||
767 | mt9v032->pixel_rate = | 785 | mt9v032->pixel_rate = |
768 | v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, | 786 | v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, |
@@ -784,8 +802,6 @@ static int mt9v032_probe(struct i2c_client *client, | |||
784 | v4l2_ctrl_cluster(2, &mt9v032->link_freq); | 802 | v4l2_ctrl_cluster(2, &mt9v032->link_freq); |
785 | } | 803 | } |
786 | 804 | ||
787 | for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i) | ||
788 | v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL); | ||
789 | 805 | ||
790 | mt9v032->subdev.ctrl_handler = &mt9v032->ctrls; | 806 | mt9v032->subdev.ctrl_handler = &mt9v032->ctrls; |
791 | 807 | ||
diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 78ac5744cb5d..d2d298b6354e 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c | |||
@@ -684,6 +684,11 @@ static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl) | |||
684 | &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev; | 684 | &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev; |
685 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 685 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
686 | u8 val; | 686 | u8 val; |
687 | int ret; | ||
688 | |||
689 | ret = i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS); | ||
690 | if (ret < 0) | ||
691 | return ret; | ||
687 | 692 | ||
688 | switch (ctrl->id) { | 693 | switch (ctrl->id) { |
689 | case V4L2_CID_VFLIP: | 694 | case V4L2_CID_VFLIP: |
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c index e5c0eedebc58..c31cc04fffd2 100644 --- a/drivers/media/i2c/ths7303.c +++ b/drivers/media/i2c/ths7303.c | |||
@@ -28,6 +28,18 @@ | |||
28 | #include <media/v4l2-subdev.h> | 28 | #include <media/v4l2-subdev.h> |
29 | #include <media/v4l2-chip-ident.h> | 29 | #include <media/v4l2-chip-ident.h> |
30 | 30 | ||
31 | #define THS7303_CHANNEL_1 1 | ||
32 | #define THS7303_CHANNEL_2 2 | ||
33 | #define THS7303_CHANNEL_3 3 | ||
34 | |||
35 | enum ths7303_filter_mode { | ||
36 | THS7303_FILTER_MODE_480I_576I, | ||
37 | THS7303_FILTER_MODE_480P_576P, | ||
38 | THS7303_FILTER_MODE_720P_1080I, | ||
39 | THS7303_FILTER_MODE_1080P, | ||
40 | THS7303_FILTER_MODE_DISABLE | ||
41 | }; | ||
42 | |||
31 | MODULE_DESCRIPTION("TI THS7303 video amplifier driver"); | 43 | MODULE_DESCRIPTION("TI THS7303 video amplifier driver"); |
32 | MODULE_AUTHOR("Chaithrika U S"); | 44 | MODULE_AUTHOR("Chaithrika U S"); |
33 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
@@ -37,35 +49,96 @@ module_param(debug, int, 0644); | |||
37 | MODULE_PARM_DESC(debug, "Debug level 0-1"); | 49 | MODULE_PARM_DESC(debug, "Debug level 0-1"); |
38 | 50 | ||
39 | /* following function is used to set ths7303 */ | 51 | /* following function is used to set ths7303 */ |
40 | static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std) | 52 | int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode) |
41 | { | 53 | { |
54 | u8 input_bias_chroma = 3; | ||
55 | u8 input_bias_luma = 3; | ||
56 | int disable = 0; | ||
42 | int err = 0; | 57 | int err = 0; |
43 | u8 val; | 58 | u8 val = 0; |
44 | struct i2c_client *client; | 59 | u8 temp; |
45 | 60 | ||
46 | client = v4l2_get_subdevdata(sd); | 61 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
47 | 62 | ||
48 | if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) { | 63 | if (!client) |
49 | val = 0x02; | 64 | return -EINVAL; |
50 | v4l2_dbg(1, debug, sd, "setting value for SDTV format\n"); | 65 | |
51 | } else { | 66 | switch (mode) { |
52 | val = 0x00; | 67 | case THS7303_FILTER_MODE_1080P: |
53 | v4l2_dbg(1, debug, sd, "disabling all channels\n"); | 68 | val = (3 << 6); |
69 | val |= (3 << 3); | ||
70 | break; | ||
71 | case THS7303_FILTER_MODE_720P_1080I: | ||
72 | val = (2 << 6); | ||
73 | val |= (2 << 3); | ||
74 | break; | ||
75 | case THS7303_FILTER_MODE_480P_576P: | ||
76 | val = (1 << 6); | ||
77 | val |= (1 << 3); | ||
78 | break; | ||
79 | case THS7303_FILTER_MODE_480I_576I: | ||
80 | break; | ||
81 | case THS7303_FILTER_MODE_DISABLE: | ||
82 | pr_info("mode disabled\n"); | ||
83 | /* disable all channels */ | ||
84 | disable = 1; | ||
85 | default: | ||
86 | /* disable all channels */ | ||
87 | disable = 1; | ||
54 | } | 88 | } |
89 | /* Setup channel 2 - Luma - Green */ | ||
90 | temp = val; | ||
91 | if (!disable) | ||
92 | val |= input_bias_luma; | ||
93 | err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_2, val); | ||
94 | if (err) | ||
95 | goto out; | ||
55 | 96 | ||
56 | err |= i2c_smbus_write_byte_data(client, 0x01, val); | 97 | /* setup two chroma channels */ |
57 | err |= i2c_smbus_write_byte_data(client, 0x02, val); | 98 | if (!disable) |
58 | err |= i2c_smbus_write_byte_data(client, 0x03, val); | 99 | temp |= input_bias_chroma; |
59 | 100 | ||
101 | err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_1, temp); | ||
60 | if (err) | 102 | if (err) |
61 | v4l2_err(sd, "write failed\n"); | 103 | goto out; |
62 | 104 | ||
105 | err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_3, temp); | ||
106 | if (err) | ||
107 | goto out; | ||
108 | return err; | ||
109 | out: | ||
110 | pr_info("write byte data failed\n"); | ||
63 | return err; | 111 | return err; |
64 | } | 112 | } |
65 | 113 | ||
66 | static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) | 114 | static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) |
67 | { | 115 | { |
68 | return ths7303_setvalue(sd, norm); | 116 | if (norm & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) |
117 | return ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I); | ||
118 | else | ||
119 | return ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE); | ||
120 | } | ||
121 | |||
122 | /* for setting filter for HD output */ | ||
123 | static int ths7303_s_dv_timings(struct v4l2_subdev *sd, | ||
124 | struct v4l2_dv_timings *dv_timings) | ||
125 | { | ||
126 | u32 height = dv_timings->bt.height; | ||
127 | int interlaced = dv_timings->bt.interlaced; | ||
128 | int res = 0; | ||
129 | |||
130 | if (height == 1080 && !interlaced) | ||
131 | res = ths7303_setval(sd, THS7303_FILTER_MODE_1080P); | ||
132 | else if ((height == 720 && !interlaced) || | ||
133 | (height == 1080 && interlaced)) | ||
134 | res = ths7303_setval(sd, THS7303_FILTER_MODE_720P_1080I); | ||
135 | else if ((height == 480 || height == 576) && !interlaced) | ||
136 | res = ths7303_setval(sd, THS7303_FILTER_MODE_480P_576P); | ||
137 | else | ||
138 | /* disable all channels */ | ||
139 | res = ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE); | ||
140 | |||
141 | return res; | ||
69 | } | 142 | } |
70 | 143 | ||
71 | static int ths7303_g_chip_ident(struct v4l2_subdev *sd, | 144 | static int ths7303_g_chip_ident(struct v4l2_subdev *sd, |
@@ -78,6 +151,7 @@ static int ths7303_g_chip_ident(struct v4l2_subdev *sd, | |||
78 | 151 | ||
79 | static const struct v4l2_subdev_video_ops ths7303_video_ops = { | 152 | static const struct v4l2_subdev_video_ops ths7303_video_ops = { |
80 | .s_std_output = ths7303_s_std_output, | 153 | .s_std_output = ths7303_s_std_output, |
154 | .s_dv_timings = ths7303_s_dv_timings, | ||
81 | }; | 155 | }; |
82 | 156 | ||
83 | static const struct v4l2_subdev_core_ops ths7303_core_ops = { | 157 | static const struct v4l2_subdev_core_ops ths7303_core_ops = { |
@@ -107,7 +181,7 @@ static int ths7303_probe(struct i2c_client *client, | |||
107 | 181 | ||
108 | v4l2_i2c_subdev_init(sd, client, &ths7303_ops); | 182 | v4l2_i2c_subdev_init(sd, client, &ths7303_ops); |
109 | 183 | ||
110 | return ths7303_setvalue(sd, std_id); | 184 | return ths7303_s_std_output(sd, std_id); |
111 | } | 185 | } |
112 | 186 | ||
113 | static int ths7303_remove(struct i2c_client *client) | 187 | static int ths7303_remove(struct i2c_client *client) |
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 1f3943bb87d5..d5e10215a28f 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c | |||
@@ -519,6 +519,12 @@ static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) | |||
519 | 519 | ||
520 | *std_id = V4L2_STD_UNKNOWN; | 520 | *std_id = V4L2_STD_UNKNOWN; |
521 | 521 | ||
522 | /* To query the standard the TVP514x must power on the ADCs. */ | ||
523 | if (!decoder->streaming) { | ||
524 | tvp514x_s_stream(sd, 1); | ||
525 | msleep(LOCK_RETRY_DELAY); | ||
526 | } | ||
527 | |||
522 | /* query the current standard */ | 528 | /* query the current standard */ |
523 | current_std = tvp514x_query_current_std(sd); | 529 | current_std = tvp514x_query_current_std(sd); |
524 | if (current_std == STD_INVALID) | 530 | if (current_std == STD_INVALID) |
@@ -625,25 +631,12 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd, | |||
625 | int err; | 631 | int err; |
626 | enum tvp514x_input input_sel; | 632 | enum tvp514x_input input_sel; |
627 | enum tvp514x_output output_sel; | 633 | enum tvp514x_output output_sel; |
628 | u8 sync_lock_status, lock_mask; | ||
629 | int try_count = LOCK_RETRY_COUNT; | ||
630 | 634 | ||
631 | if ((input >= INPUT_INVALID) || | 635 | if ((input >= INPUT_INVALID) || |
632 | (output >= OUTPUT_INVALID)) | 636 | (output >= OUTPUT_INVALID)) |
633 | /* Index out of bound */ | 637 | /* Index out of bound */ |
634 | return -EINVAL; | 638 | return -EINVAL; |
635 | 639 | ||
636 | /* | ||
637 | * For the sequence streamon -> streamoff and again s_input | ||
638 | * it fails to lock the signal, since streamoff puts TVP514x | ||
639 | * into power off state which leads to failure in sub-sequent s_input. | ||
640 | * | ||
641 | * So power up the TVP514x device here, since it is important to lock | ||
642 | * the signal at this stage. | ||
643 | */ | ||
644 | if (!decoder->streaming) | ||
645 | tvp514x_s_stream(sd, 1); | ||
646 | |||
647 | input_sel = input; | 640 | input_sel = input; |
648 | output_sel = output; | 641 | output_sel = output; |
649 | 642 | ||
@@ -660,64 +653,6 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd, | |||
660 | 653 | ||
661 | decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel; | 654 | decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel; |
662 | decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel; | 655 | decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel; |
663 | |||
664 | /* Clear status */ | ||
665 | msleep(LOCK_RETRY_DELAY); | ||
666 | err = | ||
667 | tvp514x_write_reg(sd, REG_CLEAR_LOST_LOCK, 0x01); | ||
668 | if (err) | ||
669 | return err; | ||
670 | |||
671 | switch (input_sel) { | ||
672 | case INPUT_CVBS_VI1A: | ||
673 | case INPUT_CVBS_VI1B: | ||
674 | case INPUT_CVBS_VI1C: | ||
675 | case INPUT_CVBS_VI2A: | ||
676 | case INPUT_CVBS_VI2B: | ||
677 | case INPUT_CVBS_VI2C: | ||
678 | case INPUT_CVBS_VI3A: | ||
679 | case INPUT_CVBS_VI3B: | ||
680 | case INPUT_CVBS_VI3C: | ||
681 | case INPUT_CVBS_VI4A: | ||
682 | lock_mask = STATUS_CLR_SUBCAR_LOCK_BIT | | ||
683 | STATUS_HORZ_SYNC_LOCK_BIT | | ||
684 | STATUS_VIRT_SYNC_LOCK_BIT; | ||
685 | break; | ||
686 | |||
687 | case INPUT_SVIDEO_VI2A_VI1A: | ||
688 | case INPUT_SVIDEO_VI2B_VI1B: | ||
689 | case INPUT_SVIDEO_VI2C_VI1C: | ||
690 | case INPUT_SVIDEO_VI2A_VI3A: | ||
691 | case INPUT_SVIDEO_VI2B_VI3B: | ||
692 | case INPUT_SVIDEO_VI2C_VI3C: | ||
693 | case INPUT_SVIDEO_VI4A_VI1A: | ||
694 | case INPUT_SVIDEO_VI4A_VI1B: | ||
695 | case INPUT_SVIDEO_VI4A_VI1C: | ||
696 | case INPUT_SVIDEO_VI4A_VI3A: | ||
697 | case INPUT_SVIDEO_VI4A_VI3B: | ||
698 | case INPUT_SVIDEO_VI4A_VI3C: | ||
699 | lock_mask = STATUS_HORZ_SYNC_LOCK_BIT | | ||
700 | STATUS_VIRT_SYNC_LOCK_BIT; | ||
701 | break; | ||
702 | /* Need to add other interfaces*/ | ||
703 | default: | ||
704 | return -EINVAL; | ||
705 | } | ||
706 | |||
707 | while (try_count-- > 0) { | ||
708 | /* Allow decoder to sync up with new input */ | ||
709 | msleep(LOCK_RETRY_DELAY); | ||
710 | |||
711 | sync_lock_status = tvp514x_read_reg(sd, | ||
712 | REG_STATUS1); | ||
713 | if (lock_mask == (sync_lock_status & lock_mask)) | ||
714 | /* Input detected */ | ||
715 | break; | ||
716 | } | ||
717 | |||
718 | if (try_count < 0) | ||
719 | return -EINVAL; | ||
720 | |||
721 | decoder->input = input; | 656 | decoder->input = input; |
722 | decoder->output = output; | 657 | decoder->output = output; |
723 | 658 | ||