aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/mt9m001.c30
-rw-r--r--drivers/media/video/mt9m111.c1
-rw-r--r--drivers/media/video/mt9t031.c24
-rw-r--r--drivers/media/video/mt9v022.c32
-rw-r--r--drivers/media/video/pxa_camera.c9
-rw-r--r--drivers/media/video/soc_camera_platform.c1
-rw-r--r--include/media/soc_camera.h1
-rw-r--r--include/media/v4l2-subdev.h22
8 files changed, 90 insertions, 30 deletions
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 45388d2ce2fd..17be2d46fd40 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -82,6 +82,7 @@ struct mt9m001 {
82 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ 82 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
83 unsigned int gain; 83 unsigned int gain;
84 unsigned int exposure; 84 unsigned int exposure;
85 unsigned short y_skip_top; /* Lines to skip at the top */
85 unsigned char autoexposure; 86 unsigned char autoexposure;
86}; 87};
87 88
@@ -222,7 +223,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
222 soc_camera_limit_side(&rect.top, &rect.height, 223 soc_camera_limit_side(&rect.top, &rect.height,
223 MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT); 224 MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
224 225
225 total_h = rect.height + icd->y_skip_top + vblank; 226 total_h = rect.height + mt9m001->y_skip_top + vblank;
226 227
227 /* Blanking and start values - default... */ 228 /* Blanking and start values - default... */
228 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); 229 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
@@ -239,7 +240,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
239 ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1); 240 ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
240 if (!ret) 241 if (!ret)
241 ret = reg_write(client, MT9M001_WINDOW_HEIGHT, 242 ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
242 rect.height + icd->y_skip_top - 1); 243 rect.height + mt9m001->y_skip_top - 1);
243 if (!ret && mt9m001->autoexposure) { 244 if (!ret && mt9m001->autoexposure) {
244 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h); 245 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
245 if (!ret) { 246 if (!ret) {
@@ -327,13 +328,13 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
327static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 328static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
328{ 329{
329 struct i2c_client *client = sd->priv; 330 struct i2c_client *client = sd->priv;
330 struct soc_camera_device *icd = client->dev.platform_data; 331 struct mt9m001 *mt9m001 = to_mt9m001(client);
331 struct v4l2_pix_format *pix = &f->fmt.pix; 332 struct v4l2_pix_format *pix = &f->fmt.pix;
332 333
333 v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH, 334 v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH,
334 MT9M001_MAX_WIDTH, 1, 335 MT9M001_MAX_WIDTH, 1,
335 &pix->height, MT9M001_MIN_HEIGHT + icd->y_skip_top, 336 &pix->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top,
336 MT9M001_MAX_HEIGHT + icd->y_skip_top, 0, 0); 337 MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0);
337 338
338 if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || 339 if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
339 pix->pixelformat == V4L2_PIX_FMT_SBGGR16) 340 pix->pixelformat == V4L2_PIX_FMT_SBGGR16)
@@ -552,7 +553,7 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
552 if (ctrl->value) { 553 if (ctrl->value) {
553 const u16 vblank = 25; 554 const u16 vblank = 25;
554 unsigned int total_h = mt9m001->rect.height + 555 unsigned int total_h = mt9m001->rect.height +
555 icd->y_skip_top + vblank; 556 mt9m001->y_skip_top + vblank;
556 if (reg_write(client, MT9M001_SHUTTER_WIDTH, 557 if (reg_write(client, MT9M001_SHUTTER_WIDTH,
557 total_h) < 0) 558 total_h) < 0)
558 return -EIO; 559 return -EIO;
@@ -655,6 +656,16 @@ static void mt9m001_video_remove(struct soc_camera_device *icd)
655 icl->free_bus(icl); 656 icl->free_bus(icl);
656} 657}
657 658
659static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
660{
661 struct i2c_client *client = sd->priv;
662 struct mt9m001 *mt9m001 = to_mt9m001(client);
663
664 *lines = mt9m001->y_skip_top;
665
666 return 0;
667}
668
658static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { 669static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
659 .g_ctrl = mt9m001_g_ctrl, 670 .g_ctrl = mt9m001_g_ctrl,
660 .s_ctrl = mt9m001_s_ctrl, 671 .s_ctrl = mt9m001_s_ctrl,
@@ -675,9 +686,14 @@ static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
675 .cropcap = mt9m001_cropcap, 686 .cropcap = mt9m001_cropcap,
676}; 687};
677 688
689static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
690 .g_skip_top_lines = mt9m001_g_skip_top_lines,
691};
692
678static struct v4l2_subdev_ops mt9m001_subdev_ops = { 693static struct v4l2_subdev_ops mt9m001_subdev_ops = {
679 .core = &mt9m001_subdev_core_ops, 694 .core = &mt9m001_subdev_core_ops,
680 .video = &mt9m001_subdev_video_ops, 695 .video = &mt9m001_subdev_video_ops,
696 .sensor = &mt9m001_subdev_sensor_ops,
681}; 697};
682 698
683static int mt9m001_probe(struct i2c_client *client, 699static int mt9m001_probe(struct i2c_client *client,
@@ -714,8 +730,8 @@ static int mt9m001_probe(struct i2c_client *client,
714 730
715 /* Second stage probe - when a capture adapter is there */ 731 /* Second stage probe - when a capture adapter is there */
716 icd->ops = &mt9m001_ops; 732 icd->ops = &mt9m001_ops;
717 icd->y_skip_top = 0;
718 733
734 mt9m001->y_skip_top = 0;
719 mt9m001->rect.left = MT9M001_COLUMN_SKIP; 735 mt9m001->rect.left = MT9M001_COLUMN_SKIP;
720 mt9m001->rect.top = MT9M001_ROW_SKIP; 736 mt9m001->rect.top = MT9M001_ROW_SKIP;
721 mt9m001->rect.width = MT9M001_MAX_WIDTH; 737 mt9m001->rect.width = MT9M001_MAX_WIDTH;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 90da699601ea..30db625455e4 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -1019,7 +1019,6 @@ static int mt9m111_probe(struct i2c_client *client,
1019 1019
1020 /* Second stage probe - when a capture adapter is there */ 1020 /* Second stage probe - when a capture adapter is there */
1021 icd->ops = &mt9m111_ops; 1021 icd->ops = &mt9m111_ops;
1022 icd->y_skip_top = 0;
1023 1022
1024 mt9m111->rect.left = MT9M111_MIN_DARK_COLS; 1023 mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
1025 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; 1024 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 6966f644977e..1adbb7b2b580 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -74,6 +74,7 @@ struct mt9t031 {
74 u16 xskip; 74 u16 xskip;
75 u16 yskip; 75 u16 yskip;
76 unsigned int gain; 76 unsigned int gain;
77 unsigned short y_skip_top; /* Lines to skip at the top */
77 unsigned int exposure; 78 unsigned int exposure;
78 unsigned char autoexposure; 79 unsigned char autoexposure;
79}; 80};
@@ -301,9 +302,9 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
301 ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1); 302 ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1);
302 if (ret >= 0) 303 if (ret >= 0)
303 ret = reg_write(client, MT9T031_WINDOW_HEIGHT, 304 ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
304 rect->height + icd->y_skip_top - 1); 305 rect->height + mt9t031->y_skip_top - 1);
305 if (ret >= 0 && mt9t031->autoexposure) { 306 if (ret >= 0 && mt9t031->autoexposure) {
306 unsigned int total_h = rect->height + icd->y_skip_top + vblank; 307 unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank;
307 ret = set_shutter(client, total_h); 308 ret = set_shutter(client, total_h);
308 if (ret >= 0) { 309 if (ret >= 0) {
309 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 310 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
@@ -657,7 +658,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
657 const u16 vblank = MT9T031_VERTICAL_BLANK; 658 const u16 vblank = MT9T031_VERTICAL_BLANK;
658 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 659 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
659 unsigned int total_h = mt9t031->rect.height + 660 unsigned int total_h = mt9t031->rect.height +
660 icd->y_skip_top + vblank; 661 mt9t031->y_skip_top + vblank;
661 662
662 if (set_shutter(client, total_h) < 0) 663 if (set_shutter(client, total_h) < 0)
663 return -EIO; 664 return -EIO;
@@ -714,6 +715,16 @@ static int mt9t031_video_probe(struct i2c_client *client)
714 return ret; 715 return ret;
715} 716}
716 717
718static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
719{
720 struct i2c_client *client = sd->priv;
721 struct mt9t031 *mt9t031 = to_mt9t031(client);
722
723 *lines = mt9t031->y_skip_top;
724
725 return 0;
726}
727
717static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { 728static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
718 .g_ctrl = mt9t031_g_ctrl, 729 .g_ctrl = mt9t031_g_ctrl,
719 .s_ctrl = mt9t031_s_ctrl, 730 .s_ctrl = mt9t031_s_ctrl,
@@ -734,9 +745,14 @@ static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
734 .cropcap = mt9t031_cropcap, 745 .cropcap = mt9t031_cropcap,
735}; 746};
736 747
748static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
749 .g_skip_top_lines = mt9t031_g_skip_top_lines,
750};
751
737static struct v4l2_subdev_ops mt9t031_subdev_ops = { 752static struct v4l2_subdev_ops mt9t031_subdev_ops = {
738 .core = &mt9t031_subdev_core_ops, 753 .core = &mt9t031_subdev_core_ops,
739 .video = &mt9t031_subdev_video_ops, 754 .video = &mt9t031_subdev_video_ops,
755 .sensor = &mt9t031_subdev_sensor_ops,
740}; 756};
741 757
742static int mt9t031_probe(struct i2c_client *client, 758static int mt9t031_probe(struct i2c_client *client,
@@ -773,8 +789,8 @@ static int mt9t031_probe(struct i2c_client *client,
773 789
774 /* Second stage probe - when a capture adapter is there */ 790 /* Second stage probe - when a capture adapter is there */
775 icd->ops = &mt9t031_ops; 791 icd->ops = &mt9t031_ops;
776 icd->y_skip_top = 0;
777 792
793 mt9t031->y_skip_top = 0;
778 mt9t031->rect.left = MT9T031_COLUMN_SKIP; 794 mt9t031->rect.left = MT9T031_COLUMN_SKIP;
779 mt9t031->rect.top = MT9T031_ROW_SKIP; 795 mt9t031->rect.top = MT9T031_ROW_SKIP;
780 mt9t031->rect.width = MT9T031_MAX_WIDTH; 796 mt9t031->rect.width = MT9T031_MAX_WIDTH;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 995607f9d3ba..b71898f1b085 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -97,6 +97,7 @@ struct mt9v022 {
97 __u32 fourcc; 97 __u32 fourcc;
98 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ 98 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
99 u16 chip_control; 99 u16 chip_control;
100 unsigned short y_skip_top; /* Lines to skip at the top */
100}; 101};
101 102
102static struct mt9v022 *to_mt9v022(const struct i2c_client *client) 103static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
@@ -265,7 +266,6 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
265 struct i2c_client *client = sd->priv; 266 struct i2c_client *client = sd->priv;
266 struct mt9v022 *mt9v022 = to_mt9v022(client); 267 struct mt9v022 *mt9v022 = to_mt9v022(client);
267 struct v4l2_rect rect = a->c; 268 struct v4l2_rect rect = a->c;
268 struct soc_camera_device *icd = client->dev.platform_data;
269 int ret; 269 int ret;
270 270
271 /* Bayer format - even size lengths */ 271 /* Bayer format - even size lengths */
@@ -287,10 +287,10 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
287 if (ret >= 0) { 287 if (ret >= 0) {
288 if (ret & 1) /* Autoexposure */ 288 if (ret & 1) /* Autoexposure */
289 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 289 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
290 rect.height + icd->y_skip_top + 43); 290 rect.height + mt9v022->y_skip_top + 43);
291 else 291 else
292 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 292 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
293 rect.height + icd->y_skip_top + 43); 293 rect.height + mt9v022->y_skip_top + 43);
294 } 294 }
295 /* Setup frame format: defaults apart from width and height */ 295 /* Setup frame format: defaults apart from width and height */
296 if (!ret) 296 if (!ret)
@@ -309,7 +309,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
309 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width); 309 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
310 if (!ret) 310 if (!ret)
311 ret = reg_write(client, MT9V022_WINDOW_HEIGHT, 311 ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
312 rect.height + icd->y_skip_top); 312 rect.height + mt9v022->y_skip_top);
313 313
314 if (ret < 0) 314 if (ret < 0)
315 return ret; 315 return ret;
@@ -410,15 +410,15 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
410static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 410static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
411{ 411{
412 struct i2c_client *client = sd->priv; 412 struct i2c_client *client = sd->priv;
413 struct soc_camera_device *icd = client->dev.platform_data; 413 struct mt9v022 *mt9v022 = to_mt9v022(client);
414 struct v4l2_pix_format *pix = &f->fmt.pix; 414 struct v4l2_pix_format *pix = &f->fmt.pix;
415 int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || 415 int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
416 pix->pixelformat == V4L2_PIX_FMT_SBGGR16; 416 pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
417 417
418 v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH, 418 v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH,
419 MT9V022_MAX_WIDTH, align, 419 MT9V022_MAX_WIDTH, align,
420 &pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top, 420 &pix->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
421 MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0); 421 MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
422 422
423 return 0; 423 return 0;
424} 424}
@@ -787,6 +787,16 @@ static void mt9v022_video_remove(struct soc_camera_device *icd)
787 icl->free_bus(icl); 787 icl->free_bus(icl);
788} 788}
789 789
790static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
791{
792 struct i2c_client *client = sd->priv;
793 struct mt9v022 *mt9v022 = to_mt9v022(client);
794
795 *lines = mt9v022->y_skip_top;
796
797 return 0;
798}
799
790static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { 800static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
791 .g_ctrl = mt9v022_g_ctrl, 801 .g_ctrl = mt9v022_g_ctrl,
792 .s_ctrl = mt9v022_s_ctrl, 802 .s_ctrl = mt9v022_s_ctrl,
@@ -807,9 +817,14 @@ static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
807 .cropcap = mt9v022_cropcap, 817 .cropcap = mt9v022_cropcap,
808}; 818};
809 819
820static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
821 .g_skip_top_lines = mt9v022_g_skip_top_lines,
822};
823
810static struct v4l2_subdev_ops mt9v022_subdev_ops = { 824static struct v4l2_subdev_ops mt9v022_subdev_ops = {
811 .core = &mt9v022_subdev_core_ops, 825 .core = &mt9v022_subdev_core_ops,
812 .video = &mt9v022_subdev_video_ops, 826 .video = &mt9v022_subdev_video_ops,
827 .sensor = &mt9v022_subdev_sensor_ops,
813}; 828};
814 829
815static int mt9v022_probe(struct i2c_client *client, 830static int mt9v022_probe(struct i2c_client *client,
@@ -851,8 +866,7 @@ static int mt9v022_probe(struct i2c_client *client,
851 * MT9V022 _really_ corrupts the first read out line. 866 * MT9V022 _really_ corrupts the first read out line.
852 * TODO: verify on i.MX31 867 * TODO: verify on i.MX31
853 */ 868 */
854 icd->y_skip_top = 1; 869 mt9v022->y_skip_top = 1;
855
856 mt9v022->rect.left = MT9V022_COLUMN_SKIP; 870 mt9v022->rect.left = MT9V022_COLUMN_SKIP;
857 mt9v022->rect.top = MT9V022_ROW_SKIP; 871 mt9v022->rect.top = MT9V022_ROW_SKIP;
858 mt9v022->rect.width = MT9V022_MAX_WIDTH; 872 mt9v022->rect.width = MT9V022_MAX_WIDTH;
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 51b683c63b70..4df09a693ec7 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1051,8 +1051,13 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1051{ 1051{
1052 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1052 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1053 struct pxa_camera_dev *pcdev = ici->priv; 1053 struct pxa_camera_dev *pcdev = ici->priv;
1054 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1054 unsigned long dw, bpp; 1055 unsigned long dw, bpp;
1055 u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0; 1056 u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0, y_skip_top;
1057 int ret = v4l2_subdev_call(sd, sensor, g_skip_top_lines, &y_skip_top);
1058
1059 if (ret < 0)
1060 y_skip_top = 0;
1056 1061
1057 /* Datawidth is now guaranteed to be equal to one of the three values. 1062 /* Datawidth is now guaranteed to be equal to one of the three values.
1058 * We fix bit-per-pixel equal to data-width... */ 1063 * We fix bit-per-pixel equal to data-width... */
@@ -1118,7 +1123,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1118 1123
1119 cicr2 = 0; 1124 cicr2 = 0;
1120 cicr3 = CICR3_LPF_VAL(icd->user_height - 1) | 1125 cicr3 = CICR3_LPF_VAL(icd->user_height - 1) |
1121 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); 1126 CICR3_BFW_VAL(min((u32)255, y_skip_top));
1122 cicr4 |= pcdev->mclk_divisor; 1127 cicr4 |= pcdev->mclk_divisor;
1123 1128
1124 __raw_writel(cicr1, pcdev->base + CICR1); 1129 __raw_writel(cicr1, pcdev->base + CICR1);
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index b6a575ce5da2..c7c91518c391 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -128,7 +128,6 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
128 /* Set the control device reference */ 128 /* Set the control device reference */
129 dev_set_drvdata(&icd->dev, &pdev->dev); 129 dev_set_drvdata(&icd->dev, &pdev->dev);
130 130
131 icd->y_skip_top = 0;
132 icd->ops = &soc_camera_platform_ops; 131 icd->ops = &soc_camera_platform_ops;
133 132
134 ici = to_soc_camera_host(icd->dev.parent); 133 ici = to_soc_camera_host(icd->dev.parent);
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index c5afc8cf8e1a..218639f133d3 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -24,7 +24,6 @@ struct soc_camera_device {
24 struct device *pdev; /* Platform device */ 24 struct device *pdev; /* Platform device */
25 s32 user_width; 25 s32 user_width;
26 s32 user_height; 26 s32 user_height;
27 unsigned short y_skip_top; /* Lines to skip at the top */
28 unsigned char iface; /* Host number */ 27 unsigned char iface; /* Host number */
29 unsigned char devnum; /* Device number per host */ 28 unsigned char devnum; /* Device number per host */
30 unsigned char buswidth; /* See comment in .c */ 29 unsigned char buswidth; /* See comment in .c */
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 7a3408f9d0f2..a128458dc9eb 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -263,6 +263,17 @@ struct v4l2_subdev_video_ops {
263 struct v4l2_dv_timings *timings); 263 struct v4l2_dv_timings *timings);
264}; 264};
265 265
266/**
267 * struct v4l2_subdev_sensor_ops - v4l2-subdev sensor operations
268 * @g_skip_top_lines: number of lines at the top of the image to be skipped.
269 * This is needed for some sensors, which always corrupt
270 * several top lines of the output image, or which send their
271 * metadata in them.
272 */
273struct v4l2_subdev_sensor_ops {
274 int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines);
275};
276
266/* 277/*
267 interrupt_service_routine: Called by the bridge chip's interrupt service 278 interrupt_service_routine: Called by the bridge chip's interrupt service
268 handler, when an IR interrupt status has be raised due to this subdev, 279 handler, when an IR interrupt status has be raised due to this subdev,
@@ -347,11 +358,12 @@ struct v4l2_subdev_ir_ops {
347}; 358};
348 359
349struct v4l2_subdev_ops { 360struct v4l2_subdev_ops {
350 const struct v4l2_subdev_core_ops *core; 361 const struct v4l2_subdev_core_ops *core;
351 const struct v4l2_subdev_tuner_ops *tuner; 362 const struct v4l2_subdev_tuner_ops *tuner;
352 const struct v4l2_subdev_audio_ops *audio; 363 const struct v4l2_subdev_audio_ops *audio;
353 const struct v4l2_subdev_video_ops *video; 364 const struct v4l2_subdev_video_ops *video;
354 const struct v4l2_subdev_ir_ops *ir; 365 const struct v4l2_subdev_ir_ops *ir;
366 const struct v4l2_subdev_sensor_ops *sensor;
355}; 367};
356 368
357#define V4L2_SUBDEV_NAME_SIZE 32 369#define V4L2_SUBDEV_NAME_SIZE 32