Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Guennadi Liakhovetski and committed by
Mauro Carvalho Chehab
760697be 9a74251d

+1389 -986
+2 -1
arch/sh/boards/mach-ap325rxa/setup.c
··· 316 316 .format_name = "UYVY", 317 317 .format_depth = 16, 318 318 .format = { 319 - .pixelformat = V4L2_PIX_FMT_UYVY, 319 + .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, 320 320 .colorspace = V4L2_COLORSPACE_SMPTE170M, 321 + .field = V4L2_FIELD_NONE, 321 322 .width = 640, 322 323 .height = 480, 323 324 },
+85 -56
drivers/media/video/mt9m001.c
··· 48 48 #define MT9M001_COLUMN_SKIP 20 49 49 #define MT9M001_ROW_SKIP 12 50 50 51 - static const struct soc_camera_data_format mt9m001_colour_formats[] = { 51 + /* MT9M001 has only one fixed colorspace per pixelcode */ 52 + struct mt9m001_datafmt { 53 + enum v4l2_mbus_pixelcode code; 54 + enum v4l2_colorspace colorspace; 55 + }; 56 + 57 + /* Find a data format by a pixel code in an array */ 58 + static const struct mt9m001_datafmt *mt9m001_find_datafmt( 59 + enum v4l2_mbus_pixelcode code, const struct mt9m001_datafmt *fmt, 60 + int n) 61 + { 62 + int i; 63 + for (i = 0; i < n; i++) 64 + if (fmt[i].code == code) 65 + return fmt + i; 66 + 67 + return NULL; 68 + } 69 + 70 + static const struct mt9m001_datafmt mt9m001_colour_fmts[] = { 52 71 /* 53 72 * Order important: first natively supported, 54 73 * second supported with a GPIO extender 55 74 */ 56 - { 57 - .name = "Bayer (sRGB) 10 bit", 58 - .depth = 10, 59 - .fourcc = V4L2_PIX_FMT_SBGGR16, 60 - .colorspace = V4L2_COLORSPACE_SRGB, 61 - }, { 62 - .name = "Bayer (sRGB) 8 bit", 63 - .depth = 8, 64 - .fourcc = V4L2_PIX_FMT_SBGGR8, 65 - .colorspace = V4L2_COLORSPACE_SRGB, 66 - } 75 + {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, 76 + {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, 67 77 }; 68 78 69 - static const struct soc_camera_data_format mt9m001_monochrome_formats[] = { 79 + static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = { 70 80 /* Order important - see above */ 71 - { 72 - .name = "Monochrome 10 bit", 73 - .depth = 10, 74 - .fourcc = V4L2_PIX_FMT_Y16, 75 - }, { 76 - .name = "Monochrome 8 bit", 77 - .depth = 8, 78 - .fourcc = V4L2_PIX_FMT_GREY, 79 - }, 81 + {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, 82 + {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, 80 83 }; 81 84 82 85 struct mt9m001 { 83 86 struct v4l2_subdev subdev; 84 87 struct v4l2_rect rect; /* Sensor window */ 85 - __u32 fourcc; 88 + const struct mt9m001_datafmt *fmt; 89 + const struct mt9m001_datafmt *fmts; 90 + int num_fmts; 86 91 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ 87 92 unsigned int gain; 88 93 unsigned int exposure; ··· 214 209 const u16 hblank = 9, vblank = 25; 215 210 unsigned int total_h; 216 211 217 - if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 || 218 - mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16) 212 + if (mt9m001->fmts == mt9m001_colour_fmts) 219 213 /* 220 214 * Bayer format - even number of rows for simplicity, 221 215 * but let the user play with the top row. ··· 294 290 return 0; 295 291 } 296 292 297 - static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 293 + static int mt9m001_g_fmt(struct v4l2_subdev *sd, 294 + struct v4l2_mbus_framefmt *mf) 298 295 { 299 296 struct i2c_client *client = sd->priv; 300 297 struct mt9m001 *mt9m001 = to_mt9m001(client); 301 - struct v4l2_pix_format *pix = &f->fmt.pix; 302 298 303 - pix->width = mt9m001->rect.width; 304 - pix->height = mt9m001->rect.height; 305 - pix->pixelformat = mt9m001->fourcc; 306 - pix->field = V4L2_FIELD_NONE; 307 - pix->colorspace = V4L2_COLORSPACE_SRGB; 299 + mf->width = mt9m001->rect.width; 300 + mf->height = mt9m001->rect.height; 301 + mf->code = mt9m001->fmt->code; 302 + mf->colorspace = mt9m001->fmt->colorspace; 303 + mf->field = V4L2_FIELD_NONE; 308 304 309 305 return 0; 310 306 } 311 307 312 - static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 308 + static int mt9m001_s_fmt(struct v4l2_subdev *sd, 309 + struct v4l2_mbus_framefmt *mf) 313 310 { 314 311 struct i2c_client *client = sd->priv; 315 312 struct mt9m001 *mt9m001 = to_mt9m001(client); 316 - struct v4l2_pix_format *pix = &f->fmt.pix; 317 313 struct v4l2_crop a = { 318 314 .c = { 319 315 .left = mt9m001->rect.left, 320 316 .top = mt9m001->rect.top, 321 - .width = pix->width, 322 - .height = pix->height, 317 + .width = mf->width, 318 + .height = mf->height, 323 319 }, 324 320 }; 325 321 int ret; ··· 327 323 /* No support for scaling so far, just crop. TODO: use skipping */ 328 324 ret = mt9m001_s_crop(sd, &a); 329 325 if (!ret) { 330 - pix->width = mt9m001->rect.width; 331 - pix->height = mt9m001->rect.height; 332 - mt9m001->fourcc = pix->pixelformat; 326 + mf->width = mt9m001->rect.width; 327 + mf->height = mt9m001->rect.height; 328 + mt9m001->fmt = mt9m001_find_datafmt(mf->code, 329 + mt9m001->fmts, mt9m001->num_fmts); 330 + mf->colorspace = mt9m001->fmt->colorspace; 333 331 } 334 332 335 333 return ret; 336 334 } 337 335 338 - static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 336 + static int mt9m001_try_fmt(struct v4l2_subdev *sd, 337 + struct v4l2_mbus_framefmt *mf) 339 338 { 340 339 struct i2c_client *client = sd->priv; 341 340 struct mt9m001 *mt9m001 = to_mt9m001(client); 342 - struct v4l2_pix_format *pix = &f->fmt.pix; 341 + const struct mt9m001_datafmt *fmt; 343 342 344 - v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH, 343 + v4l_bound_align_image(&mf->width, MT9M001_MIN_WIDTH, 345 344 MT9M001_MAX_WIDTH, 1, 346 - &pix->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top, 345 + &mf->height, MT9M001_MIN_HEIGHT + mt9m001->y_skip_top, 347 346 MT9M001_MAX_HEIGHT + mt9m001->y_skip_top, 0, 0); 348 347 349 - if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || 350 - pix->pixelformat == V4L2_PIX_FMT_SBGGR16) 351 - pix->height = ALIGN(pix->height - 1, 2); 348 + if (mt9m001->fmts == mt9m001_colour_fmts) 349 + mf->height = ALIGN(mf->height - 1, 2); 350 + 351 + fmt = mt9m001_find_datafmt(mf->code, mt9m001->fmts, 352 + mt9m001->num_fmts); 353 + if (!fmt) { 354 + fmt = mt9m001->fmt; 355 + mf->code = fmt->code; 356 + } 357 + 358 + mf->colorspace = fmt->colorspace; 352 359 353 360 return 0; 354 361 } ··· 623 608 case 0x8411: 624 609 case 0x8421: 625 610 mt9m001->model = V4L2_IDENT_MT9M001C12ST; 626 - icd->formats = mt9m001_colour_formats; 611 + mt9m001->fmts = mt9m001_colour_fmts; 627 612 break; 628 613 case 0x8431: 629 614 mt9m001->model = V4L2_IDENT_MT9M001C12STM; 630 - icd->formats = mt9m001_monochrome_formats; 615 + mt9m001->fmts = mt9m001_monochrome_fmts; 631 616 break; 632 617 default: 633 618 dev_err(&client->dev, ··· 635 620 return -ENODEV; 636 621 } 637 622 638 - icd->num_formats = 0; 623 + mt9m001->num_fmts = 0; 639 624 640 625 /* 641 626 * This is a 10bit sensor, so by default we only allow 10bit. ··· 648 633 flags = SOCAM_DATAWIDTH_10; 649 634 650 635 if (flags & SOCAM_DATAWIDTH_10) 651 - icd->num_formats++; 636 + mt9m001->num_fmts++; 652 637 else 653 - icd->formats++; 638 + mt9m001->fmts++; 654 639 655 640 if (flags & SOCAM_DATAWIDTH_8) 656 - icd->num_formats++; 641 + mt9m001->num_fmts++; 657 642 658 - mt9m001->fourcc = icd->formats->fourcc; 643 + mt9m001->fmt = &mt9m001->fmts[0]; 659 644 660 645 dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, 661 646 data == 0x8431 ? "C12STM" : "C12ST"); ··· 701 686 #endif 702 687 }; 703 688 689 + static int mt9m001_enum_fmt(struct v4l2_subdev *sd, int index, 690 + enum v4l2_mbus_pixelcode *code) 691 + { 692 + struct i2c_client *client = sd->priv; 693 + struct mt9m001 *mt9m001 = to_mt9m001(client); 694 + 695 + if ((unsigned int)index >= mt9m001->num_fmts) 696 + return -EINVAL; 697 + 698 + *code = mt9m001->fmts[index].code; 699 + return 0; 700 + } 701 + 704 702 static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { 705 703 .s_stream = mt9m001_s_stream, 706 - .s_fmt = mt9m001_s_fmt, 707 - .g_fmt = mt9m001_g_fmt, 708 - .try_fmt = mt9m001_try_fmt, 704 + .s_mbus_fmt = mt9m001_s_fmt, 705 + .g_mbus_fmt = mt9m001_g_fmt, 706 + .try_mbus_fmt = mt9m001_try_fmt, 709 707 .s_crop = mt9m001_s_crop, 710 708 .g_crop = mt9m001_g_crop, 711 709 .cropcap = mt9m001_cropcap, 710 + .enum_mbus_fmt = mt9m001_enum_fmt, 712 711 }; 713 712 714 713 static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
+113 -73
drivers/media/video/mt9m111.c
··· 123 123 #define MT9M111_MAX_HEIGHT 1024 124 124 #define MT9M111_MAX_WIDTH 1280 125 125 126 - #define COL_FMT(_name, _depth, _fourcc, _colorspace) \ 127 - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ 128 - .colorspace = _colorspace } 129 - #define RGB_FMT(_name, _depth, _fourcc) \ 130 - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB) 131 - #define JPG_FMT(_name, _depth, _fourcc) \ 132 - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) 126 + /* MT9M111 has only one fixed colorspace per pixelcode */ 127 + struct mt9m111_datafmt { 128 + enum v4l2_mbus_pixelcode code; 129 + enum v4l2_colorspace colorspace; 130 + }; 133 131 134 - static const struct soc_camera_data_format mt9m111_colour_formats[] = { 135 - JPG_FMT("CbYCrY 16 bit", 16, V4L2_PIX_FMT_UYVY), 136 - JPG_FMT("CrYCbY 16 bit", 16, V4L2_PIX_FMT_VYUY), 137 - JPG_FMT("YCbYCr 16 bit", 16, V4L2_PIX_FMT_YUYV), 138 - JPG_FMT("YCrYCb 16 bit", 16, V4L2_PIX_FMT_YVYU), 139 - RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565), 140 - RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555), 141 - RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16), 142 - RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8), 132 + /* Find a data format by a pixel code in an array */ 133 + static const struct mt9m111_datafmt *mt9m111_find_datafmt( 134 + enum v4l2_mbus_pixelcode code, const struct mt9m111_datafmt *fmt, 135 + int n) 136 + { 137 + int i; 138 + for (i = 0; i < n; i++) 139 + if (fmt[i].code == code) 140 + return fmt + i; 141 + 142 + return NULL; 143 + } 144 + 145 + static const struct mt9m111_datafmt mt9m111_colour_fmts[] = { 146 + {V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG}, 147 + {V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG}, 148 + {V4L2_MBUS_FMT_YUYV8_2X8_BE, V4L2_COLORSPACE_JPEG}, 149 + {V4L2_MBUS_FMT_YVYU8_2X8_BE, V4L2_COLORSPACE_JPEG}, 150 + {V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, 151 + {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, 152 + {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, 153 + {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, 143 154 }; 144 155 145 156 enum mt9m111_context { ··· 163 152 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ 164 153 enum mt9m111_context context; 165 154 struct v4l2_rect rect; 166 - u32 pixfmt; 155 + const struct mt9m111_datafmt *fmt; 167 156 unsigned int gain; 168 157 unsigned char autoexposure; 169 158 unsigned char datawidth; ··· 269 258 int width = rect->width; 270 259 int height = rect->height; 271 260 272 - if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 || 273 - mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) 261 + if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || 262 + mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) 274 263 is_raw_format = 1; 275 264 else 276 265 is_raw_format = 0; ··· 318 307 319 308 static int mt9m111_setfmt_bayer8(struct i2c_client *client) 320 309 { 321 - return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER); 310 + return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER | 311 + MT9M111_OUTFMT_RGB); 322 312 } 323 313 324 314 static int mt9m111_setfmt_bayer10(struct i2c_client *client) ··· 413 401 { 414 402 struct mt9m111 *mt9m111 = to_mt9m111(client); 415 403 416 - if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 || 417 - mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) { 404 + if (mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR8_1X8 || 405 + mt9m111->fmt->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE) { 418 406 /* Bayer format - even size lengths */ 419 407 rect->width = ALIGN(rect->width, 2); 420 408 rect->height = ALIGN(rect->height, 2); ··· 472 460 return 0; 473 461 } 474 462 475 - static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 463 + static int mt9m111_g_fmt(struct v4l2_subdev *sd, 464 + struct v4l2_mbus_framefmt *mf) 476 465 { 477 466 struct i2c_client *client = sd->priv; 478 467 struct mt9m111 *mt9m111 = to_mt9m111(client); 479 - struct v4l2_pix_format *pix = &f->fmt.pix; 480 468 481 - pix->width = mt9m111->rect.width; 482 - pix->height = mt9m111->rect.height; 483 - pix->pixelformat = mt9m111->pixfmt; 484 - pix->field = V4L2_FIELD_NONE; 485 - pix->colorspace = V4L2_COLORSPACE_SRGB; 469 + mf->width = mt9m111->rect.width; 470 + mf->height = mt9m111->rect.height; 471 + mf->code = mt9m111->fmt->code; 472 + mf->field = V4L2_FIELD_NONE; 486 473 487 474 return 0; 488 475 } 489 476 490 - static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt) 477 + static int mt9m111_set_pixfmt(struct i2c_client *client, 478 + enum v4l2_mbus_pixelcode code) 491 479 { 492 480 struct mt9m111 *mt9m111 = to_mt9m111(client); 493 481 int ret; 494 482 495 - switch (pixfmt) { 496 - case V4L2_PIX_FMT_SBGGR8: 483 + switch (code) { 484 + case V4L2_MBUS_FMT_SBGGR8_1X8: 497 485 ret = mt9m111_setfmt_bayer8(client); 498 486 break; 499 - case V4L2_PIX_FMT_SBGGR16: 487 + case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: 500 488 ret = mt9m111_setfmt_bayer10(client); 501 489 break; 502 - case V4L2_PIX_FMT_RGB555: 490 + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: 503 491 ret = mt9m111_setfmt_rgb555(client); 504 492 break; 505 - case V4L2_PIX_FMT_RGB565: 493 + case V4L2_MBUS_FMT_RGB565_2X8_LE: 506 494 ret = mt9m111_setfmt_rgb565(client); 507 495 break; 508 - case V4L2_PIX_FMT_UYVY: 496 + case V4L2_MBUS_FMT_YUYV8_2X8_BE: 509 497 mt9m111->swap_yuv_y_chromas = 0; 510 498 mt9m111->swap_yuv_cb_cr = 0; 511 499 ret = mt9m111_setfmt_yuv(client); 512 500 break; 513 - case V4L2_PIX_FMT_VYUY: 501 + case V4L2_MBUS_FMT_YVYU8_2X8_BE: 514 502 mt9m111->swap_yuv_y_chromas = 0; 515 503 mt9m111->swap_yuv_cb_cr = 1; 516 504 ret = mt9m111_setfmt_yuv(client); 517 505 break; 518 - case V4L2_PIX_FMT_YUYV: 506 + case V4L2_MBUS_FMT_YUYV8_2X8_LE: 519 507 mt9m111->swap_yuv_y_chromas = 1; 520 508 mt9m111->swap_yuv_cb_cr = 0; 521 509 ret = mt9m111_setfmt_yuv(client); 522 510 break; 523 - case V4L2_PIX_FMT_YVYU: 511 + case V4L2_MBUS_FMT_YVYU8_2X8_LE: 524 512 mt9m111->swap_yuv_y_chromas = 1; 525 513 mt9m111->swap_yuv_cb_cr = 1; 526 514 ret = mt9m111_setfmt_yuv(client); 527 515 break; 528 516 default: 529 517 dev_err(&client->dev, "Pixel format not handled : %x\n", 530 - pixfmt); 518 + code); 531 519 ret = -EINVAL; 532 520 } 533 521 534 - if (!ret) 535 - mt9m111->pixfmt = pixfmt; 536 - 537 522 return ret; 538 523 } 539 524 540 - static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 525 + static int mt9m111_s_fmt(struct v4l2_subdev *sd, 526 + struct v4l2_mbus_framefmt *mf) 541 527 { 542 528 struct i2c_client *client = sd->priv; 529 + const struct mt9m111_datafmt *fmt; 543 530 struct mt9m111 *mt9m111 = to_mt9m111(client); 544 - struct v4l2_pix_format *pix = &f->fmt.pix; 545 531 struct v4l2_rect rect = { 546 532 .left = mt9m111->rect.left, 547 533 .top = mt9m111->rect.top, 548 - .width = pix->width, 549 - .height = pix->height, 534 + .width = mf->width, 535 + .height = mf->height, 550 536 }; 551 537 int ret; 552 538 539 + fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts, 540 + ARRAY_SIZE(mt9m111_colour_fmts)); 541 + if (!fmt) 542 + return -EINVAL; 543 + 553 544 dev_dbg(&client->dev, 554 - "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__, 555 - pix->pixelformat, rect.left, rect.top, rect.width, rect.height); 545 + "%s code=%x left=%d, top=%d, width=%d, height=%d\n", __func__, 546 + mf->code, rect.left, rect.top, rect.width, rect.height); 556 547 557 548 ret = mt9m111_make_rect(client, &rect); 558 549 if (!ret) 559 - ret = mt9m111_set_pixfmt(client, pix->pixelformat); 560 - if (!ret) 561 - mt9m111->rect = rect; 550 + ret = mt9m111_set_pixfmt(client, mf->code); 551 + if (!ret) { 552 + mt9m111->rect = rect; 553 + mt9m111->fmt = fmt; 554 + mf->colorspace = fmt->colorspace; 555 + } 556 + 562 557 return ret; 563 558 } 564 559 565 - static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 560 + static int mt9m111_try_fmt(struct v4l2_subdev *sd, 561 + struct v4l2_mbus_framefmt *mf) 566 562 { 567 - struct v4l2_pix_format *pix = &f->fmt.pix; 568 - bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || 569 - pix->pixelformat == V4L2_PIX_FMT_SBGGR16; 563 + struct i2c_client *client = sd->priv; 564 + struct mt9m111 *mt9m111 = to_mt9m111(client); 565 + const struct mt9m111_datafmt *fmt; 566 + bool bayer = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || 567 + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE; 568 + 569 + fmt = mt9m111_find_datafmt(mf->code, mt9m111_colour_fmts, 570 + ARRAY_SIZE(mt9m111_colour_fmts)); 571 + if (!fmt) { 572 + fmt = mt9m111->fmt; 573 + mf->code = fmt->code; 574 + } 570 575 571 576 /* 572 577 * With Bayer format enforce even side lengths, but let the user play 573 578 * with the starting pixel 574 579 */ 575 580 576 - if (pix->height > MT9M111_MAX_HEIGHT) 577 - pix->height = MT9M111_MAX_HEIGHT; 578 - else if (pix->height < 2) 579 - pix->height = 2; 581 + if (mf->height > MT9M111_MAX_HEIGHT) 582 + mf->height = MT9M111_MAX_HEIGHT; 583 + else if (mf->height < 2) 584 + mf->height = 2; 580 585 else if (bayer) 581 - pix->height = ALIGN(pix->height, 2); 586 + mf->height = ALIGN(mf->height, 2); 582 587 583 - if (pix->width > MT9M111_MAX_WIDTH) 584 - pix->width = MT9M111_MAX_WIDTH; 585 - else if (pix->width < 2) 586 - pix->width = 2; 588 + if (mf->width > MT9M111_MAX_WIDTH) 589 + mf->width = MT9M111_MAX_WIDTH; 590 + else if (mf->width < 2) 591 + mf->width = 2; 587 592 else if (bayer) 588 - pix->width = ALIGN(pix->width, 2); 593 + mf->width = ALIGN(mf->width, 2); 594 + 595 + mf->colorspace = fmt->colorspace; 589 596 590 597 return 0; 591 598 } ··· 894 863 struct mt9m111 *mt9m111 = to_mt9m111(client); 895 864 896 865 mt9m111_set_context(client, mt9m111->context); 897 - mt9m111_set_pixfmt(client, mt9m111->pixfmt); 866 + mt9m111_set_pixfmt(client, mt9m111->fmt->code); 898 867 mt9m111_setup_rect(client, &mt9m111->rect); 899 868 mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); 900 869 mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); ··· 983 952 goto ei2c; 984 953 } 985 954 986 - icd->formats = mt9m111_colour_formats; 987 - icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); 988 - 989 955 dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data); 990 956 991 957 ei2c: ··· 999 971 #endif 1000 972 }; 1001 973 974 + static int mt9m111_enum_fmt(struct v4l2_subdev *sd, int index, 975 + enum v4l2_mbus_pixelcode *code) 976 + { 977 + if ((unsigned int)index >= ARRAY_SIZE(mt9m111_colour_fmts)) 978 + return -EINVAL; 979 + 980 + *code = mt9m111_colour_fmts[index].code; 981 + return 0; 982 + } 983 + 1002 984 static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { 1003 - .s_fmt = mt9m111_s_fmt, 1004 - .g_fmt = mt9m111_g_fmt, 1005 - .try_fmt = mt9m111_try_fmt, 985 + .s_mbus_fmt = mt9m111_s_fmt, 986 + .g_mbus_fmt = mt9m111_g_fmt, 987 + .try_mbus_fmt = mt9m111_try_fmt, 1006 988 .s_crop = mt9m111_s_crop, 1007 989 .g_crop = mt9m111_g_crop, 1008 990 .cropcap = mt9m111_cropcap, 991 + .enum_mbus_fmt = mt9m111_enum_fmt, 1009 992 }; 1010 993 1011 994 static struct v4l2_subdev_ops mt9m111_subdev_ops = { ··· 1063 1024 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; 1064 1025 mt9m111->rect.width = MT9M111_MAX_WIDTH; 1065 1026 mt9m111->rect.height = MT9M111_MAX_HEIGHT; 1027 + mt9m111->fmt = &mt9m111_colour_fmts[0]; 1066 1028 1067 1029 ret = mt9m111_video_probe(icd, client); 1068 1030 if (ret) {
+35 -31
drivers/media/video/mt9t031.c
··· 60 60 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | \ 61 61 SOCAM_MASTER | SOCAM_DATAWIDTH_10) 62 62 63 - static const struct soc_camera_data_format mt9t031_colour_formats[] = { 64 - { 65 - .name = "Bayer (sRGB) 10 bit", 66 - .depth = 10, 67 - .fourcc = V4L2_PIX_FMT_SGRBG10, 68 - .colorspace = V4L2_COLORSPACE_SRGB, 69 - } 70 - }; 71 - 72 63 struct mt9t031 { 73 64 struct v4l2_subdev subdev; 74 65 struct v4l2_rect rect; /* Sensor window */ ··· 369 378 return 0; 370 379 } 371 380 372 - static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 381 + static int mt9t031_g_fmt(struct v4l2_subdev *sd, 382 + struct v4l2_mbus_framefmt *mf) 373 383 { 374 384 struct i2c_client *client = sd->priv; 375 385 struct mt9t031 *mt9t031 = to_mt9t031(client); 376 - struct v4l2_pix_format *pix = &f->fmt.pix; 377 386 378 - pix->width = mt9t031->rect.width / mt9t031->xskip; 379 - pix->height = mt9t031->rect.height / mt9t031->yskip; 380 - pix->pixelformat = V4L2_PIX_FMT_SGRBG10; 381 - pix->field = V4L2_FIELD_NONE; 382 - pix->colorspace = V4L2_COLORSPACE_SRGB; 387 + mf->width = mt9t031->rect.width / mt9t031->xskip; 388 + mf->height = mt9t031->rect.height / mt9t031->yskip; 389 + mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; 390 + mf->colorspace = V4L2_COLORSPACE_SRGB; 391 + mf->field = V4L2_FIELD_NONE; 383 392 384 393 return 0; 385 394 } 386 395 387 - static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 396 + static int mt9t031_s_fmt(struct v4l2_subdev *sd, 397 + struct v4l2_mbus_framefmt *mf) 388 398 { 389 399 struct i2c_client *client = sd->priv; 390 400 struct mt9t031 *mt9t031 = to_mt9t031(client); 391 401 struct soc_camera_device *icd = client->dev.platform_data; 392 - struct v4l2_pix_format *pix = &f->fmt.pix; 393 402 u16 xskip, yskip; 394 403 struct v4l2_rect rect = mt9t031->rect; 395 404 ··· 397 406 * try_fmt has put width and height within limits. 398 407 * S_FMT: use binning and skipping for scaling 399 408 */ 400 - xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH); 401 - yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT); 409 + xskip = mt9t031_skip(&rect.width, mf->width, MT9T031_MAX_WIDTH); 410 + yskip = mt9t031_skip(&rect.height, mf->height, MT9T031_MAX_HEIGHT); 411 + 412 + mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; 413 + mf->colorspace = V4L2_COLORSPACE_SRGB; 402 414 403 415 /* mt9t031_set_params() doesn't change width and height */ 404 416 return mt9t031_set_params(icd, &rect, xskip, yskip); ··· 411 417 * If a user window larger than sensor window is requested, we'll increase the 412 418 * sensor window. 413 419 */ 414 - static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 420 + static int mt9t031_try_fmt(struct v4l2_subdev *sd, 421 + struct v4l2_mbus_framefmt *mf) 415 422 { 416 - struct v4l2_pix_format *pix = &f->fmt.pix; 417 - 418 423 v4l_bound_align_image( 419 - &pix->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, 420 - &pix->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); 424 + &mf->width, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH, 1, 425 + &mf->height, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT, 1, 0); 426 + 427 + mf->code = V4L2_MBUS_FMT_SBGGR10_1X10; 428 + mf->colorspace = V4L2_COLORSPACE_SRGB; 421 429 422 430 return 0; 423 431 } ··· 680 684 */ 681 685 static int mt9t031_video_probe(struct i2c_client *client) 682 686 { 683 - struct soc_camera_device *icd = client->dev.platform_data; 684 687 struct mt9t031 *mt9t031 = to_mt9t031(client); 685 688 s32 data; 686 689 int ret; ··· 694 699 switch (data) { 695 700 case 0x1621: 696 701 mt9t031->model = V4L2_IDENT_MT9T031; 697 - icd->formats = mt9t031_colour_formats; 698 - icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats); 699 702 break; 700 703 default: 701 704 dev_err(&client->dev, ··· 734 741 #endif 735 742 }; 736 743 744 + static int mt9t031_enum_fmt(struct v4l2_subdev *sd, int index, 745 + enum v4l2_mbus_pixelcode *code) 746 + { 747 + if (index) 748 + return -EINVAL; 749 + 750 + *code = V4L2_MBUS_FMT_SBGGR10_1X10; 751 + return 0; 752 + } 753 + 737 754 static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { 738 755 .s_stream = mt9t031_s_stream, 739 - .s_fmt = mt9t031_s_fmt, 740 - .g_fmt = mt9t031_g_fmt, 741 - .try_fmt = mt9t031_try_fmt, 756 + .s_mbus_fmt = mt9t031_s_fmt, 757 + .g_mbus_fmt = mt9t031_g_fmt, 758 + .try_mbus_fmt = mt9t031_try_fmt, 742 759 .s_crop = mt9t031_s_crop, 743 760 .g_crop = mt9t031_g_crop, 744 761 .cropcap = mt9t031_cropcap, 762 + .enum_mbus_fmt = mt9t031_enum_fmt, 745 763 }; 746 764 747 765 static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
+90 -60
drivers/media/video/mt9v022.c
··· 64 64 #define MT9V022_COLUMN_SKIP 1 65 65 #define MT9V022_ROW_SKIP 4 66 66 67 - static const struct soc_camera_data_format mt9v022_colour_formats[] = { 67 + /* MT9V022 has only one fixed colorspace per pixelcode */ 68 + struct 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 */ 74 + static 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 + 86 + static const struct mt9v022_datafmt mt9v022_colour_fmts[] = { 68 87 /* 69 88 * Order important: first natively supported, 70 89 * second supported with a GPIO extender 71 90 */ 72 - { 73 - .name = "Bayer (sRGB) 10 bit", 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 - } 91 + {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, 92 + {V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB}, 83 93 }; 84 94 85 - static const struct soc_camera_data_format mt9v022_monochrome_formats[] = { 95 + static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = { 86 96 /* Order important - see above */ 87 - { 88 - .name = "Monochrome 10 bit", 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 - }, 97 + {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, 98 + {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, 96 99 }; 97 100 98 101 struct mt9v022 { 99 102 struct v4l2_subdev subdev; 100 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 107 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ 103 108 u16 chip_control; 104 109 unsigned short y_skip_top; /* Lines to skip at the top */ ··· 280 275 int ret; 281 276 282 277 /* Bayer format - even size lengths */ 283 - if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 || 284 - mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) { 278 + if (mt9v022->fmts == mt9v022_colour_fmts) { 285 279 rect.width = ALIGN(rect.width, 2); 286 280 rect.height = ALIGN(rect.height, 2); 287 281 /* Let the user play with the starting pixel */ ··· 358 354 return 0; 359 355 } 360 356 361 - static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 357 + static int mt9v022_g_fmt(struct v4l2_subdev *sd, 358 + struct v4l2_mbus_framefmt *mf) 362 359 { 363 360 struct i2c_client *client = sd->priv; 364 361 struct mt9v022 *mt9v022 = to_mt9v022(client); 365 - struct v4l2_pix_format *pix = &f->fmt.pix; 366 362 367 - pix->width = mt9v022->rect.width; 368 - pix->height = mt9v022->rect.height; 369 - pix->pixelformat = mt9v022->fourcc; 370 - pix->field = V4L2_FIELD_NONE; 371 - pix->colorspace = V4L2_COLORSPACE_SRGB; 363 + mf->width = mt9v022->rect.width; 364 + mf->height = mt9v022->rect.height; 365 + mf->code = mt9v022->fmt->code; 366 + mf->colorspace = mt9v022->fmt->colorspace; 367 + mf->field = V4L2_FIELD_NONE; 372 368 373 369 return 0; 374 370 } 375 371 376 - static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 372 + static int mt9v022_s_fmt(struct v4l2_subdev *sd, 373 + struct v4l2_mbus_framefmt *mf) 377 374 { 378 375 struct i2c_client *client = sd->priv; 379 376 struct mt9v022 *mt9v022 = to_mt9v022(client); 380 - struct v4l2_pix_format *pix = &f->fmt.pix; 381 377 struct v4l2_crop a = { 382 378 .c = { 383 379 .left = mt9v022->rect.left, 384 380 .top = mt9v022->rect.top, 385 - .width = pix->width, 386 - .height = pix->height, 381 + .width = mf->width, 382 + .height = mf->height, 387 383 }, 388 384 }; 389 385 int ret; ··· 392 388 * The caller provides a supported format, as verified per call to 393 389 * icd->try_fmt(), datawidth is from our supported format list 394 390 */ 395 - switch (pix->pixelformat) { 396 - case V4L2_PIX_FMT_GREY: 397 - case V4L2_PIX_FMT_Y16: 391 + switch (mf->code) { 392 + case V4L2_MBUS_FMT_GREY8_1X8: 393 + case V4L2_MBUS_FMT_Y10_1X10: 398 394 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) 399 395 return -EINVAL; 400 396 break; 401 - case V4L2_PIX_FMT_SBGGR8: 402 - case V4L2_PIX_FMT_SBGGR16: 397 + case V4L2_MBUS_FMT_SBGGR8_1X8: 398 + case V4L2_MBUS_FMT_SBGGR10_1X10: 403 399 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) 404 400 return -EINVAL; 405 401 break; ··· 413 409 /* No support for scaling on this camera, just crop. */ 414 410 ret = mt9v022_s_crop(sd, &a); 415 411 if (!ret) { 416 - pix->width = mt9v022->rect.width; 417 - pix->height = mt9v022->rect.height; 418 - mt9v022->fourcc = pix->pixelformat; 412 + mf->width = mt9v022->rect.width; 413 + mf->height = mt9v022->rect.height; 414 + mt9v022->fmt = mt9v022_find_datafmt(mf->code, 415 + mt9v022->fmts, mt9v022->num_fmts); 416 + mf->colorspace = mt9v022->fmt->colorspace; 419 417 } 420 418 421 419 return ret; 422 420 } 423 421 424 - static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 422 + static int mt9v022_try_fmt(struct v4l2_subdev *sd, 423 + struct v4l2_mbus_framefmt *mf) 425 424 { 426 425 struct i2c_client *client = sd->priv; 427 426 struct mt9v022 *mt9v022 = to_mt9v022(client); 428 - struct v4l2_pix_format *pix = &f->fmt.pix; 429 - int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 || 430 - pix->pixelformat == V4L2_PIX_FMT_SBGGR16; 427 + const struct mt9v022_datafmt *fmt; 428 + int align = mf->code == V4L2_MBUS_FMT_SBGGR8_1X8 || 429 + mf->code == V4L2_MBUS_FMT_SBGGR10_1X10; 431 430 432 - v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH, 431 + v4l_bound_align_image(&mf->width, MT9V022_MIN_WIDTH, 433 432 MT9V022_MAX_WIDTH, align, 434 - &pix->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, 433 + &mf->height, MT9V022_MIN_HEIGHT + mt9v022->y_skip_top, 435 434 MT9V022_MAX_HEIGHT + mt9v022->y_skip_top, align, 0); 435 + 436 + fmt = mt9v022_find_datafmt(mf->code, mt9v022->fmts, 437 + mt9v022->num_fmts); 438 + if (!fmt) { 439 + fmt = mt9v022->fmt; 440 + mf->code = fmt->code; 441 + } 442 + 443 + mf->colorspace = fmt->colorspace; 436 444 437 445 return 0; 438 446 } ··· 765 749 !strcmp("color", sensor_type))) { 766 750 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); 767 751 mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; 768 - icd->formats = mt9v022_colour_formats; 752 + mt9v022->fmts = mt9v022_colour_fmts; 769 753 } else { 770 754 ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); 771 755 mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; 772 - icd->formats = mt9v022_monochrome_formats; 756 + mt9v022->fmts = mt9v022_monochrome_fmts; 773 757 } 774 758 775 759 if (ret < 0) 776 760 goto ei2c; 777 761 778 - icd->num_formats = 0; 762 + mt9v022->num_fmts = 0; 779 763 780 764 /* 781 765 * This is a 10bit sensor, so by default we only allow 10bit. ··· 788 772 flags = SOCAM_DATAWIDTH_10; 789 773 790 774 if (flags & SOCAM_DATAWIDTH_10) 791 - icd->num_formats++; 775 + mt9v022->num_fmts++; 792 776 else 793 - icd->formats++; 777 + mt9v022->fmts++; 794 778 795 779 if (flags & SOCAM_DATAWIDTH_8) 796 - icd->num_formats++; 780 + mt9v022->num_fmts++; 797 781 798 - mt9v022->fourcc = icd->formats->fourcc; 782 + mt9v022->fmt = &mt9v022->fmts[0]; 799 783 800 784 dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", 801 785 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? ··· 839 823 #endif 840 824 }; 841 825 826 + static int mt9v022_enum_fmt(struct v4l2_subdev *sd, int index, 827 + enum v4l2_mbus_pixelcode *code) 828 + { 829 + struct i2c_client *client = sd->priv; 830 + struct mt9v022 *mt9v022 = to_mt9v022(client); 831 + 832 + if ((unsigned int)index >= mt9v022->num_fmts) 833 + return -EINVAL; 834 + 835 + *code = mt9v022->fmts[index].code; 836 + return 0; 837 + } 838 + 842 839 static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { 843 840 .s_stream = mt9v022_s_stream, 844 - .s_fmt = mt9v022_s_fmt, 845 - .g_fmt = mt9v022_g_fmt, 846 - .try_fmt = mt9v022_try_fmt, 841 + .s_mbus_fmt = mt9v022_s_fmt, 842 + .g_mbus_fmt = mt9v022_g_fmt, 843 + .try_mbus_fmt = mt9v022_try_fmt, 847 844 .s_crop = mt9v022_s_crop, 848 845 .g_crop = mt9v022_g_crop, 849 846 .cropcap = mt9v022_cropcap, 847 + .enum_mbus_fmt = mt9v022_enum_fmt, 850 848 }; 851 849 852 850 static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
+73 -17
drivers/media/video/mx1_camera.c
··· 37 37 #include <media/v4l2-common.h> 38 38 #include <media/v4l2-dev.h> 39 39 #include <media/videobuf-dma-contig.h> 40 + #include <media/soc_mediabus.h> 40 41 41 42 #include <asm/dma.h> 42 43 #include <asm/fiq.h> ··· 95 94 /* buffer for one video frame */ 96 95 struct mx1_buffer { 97 96 /* common v4l buffer stuff -- must be first */ 98 - struct videobuf_buffer vb; 99 - const struct soc_camera_data_format *fmt; 100 - int inwork; 97 + struct videobuf_buffer vb; 98 + enum v4l2_mbus_pixelcode code; 99 + int inwork; 101 100 }; 102 101 103 102 /* ··· 129 128 unsigned int *size) 130 129 { 131 130 struct soc_camera_device *icd = vq->priv_data; 131 + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 132 + icd->current_fmt->host_fmt); 132 133 133 - *size = icd->user_width * icd->user_height * 134 - ((icd->current_fmt->depth + 7) >> 3); 134 + if (bytes_per_line < 0) 135 + return bytes_per_line; 136 + 137 + *size = bytes_per_line * icd->user_height; 135 138 136 139 if (!*count) 137 140 *count = 32; ··· 174 169 struct soc_camera_device *icd = vq->priv_data; 175 170 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 176 171 int ret; 172 + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 173 + icd->current_fmt->host_fmt); 174 + 175 + if (bytes_per_line < 0) 176 + return bytes_per_line; 177 177 178 178 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 179 179 vb, vb->baddr, vb->bsize); ··· 194 184 */ 195 185 buf->inwork = 1; 196 186 197 - if (buf->fmt != icd->current_fmt || 187 + if (buf->code != icd->current_fmt->code || 198 188 vb->width != icd->user_width || 199 189 vb->height != icd->user_height || 200 190 vb->field != field) { 201 - buf->fmt = icd->current_fmt; 191 + buf->code = icd->current_fmt->code; 202 192 vb->width = icd->user_width; 203 193 vb->height = icd->user_height; 204 194 vb->field = field; 205 195 vb->state = VIDEOBUF_NEEDS_INIT; 206 196 } 207 197 208 - vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); 198 + vb->size = bytes_per_line * vb->height; 209 199 if (0 != vb->baddr && vb->bsize < vb->size) { 210 200 ret = -EINVAL; 211 201 goto out; ··· 507 497 508 498 /* MX1 supports only 8bit buswidth */ 509 499 common_flags = soc_camera_bus_param_compatible(camera_flags, 510 - CSI_BUS_FLAGS); 500 + CSI_BUS_FLAGS); 511 501 if (!common_flags) 512 502 return -EINVAL; 513 - 514 - icd->buswidth = 8; 515 503 516 504 /* Make choises, based on platform choice */ 517 505 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && ··· 563 555 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 564 556 const struct soc_camera_format_xlate *xlate; 565 557 struct v4l2_pix_format *pix = &f->fmt.pix; 566 - int ret; 558 + struct v4l2_mbus_framefmt mf; 559 + int ret, buswidth; 567 560 568 561 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 569 562 if (!xlate) { ··· 573 564 return -EINVAL; 574 565 } 575 566 576 - ret = v4l2_subdev_call(sd, video, s_fmt, f); 577 - if (!ret) { 578 - icd->buswidth = xlate->buswidth; 579 - icd->current_fmt = xlate->host_fmt; 567 + buswidth = xlate->host_fmt->bits_per_sample; 568 + if (buswidth > 8) { 569 + dev_warn(icd->dev.parent, 570 + "bits-per-sample %d for format %x unsupported\n", 571 + buswidth, pix->pixelformat); 572 + return -EINVAL; 580 573 } 574 + 575 + mf.width = pix->width; 576 + mf.height = pix->height; 577 + mf.field = pix->field; 578 + mf.colorspace = pix->colorspace; 579 + mf.code = xlate->code; 580 + 581 + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); 582 + if (ret < 0) 583 + return ret; 584 + 585 + if (mf.code != xlate->code) 586 + return -EINVAL; 587 + 588 + pix->width = mf.width; 589 + pix->height = mf.height; 590 + pix->field = mf.field; 591 + pix->colorspace = mf.colorspace; 592 + icd->current_fmt = xlate; 581 593 582 594 return ret; 583 595 } ··· 607 577 struct v4l2_format *f) 608 578 { 609 579 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 580 + const struct soc_camera_format_xlate *xlate; 581 + struct v4l2_pix_format *pix = &f->fmt.pix; 582 + struct v4l2_mbus_framefmt mf; 583 + int ret; 610 584 /* TODO: limit to mx1 hardware capabilities */ 611 585 586 + xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 587 + if (!xlate) { 588 + dev_warn(icd->dev.parent, "Format %x not found\n", 589 + pix->pixelformat); 590 + return -EINVAL; 591 + } 592 + 593 + mf.width = pix->width; 594 + mf.height = pix->height; 595 + mf.field = pix->field; 596 + mf.colorspace = pix->colorspace; 597 + mf.code = xlate->code; 598 + 612 599 /* limit to sensor capabilities */ 613 - return v4l2_subdev_call(sd, video, try_fmt, f); 600 + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); 601 + if (ret < 0) 602 + return ret; 603 + 604 + pix->width = mf.width; 605 + pix->height = mf.height; 606 + pix->field = mf.field; 607 + pix->colorspace = mf.colorspace; 608 + 609 + return 0; 614 610 } 615 611 616 612 static int mx1_camera_reqbufs(struct soc_camera_file *icf,
+164 -120
drivers/media/video/mx3_camera.c
··· 23 23 #include <media/v4l2-dev.h> 24 24 #include <media/videobuf-dma-contig.h> 25 25 #include <media/soc_camera.h> 26 + #include <media/soc_mediabus.h> 26 27 27 28 #include <mach/ipu.h> 28 29 #include <mach/mx3_camera.h> ··· 64 63 struct mx3_camera_buffer { 65 64 /* common v4l buffer stuff -- must be first */ 66 65 struct videobuf_buffer vb; 67 - const struct soc_camera_data_format *fmt; 66 + enum v4l2_mbus_pixelcode code; 68 67 69 68 /* One descriptot per scatterlist (per frame) */ 70 69 struct dma_async_tx_descriptor *txd; ··· 118 117 struct mx3_camera_dev *mx3_cam; 119 118 enum ipu_channel id; 120 119 }; 121 - 122 - static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt); 123 120 124 121 static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg) 125 122 { ··· 210 211 struct soc_camera_device *icd = vq->priv_data; 211 212 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 212 213 struct mx3_camera_dev *mx3_cam = ici->priv; 213 - /* 214 - * bits-per-pixel (depth) as specified in camera's pixel format does 215 - * not necessarily match what the camera interface writes to RAM, but 216 - * it should be good enough for now. 217 - */ 218 - unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8); 214 + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 215 + icd->current_fmt->host_fmt); 216 + 217 + if (bytes_per_line < 0) 218 + return bytes_per_line; 219 219 220 220 if (!mx3_cam->idmac_channel[0]) 221 221 return -EINVAL; 222 222 223 - *size = icd->user_width * icd->user_height * bpp; 223 + *size = bytes_per_line * icd->user_height; 224 224 225 225 if (!*count) 226 226 *count = 32; ··· 239 241 struct mx3_camera_dev *mx3_cam = ici->priv; 240 242 struct mx3_camera_buffer *buf = 241 243 container_of(vb, struct mx3_camera_buffer, vb); 242 - /* current_fmt _must_ always be set */ 243 - size_t new_size = icd->user_width * icd->user_height * 244 - ((icd->current_fmt->depth + 7) >> 3); 244 + size_t new_size; 245 245 int ret; 246 + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 247 + icd->current_fmt->host_fmt); 248 + 249 + if (bytes_per_line < 0) 250 + return bytes_per_line; 251 + 252 + new_size = bytes_per_line * icd->user_height; 246 253 247 254 /* 248 255 * I think, in buf_prepare you only have to protect global data, 249 256 * the actual buffer is yours 250 257 */ 251 258 252 - if (buf->fmt != icd->current_fmt || 259 + if (buf->code != icd->current_fmt->code || 253 260 vb->width != icd->user_width || 254 261 vb->height != icd->user_height || 255 262 vb->field != field) { 256 - buf->fmt = icd->current_fmt; 263 + buf->code = icd->current_fmt->code; 257 264 vb->width = icd->user_width; 258 265 vb->height = icd->user_height; 259 266 vb->field = field; ··· 351 348 struct dma_async_tx_descriptor *txd = buf->txd; 352 349 struct idmac_channel *ichan = to_idmac_chan(txd->chan); 353 350 struct idmac_video_param *video = &ichan->params.video; 354 - const struct soc_camera_data_format *data_fmt = icd->current_fmt; 355 351 dma_cookie_t cookie; 352 + u32 fourcc = icd->current_fmt->host_fmt->fourcc; 356 353 357 354 BUG_ON(!irqs_disabled()); 358 355 359 356 /* This is the configuration of one sg-element */ 360 - video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); 357 + video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); 361 358 video->out_width = icd->user_width; 362 359 video->out_height = icd->user_height; 363 360 video->out_stride = icd->user_width; ··· 571 568 * If requested data width is supported by the platform, use it or any 572 569 * possible lower value - i.MX31 is smart enough to schift bits 573 570 */ 574 - switch (buswidth) { 575 - case 15: 576 - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)) 577 - return -EINVAL; 571 + if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15) 578 572 *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 | 579 573 SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; 580 - break; 581 - case 10: 582 - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)) 583 - return -EINVAL; 574 + else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10) 584 575 *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 | 585 576 SOCAM_DATAWIDTH_4; 577 + else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8) 578 + *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; 579 + else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4) 580 + *flags |= SOCAM_DATAWIDTH_4; 581 + 582 + switch (buswidth) { 583 + case 15: 584 + if (!(*flags & SOCAM_DATAWIDTH_15)) 585 + return -EINVAL; 586 + break; 587 + case 10: 588 + if (!(*flags & SOCAM_DATAWIDTH_10)) 589 + return -EINVAL; 586 590 break; 587 591 case 8: 588 - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)) 592 + if (!(*flags & SOCAM_DATAWIDTH_8)) 589 593 return -EINVAL; 590 - *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; 591 594 break; 592 595 case 4: 593 - if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)) 596 + if (!(*flags & SOCAM_DATAWIDTH_4)) 594 597 return -EINVAL; 595 - *flags |= SOCAM_DATAWIDTH_4; 596 598 break; 597 599 default: 598 600 dev_warn(mx3_cam->soc_host.v4l2_dev.dev, ··· 646 638 pdata->dma_dev == chan->device->dev; 647 639 } 648 640 649 - static const struct soc_camera_data_format mx3_camera_formats[] = { 641 + static const struct soc_mbus_pixelfmt mx3_camera_formats[] = { 650 642 { 651 - .name = "Bayer (sRGB) 8 bit", 652 - .depth = 8, 653 - .fourcc = V4L2_PIX_FMT_SBGGR8, 654 - .colorspace = V4L2_COLORSPACE_SRGB, 643 + .fourcc = V4L2_PIX_FMT_SBGGR8, 644 + .name = "Bayer BGGR (sRGB) 8 bit", 645 + .bits_per_sample = 8, 646 + .packing = SOC_MBUS_PACKING_NONE, 647 + .order = SOC_MBUS_ORDER_LE, 655 648 }, { 656 - .name = "Monochrome 8 bit", 657 - .depth = 8, 658 - .fourcc = V4L2_PIX_FMT_GREY, 659 - .colorspace = V4L2_COLORSPACE_JPEG, 649 + .fourcc = V4L2_PIX_FMT_GREY, 650 + .name = "Monochrome 8 bit", 651 + .bits_per_sample = 8, 652 + .packing = SOC_MBUS_PACKING_NONE, 653 + .order = SOC_MBUS_ORDER_LE, 660 654 }, 661 655 }; 662 656 663 - static bool buswidth_supported(struct soc_camera_host *ici, int depth) 657 + /* This will be corrected as we get more formats */ 658 + static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) 664 659 { 665 - struct mx3_camera_dev *mx3_cam = ici->priv; 666 - 667 - switch (depth) { 668 - case 4: 669 - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4); 670 - case 8: 671 - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8); 672 - case 10: 673 - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10); 674 - case 15: 675 - return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15); 676 - } 677 - return false; 660 + return fmt->packing == SOC_MBUS_PACKING_NONE || 661 + (fmt->bits_per_sample == 8 && 662 + fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || 663 + (fmt->bits_per_sample > 8 && 664 + fmt->packing == SOC_MBUS_PACKING_EXTEND16); 678 665 } 679 666 680 667 static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, 681 668 struct soc_camera_format_xlate *xlate) 682 669 { 683 - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 684 - int formats = 0, buswidth, ret; 670 + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 671 + struct device *dev = icd->dev.parent; 672 + int formats = 0, ret; 673 + enum v4l2_mbus_pixelcode code; 674 + const struct soc_mbus_pixelfmt *fmt; 685 675 686 - buswidth = icd->formats[idx].depth; 687 - 688 - if (!buswidth_supported(ici, buswidth)) 676 + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); 677 + if (ret < 0) 678 + /* No more formats */ 689 679 return 0; 690 680 691 - ret = mx3_camera_try_bus_param(icd, buswidth); 681 + fmt = soc_mbus_get_fmtdesc(code); 682 + if (!fmt) { 683 + dev_err(icd->dev.parent, 684 + "Invalid format code #%d: %d\n", idx, code); 685 + return 0; 686 + } 687 + 688 + /* This also checks support for the requested bits-per-sample */ 689 + ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample); 692 690 if (ret < 0) 693 691 return 0; 694 692 695 - switch (icd->formats[idx].fourcc) { 696 - case V4L2_PIX_FMT_SGRBG10: 693 + switch (code) { 694 + case V4L2_MBUS_FMT_SBGGR10_1X10: 697 695 formats++; 698 696 if (xlate) { 699 - xlate->host_fmt = &mx3_camera_formats[0]; 700 - xlate->cam_fmt = icd->formats + idx; 701 - xlate->buswidth = buswidth; 697 + xlate->host_fmt = &mx3_camera_formats[0]; 698 + xlate->code = code; 702 699 xlate++; 703 - dev_dbg(icd->dev.parent, 704 - "Providing format %s using %s\n", 705 - mx3_camera_formats[0].name, 706 - icd->formats[idx].name); 700 + dev_dbg(dev, "Providing format %s using code %d\n", 701 + mx3_camera_formats[0].name, code); 707 702 } 708 - goto passthrough; 709 - case V4L2_PIX_FMT_Y16: 703 + break; 704 + case V4L2_MBUS_FMT_Y10_1X10: 710 705 formats++; 711 706 if (xlate) { 712 - xlate->host_fmt = &mx3_camera_formats[1]; 713 - xlate->cam_fmt = icd->formats + idx; 714 - xlate->buswidth = buswidth; 707 + xlate->host_fmt = &mx3_camera_formats[1]; 708 + xlate->code = code; 715 709 xlate++; 716 - dev_dbg(icd->dev.parent, 717 - "Providing format %s using %s\n", 718 - mx3_camera_formats[0].name, 719 - icd->formats[idx].name); 710 + dev_dbg(dev, "Providing format %s using code %d\n", 711 + mx3_camera_formats[1].name, code); 720 712 } 713 + break; 721 714 default: 722 - passthrough: 723 - /* Generic pass-through */ 724 - formats++; 725 - if (xlate) { 726 - xlate->host_fmt = icd->formats + idx; 727 - xlate->cam_fmt = icd->formats + idx; 728 - xlate->buswidth = buswidth; 729 - xlate++; 730 - dev_dbg(icd->dev.parent, 731 - "Providing format %s in pass-through mode\n", 732 - icd->formats[idx].name); 733 - } 715 + if (!mx3_camera_packing_supported(fmt)) 716 + return 0; 717 + } 718 + 719 + /* Generic pass-through */ 720 + formats++; 721 + if (xlate) { 722 + xlate->host_fmt = fmt; 723 + xlate->code = code; 724 + xlate++; 725 + dev_dbg(dev, "Providing format %x in pass-through mode\n", 726 + xlate->host_fmt->fourcc); 734 727 } 735 728 736 729 return formats; ··· 815 806 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 816 807 struct mx3_camera_dev *mx3_cam = ici->priv; 817 808 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 818 - struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE}; 819 - struct v4l2_pix_format *pix = &f.fmt.pix; 809 + struct v4l2_mbus_framefmt mf; 820 810 int ret; 821 811 822 812 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096); ··· 826 818 return ret; 827 819 828 820 /* The capture device might have changed its output */ 829 - ret = v4l2_subdev_call(sd, video, g_fmt, &f); 821 + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); 830 822 if (ret < 0) 831 823 return ret; 832 824 833 - if (pix->width & 7) { 825 + if (mf.width & 7) { 834 826 /* Ouch! We can only handle 8-byte aligned width... */ 835 - stride_align(&pix->width); 836 - ret = v4l2_subdev_call(sd, video, s_fmt, &f); 827 + stride_align(&mf.width); 828 + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); 837 829 if (ret < 0) 838 830 return ret; 839 831 } 840 832 841 - if (pix->width != icd->user_width || pix->height != icd->user_height) { 833 + if (mf.width != icd->user_width || mf.height != icd->user_height) { 842 834 /* 843 835 * We now know pixel formats and can decide upon DMA-channel(s) 844 836 * So far only direct camera-to-memory is supported ··· 849 841 return ret; 850 842 } 851 843 852 - configure_geometry(mx3_cam, pix->width, pix->height); 844 + configure_geometry(mx3_cam, mf.width, mf.height); 853 845 } 854 846 855 847 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", 856 - pix->width, pix->height); 848 + mf.width, mf.height); 857 849 858 - icd->user_width = pix->width; 859 - icd->user_height = pix->height; 850 + icd->user_width = mf.width; 851 + icd->user_height = mf.height; 860 852 861 853 return ret; 862 854 } ··· 869 861 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 870 862 const struct soc_camera_format_xlate *xlate; 871 863 struct v4l2_pix_format *pix = &f->fmt.pix; 864 + struct v4l2_mbus_framefmt mf; 872 865 int ret; 873 866 874 867 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); ··· 894 885 895 886 configure_geometry(mx3_cam, pix->width, pix->height); 896 887 897 - ret = v4l2_subdev_call(sd, video, s_fmt, f); 898 - if (!ret) { 899 - icd->buswidth = xlate->buswidth; 900 - icd->current_fmt = xlate->host_fmt; 901 - } 888 + mf.width = pix->width; 889 + mf.height = pix->height; 890 + mf.field = pix->field; 891 + mf.colorspace = pix->colorspace; 892 + mf.code = xlate->code; 893 + 894 + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); 895 + if (ret < 0) 896 + return ret; 897 + 898 + if (mf.code != xlate->code) 899 + return -EINVAL; 900 + 901 + pix->width = mf.width; 902 + pix->height = mf.height; 903 + pix->field = mf.field; 904 + pix->colorspace = mf.colorspace; 905 + icd->current_fmt = xlate; 902 906 903 907 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height); 904 908 ··· 924 902 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 925 903 const struct soc_camera_format_xlate *xlate; 926 904 struct v4l2_pix_format *pix = &f->fmt.pix; 905 + struct v4l2_mbus_framefmt mf; 927 906 __u32 pixfmt = pix->pixelformat; 928 - enum v4l2_field field; 929 907 int ret; 930 908 931 909 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); ··· 940 918 if (pix->width > 4096) 941 919 pix->width = 4096; 942 920 943 - pix->bytesperline = pix->width * 944 - DIV_ROUND_UP(xlate->host_fmt->depth, 8); 921 + pix->bytesperline = soc_mbus_bytes_per_line(pix->width, 922 + xlate->host_fmt); 923 + if (pix->bytesperline < 0) 924 + return pix->bytesperline; 945 925 pix->sizeimage = pix->height * pix->bytesperline; 946 926 947 - /* camera has to see its format, but the user the original one */ 948 - pix->pixelformat = xlate->cam_fmt->fourcc; 949 927 /* limit to sensor capabilities */ 950 - ret = v4l2_subdev_call(sd, video, try_fmt, f); 951 - pix->pixelformat = xlate->host_fmt->fourcc; 928 + mf.width = pix->width; 929 + mf.height = pix->height; 930 + mf.field = pix->field; 931 + mf.colorspace = pix->colorspace; 932 + mf.code = xlate->code; 952 933 953 - field = pix->field; 934 + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); 935 + if (ret < 0) 936 + return ret; 954 937 955 - if (field == V4L2_FIELD_ANY) { 938 + pix->width = mf.width; 939 + pix->height = mf.height; 940 + pix->colorspace = mf.colorspace; 941 + 942 + switch (mf.field) { 943 + case V4L2_FIELD_ANY: 956 944 pix->field = V4L2_FIELD_NONE; 957 - } else if (field != V4L2_FIELD_NONE) { 958 - dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); 959 - return -EINVAL; 945 + break; 946 + case V4L2_FIELD_NONE: 947 + break; 948 + default: 949 + dev_err(icd->dev.parent, "Field type %d unsupported.\n", 950 + mf.field); 951 + ret = -EINVAL; 960 952 } 961 953 962 954 return ret; ··· 1006 970 struct mx3_camera_dev *mx3_cam = ici->priv; 1007 971 unsigned long bus_flags, camera_flags, common_flags; 1008 972 u32 dw, sens_conf; 1009 - int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags); 973 + const struct soc_mbus_pixelfmt *fmt; 974 + int buswidth; 975 + int ret; 1010 976 const struct soc_camera_format_xlate *xlate; 1011 977 struct device *dev = icd->dev.parent; 978 + 979 + fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); 980 + if (!fmt) 981 + return -EINVAL; 982 + 983 + buswidth = fmt->bits_per_sample; 984 + ret = test_platform_param(mx3_cam, buswidth, &bus_flags); 1012 985 1013 986 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1014 987 if (!xlate) { ··· 1025 980 return -EINVAL; 1026 981 } 1027 982 1028 - dev_dbg(dev, "requested bus width %d bit: %d\n", 1029 - icd->buswidth, ret); 983 + dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret); 1030 984 1031 985 if (ret < 0) 1032 986 return ret; ··· 1126 1082 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; 1127 1083 1128 1084 /* Just do what we're asked to do */ 1129 - switch (xlate->host_fmt->depth) { 1085 + switch (xlate->host_fmt->bits_per_sample) { 1130 1086 case 4: 1131 1087 dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; 1132 1088 break;
+114 -115
drivers/media/video/ov772x.c
··· 24 24 #include <media/v4l2-chip-ident.h> 25 25 #include <media/v4l2-subdev.h> 26 26 #include <media/soc_camera.h> 27 + #include <media/soc_mediabus.h> 27 28 #include <media/ov772x.h> 28 29 29 30 /* ··· 383 382 }; 384 383 385 384 struct ov772x_color_format { 386 - const struct soc_camera_data_format *format; 385 + enum v4l2_mbus_pixelcode code; 386 + enum v4l2_colorspace colorspace; 387 387 u8 dsp3; 388 388 u8 com3; 389 389 u8 com7; ··· 401 399 struct ov772x_priv { 402 400 struct v4l2_subdev subdev; 403 401 struct ov772x_camera_info *info; 404 - const struct ov772x_color_format *fmt; 402 + const struct ov772x_color_format *cfmt; 405 403 const struct ov772x_win_size *win; 406 404 int model; 407 405 unsigned short flag_vflip:1; ··· 436 434 }; 437 435 438 436 /* 439 - * supported format list 440 - */ 441 - 442 - #define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type) 443 - static const struct soc_camera_data_format ov772x_fmt_lists[] = { 444 - { 445 - SETFOURCC(YUYV), 446 - .depth = 16, 447 - .colorspace = V4L2_COLORSPACE_JPEG, 448 - }, 449 - { 450 - SETFOURCC(YVYU), 451 - .depth = 16, 452 - .colorspace = V4L2_COLORSPACE_JPEG, 453 - }, 454 - { 455 - SETFOURCC(UYVY), 456 - .depth = 16, 457 - .colorspace = V4L2_COLORSPACE_JPEG, 458 - }, 459 - { 460 - SETFOURCC(RGB555), 461 - .depth = 16, 462 - .colorspace = V4L2_COLORSPACE_SRGB, 463 - }, 464 - { 465 - SETFOURCC(RGB555X), 466 - .depth = 16, 467 - .colorspace = V4L2_COLORSPACE_SRGB, 468 - }, 469 - { 470 - SETFOURCC(RGB565), 471 - .depth = 16, 472 - .colorspace = V4L2_COLORSPACE_SRGB, 473 - }, 474 - { 475 - SETFOURCC(RGB565X), 476 - .depth = 16, 477 - .colorspace = V4L2_COLORSPACE_SRGB, 478 - }, 479 - }; 480 - 481 - /* 482 - * color format list 437 + * supported color format list 483 438 */ 484 439 static const struct ov772x_color_format ov772x_cfmts[] = { 485 440 { 486 - .format = &ov772x_fmt_lists[0], 487 - .dsp3 = 0x0, 488 - .com3 = SWAP_YUV, 489 - .com7 = OFMT_YUV, 441 + .code = V4L2_MBUS_FMT_YUYV8_2X8_LE, 442 + .colorspace = V4L2_COLORSPACE_JPEG, 443 + .dsp3 = 0x0, 444 + .com3 = SWAP_YUV, 445 + .com7 = OFMT_YUV, 490 446 }, 491 447 { 492 - .format = &ov772x_fmt_lists[1], 493 - .dsp3 = UV_ON, 494 - .com3 = SWAP_YUV, 495 - .com7 = OFMT_YUV, 448 + .code = V4L2_MBUS_FMT_YVYU8_2X8_LE, 449 + .colorspace = V4L2_COLORSPACE_JPEG, 450 + .dsp3 = UV_ON, 451 + .com3 = SWAP_YUV, 452 + .com7 = OFMT_YUV, 496 453 }, 497 454 { 498 - .format = &ov772x_fmt_lists[2], 499 - .dsp3 = 0x0, 500 - .com3 = 0x0, 501 - .com7 = OFMT_YUV, 455 + .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, 456 + .colorspace = V4L2_COLORSPACE_JPEG, 457 + .dsp3 = 0x0, 458 + .com3 = 0x0, 459 + .com7 = OFMT_YUV, 502 460 }, 503 461 { 504 - .format = &ov772x_fmt_lists[3], 505 - .dsp3 = 0x0, 506 - .com3 = SWAP_RGB, 507 - .com7 = FMT_RGB555 | OFMT_RGB, 462 + .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, 463 + .colorspace = V4L2_COLORSPACE_SRGB, 464 + .dsp3 = 0x0, 465 + .com3 = SWAP_RGB, 466 + .com7 = FMT_RGB555 | OFMT_RGB, 508 467 }, 509 468 { 510 - .format = &ov772x_fmt_lists[4], 511 - .dsp3 = 0x0, 512 - .com3 = 0x0, 513 - .com7 = FMT_RGB555 | OFMT_RGB, 469 + .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, 470 + .colorspace = V4L2_COLORSPACE_SRGB, 471 + .dsp3 = 0x0, 472 + .com3 = 0x0, 473 + .com7 = FMT_RGB555 | OFMT_RGB, 514 474 }, 515 475 { 516 - .format = &ov772x_fmt_lists[5], 517 - .dsp3 = 0x0, 518 - .com3 = SWAP_RGB, 519 - .com7 = FMT_RGB565 | OFMT_RGB, 476 + .code = V4L2_MBUS_FMT_RGB565_2X8_LE, 477 + .colorspace = V4L2_COLORSPACE_SRGB, 478 + .dsp3 = 0x0, 479 + .com3 = SWAP_RGB, 480 + .com7 = FMT_RGB565 | OFMT_RGB, 520 481 }, 521 482 { 522 - .format = &ov772x_fmt_lists[6], 523 - .dsp3 = 0x0, 524 - .com3 = 0x0, 525 - .com7 = FMT_RGB565 | OFMT_RGB, 483 + .code = V4L2_MBUS_FMT_RGB565_2X8_BE, 484 + .colorspace = V4L2_COLORSPACE_SRGB, 485 + .dsp3 = 0x0, 486 + .com3 = 0x0, 487 + .com7 = FMT_RGB565 | OFMT_RGB, 526 488 }, 527 489 }; 528 490 ··· 608 642 return 0; 609 643 } 610 644 611 - if (!priv->win || !priv->fmt) { 645 + if (!priv->win || !priv->cfmt) { 612 646 dev_err(&client->dev, "norm or win select error\n"); 613 647 return -EPERM; 614 648 } 615 649 616 650 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); 617 651 618 - dev_dbg(&client->dev, "format %s, win %s\n", 619 - priv->fmt->format->name, priv->win->name); 652 + dev_dbg(&client->dev, "format %d, win %s\n", 653 + priv->cfmt->code, priv->win->name); 620 654 621 655 return 0; 622 656 } ··· 772 806 return win; 773 807 } 774 808 775 - static int ov772x_set_params(struct i2c_client *client, 776 - u32 *width, u32 *height, u32 pixfmt) 809 + static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, 810 + enum v4l2_mbus_pixelcode code) 777 811 { 778 812 struct ov772x_priv *priv = to_ov772x(client); 779 813 int ret = -EINVAL; ··· 783 817 /* 784 818 * select format 785 819 */ 786 - priv->fmt = NULL; 820 + priv->cfmt = NULL; 787 821 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { 788 - if (pixfmt == ov772x_cfmts[i].format->fourcc) { 789 - priv->fmt = ov772x_cfmts + i; 822 + if (code == ov772x_cfmts[i].code) { 823 + priv->cfmt = ov772x_cfmts + i; 790 824 break; 791 825 } 792 826 } 793 - if (!priv->fmt) 827 + if (!priv->cfmt) 794 828 goto ov772x_set_fmt_error; 795 829 796 830 /* ··· 860 894 /* 861 895 * set DSP_CTRL3 862 896 */ 863 - val = priv->fmt->dsp3; 897 + val = priv->cfmt->dsp3; 864 898 if (val) { 865 899 ret = ov772x_mask_set(client, 866 900 DSP_CTRL3, UV_MASK, val); ··· 871 905 /* 872 906 * set COM3 873 907 */ 874 - val = priv->fmt->com3; 908 + val = priv->cfmt->com3; 875 909 if (priv->info->flags & OV772X_FLAG_VFLIP) 876 910 val |= VFLIP_IMG; 877 911 if (priv->info->flags & OV772X_FLAG_HFLIP) ··· 889 923 /* 890 924 * set COM7 891 925 */ 892 - val = priv->win->com7_bit | priv->fmt->com7; 926 + val = priv->win->com7_bit | priv->cfmt->com7; 893 927 ret = ov772x_mask_set(client, 894 - COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), 928 + COM7, SLCT_MASK | FMT_MASK | OFMT_MASK, 895 929 val); 896 930 if (ret < 0) 897 931 goto ov772x_set_fmt_error; ··· 917 951 918 952 ov772x_reset(client); 919 953 priv->win = NULL; 920 - priv->fmt = NULL; 954 + priv->cfmt = NULL; 921 955 922 956 return ret; 923 957 } ··· 947 981 return 0; 948 982 } 949 983 950 - static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 984 + static int ov772x_g_fmt(struct v4l2_subdev *sd, 985 + struct v4l2_mbus_framefmt *mf) 951 986 { 952 987 struct i2c_client *client = sd->priv; 953 988 struct ov772x_priv *priv = to_ov772x(client); 954 - struct v4l2_pix_format *pix = &f->fmt.pix; 955 989 956 - if (!priv->win || !priv->fmt) { 990 + if (!priv->win || !priv->cfmt) { 957 991 u32 width = VGA_WIDTH, height = VGA_HEIGHT; 958 992 int ret = ov772x_set_params(client, &width, &height, 959 - V4L2_PIX_FMT_YUYV); 993 + V4L2_MBUS_FMT_YUYV8_2X8_LE); 960 994 if (ret < 0) 961 995 return ret; 962 996 } 963 997 964 - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 965 - 966 - pix->width = priv->win->width; 967 - pix->height = priv->win->height; 968 - pix->pixelformat = priv->fmt->format->fourcc; 969 - pix->colorspace = priv->fmt->format->colorspace; 970 - pix->field = V4L2_FIELD_NONE; 998 + mf->width = priv->win->width; 999 + mf->height = priv->win->height; 1000 + mf->code = priv->cfmt->code; 1001 + mf->colorspace = priv->cfmt->colorspace; 1002 + mf->field = V4L2_FIELD_NONE; 971 1003 972 1004 return 0; 973 1005 } 974 1006 975 - static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 1007 + static int ov772x_s_fmt(struct v4l2_subdev *sd, 1008 + struct v4l2_mbus_framefmt *mf) 976 1009 { 977 1010 struct i2c_client *client = sd->priv; 978 - struct v4l2_pix_format *pix = &f->fmt.pix; 1011 + struct ov772x_priv *priv = to_ov772x(client); 1012 + int ret = ov772x_set_params(client, &mf->width, &mf->height, 1013 + mf->code); 979 1014 980 - return ov772x_set_params(client, &pix->width, &pix->height, 981 - pix->pixelformat); 1015 + if (!ret) 1016 + mf->colorspace = priv->cfmt->colorspace; 1017 + 1018 + return ret; 982 1019 } 983 1020 984 1021 static int ov772x_try_fmt(struct v4l2_subdev *sd, 985 - struct v4l2_format *f) 1022 + struct v4l2_mbus_framefmt *mf) 986 1023 { 987 - struct v4l2_pix_format *pix = &f->fmt.pix; 1024 + struct i2c_client *client = sd->priv; 1025 + struct ov772x_priv *priv = to_ov772x(client); 988 1026 const struct ov772x_win_size *win; 1027 + int i; 989 1028 990 1029 /* 991 1030 * select suitable win 992 1031 */ 993 - win = ov772x_select_win(pix->width, pix->height); 1032 + win = ov772x_select_win(mf->width, mf->height); 994 1033 995 - pix->width = win->width; 996 - pix->height = win->height; 997 - pix->field = V4L2_FIELD_NONE; 1034 + mf->width = win->width; 1035 + mf->height = win->height; 1036 + mf->field = V4L2_FIELD_NONE; 1037 + 1038 + for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) 1039 + if (mf->code == ov772x_cfmts[i].code) 1040 + break; 1041 + 1042 + if (i == ARRAY_SIZE(ov772x_cfmts)) { 1043 + /* Unsupported format requested. Propose either */ 1044 + if (priv->cfmt) { 1045 + /* the current one or */ 1046 + mf->colorspace = priv->cfmt->colorspace; 1047 + mf->code = priv->cfmt->code; 1048 + } else { 1049 + /* the default one */ 1050 + mf->colorspace = ov772x_cfmts[0].colorspace; 1051 + mf->code = ov772x_cfmts[0].code; 1052 + } 1053 + } else { 1054 + /* Also return the colorspace */ 1055 + mf->colorspace = ov772x_cfmts[i].colorspace; 1056 + } 998 1057 999 1058 return 0; 1000 1059 } ··· 1047 1056 dev_err(&client->dev, "bus width error\n"); 1048 1057 return -ENODEV; 1049 1058 } 1050 - 1051 - icd->formats = ov772x_fmt_lists; 1052 - icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists); 1053 1059 1054 1060 /* 1055 1061 * check and show product ID and manufacturer ID ··· 1097 1109 #endif 1098 1110 }; 1099 1111 1112 + static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index, 1113 + enum v4l2_mbus_pixelcode *code) 1114 + { 1115 + if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts)) 1116 + return -EINVAL; 1117 + 1118 + *code = ov772x_cfmts[index].code; 1119 + return 0; 1120 + } 1121 + 1100 1122 static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { 1101 1123 .s_stream = ov772x_s_stream, 1102 - .g_fmt = ov772x_g_fmt, 1103 - .s_fmt = ov772x_s_fmt, 1104 - .try_fmt = ov772x_try_fmt, 1124 + .g_mbus_fmt = ov772x_g_fmt, 1125 + .s_mbus_fmt = ov772x_s_fmt, 1126 + .try_mbus_fmt = ov772x_try_fmt, 1105 1127 .cropcap = ov772x_cropcap, 1106 1128 .g_crop = ov772x_g_crop, 1129 + .enum_mbus_fmt = ov772x_enum_fmt, 1107 1130 }; 1108 1131 1109 1132 static struct v4l2_subdev_ops ov772x_subdev_ops = {
+69 -38
drivers/media/video/ov9640.c
··· 154 154 { OV9640_MTXS, 0x65 }, 155 155 }; 156 156 157 - /* 158 - * TODO: this sensor also supports RGB555 and RGB565 formats, but support for 159 - * them has not yet been sufficiently tested and so it is not included with 160 - * this version of the driver. To test and debug these formats add two entries 161 - * to the below array, see ov722x.c for an example. 162 - */ 163 - static const struct soc_camera_data_format ov9640_fmt_lists[] = { 164 - { 165 - .name = "UYVY", 166 - .fourcc = V4L2_PIX_FMT_UYVY, 167 - .depth = 16, 168 - .colorspace = V4L2_COLORSPACE_JPEG, 169 - }, 157 + static enum v4l2_mbus_pixelcode ov9640_codes[] = { 158 + V4L2_MBUS_FMT_YUYV8_2X8_BE, 159 + V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, 160 + V4L2_MBUS_FMT_RGB565_2X8_LE, 170 161 }; 171 162 172 163 static const struct v4l2_queryctrl ov9640_controls[] = { ··· 425 434 } 426 435 427 436 /* Prepare necessary register changes depending on color encoding */ 428 - static void ov9640_alter_regs(u32 pixfmt, struct ov9640_reg_alt *alt) 437 + static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, 438 + struct ov9640_reg_alt *alt) 429 439 { 430 - switch (pixfmt) { 431 - case V4L2_PIX_FMT_UYVY: 440 + switch (code) { 441 + default: 442 + case V4L2_MBUS_FMT_YUYV8_2X8_BE: 432 443 alt->com12 = OV9640_COM12_YUV_AVG; 433 444 alt->com13 = OV9640_COM13_Y_DELAY_EN | 434 445 OV9640_COM13_YUV_DLY(0x01); 435 446 break; 436 - case V4L2_PIX_FMT_RGB555: 447 + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: 437 448 alt->com7 = OV9640_COM7_RGB; 438 449 alt->com13 = OV9640_COM13_RGB_AVG; 439 450 alt->com15 = OV9640_COM15_RGB_555; 440 451 break; 441 - case V4L2_PIX_FMT_RGB565: 452 + case V4L2_MBUS_FMT_RGB565_2X8_LE: 442 453 alt->com7 = OV9640_COM7_RGB; 443 454 alt->com13 = OV9640_COM13_RGB_AVG; 444 455 alt->com15 = OV9640_COM15_RGB_565; ··· 449 456 } 450 457 451 458 /* Setup registers according to resolution and color encoding */ 452 - static int ov9640_write_regs(struct i2c_client *client, 453 - u32 width, u32 pixfmt, struct ov9640_reg_alt *alts) 459 + static int ov9640_write_regs(struct i2c_client *client, u32 width, 460 + enum v4l2_mbus_pixelcode code, struct ov9640_reg_alt *alts) 454 461 { 455 462 const struct ov9640_reg *ov9640_regs, *matrix_regs; 456 463 int ov9640_regs_len, matrix_regs_len; ··· 493 500 } 494 501 495 502 /* select color matrix configuration for given color encoding */ 496 - if (pixfmt == V4L2_PIX_FMT_UYVY) { 503 + if (code == V4L2_MBUS_FMT_YUYV8_2X8_BE) { 497 504 matrix_regs = ov9640_regs_yuv; 498 505 matrix_regs_len = ARRAY_SIZE(ov9640_regs_yuv); 499 506 } else { ··· 555 562 } 556 563 557 564 /* set the format we will capture in */ 558 - static int ov9640_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 565 + static int ov9640_s_fmt(struct v4l2_subdev *sd, 566 + struct v4l2_mbus_framefmt *mf) 559 567 { 560 568 struct i2c_client *client = sd->priv; 561 - struct v4l2_pix_format *pix = &f->fmt.pix; 562 569 struct ov9640_reg_alt alts = {0}; 570 + enum v4l2_colorspace cspace; 571 + enum v4l2_mbus_pixelcode code = mf->code; 563 572 int ret; 564 573 565 - ov9640_res_roundup(&pix->width, &pix->height); 566 - ov9640_alter_regs(pix->pixelformat, &alts); 574 + ov9640_res_roundup(&mf->width, &mf->height); 575 + ov9640_alter_regs(mf->code, &alts); 567 576 568 577 ov9640_reset(client); 569 578 ··· 573 578 if (ret) 574 579 return ret; 575 580 576 - return ov9640_write_regs(client, pix->width, pix->pixelformat, &alts); 581 + switch (code) { 582 + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: 583 + case V4L2_MBUS_FMT_RGB565_2X8_LE: 584 + cspace = V4L2_COLORSPACE_SRGB; 585 + break; 586 + default: 587 + code = V4L2_MBUS_FMT_YUYV8_2X8_BE; 588 + case V4L2_MBUS_FMT_YUYV8_2X8_BE: 589 + cspace = V4L2_COLORSPACE_JPEG; 590 + } 591 + 592 + ret = ov9640_write_regs(client, mf->width, code, &alts); 593 + if (!ret) { 594 + mf->code = code; 595 + mf->colorspace = cspace; 596 + } 597 + 598 + return ret; 577 599 } 578 600 579 - static int ov9640_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 601 + static int ov9640_try_fmt(struct v4l2_subdev *sd, 602 + struct v4l2_mbus_framefmt *mf) 580 603 { 581 - struct v4l2_pix_format *pix = &f->fmt.pix; 604 + ov9640_res_roundup(&mf->width, &mf->height); 582 605 583 - ov9640_res_roundup(&pix->width, &pix->height); 584 - pix->field = V4L2_FIELD_NONE; 606 + mf->field = V4L2_FIELD_NONE; 585 607 608 + switch (mf->code) { 609 + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: 610 + case V4L2_MBUS_FMT_RGB565_2X8_LE: 611 + mf->colorspace = V4L2_COLORSPACE_SRGB; 612 + break; 613 + default: 614 + mf->code = V4L2_MBUS_FMT_YUYV8_2X8_BE; 615 + case V4L2_MBUS_FMT_YUYV8_2X8_BE: 616 + mf->colorspace = V4L2_COLORSPACE_JPEG; 617 + } 618 + 619 + return 0; 620 + } 621 + 622 + static int ov9640_enum_fmt(struct v4l2_subdev *sd, int index, 623 + enum v4l2_mbus_pixelcode *code) 624 + { 625 + if ((unsigned int)index >= ARRAY_SIZE(ov9640_codes)) 626 + return -EINVAL; 627 + 628 + *code = ov9640_codes[index]; 586 629 return 0; 587 630 } 588 631 ··· 669 636 ret = -ENODEV; 670 637 goto err; 671 638 } 672 - 673 - icd->formats = ov9640_fmt_lists; 674 - icd->num_formats = ARRAY_SIZE(ov9640_fmt_lists); 675 639 676 640 /* 677 641 * check and show product ID and manufacturer ID ··· 732 702 }; 733 703 734 704 static struct v4l2_subdev_video_ops ov9640_video_ops = { 735 - .s_stream = ov9640_s_stream, 736 - .s_fmt = ov9640_s_fmt, 737 - .try_fmt = ov9640_try_fmt, 738 - .cropcap = ov9640_cropcap, 739 - .g_crop = ov9640_g_crop, 705 + .s_stream = ov9640_s_stream, 706 + .s_mbus_fmt = ov9640_s_fmt, 707 + .try_mbus_fmt = ov9640_try_fmt, 708 + .enum_mbus_fmt = ov9640_enum_fmt, 709 + .cropcap = ov9640_cropcap, 710 + .g_crop = ov9640_g_crop, 740 711 741 712 }; 742 713
+144 -130
drivers/media/video/pxa_camera.c
··· 32 32 #include <media/v4l2-dev.h> 33 33 #include <media/videobuf-dma-sg.h> 34 34 #include <media/soc_camera.h> 35 + #include <media/soc_mediabus.h> 35 36 36 37 #include <linux/videodev2.h> 37 38 ··· 184 183 /* buffer for one video frame */ 185 184 struct pxa_buffer { 186 185 /* common v4l buffer stuff -- must be first */ 187 - struct videobuf_buffer vb; 188 - 189 - const struct soc_camera_data_format *fmt; 190 - 186 + struct videobuf_buffer vb; 187 + enum v4l2_mbus_pixelcode code; 191 188 /* our descriptor lists for Y, U and V channels */ 192 - struct pxa_cam_dma dmas[3]; 193 - 194 - int inwork; 195 - 196 - enum pxa_camera_active_dma active_dma; 189 + struct pxa_cam_dma dmas[3]; 190 + int inwork; 191 + enum pxa_camera_active_dma active_dma; 197 192 }; 198 193 199 194 struct pxa_camera_dev { ··· 240 243 unsigned int *size) 241 244 { 242 245 struct soc_camera_device *icd = vq->priv_data; 246 + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 247 + icd->current_fmt->host_fmt); 248 + 249 + if (bytes_per_line < 0) 250 + return bytes_per_line; 243 251 244 252 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); 245 253 246 - *size = roundup(icd->user_width * icd->user_height * 247 - ((icd->current_fmt->depth + 7) >> 3), 8); 254 + *size = bytes_per_line * icd->user_height; 248 255 249 256 if (0 == *count) 250 257 *count = 32; ··· 434 433 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 435 434 int ret; 436 435 int size_y, size_u = 0, size_v = 0; 436 + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 437 + icd->current_fmt->host_fmt); 438 + 439 + if (bytes_per_line < 0) 440 + return bytes_per_line; 437 441 438 442 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 439 443 vb, vb->baddr, vb->bsize); ··· 462 456 */ 463 457 buf->inwork = 1; 464 458 465 - if (buf->fmt != icd->current_fmt || 459 + if (buf->code != icd->current_fmt->code || 466 460 vb->width != icd->user_width || 467 461 vb->height != icd->user_height || 468 462 vb->field != field) { 469 - buf->fmt = icd->current_fmt; 463 + buf->code = icd->current_fmt->code; 470 464 vb->width = icd->user_width; 471 465 vb->height = icd->user_height; 472 466 vb->field = field; 473 467 vb->state = VIDEOBUF_NEEDS_INIT; 474 468 } 475 469 476 - vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); 470 + vb->size = bytes_per_line * vb->height; 477 471 if (0 != vb->baddr && vb->bsize < vb->size) { 478 472 ret = -EINVAL; 479 473 goto out; ··· 1163 1157 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1164 1158 struct pxa_camera_dev *pcdev = ici->priv; 1165 1159 unsigned long bus_flags, camera_flags, common_flags; 1166 - int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); 1160 + const struct soc_mbus_pixelfmt *fmt; 1161 + int ret; 1167 1162 struct pxa_cam *cam = icd->host_priv; 1168 1163 1164 + fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); 1165 + if (!fmt) 1166 + return -EINVAL; 1167 + 1168 + ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags); 1169 1169 if (ret < 0) 1170 1170 return ret; 1171 1171 ··· 1235 1223 return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; 1236 1224 } 1237 1225 1238 - static const struct soc_camera_data_format pxa_camera_formats[] = { 1226 + static const struct soc_mbus_pixelfmt pxa_camera_formats[] = { 1239 1227 { 1240 - .name = "Planar YUV422 16 bit", 1241 - .depth = 16, 1242 - .fourcc = V4L2_PIX_FMT_YUV422P, 1243 - .colorspace = V4L2_COLORSPACE_JPEG, 1228 + .fourcc = V4L2_PIX_FMT_YUV422P, 1229 + .name = "Planar YUV422 16 bit", 1230 + .bits_per_sample = 8, 1231 + .packing = SOC_MBUS_PACKING_2X8_PADHI, 1232 + .order = SOC_MBUS_ORDER_LE, 1244 1233 }, 1245 1234 }; 1246 1235 1247 - static bool buswidth_supported(struct soc_camera_device *icd, int depth) 1236 + /* This will be corrected as we get more formats */ 1237 + static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) 1248 1238 { 1249 - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1250 - struct pxa_camera_dev *pcdev = ici->priv; 1251 - 1252 - switch (depth) { 1253 - case 8: 1254 - return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8); 1255 - case 9: 1256 - return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9); 1257 - case 10: 1258 - return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10); 1259 - } 1260 - return false; 1261 - } 1262 - 1263 - static int required_buswidth(const struct soc_camera_data_format *fmt) 1264 - { 1265 - switch (fmt->fourcc) { 1266 - case V4L2_PIX_FMT_UYVY: 1267 - case V4L2_PIX_FMT_VYUY: 1268 - case V4L2_PIX_FMT_YUYV: 1269 - case V4L2_PIX_FMT_YVYU: 1270 - case V4L2_PIX_FMT_RGB565: 1271 - case V4L2_PIX_FMT_RGB555: 1272 - return 8; 1273 - default: 1274 - return fmt->depth; 1275 - } 1239 + return fmt->packing == SOC_MBUS_PACKING_NONE || 1240 + (fmt->bits_per_sample == 8 && 1241 + fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || 1242 + (fmt->bits_per_sample > 8 && 1243 + fmt->packing == SOC_MBUS_PACKING_EXTEND16); 1276 1244 } 1277 1245 1278 1246 static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, 1279 1247 struct soc_camera_format_xlate *xlate) 1280 1248 { 1249 + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1281 1250 struct device *dev = icd->dev.parent; 1282 - int formats = 0, buswidth, ret; 1251 + int formats = 0, ret; 1283 1252 struct pxa_cam *cam; 1253 + enum v4l2_mbus_pixelcode code; 1254 + const struct soc_mbus_pixelfmt *fmt; 1284 1255 1285 - buswidth = required_buswidth(icd->formats + idx); 1286 - 1287 - if (!buswidth_supported(icd, buswidth)) 1256 + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); 1257 + if (ret < 0) 1258 + /* No more formats */ 1288 1259 return 0; 1289 1260 1290 - ret = pxa_camera_try_bus_param(icd, buswidth); 1261 + fmt = soc_mbus_get_fmtdesc(code); 1262 + if (!fmt) { 1263 + dev_err(dev, "Invalid format code #%d: %d\n", idx, code); 1264 + return 0; 1265 + } 1266 + 1267 + /* This also checks support for the requested bits-per-sample */ 1268 + ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample); 1291 1269 if (ret < 0) 1292 1270 return 0; 1293 1271 ··· 1291 1289 cam = icd->host_priv; 1292 1290 } 1293 1291 1294 - switch (icd->formats[idx].fourcc) { 1295 - case V4L2_PIX_FMT_UYVY: 1292 + switch (code) { 1293 + case V4L2_MBUS_FMT_YUYV8_2X8_BE: 1296 1294 formats++; 1297 1295 if (xlate) { 1298 - xlate->host_fmt = &pxa_camera_formats[0]; 1299 - xlate->cam_fmt = icd->formats + idx; 1300 - xlate->buswidth = buswidth; 1296 + xlate->host_fmt = &pxa_camera_formats[0]; 1297 + xlate->code = code; 1301 1298 xlate++; 1302 - dev_dbg(dev, "Providing format %s using %s\n", 1303 - pxa_camera_formats[0].name, 1304 - icd->formats[idx].name); 1299 + dev_dbg(dev, "Providing format %s using code %d\n", 1300 + pxa_camera_formats[0].name, code); 1305 1301 } 1306 - case V4L2_PIX_FMT_VYUY: 1307 - case V4L2_PIX_FMT_YUYV: 1308 - case V4L2_PIX_FMT_YVYU: 1309 - case V4L2_PIX_FMT_RGB565: 1310 - case V4L2_PIX_FMT_RGB555: 1311 - formats++; 1312 - if (xlate) { 1313 - xlate->host_fmt = icd->formats + idx; 1314 - xlate->cam_fmt = icd->formats + idx; 1315 - xlate->buswidth = buswidth; 1316 - xlate++; 1302 + case V4L2_MBUS_FMT_YVYU8_2X8_BE: 1303 + case V4L2_MBUS_FMT_YUYV8_2X8_LE: 1304 + case V4L2_MBUS_FMT_YVYU8_2X8_LE: 1305 + case V4L2_MBUS_FMT_RGB565_2X8_LE: 1306 + case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE: 1307 + if (xlate) 1317 1308 dev_dbg(dev, "Providing format %s packed\n", 1318 - icd->formats[idx].name); 1319 - } 1309 + fmt->name); 1320 1310 break; 1321 1311 default: 1322 - /* Generic pass-through */ 1323 - formats++; 1324 - if (xlate) { 1325 - xlate->host_fmt = icd->formats + idx; 1326 - xlate->cam_fmt = icd->formats + idx; 1327 - xlate->buswidth = icd->formats[idx].depth; 1328 - xlate++; 1312 + if (!pxa_camera_packing_supported(fmt)) 1313 + return 0; 1314 + if (xlate) 1329 1315 dev_dbg(dev, 1330 1316 "Providing format %s in pass-through mode\n", 1331 - icd->formats[idx].name); 1332 - } 1317 + fmt->name); 1318 + } 1319 + 1320 + /* Generic pass-through */ 1321 + formats++; 1322 + if (xlate) { 1323 + xlate->host_fmt = fmt; 1324 + xlate->code = code; 1325 + xlate++; 1333 1326 } 1334 1327 1335 1328 return formats; ··· 1336 1339 icd->host_priv = NULL; 1337 1340 } 1338 1341 1339 - static int pxa_camera_check_frame(struct v4l2_pix_format *pix) 1342 + static int pxa_camera_check_frame(u32 width, u32 height) 1340 1343 { 1341 1344 /* limit to pxa hardware capabilities */ 1342 - return pix->height < 32 || pix->height > 2048 || pix->width < 48 || 1343 - pix->width > 2048 || (pix->width & 0x01); 1345 + return height < 32 || height > 2048 || width < 48 || width > 2048 || 1346 + (width & 0x01); 1344 1347 } 1345 1348 1346 1349 static int pxa_camera_set_crop(struct soc_camera_device *icd, ··· 1355 1358 .master_clock = pcdev->mclk, 1356 1359 .pixel_clock_max = pcdev->ciclk / 4, 1357 1360 }; 1358 - struct v4l2_format f; 1359 - struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp; 1361 + struct v4l2_mbus_framefmt mf; 1360 1362 struct pxa_cam *cam = icd->host_priv; 1363 + u32 fourcc = icd->current_fmt->host_fmt->fourcc; 1361 1364 int ret; 1362 1365 1363 1366 /* If PCLK is used to latch data from the sensor, check sense */ ··· 1374 1377 return ret; 1375 1378 } 1376 1379 1377 - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1378 - 1379 - ret = v4l2_subdev_call(sd, video, g_fmt, &f); 1380 + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); 1380 1381 if (ret < 0) 1381 1382 return ret; 1382 1383 1383 - pix_tmp = *pix; 1384 - if (pxa_camera_check_frame(pix)) { 1384 + if (pxa_camera_check_frame(mf.width, mf.height)) { 1385 1385 /* 1386 1386 * Camera cropping produced a frame beyond our capabilities. 1387 1387 * FIXME: just extract a subframe, that we can process. 1388 1388 */ 1389 - v4l_bound_align_image(&pix->width, 48, 2048, 1, 1390 - &pix->height, 32, 2048, 0, 1391 - icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 1392 - 4 : 0); 1393 - ret = v4l2_subdev_call(sd, video, s_fmt, &f); 1389 + v4l_bound_align_image(&mf.width, 48, 2048, 1, 1390 + &mf.height, 32, 2048, 0, 1391 + fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); 1392 + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); 1394 1393 if (ret < 0) 1395 1394 return ret; 1396 1395 1397 - if (pxa_camera_check_frame(pix)) { 1396 + if (pxa_camera_check_frame(mf.width, mf.height)) { 1398 1397 dev_warn(icd->dev.parent, 1399 1398 "Inconsistent state. Use S_FMT to repair\n"); 1400 1399 return -EINVAL; ··· 1407 1414 recalculate_fifo_timeout(pcdev, sense.pixel_clock); 1408 1415 } 1409 1416 1410 - icd->user_width = pix->width; 1411 - icd->user_height = pix->height; 1417 + icd->user_width = mf.width; 1418 + icd->user_height = mf.height; 1412 1419 1413 - pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc); 1420 + pxa_camera_setup_cicr(icd, cam->flags, fourcc); 1414 1421 1415 1422 return ret; 1416 1423 } ··· 1422 1429 struct pxa_camera_dev *pcdev = ici->priv; 1423 1430 struct device *dev = icd->dev.parent; 1424 1431 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1425 - const struct soc_camera_data_format *cam_fmt = NULL; 1426 1432 const struct soc_camera_format_xlate *xlate = NULL; 1427 1433 struct soc_camera_sense sense = { 1428 1434 .master_clock = pcdev->mclk, 1429 1435 .pixel_clock_max = pcdev->ciclk / 4, 1430 1436 }; 1431 1437 struct v4l2_pix_format *pix = &f->fmt.pix; 1432 - struct v4l2_format cam_f = *f; 1438 + struct v4l2_mbus_framefmt mf; 1433 1439 int ret; 1434 1440 1435 1441 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); ··· 1437 1445 return -EINVAL; 1438 1446 } 1439 1447 1440 - cam_fmt = xlate->cam_fmt; 1441 - 1442 1448 /* If PCLK is used to latch data from the sensor, check sense */ 1443 1449 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) 1450 + /* The caller holds a mutex. */ 1444 1451 icd->sense = &sense; 1445 1452 1446 - cam_f.fmt.pix.pixelformat = cam_fmt->fourcc; 1447 - ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f); 1448 - cam_f.fmt.pix.pixelformat = pix->pixelformat; 1449 - *pix = cam_f.fmt.pix; 1453 + mf.width = pix->width; 1454 + mf.height = pix->height; 1455 + mf.field = pix->field; 1456 + mf.colorspace = pix->colorspace; 1457 + mf.code = xlate->code; 1458 + 1459 + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); 1460 + 1461 + if (mf.code != xlate->code) 1462 + return -EINVAL; 1450 1463 1451 1464 icd->sense = NULL; 1452 1465 1453 1466 if (ret < 0) { 1454 1467 dev_warn(dev, "Failed to configure for format %x\n", 1455 1468 pix->pixelformat); 1456 - } else if (pxa_camera_check_frame(pix)) { 1469 + } else if (pxa_camera_check_frame(mf.width, mf.height)) { 1457 1470 dev_warn(dev, 1458 1471 "Camera driver produced an unsupported frame %dx%d\n", 1459 - pix->width, pix->height); 1472 + mf.width, mf.height); 1460 1473 ret = -EINVAL; 1461 1474 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1462 1475 if (sense.pixel_clock > sense.pixel_clock_max) { ··· 1473 1476 recalculate_fifo_timeout(pcdev, sense.pixel_clock); 1474 1477 } 1475 1478 1476 - if (!ret) { 1477 - icd->buswidth = xlate->buswidth; 1478 - icd->current_fmt = xlate->host_fmt; 1479 - } 1479 + if (ret < 0) 1480 + return ret; 1481 + 1482 + pix->width = mf.width; 1483 + pix->height = mf.height; 1484 + pix->field = mf.field; 1485 + pix->colorspace = mf.colorspace; 1486 + icd->current_fmt = xlate; 1480 1487 1481 1488 return ret; 1482 1489 } ··· 1488 1487 static int pxa_camera_try_fmt(struct soc_camera_device *icd, 1489 1488 struct v4l2_format *f) 1490 1489 { 1491 - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1492 1490 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1493 1491 const struct soc_camera_format_xlate *xlate; 1494 1492 struct v4l2_pix_format *pix = &f->fmt.pix; 1493 + struct v4l2_mbus_framefmt mf; 1495 1494 __u32 pixfmt = pix->pixelformat; 1496 - enum v4l2_field field; 1497 1495 int ret; 1498 1496 1499 1497 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1500 1498 if (!xlate) { 1501 - dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt); 1499 + dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt); 1502 1500 return -EINVAL; 1503 1501 } 1504 1502 ··· 1511 1511 &pix->height, 32, 2048, 0, 1512 1512 pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0); 1513 1513 1514 - pix->bytesperline = pix->width * 1515 - DIV_ROUND_UP(xlate->host_fmt->depth, 8); 1514 + pix->bytesperline = soc_mbus_bytes_per_line(pix->width, 1515 + xlate->host_fmt); 1516 + if (pix->bytesperline < 0) 1517 + return pix->bytesperline; 1516 1518 pix->sizeimage = pix->height * pix->bytesperline; 1517 1519 1518 - /* camera has to see its format, but the user the original one */ 1519 - pix->pixelformat = xlate->cam_fmt->fourcc; 1520 1520 /* limit to sensor capabilities */ 1521 - ret = v4l2_subdev_call(sd, video, try_fmt, f); 1522 - pix->pixelformat = pixfmt; 1521 + mf.width = pix->width; 1522 + mf.height = pix->height; 1523 + mf.field = pix->field; 1524 + mf.colorspace = pix->colorspace; 1525 + mf.code = xlate->code; 1523 1526 1524 - field = pix->field; 1527 + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); 1528 + if (ret < 0) 1529 + return ret; 1525 1530 1526 - if (field == V4L2_FIELD_ANY) { 1527 - pix->field = V4L2_FIELD_NONE; 1528 - } else if (field != V4L2_FIELD_NONE) { 1529 - dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); 1531 + pix->width = mf.width; 1532 + pix->height = mf.height; 1533 + pix->colorspace = mf.colorspace; 1534 + 1535 + switch (mf.field) { 1536 + case V4L2_FIELD_ANY: 1537 + case V4L2_FIELD_NONE: 1538 + pix->field = V4L2_FIELD_NONE; 1539 + break; 1540 + default: 1541 + /* TODO: support interlaced at least in pass-through mode */ 1542 + dev_err(icd->dev.parent, "Field type %d unsupported.\n", 1543 + mf.field); 1530 1544 return -EINVAL; 1531 1545 } 1532 1546
+149 -52
drivers/media/video/rj54n1cb0c.c
··· 16 16 #include <media/v4l2-subdev.h> 17 17 #include <media/v4l2-chip-ident.h> 18 18 #include <media/soc_camera.h> 19 + #include <media/soc_mediabus.h> 19 20 20 21 #define RJ54N1_DEV_CODE 0x0400 21 22 #define RJ54N1_DEV_CODE2 0x0401 ··· 86 85 87 86 /* I2C addresses: 0x50, 0x51, 0x60, 0x61 */ 88 87 89 - static const struct soc_camera_data_format rj54n1_colour_formats[] = { 90 - { 91 - .name = "YUYV", 92 - .depth = 16, 93 - .fourcc = V4L2_PIX_FMT_YUYV, 94 - .colorspace = V4L2_COLORSPACE_JPEG, 95 - }, { 96 - .name = "RGB565", 97 - .depth = 16, 98 - .fourcc = V4L2_PIX_FMT_RGB565, 99 - .colorspace = V4L2_COLORSPACE_SRGB, 100 - } 88 + /* RJ54N1CB0C has only one fixed colorspace per pixelcode */ 89 + struct rj54n1_datafmt { 90 + enum v4l2_mbus_pixelcode code; 91 + enum v4l2_colorspace colorspace; 92 + }; 93 + 94 + /* Find a data format by a pixel code in an array */ 95 + static const struct rj54n1_datafmt *rj54n1_find_datafmt( 96 + enum v4l2_mbus_pixelcode code, const struct rj54n1_datafmt *fmt, 97 + int n) 98 + { 99 + int i; 100 + for (i = 0; i < n; i++) 101 + if (fmt[i].code == code) 102 + return fmt + i; 103 + 104 + return NULL; 105 + } 106 + 107 + static const struct rj54n1_datafmt rj54n1_colour_fmts[] = { 108 + {V4L2_MBUS_FMT_YUYV8_2X8_LE, V4L2_COLORSPACE_JPEG}, 109 + {V4L2_MBUS_FMT_YVYU8_2X8_LE, V4L2_COLORSPACE_JPEG}, 110 + {V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB}, 111 + {V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB}, 112 + {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_COLORSPACE_SRGB}, 113 + {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, V4L2_COLORSPACE_SRGB}, 114 + {V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_COLORSPACE_SRGB}, 115 + {V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_COLORSPACE_SRGB}, 116 + {V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB}, 101 117 }; 102 118 103 119 struct rj54n1_clock_div { ··· 127 109 128 110 struct rj54n1 { 129 111 struct v4l2_subdev subdev; 112 + const struct rj54n1_datafmt *fmt; 130 113 struct v4l2_rect rect; /* Sensor window */ 131 114 unsigned short width; /* Output window */ 132 115 unsigned short height; 133 116 unsigned short resize; /* Sensor * 1024 / resize = Output */ 134 117 struct rj54n1_clock_div clk_div; 135 - u32 fourcc; 136 118 unsigned short scale; 137 119 u8 bank; 138 120 }; ··· 458 440 return 0; 459 441 } 460 442 443 + static int rj54n1_enum_fmt(struct v4l2_subdev *sd, int index, 444 + enum v4l2_mbus_pixelcode *code) 445 + { 446 + if ((unsigned int)index >= ARRAY_SIZE(rj54n1_colour_fmts)) 447 + return -EINVAL; 448 + 449 + *code = rj54n1_colour_fmts[index].code; 450 + return 0; 451 + } 452 + 461 453 static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable) 462 454 { 463 455 /* TODO: start / stop streaming */ ··· 555 527 return 0; 556 528 } 557 529 558 - static int rj54n1_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 530 + static int rj54n1_g_fmt(struct v4l2_subdev *sd, 531 + struct v4l2_mbus_framefmt *mf) 559 532 { 560 533 struct i2c_client *client = sd->priv; 561 534 struct rj54n1 *rj54n1 = to_rj54n1(client); 562 - struct v4l2_pix_format *pix = &f->fmt.pix; 563 535 564 - pix->pixelformat = rj54n1->fourcc; 565 - pix->field = V4L2_FIELD_NONE; 566 - pix->width = rj54n1->width; 567 - pix->height = rj54n1->height; 536 + mf->code = rj54n1->fmt->code; 537 + mf->colorspace = rj54n1->fmt->colorspace; 538 + mf->field = V4L2_FIELD_NONE; 539 + mf->width = rj54n1->width; 540 + mf->height = rj54n1->height; 568 541 569 542 return 0; 570 543 } ··· 816 787 } 817 788 818 789 /* FIXME: streaming output only up to 800x600 is functional */ 819 - static int rj54n1_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 790 + static int rj54n1_try_fmt(struct v4l2_subdev *sd, 791 + struct v4l2_mbus_framefmt *mf) 820 792 { 821 - struct v4l2_pix_format *pix = &f->fmt.pix; 793 + struct i2c_client *client = sd->priv; 794 + struct rj54n1 *rj54n1 = to_rj54n1(client); 795 + const struct rj54n1_datafmt *fmt; 796 + int align = mf->code == V4L2_MBUS_FMT_SBGGR10_1X10 || 797 + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE || 798 + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE || 799 + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE || 800 + mf->code == V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE; 822 801 823 - pix->field = V4L2_FIELD_NONE; 802 + dev_dbg(&client->dev, "%s: code = %d, width = %u, height = %u\n", 803 + __func__, mf->code, mf->width, mf->height); 824 804 825 - if (pix->width > 800) 826 - pix->width = 800; 827 - if (pix->height > 600) 828 - pix->height = 600; 805 + fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts, 806 + ARRAY_SIZE(rj54n1_colour_fmts)); 807 + if (!fmt) { 808 + fmt = rj54n1->fmt; 809 + mf->code = fmt->code; 810 + } 811 + 812 + mf->field = V4L2_FIELD_NONE; 813 + mf->colorspace = fmt->colorspace; 814 + 815 + v4l_bound_align_image(&mf->width, 112, RJ54N1_MAX_WIDTH, align, 816 + &mf->height, 84, RJ54N1_MAX_HEIGHT, align, 0); 829 817 830 818 return 0; 831 819 } 832 820 833 - static int rj54n1_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 821 + static int rj54n1_s_fmt(struct v4l2_subdev *sd, 822 + struct v4l2_mbus_framefmt *mf) 834 823 { 835 824 struct i2c_client *client = sd->priv; 836 825 struct rj54n1 *rj54n1 = to_rj54n1(client); 837 - struct v4l2_pix_format *pix = &f->fmt.pix; 838 - unsigned int output_w, output_h, 826 + const struct rj54n1_datafmt *fmt; 827 + unsigned int output_w, output_h, max_w, max_h, 839 828 input_w = rj54n1->rect.width, input_h = rj54n1->rect.height; 840 829 int ret; 841 830 ··· 861 814 * The host driver can call us without .try_fmt(), so, we have to take 862 815 * care ourseleves 863 816 */ 864 - ret = rj54n1_try_fmt(sd, f); 817 + ret = rj54n1_try_fmt(sd, mf); 865 818 866 819 /* 867 820 * Verify if the sensor has just been powered on. TODO: replace this ··· 879 832 } 880 833 881 834 /* RA_SEL_UL is only relevant for raw modes, ignored otherwise. */ 882 - switch (pix->pixelformat) { 883 - case V4L2_PIX_FMT_YUYV: 835 + switch (mf->code) { 836 + case V4L2_MBUS_FMT_YUYV8_2X8_LE: 884 837 ret = reg_write(client, RJ54N1_OUT_SEL, 0); 885 838 if (!ret) 886 839 ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); 887 840 break; 888 - case V4L2_PIX_FMT_RGB565: 841 + case V4L2_MBUS_FMT_YVYU8_2X8_LE: 842 + ret = reg_write(client, RJ54N1_OUT_SEL, 0); 843 + if (!ret) 844 + ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); 845 + break; 846 + case V4L2_MBUS_FMT_RGB565_2X8_LE: 889 847 ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); 890 848 if (!ret) 891 849 ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); 850 + break; 851 + case V4L2_MBUS_FMT_RGB565_2X8_BE: 852 + ret = reg_write(client, RJ54N1_OUT_SEL, 0x11); 853 + if (!ret) 854 + ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); 855 + break; 856 + case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE: 857 + ret = reg_write(client, RJ54N1_OUT_SEL, 4); 858 + if (!ret) 859 + ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); 860 + if (!ret) 861 + ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); 862 + break; 863 + case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE: 864 + ret = reg_write(client, RJ54N1_OUT_SEL, 4); 865 + if (!ret) 866 + ret = reg_set(client, RJ54N1_BYTE_SWAP, 8, 8); 867 + if (!ret) 868 + ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); 869 + break; 870 + case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE: 871 + ret = reg_write(client, RJ54N1_OUT_SEL, 4); 872 + if (!ret) 873 + ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); 874 + if (!ret) 875 + ret = reg_write(client, RJ54N1_RA_SEL_UL, 0); 876 + break; 877 + case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE: 878 + ret = reg_write(client, RJ54N1_OUT_SEL, 4); 879 + if (!ret) 880 + ret = reg_set(client, RJ54N1_BYTE_SWAP, 0, 8); 881 + if (!ret) 882 + ret = reg_write(client, RJ54N1_RA_SEL_UL, 8); 883 + break; 884 + case V4L2_MBUS_FMT_SBGGR10_1X10: 885 + ret = reg_write(client, RJ54N1_OUT_SEL, 5); 892 886 break; 893 887 default: 894 888 ret = -EINVAL; 895 889 } 896 890 891 + /* Special case: a raw mode with 10 bits of data per clock tick */ 892 + if (!ret) 893 + ret = reg_set(client, RJ54N1_OCLK_SEL_EN, 894 + (mf->code == V4L2_MBUS_FMT_SBGGR10_1X10) << 1, 2); 895 + 897 896 if (ret < 0) 898 897 return ret; 899 898 900 - /* Supported scales 1:1 - 1:16 */ 901 - if (pix->width < input_w / 16) 902 - pix->width = input_w / 16; 903 - if (pix->height < input_h / 16) 904 - pix->height = input_h / 16; 899 + /* Supported scales 1:1 >= scale > 1:16 */ 900 + max_w = mf->width * (16 * 1024 - 1) / 1024; 901 + if (input_w > max_w) 902 + input_w = max_w; 903 + max_h = mf->height * (16 * 1024 - 1) / 1024; 904 + if (input_h > max_h) 905 + input_h = max_h; 905 906 906 - output_w = pix->width; 907 - output_h = pix->height; 907 + output_w = mf->width; 908 + output_h = mf->height; 908 909 909 910 ret = rj54n1_sensor_scale(sd, &input_w, &input_h, &output_w, &output_h); 910 911 if (ret < 0) 911 912 return ret; 912 913 913 - rj54n1->fourcc = pix->pixelformat; 914 + fmt = rj54n1_find_datafmt(mf->code, rj54n1_colour_fmts, 915 + ARRAY_SIZE(rj54n1_colour_fmts)); 916 + 917 + rj54n1->fmt = fmt; 914 918 rj54n1->resize = ret; 915 919 rj54n1->rect.width = input_w; 916 920 rj54n1->rect.height = input_h; 917 921 rj54n1->width = output_w; 918 922 rj54n1->height = output_h; 919 923 920 - pix->width = output_w; 921 - pix->height = output_h; 922 - pix->field = V4L2_FIELD_NONE; 924 + mf->width = output_w; 925 + mf->height = output_h; 926 + mf->field = V4L2_FIELD_NONE; 927 + mf->colorspace = fmt->colorspace; 923 928 924 - return ret; 929 + return 0; 925 930 } 926 931 927 932 static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, ··· 1153 1054 1154 1055 static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { 1155 1056 .s_stream = rj54n1_s_stream, 1156 - .s_fmt = rj54n1_s_fmt, 1157 - .g_fmt = rj54n1_g_fmt, 1158 - .try_fmt = rj54n1_try_fmt, 1057 + .s_mbus_fmt = rj54n1_s_fmt, 1058 + .g_mbus_fmt = rj54n1_g_fmt, 1059 + .try_mbus_fmt = rj54n1_try_fmt, 1060 + .enum_mbus_fmt = rj54n1_enum_fmt, 1159 1061 .g_crop = rj54n1_g_crop, 1160 1062 .cropcap = rj54n1_cropcap, 1161 1063 }; ··· 1253 1153 rj54n1->rect.height = RJ54N1_MAX_HEIGHT; 1254 1154 rj54n1->width = RJ54N1_MAX_WIDTH; 1255 1155 rj54n1->height = RJ54N1_MAX_HEIGHT; 1256 - rj54n1->fourcc = V4L2_PIX_FMT_YUYV; 1156 + rj54n1->fmt = &rj54n1_colour_fmts[0]; 1257 1157 rj54n1->resize = 1024; 1258 1158 1259 1159 ret = rj54n1_video_probe(icd, client); ··· 1263 1163 kfree(rj54n1); 1264 1164 return ret; 1265 1165 } 1266 - 1267 - icd->formats = rj54n1_colour_formats; 1268 - icd->num_formats = ARRAY_SIZE(rj54n1_colour_formats); 1269 1166 1270 1167 return ret; 1271 1168 }
+234 -169
drivers/media/video/sh_mobile_ceu_camera.c
··· 38 38 #include <media/soc_camera.h> 39 39 #include <media/sh_mobile_ceu.h> 40 40 #include <media/videobuf-dma-contig.h> 41 + #include <media/v4l2-mediabus.h> 42 + #include <media/soc_mediabus.h> 41 43 42 44 /* register offsets for sh7722 / sh7723 */ 43 45 ··· 87 85 /* per video frame buffer */ 88 86 struct sh_mobile_ceu_buffer { 89 87 struct videobuf_buffer vb; /* v4l buffer must be first */ 90 - const struct soc_camera_data_format *fmt; 88 + enum v4l2_mbus_pixelcode code; 91 89 }; 92 90 93 91 struct sh_mobile_ceu_dev { ··· 116 114 struct v4l2_rect ceu_rect; 117 115 unsigned int cam_width; 118 116 unsigned int cam_height; 119 - const struct soc_camera_data_format *extra_fmt; 120 - const struct soc_camera_data_format *camera_fmt; 117 + const struct soc_mbus_pixelfmt *extra_fmt; 118 + enum v4l2_mbus_pixelcode code; 121 119 }; 122 120 123 121 static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev) ··· 199 197 struct soc_camera_device *icd = vq->priv_data; 200 198 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 201 199 struct sh_mobile_ceu_dev *pcdev = ici->priv; 202 - int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; 200 + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 201 + icd->current_fmt->host_fmt); 203 202 204 - *size = PAGE_ALIGN(icd->user_width * icd->user_height * 205 - bytes_per_pixel); 203 + if (bytes_per_line < 0) 204 + return bytes_per_line; 205 + 206 + *size = PAGE_ALIGN(bytes_per_line * icd->user_height); 206 207 207 208 if (0 == *count) 208 209 *count = 2; ··· 289 284 ceu_write(pcdev, CDBYR, phys_addr_bottom); 290 285 } 291 286 292 - switch (icd->current_fmt->fourcc) { 287 + switch (icd->current_fmt->host_fmt->fourcc) { 293 288 case V4L2_PIX_FMT_NV12: 294 289 case V4L2_PIX_FMT_NV21: 295 290 case V4L2_PIX_FMT_NV16: ··· 316 311 { 317 312 struct soc_camera_device *icd = vq->priv_data; 318 313 struct sh_mobile_ceu_buffer *buf; 314 + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 315 + icd->current_fmt->host_fmt); 319 316 int ret; 317 + 318 + if (bytes_per_line < 0) 319 + return bytes_per_line; 320 320 321 321 buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); 322 322 ··· 341 331 342 332 BUG_ON(NULL == icd->current_fmt); 343 333 344 - if (buf->fmt != icd->current_fmt || 334 + if (buf->code != icd->current_fmt->code || 345 335 vb->width != icd->user_width || 346 336 vb->height != icd->user_height || 347 337 vb->field != field) { 348 - buf->fmt = icd->current_fmt; 338 + buf->code = icd->current_fmt->code; 349 339 vb->width = icd->user_width; 350 340 vb->height = icd->user_height; 351 341 vb->field = field; 352 342 vb->state = VIDEOBUF_NEEDS_INIT; 353 343 } 354 344 355 - vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); 345 + vb->size = vb->height * bytes_per_line; 356 346 if (0 != vb->baddr && vb->bsize < vb->size) { 357 347 ret = -EINVAL; 358 348 goto out; ··· 574 564 in_width *= 2; 575 565 left_offset *= 2; 576 566 } 577 - width = cdwdr_width = out_width; 567 + width = out_width; 568 + cdwdr_width = out_width; 578 569 } else { 579 - unsigned int w_factor = (icd->current_fmt->depth + 7) >> 3; 570 + int bytes_per_line = soc_mbus_bytes_per_line(out_width, 571 + icd->current_fmt->host_fmt); 572 + unsigned int w_factor; 580 573 581 - width = out_width * w_factor / 2; 574 + width = out_width; 582 575 583 - if (!pcdev->is_16bit) 584 - w_factor *= 2; 576 + switch (icd->current_fmt->host_fmt->packing) { 577 + case SOC_MBUS_PACKING_2X8_PADHI: 578 + w_factor = 2; 579 + break; 580 + default: 581 + w_factor = 1; 582 + } 585 583 586 - in_width = rect->width * w_factor / 2; 587 - left_offset = left_offset * w_factor / 2; 584 + in_width = rect->width * w_factor; 585 + left_offset = left_offset * w_factor; 588 586 589 - cdwdr_width = width * 2; 587 + if (bytes_per_line < 0) 588 + cdwdr_width = out_width; 589 + else 590 + cdwdr_width = bytes_per_line; 590 591 } 591 592 592 593 height = out_height; ··· 694 673 value = 0x00000010; /* data fetch by default */ 695 674 yuv_lineskip = 0; 696 675 697 - switch (icd->current_fmt->fourcc) { 676 + switch (icd->current_fmt->host_fmt->fourcc) { 698 677 case V4L2_PIX_FMT_NV12: 699 678 case V4L2_PIX_FMT_NV21: 700 679 yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */ 701 680 /* fall-through */ 702 681 case V4L2_PIX_FMT_NV16: 703 682 case V4L2_PIX_FMT_NV61: 704 - switch (cam->camera_fmt->fourcc) { 705 - case V4L2_PIX_FMT_UYVY: 683 + switch (cam->code) { 684 + case V4L2_MBUS_FMT_YUYV8_2X8_BE: 706 685 value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */ 707 686 break; 708 - case V4L2_PIX_FMT_VYUY: 687 + case V4L2_MBUS_FMT_YVYU8_2X8_BE: 709 688 value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */ 710 689 break; 711 - case V4L2_PIX_FMT_YUYV: 690 + case V4L2_MBUS_FMT_YUYV8_2X8_LE: 712 691 value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */ 713 692 break; 714 - case V4L2_PIX_FMT_YVYU: 693 + case V4L2_MBUS_FMT_YVYU8_2X8_LE: 715 694 value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */ 716 695 break; 717 696 default: ··· 719 698 } 720 699 } 721 700 722 - if (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21 || 723 - icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61) 701 + if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV21 || 702 + icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61) 724 703 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */ 725 704 726 705 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; ··· 767 746 return 0; 768 747 } 769 748 770 - static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd) 749 + static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, 750 + unsigned char buswidth) 771 751 { 772 752 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 773 753 struct sh_mobile_ceu_dev *pcdev = ici->priv; ··· 777 755 camera_flags = icd->ops->query_bus_param(icd); 778 756 common_flags = soc_camera_bus_param_compatible(camera_flags, 779 757 make_bus_param(pcdev)); 780 - if (!common_flags) 758 + if (!common_flags || buswidth > 16 || 759 + (buswidth > 8 && !(common_flags & SOCAM_DATAWIDTH_16))) 781 760 return -EINVAL; 782 761 783 762 return 0; 784 763 } 785 764 786 - static const struct soc_camera_data_format sh_mobile_ceu_formats[] = { 765 + static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = { 787 766 { 788 - .name = "NV12", 789 - .depth = 12, 790 - .fourcc = V4L2_PIX_FMT_NV12, 791 - .colorspace = V4L2_COLORSPACE_JPEG, 792 - }, 793 - { 794 - .name = "NV21", 795 - .depth = 12, 796 - .fourcc = V4L2_PIX_FMT_NV21, 797 - .colorspace = V4L2_COLORSPACE_JPEG, 798 - }, 799 - { 800 - .name = "NV16", 801 - .depth = 16, 802 - .fourcc = V4L2_PIX_FMT_NV16, 803 - .colorspace = V4L2_COLORSPACE_JPEG, 804 - }, 805 - { 806 - .name = "NV61", 807 - .depth = 16, 808 - .fourcc = V4L2_PIX_FMT_NV61, 809 - .colorspace = V4L2_COLORSPACE_JPEG, 767 + .fourcc = V4L2_PIX_FMT_NV12, 768 + .name = "NV12", 769 + .bits_per_sample = 12, 770 + .packing = SOC_MBUS_PACKING_NONE, 771 + .order = SOC_MBUS_ORDER_LE, 772 + }, { 773 + .fourcc = V4L2_PIX_FMT_NV21, 774 + .name = "NV21", 775 + .bits_per_sample = 12, 776 + .packing = SOC_MBUS_PACKING_NONE, 777 + .order = SOC_MBUS_ORDER_LE, 778 + }, { 779 + .fourcc = V4L2_PIX_FMT_NV16, 780 + .name = "NV16", 781 + .bits_per_sample = 16, 782 + .packing = SOC_MBUS_PACKING_NONE, 783 + .order = SOC_MBUS_ORDER_LE, 784 + }, { 785 + .fourcc = V4L2_PIX_FMT_NV61, 786 + .name = "NV61", 787 + .bits_per_sample = 16, 788 + .packing = SOC_MBUS_PACKING_NONE, 789 + .order = SOC_MBUS_ORDER_LE, 810 790 }, 811 791 }; 792 + 793 + /* This will be corrected as we get more formats */ 794 + static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt) 795 + { 796 + return fmt->packing == SOC_MBUS_PACKING_NONE || 797 + (fmt->bits_per_sample == 8 && 798 + fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || 799 + (fmt->bits_per_sample > 8 && 800 + fmt->packing == SOC_MBUS_PACKING_EXTEND16); 801 + } 812 802 813 803 static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, 814 804 struct soc_camera_format_xlate *xlate) 815 805 { 806 + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 816 807 struct device *dev = icd->dev.parent; 817 808 int ret, k, n; 818 809 int formats = 0; 819 810 struct sh_mobile_ceu_cam *cam; 811 + enum v4l2_mbus_pixelcode code; 812 + const struct soc_mbus_pixelfmt *fmt; 820 813 821 - ret = sh_mobile_ceu_try_bus_param(icd); 814 + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); 815 + if (ret < 0) 816 + /* No more formats */ 817 + return 0; 818 + 819 + fmt = soc_mbus_get_fmtdesc(code); 820 + if (!fmt) { 821 + dev_err(icd->dev.parent, 822 + "Invalid format code #%d: %d\n", idx, code); 823 + return -EINVAL; 824 + } 825 + 826 + ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); 822 827 if (ret < 0) 823 828 return 0; 824 829 ··· 863 814 if (!idx) 864 815 cam->extra_fmt = NULL; 865 816 866 - switch (icd->formats[idx].fourcc) { 867 - case V4L2_PIX_FMT_UYVY: 868 - case V4L2_PIX_FMT_VYUY: 869 - case V4L2_PIX_FMT_YUYV: 870 - case V4L2_PIX_FMT_YVYU: 817 + switch (code) { 818 + case V4L2_MBUS_FMT_YUYV8_2X8_BE: 819 + case V4L2_MBUS_FMT_YVYU8_2X8_BE: 820 + case V4L2_MBUS_FMT_YUYV8_2X8_LE: 821 + case V4L2_MBUS_FMT_YVYU8_2X8_LE: 871 822 if (cam->extra_fmt) 872 - goto add_single_format; 823 + break; 873 824 874 825 /* 875 826 * Our case is simple so far: for any of the above four camera ··· 880 831 * the host_priv pointer and check whether the format you're 881 832 * going to add now is already there. 882 833 */ 883 - cam->extra_fmt = (void *)sh_mobile_ceu_formats; 834 + cam->extra_fmt = sh_mobile_ceu_formats; 884 835 885 836 n = ARRAY_SIZE(sh_mobile_ceu_formats); 886 837 formats += n; 887 838 for (k = 0; xlate && k < n; k++) { 888 - xlate->host_fmt = &sh_mobile_ceu_formats[k]; 889 - xlate->cam_fmt = icd->formats + idx; 890 - xlate->buswidth = icd->formats[idx].depth; 839 + xlate->host_fmt = &sh_mobile_ceu_formats[k]; 840 + xlate->code = code; 891 841 xlate++; 892 - dev_dbg(dev, "Providing format %s using %s\n", 893 - sh_mobile_ceu_formats[k].name, 894 - icd->formats[idx].name); 842 + dev_dbg(dev, "Providing format %s using code %d\n", 843 + sh_mobile_ceu_formats[k].name, code); 895 844 } 845 + break; 896 846 default: 897 - add_single_format: 898 - /* Generic pass-through */ 899 - formats++; 900 - if (xlate) { 901 - xlate->host_fmt = icd->formats + idx; 902 - xlate->cam_fmt = icd->formats + idx; 903 - xlate->buswidth = icd->formats[idx].depth; 904 - xlate++; 905 - dev_dbg(dev, 906 - "Providing format %s in pass-through mode\n", 907 - icd->formats[idx].name); 908 - } 847 + if (!sh_mobile_ceu_packing_supported(fmt)) 848 + return 0; 849 + } 850 + 851 + /* Generic pass-through */ 852 + formats++; 853 + if (xlate) { 854 + xlate->host_fmt = fmt; 855 + xlate->code = code; 856 + xlate++; 857 + dev_dbg(dev, "Providing format %s in pass-through mode\n", 858 + xlate->host_fmt->name); 909 859 } 910 860 911 861 return formats; ··· 1084 1036 static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect, 1085 1037 unsigned int *scale_h, unsigned int *scale_v) 1086 1038 { 1087 - struct v4l2_format f; 1039 + struct v4l2_mbus_framefmt mf; 1088 1040 int ret; 1089 1041 1090 - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1091 - 1092 - ret = v4l2_subdev_call(sd, video, g_fmt, &f); 1042 + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); 1093 1043 if (ret < 0) 1094 1044 return ret; 1095 1045 1096 - *scale_h = calc_generic_scale(rect->width, f.fmt.pix.width); 1097 - *scale_v = calc_generic_scale(rect->height, f.fmt.pix.height); 1046 + *scale_h = calc_generic_scale(rect->width, mf.width); 1047 + *scale_v = calc_generic_scale(rect->height, mf.height); 1098 1048 1099 1049 return 0; 1100 1050 } ··· 1107 1061 if (!ceu_rect->width) { 1108 1062 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1109 1063 struct device *dev = icd->dev.parent; 1110 - struct v4l2_format f; 1111 - struct v4l2_pix_format *pix = &f.fmt.pix; 1064 + struct v4l2_mbus_framefmt mf; 1112 1065 int ret; 1113 1066 /* First time */ 1114 1067 1115 - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1116 - 1117 - ret = v4l2_subdev_call(sd, video, g_fmt, &f); 1068 + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); 1118 1069 if (ret < 0) 1119 1070 return ret; 1120 1071 1121 - dev_geo(dev, "camera fmt %ux%u\n", pix->width, pix->height); 1072 + dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height); 1122 1073 1123 - if (pix->width > 2560) { 1074 + if (mf.width > 2560) { 1124 1075 ceu_rect->width = 2560; 1125 - ceu_rect->left = (pix->width - 2560) / 2; 1076 + ceu_rect->left = (mf.width - 2560) / 2; 1126 1077 } else { 1127 - ceu_rect->width = pix->width; 1078 + ceu_rect->width = mf.width; 1128 1079 ceu_rect->left = 0; 1129 1080 } 1130 1081 1131 - if (pix->height > 1920) { 1082 + if (mf.height > 1920) { 1132 1083 ceu_rect->height = 1920; 1133 - ceu_rect->top = (pix->height - 1920) / 2; 1084 + ceu_rect->top = (mf.height - 1920) / 2; 1134 1085 } else { 1135 - ceu_rect->height = pix->height; 1086 + ceu_rect->height = mf.height; 1136 1087 ceu_rect->top = 0; 1137 1088 } 1138 1089 ··· 1146 1103 return 0; 1147 1104 } 1148 1105 1149 - static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f, 1150 - bool ceu_can_scale) 1106 + static int client_s_fmt(struct soc_camera_device *icd, 1107 + struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) 1151 1108 { 1152 1109 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1153 1110 struct device *dev = icd->dev.parent; 1154 - struct v4l2_pix_format *pix = &f->fmt.pix; 1155 - unsigned int width = pix->width, height = pix->height, tmp_w, tmp_h; 1111 + unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; 1156 1112 unsigned int max_width, max_height; 1157 1113 struct v4l2_cropcap cap; 1158 1114 int ret; ··· 1165 1123 max_width = min(cap.bounds.width, 2560); 1166 1124 max_height = min(cap.bounds.height, 1920); 1167 1125 1168 - ret = v4l2_subdev_call(sd, video, s_fmt, f); 1126 + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); 1169 1127 if (ret < 0) 1170 1128 return ret; 1171 1129 1172 - dev_geo(dev, "camera scaled to %ux%u\n", pix->width, pix->height); 1130 + dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height); 1173 1131 1174 - if ((width == pix->width && height == pix->height) || !ceu_can_scale) 1132 + if ((width == mf->width && height == mf->height) || !ceu_can_scale) 1175 1133 return 0; 1176 1134 1177 1135 /* Camera set a format, but geometry is not precise, try to improve */ 1178 - tmp_w = pix->width; 1179 - tmp_h = pix->height; 1136 + tmp_w = mf->width; 1137 + tmp_h = mf->height; 1180 1138 1181 1139 /* width <= max_width && height <= max_height - guaranteed by try_fmt */ 1182 1140 while ((width > tmp_w || height > tmp_h) && 1183 1141 tmp_w < max_width && tmp_h < max_height) { 1184 1142 tmp_w = min(2 * tmp_w, max_width); 1185 1143 tmp_h = min(2 * tmp_h, max_height); 1186 - pix->width = tmp_w; 1187 - pix->height = tmp_h; 1188 - ret = v4l2_subdev_call(sd, video, s_fmt, f); 1144 + mf->width = tmp_w; 1145 + mf->height = tmp_h; 1146 + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, mf); 1189 1147 dev_geo(dev, "Camera scaled to %ux%u\n", 1190 - pix->width, pix->height); 1148 + mf->width, mf->height); 1191 1149 if (ret < 0) { 1192 1150 /* This shouldn't happen */ 1193 1151 dev_err(dev, "Client failed to set format: %d\n", ret); ··· 1205 1163 */ 1206 1164 static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect, 1207 1165 struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect, 1208 - struct v4l2_format *f, bool ceu_can_scale) 1166 + struct v4l2_mbus_framefmt *mf, bool ceu_can_scale) 1209 1167 { 1210 1168 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1211 1169 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1212 1170 struct device *dev = icd->dev.parent; 1213 - struct v4l2_format f_tmp = *f; 1214 - struct v4l2_pix_format *pix_tmp = &f_tmp.fmt.pix; 1171 + struct v4l2_mbus_framefmt mf_tmp = *mf; 1215 1172 unsigned int scale_h, scale_v; 1216 1173 int ret; 1217 1174 1218 1175 /* 5. Apply iterative camera S_FMT for camera user window. */ 1219 - ret = client_s_fmt(icd, &f_tmp, ceu_can_scale); 1176 + ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale); 1220 1177 if (ret < 0) 1221 1178 return ret; 1222 1179 1223 1180 dev_geo(dev, "5: camera scaled to %ux%u\n", 1224 - pix_tmp->width, pix_tmp->height); 1181 + mf_tmp.width, mf_tmp.height); 1225 1182 1226 1183 /* 6. Retrieve camera output window (g_fmt) */ 1227 1184 1228 - /* unneeded - it is already in "f_tmp" */ 1185 + /* unneeded - it is already in "mf_tmp" */ 1229 1186 1230 1187 /* 7. Calculate new camera scales. */ 1231 1188 ret = get_camera_scales(sd, rect, &scale_h, &scale_v); ··· 1233 1192 1234 1193 dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v); 1235 1194 1236 - cam->cam_width = pix_tmp->width; 1237 - cam->cam_height = pix_tmp->height; 1238 - f->fmt.pix.width = pix_tmp->width; 1239 - f->fmt.pix.height = pix_tmp->height; 1195 + cam->cam_width = mf_tmp.width; 1196 + cam->cam_height = mf_tmp.height; 1197 + mf->width = mf_tmp.width; 1198 + mf->height = mf_tmp.height; 1199 + mf->colorspace = mf_tmp.colorspace; 1240 1200 1241 1201 /* 1242 1202 * 8. Calculate new CEU crop - apply camera scales to previously ··· 1301 1259 struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect; 1302 1260 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1303 1261 struct device *dev = icd->dev.parent; 1304 - struct v4l2_format f; 1305 - struct v4l2_pix_format *pix = &f.fmt.pix; 1262 + struct v4l2_mbus_framefmt mf; 1306 1263 unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v, 1307 1264 out_width, out_height; 1308 1265 u32 capsr, cflcr; ··· 1350 1309 * 5. Using actual input window and calculated combined scales calculate 1351 1310 * camera target output window. 1352 1311 */ 1353 - pix->width = scale_down(cam_rect->width, scale_comb_h); 1354 - pix->height = scale_down(cam_rect->height, scale_comb_v); 1312 + mf.width = scale_down(cam_rect->width, scale_comb_h); 1313 + mf.height = scale_down(cam_rect->height, scale_comb_v); 1355 1314 1356 - dev_geo(dev, "5: camera target %ux%u\n", pix->width, pix->height); 1315 + dev_geo(dev, "5: camera target %ux%u\n", mf.width, mf.height); 1357 1316 1358 1317 /* 6. - 9. */ 1359 - pix->pixelformat = cam->camera_fmt->fourcc; 1360 - pix->colorspace = cam->camera_fmt->colorspace; 1318 + mf.code = cam->code; 1319 + mf.field = pcdev->is_interlaced ? V4L2_FIELD_INTERLACED : 1320 + V4L2_FIELD_NONE; 1361 1321 1362 1322 capsr = capture_save_reset(pcdev); 1363 1323 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); 1364 1324 1365 1325 /* Make relative to camera rectangle */ 1366 - rect->left -= cam_rect->left; 1367 - rect->top -= cam_rect->top; 1326 + rect->left -= cam_rect->left; 1327 + rect->top -= cam_rect->top; 1368 1328 1369 - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1370 - 1371 - ret = client_scale(icd, cam_rect, rect, ceu_rect, &f, 1329 + ret = client_scale(icd, cam_rect, rect, ceu_rect, &mf, 1372 1330 pcdev->image_mode && !pcdev->is_interlaced); 1373 1331 1374 1332 dev_geo(dev, "6-9: %d\n", ret); ··· 1415 1375 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1416 1376 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1417 1377 struct v4l2_pix_format *pix = &f->fmt.pix; 1418 - struct v4l2_format cam_f = *f; 1419 - struct v4l2_pix_format *cam_pix = &cam_f.fmt.pix; 1378 + struct v4l2_mbus_framefmt mf; 1420 1379 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1421 1380 struct device *dev = icd->dev.parent; 1422 1381 __u32 pixfmt = pix->pixelformat; ··· 1484 1445 * 4. Calculate camera output window by applying combined scales to real 1485 1446 * input window. 1486 1447 */ 1487 - cam_pix->width = scale_down(cam_rect->width, scale_h); 1488 - cam_pix->height = scale_down(cam_rect->height, scale_v); 1489 - cam_pix->pixelformat = xlate->cam_fmt->fourcc; 1448 + mf.width = scale_down(cam_rect->width, scale_h); 1449 + mf.height = scale_down(cam_rect->height, scale_v); 1450 + mf.field = pix->field; 1451 + mf.colorspace = pix->colorspace; 1452 + mf.code = xlate->code; 1490 1453 1491 1454 switch (pixfmt) { 1492 1455 case V4L2_PIX_FMT_NV12: ··· 1501 1460 image_mode = false; 1502 1461 } 1503 1462 1504 - dev_geo(dev, "4: camera output %ux%u\n", 1505 - cam_pix->width, cam_pix->height); 1463 + dev_geo(dev, "4: camera output %ux%u\n", mf.width, mf.height); 1506 1464 1507 1465 /* 5. - 9. */ 1508 - ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &cam_f, 1466 + ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &mf, 1509 1467 image_mode && !is_interlaced); 1510 1468 1511 1469 dev_geo(dev, "5-9: client scale %d\n", ret); ··· 1512 1472 /* Done with the camera. Now see if we can improve the result */ 1513 1473 1514 1474 dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n", 1515 - ret, cam_pix->width, cam_pix->height, pix->width, pix->height); 1475 + ret, mf.width, mf.height, pix->width, pix->height); 1516 1476 if (ret < 0) 1517 1477 return ret; 1478 + 1479 + if (mf.code != xlate->code) 1480 + return -EINVAL; 1518 1481 1519 1482 /* 10. Use CEU scaling to scale to the requested user window. */ 1520 1483 1521 1484 /* We cannot scale up */ 1522 - if (pix->width > cam_pix->width) 1523 - pix->width = cam_pix->width; 1485 + if (pix->width > mf.width) 1486 + pix->width = mf.width; 1524 1487 if (pix->width > ceu_rect.width) 1525 1488 pix->width = ceu_rect.width; 1526 1489 1527 - if (pix->height > cam_pix->height) 1528 - pix->height = cam_pix->height; 1490 + if (pix->height > mf.height) 1491 + pix->height = mf.height; 1529 1492 if (pix->height > ceu_rect.height) 1530 1493 pix->height = ceu_rect.height; 1531 1494 1532 - /* Let's rock: scale pix->{width x height} down to width x height */ 1533 - scale_h = calc_scale(ceu_rect.width, &pix->width); 1534 - scale_v = calc_scale(ceu_rect.height, &pix->height); 1495 + pix->colorspace = mf.colorspace; 1496 + 1497 + if (image_mode) { 1498 + /* Scale pix->{width x height} down to width x height */ 1499 + scale_h = calc_scale(ceu_rect.width, &pix->width); 1500 + scale_v = calc_scale(ceu_rect.height, &pix->height); 1501 + 1502 + pcdev->cflcr = scale_h | (scale_v << 16); 1503 + } else { 1504 + pix->width = ceu_rect.width; 1505 + pix->height = ceu_rect.height; 1506 + scale_h = scale_v = 0; 1507 + pcdev->cflcr = 0; 1508 + } 1535 1509 1536 1510 dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n", 1537 1511 ceu_rect.width, scale_h, pix->width, 1538 1512 ceu_rect.height, scale_v, pix->height); 1539 1513 1540 - pcdev->cflcr = scale_h | (scale_v << 16); 1541 - 1542 - icd->buswidth = xlate->buswidth; 1543 - icd->current_fmt = xlate->host_fmt; 1544 - cam->camera_fmt = xlate->cam_fmt; 1545 - cam->ceu_rect = ceu_rect; 1514 + cam->code = xlate->code; 1515 + cam->ceu_rect = ceu_rect; 1516 + icd->current_fmt = xlate; 1546 1517 1547 1518 pcdev->is_interlaced = is_interlaced; 1548 1519 pcdev->image_mode = image_mode; ··· 1567 1516 const struct soc_camera_format_xlate *xlate; 1568 1517 struct v4l2_pix_format *pix = &f->fmt.pix; 1569 1518 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1519 + struct v4l2_mbus_framefmt mf; 1570 1520 __u32 pixfmt = pix->pixelformat; 1571 1521 int width, height; 1572 1522 int ret; ··· 1586 1534 width = pix->width; 1587 1535 height = pix->height; 1588 1536 1589 - pix->bytesperline = pix->width * 1590 - DIV_ROUND_UP(xlate->host_fmt->depth, 8); 1591 - pix->sizeimage = pix->height * pix->bytesperline; 1592 - 1593 - pix->pixelformat = xlate->cam_fmt->fourcc; 1537 + pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt); 1538 + if (pix->bytesperline < 0) 1539 + return pix->bytesperline; 1540 + pix->sizeimage = height * pix->bytesperline; 1594 1541 1595 1542 /* limit to sensor capabilities */ 1596 - ret = v4l2_subdev_call(sd, video, try_fmt, f); 1597 - pix->pixelformat = pixfmt; 1543 + mf.width = pix->width; 1544 + mf.height = pix->height; 1545 + mf.field = pix->field; 1546 + mf.code = xlate->code; 1547 + mf.colorspace = pix->colorspace; 1548 + 1549 + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); 1598 1550 if (ret < 0) 1599 1551 return ret; 1552 + 1553 + pix->width = mf.width; 1554 + pix->height = mf.height; 1555 + pix->field = mf.field; 1556 + pix->colorspace = mf.colorspace; 1600 1557 1601 1558 switch (pixfmt) { 1602 1559 case V4L2_PIX_FMT_NV12: ··· 1615 1554 /* FIXME: check against rect_max after converting soc-camera */ 1616 1555 /* We can scale precisely, need a bigger image from camera */ 1617 1556 if (pix->width < width || pix->height < height) { 1618 - int tmp_w = pix->width, tmp_h = pix->height; 1619 - pix->width = 2560; 1620 - pix->height = 1920; 1621 - ret = v4l2_subdev_call(sd, video, try_fmt, f); 1557 + /* 1558 + * We presume, the sensor behaves sanely, i.e., if 1559 + * requested a bigger rectangle, it will not return a 1560 + * smaller one. 1561 + */ 1562 + mf.width = 2560; 1563 + mf.height = 1920; 1564 + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); 1622 1565 if (ret < 0) { 1623 1566 /* Shouldn't actually happen... */ 1624 1567 dev_err(icd->dev.parent, 1625 - "FIXME: try_fmt() returned %d\n", ret); 1626 - pix->width = tmp_w; 1627 - pix->height = tmp_h; 1568 + "FIXME: client try_fmt() = %d\n", ret); 1569 + return ret; 1628 1570 } 1629 1571 } 1630 - if (pix->width > width) 1572 + /* We will scale exactly */ 1573 + if (mf.width > width) 1631 1574 pix->width = width; 1632 - if (pix->height > height) 1575 + if (mf.height > height) 1633 1576 pix->height = height; 1634 1577 } 1635 1578 ··· 1728 1663 1729 1664 switch (ctrl->id) { 1730 1665 case V4L2_CID_SHARPNESS: 1731 - switch (icd->current_fmt->fourcc) { 1666 + switch (icd->current_fmt->host_fmt->fourcc) { 1732 1667 case V4L2_PIX_FMT_NV12: 1733 1668 case V4L2_PIX_FMT_NV21: 1734 1669 case V4L2_PIX_FMT_NV16:
+43 -35
drivers/media/video/soc_camera.c
··· 31 31 #include <media/v4l2-ioctl.h> 32 32 #include <media/v4l2-dev.h> 33 33 #include <media/videobuf-core.h> 34 + #include <media/soc_mediabus.h> 34 35 35 36 /* Default to VGA resolution */ 36 37 #define DEFAULT_WIDTH 640 ··· 40 39 static LIST_HEAD(hosts); 41 40 static LIST_HEAD(devices); 42 41 static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ 43 - 44 - const struct soc_camera_data_format *soc_camera_format_by_fourcc( 45 - struct soc_camera_device *icd, unsigned int fourcc) 46 - { 47 - unsigned int i; 48 - 49 - for (i = 0; i < icd->num_formats; i++) 50 - if (icd->formats[i].fourcc == fourcc) 51 - return icd->formats + i; 52 - return NULL; 53 - } 54 - EXPORT_SYMBOL(soc_camera_format_by_fourcc); 55 42 56 43 const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( 57 44 struct soc_camera_device *icd, unsigned int fourcc) ··· 196 207 /* Always entered with .video_lock held */ 197 208 static int soc_camera_init_user_formats(struct soc_camera_device *icd) 198 209 { 210 + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 199 211 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 200 - int i, fmts = 0, ret; 212 + int i, fmts = 0, raw_fmts = 0, ret; 213 + enum v4l2_mbus_pixelcode code; 214 + 215 + while (!v4l2_subdev_call(sd, video, enum_mbus_fmt, raw_fmts, &code)) 216 + raw_fmts++; 201 217 202 218 if (!ici->ops->get_formats) 203 219 /* 204 220 * Fallback mode - the host will have to serve all 205 221 * sensor-provided formats one-to-one to the user 206 222 */ 207 - fmts = icd->num_formats; 223 + fmts = raw_fmts; 208 224 else 209 225 /* 210 226 * First pass - only count formats this host-sensor 211 227 * configuration can provide 212 228 */ 213 - for (i = 0; i < icd->num_formats; i++) { 229 + for (i = 0; i < raw_fmts; i++) { 214 230 ret = ici->ops->get_formats(icd, i, NULL); 215 231 if (ret < 0) 216 232 return ret; ··· 236 242 237 243 /* Second pass - actually fill data formats */ 238 244 fmts = 0; 239 - for (i = 0; i < icd->num_formats; i++) 245 + for (i = 0; i < raw_fmts; i++) 240 246 if (!ici->ops->get_formats) { 241 - icd->user_formats[i].host_fmt = icd->formats + i; 242 - icd->user_formats[i].cam_fmt = icd->formats + i; 243 - icd->user_formats[i].buswidth = icd->formats[i].depth; 247 + v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code); 248 + icd->user_formats[i].host_fmt = 249 + soc_mbus_get_fmtdesc(code); 250 + icd->user_formats[i].code = code; 244 251 } else { 245 252 ret = ici->ops->get_formats(icd, i, 246 253 &icd->user_formats[fmts]); ··· 250 255 fmts += ret; 251 256 } 252 257 253 - icd->current_fmt = icd->user_formats[0].host_fmt; 258 + icd->current_fmt = &icd->user_formats[0]; 254 259 255 260 return 0; 256 261 ··· 276 281 #define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ 277 282 ((x) >> 24) & 0xff 278 283 279 - /* Called with .vb_lock held */ 284 + /* Called with .vb_lock held, or from the first open(2), see comment there */ 280 285 static int soc_camera_set_fmt(struct soc_camera_file *icf, 281 286 struct v4l2_format *f) 282 287 { ··· 297 302 if (ret < 0) { 298 303 return ret; 299 304 } else if (!icd->current_fmt || 300 - icd->current_fmt->fourcc != pix->pixelformat) { 305 + icd->current_fmt->host_fmt->fourcc != pix->pixelformat) { 301 306 dev_err(&icd->dev, 302 307 "Host driver hasn't set up current format correctly!\n"); 303 308 return -EINVAL; ··· 305 310 306 311 icd->user_width = pix->width; 307 312 icd->user_height = pix->height; 313 + icd->colorspace = pix->colorspace; 308 314 icf->vb_vidq.field = 309 315 icd->field = pix->field; 310 316 ··· 365 369 .width = icd->user_width, 366 370 .height = icd->user_height, 367 371 .field = icd->field, 368 - .pixelformat = icd->current_fmt->fourcc, 369 - .colorspace = icd->current_fmt->colorspace, 372 + .colorspace = icd->colorspace, 373 + .pixelformat = 374 + icd->current_fmt->host_fmt->fourcc, 370 375 }, 371 376 }; 372 377 ··· 387 390 goto eiciadd; 388 391 } 389 392 390 - /* Try to configure with default parameters */ 393 + /* 394 + * Try to configure with default parameters. Notice: this is the 395 + * very first open, so, we cannot race against other calls, 396 + * apart from someone else calling open() simultaneously, but 397 + * .video_lock is protecting us against it. 398 + */ 391 399 ret = soc_camera_set_fmt(icf, &f); 392 400 if (ret < 0) 393 401 goto esfmt; ··· 536 534 { 537 535 struct soc_camera_file *icf = file->private_data; 538 536 struct soc_camera_device *icd = icf->icd; 539 - const struct soc_camera_data_format *format; 537 + const struct soc_mbus_pixelfmt *format; 540 538 541 539 WARN_ON(priv != file->private_data); 542 540 ··· 545 543 546 544 format = icd->user_formats[f->index].host_fmt; 547 545 548 - strlcpy(f->description, format->name, sizeof(f->description)); 546 + if (format->name) 547 + strlcpy(f->description, format->name, sizeof(f->description)); 549 548 f->pixelformat = format->fourcc; 550 549 return 0; 551 550 } ··· 563 560 pix->width = icd->user_width; 564 561 pix->height = icd->user_height; 565 562 pix->field = icf->vb_vidq.field; 566 - pix->pixelformat = icd->current_fmt->fourcc; 567 - pix->bytesperline = pix->width * 568 - DIV_ROUND_UP(icd->current_fmt->depth, 8); 563 + pix->pixelformat = icd->current_fmt->host_fmt->fourcc; 564 + pix->bytesperline = soc_mbus_bytes_per_line(pix->width, 565 + icd->current_fmt->host_fmt); 566 + pix->colorspace = icd->colorspace; 567 + if (pix->bytesperline < 0) 568 + return pix->bytesperline; 569 569 pix->sizeimage = pix->height * pix->bytesperline; 570 570 dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", 571 - icd->current_fmt->fourcc); 571 + icd->current_fmt->host_fmt->fourcc); 572 572 return 0; 573 573 } 574 574 ··· 900 894 struct soc_camera_link *icl = to_soc_camera_link(icd); 901 895 struct device *control = NULL; 902 896 struct v4l2_subdev *sd; 903 - struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE}; 897 + struct v4l2_mbus_framefmt mf; 904 898 int ret; 905 899 906 900 dev_info(dev, "Probing %s\n", dev_name(dev)); ··· 971 965 972 966 /* Try to improve our guess of a reasonable window format */ 973 967 sd = soc_camera_to_subdev(icd); 974 - if (!v4l2_subdev_call(sd, video, g_fmt, &f)) { 975 - icd->user_width = f.fmt.pix.width; 976 - icd->user_height = f.fmt.pix.height; 968 + if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { 969 + icd->user_width = mf.width; 970 + icd->user_height = mf.height; 971 + icd->colorspace = mf.colorspace; 972 + icd->field = mf.field; 977 973 } 978 974 979 975 /* Do we have to sysfs_remove_link() before device_unregister()? */
+21 -24
drivers/media/video/soc_camera_platform.c
··· 22 22 23 23 struct soc_camera_platform_priv { 24 24 struct v4l2_subdev subdev; 25 - struct soc_camera_data_format format; 26 25 }; 27 26 28 27 static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev) ··· 57 58 } 58 59 59 60 static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd, 60 - struct v4l2_format *f) 61 + struct v4l2_mbus_framefmt *mf) 61 62 { 62 63 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); 63 - struct v4l2_pix_format *pix = &f->fmt.pix; 64 64 65 - pix->width = p->format.width; 66 - pix->height = p->format.height; 65 + mf->width = p->format.width; 66 + mf->height = p->format.height; 67 + mf->code = p->format.code; 68 + mf->colorspace = p->format.colorspace; 69 + 67 70 return 0; 68 - } 69 - 70 - static void soc_camera_platform_video_probe(struct soc_camera_device *icd, 71 - struct platform_device *pdev) 72 - { 73 - struct soc_camera_platform_priv *priv = get_priv(pdev); 74 - struct soc_camera_platform_info *p = pdev->dev.platform_data; 75 - 76 - priv->format.name = p->format_name; 77 - priv->format.depth = p->format_depth; 78 - priv->format.fourcc = p->format.pixelformat; 79 - priv->format.colorspace = p->format.colorspace; 80 - 81 - icd->formats = &priv->format; 82 - icd->num_formats = 1; 83 71 } 84 72 85 73 static struct v4l2_subdev_core_ops platform_subdev_core_ops; 86 74 75 + static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, int index, 76 + enum v4l2_mbus_pixelcode *code) 77 + { 78 + struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); 79 + 80 + if (index) 81 + return -EINVAL; 82 + 83 + *code = p->format.code; 84 + return 0; 85 + } 86 + 87 87 static struct v4l2_subdev_video_ops platform_subdev_video_ops = { 88 88 .s_stream = soc_camera_platform_s_stream, 89 - .try_fmt = soc_camera_platform_try_fmt, 89 + .try_mbus_fmt = soc_camera_platform_try_fmt, 90 + .enum_mbus_fmt = soc_camera_platform_enum_fmt, 90 91 }; 91 92 92 93 static struct v4l2_subdev_ops platform_subdev_ops = { ··· 127 128 /* Set the control device reference */ 128 129 dev_set_drvdata(&icd->dev, &pdev->dev); 129 130 130 - icd->ops = &soc_camera_platform_ops; 131 + icd->ops = &soc_camera_platform_ops; 131 132 132 133 ici = to_soc_camera_host(icd->dev.parent); 133 - 134 - soc_camera_platform_video_probe(icd, pdev); 135 134 136 135 v4l2_subdev_init(&priv->subdev, &platform_subdev_ops); 137 136 v4l2_set_subdevdata(&priv->subdev, p);
+46 -45
drivers/media/video/tw9910.c
··· 251 251 ENDMARKER, 252 252 }; 253 253 254 - static const struct soc_camera_data_format tw9910_color_fmt[] = { 255 - { 256 - .name = "VYUY", 257 - .fourcc = V4L2_PIX_FMT_VYUY, 258 - .depth = 16, 259 - .colorspace = V4L2_COLORSPACE_SMPTE170M, 260 - } 261 - }; 262 - 263 254 static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = { 264 255 { 265 256 .name = "NTSC SQ", ··· 805 814 return 0; 806 815 } 807 816 808 - static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 817 + static int tw9910_g_fmt(struct v4l2_subdev *sd, 818 + struct v4l2_mbus_framefmt *mf) 809 819 { 810 820 struct i2c_client *client = sd->priv; 811 821 struct tw9910_priv *priv = to_tw9910(client); 812 - struct v4l2_pix_format *pix = &f->fmt.pix; 813 822 814 823 if (!priv->scale) { 815 824 int ret; ··· 826 835 return ret; 827 836 } 828 837 829 - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 830 - 831 - pix->width = priv->scale->width; 832 - pix->height = priv->scale->height; 833 - pix->pixelformat = V4L2_PIX_FMT_VYUY; 834 - pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 835 - pix->field = V4L2_FIELD_INTERLACED; 838 + mf->width = priv->scale->width; 839 + mf->height = priv->scale->height; 840 + mf->code = V4L2_MBUS_FMT_YVYU8_2X8_BE; 841 + mf->colorspace = V4L2_COLORSPACE_JPEG; 842 + mf->field = V4L2_FIELD_INTERLACED; 836 843 837 844 return 0; 838 845 } 839 846 840 - static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 847 + static int tw9910_s_fmt(struct v4l2_subdev *sd, 848 + struct v4l2_mbus_framefmt *mf) 841 849 { 842 850 struct i2c_client *client = sd->priv; 843 851 struct tw9910_priv *priv = to_tw9910(client); 844 - struct v4l2_pix_format *pix = &f->fmt.pix; 845 852 /* See tw9910_s_crop() - no proper cropping support */ 846 853 struct v4l2_crop a = { 847 854 .c = { 848 855 .left = 0, 849 856 .top = 0, 850 - .width = pix->width, 851 - .height = pix->height, 857 + .width = mf->width, 858 + .height = mf->height, 852 859 }, 853 860 }; 854 - int i, ret; 861 + int ret; 862 + 863 + WARN_ON(mf->field != V4L2_FIELD_ANY && 864 + mf->field != V4L2_FIELD_INTERLACED); 855 865 856 866 /* 857 867 * check color format 858 868 */ 859 - for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++) 860 - if (pix->pixelformat == tw9910_color_fmt[i].fourcc) 861 - break; 862 - 863 - if (i == ARRAY_SIZE(tw9910_color_fmt)) 869 + if (mf->code != V4L2_MBUS_FMT_YVYU8_2X8_BE) 864 870 return -EINVAL; 871 + 872 + mf->colorspace = V4L2_COLORSPACE_JPEG; 865 873 866 874 ret = tw9910_s_crop(sd, &a); 867 875 if (!ret) { 868 - pix->width = priv->scale->width; 869 - pix->height = priv->scale->height; 876 + mf->width = priv->scale->width; 877 + mf->height = priv->scale->height; 870 878 } 871 879 return ret; 872 880 } 873 881 874 - static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) 882 + static int tw9910_try_fmt(struct v4l2_subdev *sd, 883 + struct v4l2_mbus_framefmt *mf) 875 884 { 876 885 struct i2c_client *client = sd->priv; 877 886 struct soc_camera_device *icd = client->dev.platform_data; 878 - struct v4l2_pix_format *pix = &f->fmt.pix; 879 887 const struct tw9910_scale_ctrl *scale; 880 888 881 - if (V4L2_FIELD_ANY == pix->field) { 882 - pix->field = V4L2_FIELD_INTERLACED; 883 - } else if (V4L2_FIELD_INTERLACED != pix->field) { 884 - dev_err(&client->dev, "Field type invalid.\n"); 889 + if (V4L2_FIELD_ANY == mf->field) { 890 + mf->field = V4L2_FIELD_INTERLACED; 891 + } else if (V4L2_FIELD_INTERLACED != mf->field) { 892 + dev_err(&client->dev, "Field type %d invalid.\n", mf->field); 885 893 return -EINVAL; 886 894 } 895 + 896 + mf->code = V4L2_MBUS_FMT_YVYU8_2X8_BE; 897 + mf->colorspace = V4L2_COLORSPACE_JPEG; 887 898 888 899 /* 889 900 * select suitable norm 890 901 */ 891 - scale = tw9910_select_norm(icd, pix->width, pix->height); 902 + scale = tw9910_select_norm(icd, mf->width, mf->height); 892 903 if (!scale) 893 904 return -EINVAL; 894 905 895 - pix->width = scale->width; 896 - pix->height = scale->height; 906 + mf->width = scale->width; 907 + mf->height = scale->height; 897 908 898 909 return 0; 899 910 } ··· 922 929 dev_err(&client->dev, "bus width error\n"); 923 930 return -ENODEV; 924 931 } 925 - 926 - icd->formats = tw9910_color_fmt; 927 - icd->num_formats = ARRAY_SIZE(tw9910_color_fmt); 928 932 929 933 /* 930 934 * check and show Product ID ··· 963 973 #endif 964 974 }; 965 975 976 + static int tw9910_enum_fmt(struct v4l2_subdev *sd, int index, 977 + enum v4l2_mbus_pixelcode *code) 978 + { 979 + if (index) 980 + return -EINVAL; 981 + 982 + *code = V4L2_MBUS_FMT_YVYU8_2X8_BE; 983 + return 0; 984 + } 985 + 966 986 static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { 967 987 .s_stream = tw9910_s_stream, 968 - .g_fmt = tw9910_g_fmt, 969 - .s_fmt = tw9910_s_fmt, 970 - .try_fmt = tw9910_try_fmt, 988 + .g_mbus_fmt = tw9910_g_fmt, 989 + .s_mbus_fmt = tw9910_s_fmt, 990 + .try_mbus_fmt = tw9910_try_fmt, 971 991 .cropcap = tw9910_cropcap, 972 992 .g_crop = tw9910_g_crop, 973 993 .s_crop = tw9910_s_crop, 994 + .enum_mbus_fmt = tw9910_enum_fmt, 974 995 }; 975 996 976 997 static struct v4l2_subdev_ops tw9910_subdev_ops = {
+6 -19
include/media/soc_camera.h
··· 24 24 struct device *pdev; /* Platform device */ 25 25 s32 user_width; 26 26 s32 user_height; 27 + enum v4l2_colorspace colorspace; 27 28 unsigned char iface; /* Host number */ 28 29 unsigned char devnum; /* Device number per host */ 29 - unsigned char buswidth; /* See comment in .c */ 30 30 struct soc_camera_sense *sense; /* See comment in struct definition */ 31 31 struct soc_camera_ops *ops; 32 32 struct video_device *vdev; 33 - const struct soc_camera_data_format *current_fmt; 34 - const struct soc_camera_data_format *formats; 35 - int num_formats; 33 + const struct soc_camera_format_xlate *current_fmt; 36 34 struct soc_camera_format_xlate *user_formats; 37 35 int num_user_formats; 38 36 enum v4l2_field field; /* Preserve field over close() */ ··· 159 161 int soc_camera_host_register(struct soc_camera_host *ici); 160 162 void soc_camera_host_unregister(struct soc_camera_host *ici); 161 163 162 - const struct soc_camera_data_format *soc_camera_format_by_fourcc( 163 - struct soc_camera_device *icd, unsigned int fourcc); 164 164 const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( 165 165 struct soc_camera_device *icd, unsigned int fourcc); 166 166 167 - struct soc_camera_data_format { 168 - const char *name; 169 - unsigned int depth; 170 - __u32 fourcc; 171 - enum v4l2_colorspace colorspace; 172 - }; 173 - 174 167 /** 175 168 * struct soc_camera_format_xlate - match between host and sensor formats 176 - * @cam_fmt: sensor format provided by the sensor 177 - * @host_fmt: host format after host translation from cam_fmt 178 - * @buswidth: bus width for this format 169 + * @code: code of a sensor provided format 170 + * @host_fmt: host format after host translation from code 179 171 * 180 172 * Host and sensor translation structure. Used in table of host and sensor 181 173 * formats matchings in soc_camera_device. A host can override the generic list ··· 173 185 * format setup. 174 186 */ 175 187 struct soc_camera_format_xlate { 176 - const struct soc_camera_data_format *cam_fmt; 177 - const struct soc_camera_data_format *host_fmt; 178 - unsigned char buswidth; 188 + enum v4l2_mbus_pixelcode code; 189 + const struct soc_mbus_pixelfmt *host_fmt; 179 190 }; 180 191 181 192 struct soc_camera_ops {
+1 -1
include/media/soc_camera_platform.h
··· 19 19 struct soc_camera_platform_info { 20 20 const char *format_name; 21 21 unsigned long format_depth; 22 - struct v4l2_pix_format format; 22 + struct v4l2_mbus_framefmt format; 23 23 unsigned long bus_param; 24 24 struct device *dev; 25 25 int (*set_capture)(struct soc_camera_platform_info *info, int enable);