aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9v022.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-12-11 09:46:49 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-16 06:27:29 -0500
commit760697beca338599a65484389c7abbe54aedb664 (patch)
tree515735429d2240629a6f048ab1a7fefaf5299e46 /drivers/media/video/mt9v022.c
parent9a74251d8bee7a25fee89a0be3ccea73e01c1a05 (diff)
V4L/DVB (13659): soc-camera: convert to the new mediabus API
Convert soc-camera core and all soc-camera drivers to the new mediabus API. This also takes soc-camera client drivers one step closer to also be usable with generic v4l2-subdev host drivers. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/mt9v022.c')
-rw-r--r--drivers/media/video/mt9v022.c150
1 files changed, 90 insertions, 60 deletions
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index f60a9a107f20..91df7ec91fb6 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -64,41 +64,46 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
64#define MT9V022_COLUMN_SKIP 1 64#define MT9V022_COLUMN_SKIP 1
65#define MT9V022_ROW_SKIP 4 65#define MT9V022_ROW_SKIP 4
66 66
67static const struct soc_camera_data_format mt9v022_colour_formats[] = { 67/* MT9V022 has only one fixed colorspace per pixelcode */
68struct mt9v022_datafmt {
69 enum v4l2_mbus_pixelcode code;
70 enum v4l2_colorspace colorspace;
71};
72
73/* Find a data format by a pixel code in an array */
74static const struct mt9v022_datafmt *mt9v022_find_datafmt(
75 enum v4l2_mbus_pixelcode code, const struct mt9v022_datafmt *fmt,
76 int n)
77{
78 int i;
79 for (i = 0; i < n; i++)
80 if (fmt[i].code == code)
81 return fmt + i;
82
83 return NULL;
84}
85
86static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
68 /* 87 /*
69 * Order important: first natively supported, 88 * Order important: first natively supported,
70 * second supported with a GPIO extender 89 * second supported with a GPIO extender
71 */ 90 */
72 { 91 {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB},
73 .name = "Bayer (sRGB) 10 bit", 92 {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB},
74 .depth = 10,
75 .fourcc = V4L2_PIX_FMT_SBGGR16,
76 .colorspace = V4L2_COLORSPACE_SRGB,
77 }, {
78 .name = "Bayer (sRGB) 8 bit",
79 .depth = 8,
80 .fourcc = V4L2_PIX_FMT_SBGGR8,
81 .colorspace = V4L2_COLORSPACE_SRGB,
82 }
83}; 93};
84 94
85static const struct soc_camera_data_format mt9v022_monochrome_formats[] = { 95static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
86 /* Order important - see above */ 96 /* Order important - see above */
87 { 97 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
88 .name = "Monochrome 10 bit", 98 {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG},
89 .depth = 10,
90 .fourcc = V4L2_PIX_FMT_Y16,
91 }, {
92 .name = "Monochrome 8 bit",
93 .depth = 8,
94 .fourcc = V4L2_PIX_FMT_GREY,
95 },
96}; 99};
97 100
98struct mt9v022 { 101struct mt9v022 {
99 struct v4l2_subdev subdev; 102 struct v4l2_subdev subdev;
100 struct v4l2_rect rect; /* Sensor window */ 103 struct v4l2_rect rect; /* Sensor window */
101 __u32 fourcc; 104 const struct mt9v022_datafmt *fmt;
105 const struct mt9v022_datafmt *fmts;
106 int num_fmts;
102 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ 107 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
103 u16 chip_control; 108 u16 chip_control;
104 unsigned short y_skip_top; /* Lines to skip at the top */ 109 unsigned short y_skip_top; /* Lines to skip at the top */
@@ -275,8 +280,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
275 int ret; 280 int ret;
276 281
277 /* Bayer format - even size lengths */ 282 /* Bayer format - even size lengths */
278 if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 || 283 if (mt9v022->fmts == mt9v022_colour_fmts) {
279 mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) {
280 rect.width = ALIGN(rect.width, 2); 284 rect.width = ALIGN(rect.width, 2);
281 rect.height = ALIGN(rect.height, 2); 285 rect.height = ALIGN(rect.height, 2);
282 /* Let the user play with the starting pixel */ 286 /* Let the user play with the starting pixel */
@@ -354,32 +358,32 @@ static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
354 return 0; 358 return 0;
355} 359}
356 360
357static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 361static int mt9v022_g_fmt(struct v4l2_subdev *sd,
362 struct v4l2_mbus_framefmt *mf)
358{ 363{
359 struct i2c_client *client = sd->priv; 364 struct i2c_client *client = sd->priv;
360 struct mt9v022 *mt9v022 = to_mt9v022(client); 365 struct mt9v022 *mt9v022 = to_mt9v022(client);
361 struct v4l2_pix_format *pix = &f->fmt.pix;
362 366
363 pix->width = mt9v022->rect.width; 367 mf->width = mt9v022->rect.width;
364 pix->height = mt9v022->rect.height; 368 mf->height = mt9v022->rect.height;
365 pix->pixelformat = mt9v022->fourcc; 369 mf->code = mt9v022->fmt->code;
366 pix->field = V4L2_FIELD_NONE; 370 mf->colorspace = mt9v022->fmt->colorspace;
367 pix->colorspace = V4L2_COLORSPACE_SRGB; 371 mf->field = V4L2_FIELD_NONE;
368 372
369 return 0; 373 return 0;
370} 374}
371 375
372static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 376static int mt9v022_s_fmt(struct v4l2_subdev *sd,
377 struct v4l2_mbus_framefmt *mf)
373{ 378{
374 struct i2c_client *client = sd->priv; 379 struct i2c_client *client = sd->priv;
375 struct mt9v022 *mt9v022 = to_mt9v022(client); 380 struct mt9v022 *mt9v022 = to_mt9v022(client);
376 struct v4l2_pix_format *pix = &f->fmt.pix;
377 struct v4l2_crop a = { 381 struct v4l2_crop a = {
378 .c = { 382 .c = {
379 .left = mt9v022->rect.left, 383 .left = mt9v022->rect.left,
380 .top = mt9v022->rect.top, 384 .top = mt9v022->rect.top,
381 .width = pix->width, 385 .width = mf->width,
382 .height = pix->height, 386 .height = mf->height,
383 }, 387 },
384 }; 388 };
385 int ret; 389 int ret;
@@ -388,14 +392,14 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
388 * The caller provides a supported format, as verified per call to 392 * The caller provides a supported format, as verified per call to
389 * icd->try_fmt(), datawidth is from our supported format list 393 * icd->try_fmt(), datawidth is from our supported format list
390 */ 394 */
391 switch (pix->pixelformat) { 395 switch (mf->code) {
392 case V4L2_PIX_FMT_GREY: 396 case V4L2_MBUS_FMT_GREY8_1X8:
393 case V4L2_PIX_FMT_Y16: 397 case V4L2_MBUS_FMT_Y10_1X10:
394 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) 398 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
395 return -EINVAL; 399 return -EINVAL;
396 break; 400 break;
397 case V4L2_PIX_FMT_SBGGR8: 401 case V4L2_MBUS_FMT_SBGGR8_1X8:
398 case V4L2_PIX_FMT_SBGGR16: 402 case V4L2_MBUS_FMT_SBGGR10_1X10:
399 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) 403 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
400 return -EINVAL; 404 return -EINVAL;
401 break; 405 break;
@@ -409,27 +413,39 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
409 /* No support for scaling on this camera, just crop. */ 413 /* No support for scaling on this camera, just crop. */
410 ret = mt9v022_s_crop(sd, &a); 414 ret = mt9v022_s_crop(sd, &a);
411 if (!ret) { 415 if (!ret) {
412 pix->width = mt9v022->rect.width; 416 mf->width = mt9v022->rect.width;
413 pix->height = mt9v022->rect.height; 417 mf->height = mt9v022->rect.height;
414 mt9v022->fourcc = pix->pixelformat; 418 mt9v022->fmt = mt9v022_find_datafmt(mf->code,
419 mt9v022->fmts, mt9v022->num_fmts);
420 mf->colorspace = mt9v022->fmt->colorspace;
415 } 421 }
416 422
417 return ret; 423 return ret;
418} 424}
419 425
420static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 426static int mt9v022_try_fmt(struct v4l2_subdev *sd,
427 struct v4l2_mbus_framefmt *mf)
421{ 428{
422 struct i2c_client *client = sd->priv; 429 struct i2c_client *client = sd->priv;
423 struct mt9v022 *mt9v022 = to_mt9v022(client); 430 struct mt9v022 *mt9v022 = to_mt9v022(client);
424 struct v4l2_pix_format *pix = &f->fmt.pix; 431 const struct mt9v022_datafmt *fmt;
425 int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || 432 int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 ||
426 pix->pixelformat == V4L2_PIX_FMT_SBGGR16; 433 mf->code == V4L2_MBUS_FMT_SBGGR10_1X10;
427 434
428 v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH, 435 v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH,
429 MT9V022_MAX_WIDTH, align, 436 MT9V022_MAX_WIDTH, align,
430 &pix->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, 437 &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top,
431 MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0); 438 MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0);
432 439
440 fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts,
441 mt9v022->num_fmts);
442 if (!fmt) {
443 fmt = mt9v022->fmt;
444 mf->code = fmt->code;
445 }
446
447 mf->colorspace = fmt->colorspace;
448
433 return 0; 449 return 0;
434} 450}
435 451
@@ -749,17 +765,17 @@ static int mt9v022_video_probe(struct soc_camera_device *icd,
749 !strcmp("color", sensor_type))) { 765 !strcmp("color", sensor_type))) {
750 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); 766 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
751 mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; 767 mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
752 icd->formats = mt9v022_colour_formats; 768 mt9v022->fmts = mt9v022_colour_fmts;
753 } else { 769 } else {
754 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); 770 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
755 mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; 771 mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
756 icd->formats = mt9v022_monochrome_formats; 772 mt9v022->fmts = mt9v022_monochrome_fmts;
757 } 773 }
758 774
759 if (ret < 0) 775 if (ret < 0)
760 goto ei2c; 776 goto ei2c;
761 777
762 icd->num_formats = 0; 778 mt9v022->num_fmts = 0;
763 779
764 /* 780 /*
765 * This is a 10bit sensor, so by default we only allow 10bit. 781 * This is a 10bit sensor, so by default we only allow 10bit.
@@ -772,14 +788,14 @@ static int mt9v022_video_probe(struct soc_camera_device *icd,
772 flags = SOCAM_DATAWIDTH_10; 788 flags = SOCAM_DATAWIDTH_10;
773 789
774 if (flags & SOCAM_DATAWIDTH_10) 790 if (flags & SOCAM_DATAWIDTH_10)
775 icd->num_formats++; 791 mt9v022->num_fmts++;
776 else 792 else
777 icd->formats++; 793 mt9v022->fmts++;
778 794
779 if (flags & SOCAM_DATAWIDTH_8) 795 if (flags & SOCAM_DATAWIDTH_8)
780 icd->num_formats++; 796 mt9v022->num_fmts++;
781 797
782 mt9v022->fourcc = icd->formats->fourcc; 798 mt9v022->fmt = &mt9v022->fmts[0];
783 799
784 dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", 800 dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
785 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? 801 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
@@ -823,14 +839,28 @@ static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
823#endif 839#endif
824}; 840};
825 841
842static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index,
843 enum v4l2_mbus_pixelcode *code)
844{
845 struct i2c_client *client = sd->priv;
846 struct mt9v022 *mt9v022 = to_mt9v022(client);
847
848 if ((unsigned int)index >= mt9v022->num_fmts)
849 return -EINVAL;
850
851 *code = mt9v022->fmts[index].code;
852 return 0;
853}
854
826static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { 855static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
827 .s_stream = mt9v022_s_stream, 856 .s_stream = mt9v022_s_stream,
828 .s_fmt = mt9v022_s_fmt, 857 .s_mbus_fmt = mt9v022_s_fmt,
829 .g_fmt = mt9v022_g_fmt, 858 .g_mbus_fmt = mt9v022_g_fmt,
830 .try_fmt = mt9v022_try_fmt, 859 .try_mbus_fmt = mt9v022_try_fmt,
831 .s_crop = mt9v022_s_crop, 860 .s_crop = mt9v022_s_crop,
832 .g_crop = mt9v022_g_crop, 861 .g_crop = mt9v022_g_crop,
833 .cropcap = mt9v022_cropcap, 862 .cropcap = mt9v022_cropcap,
863 .enum_mbus_fmt = mt9v022_enum_fmt,
834}; 864};
835 865
836static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { 866static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {