diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-12-11 09:46:49 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-16 06:27:29 -0500 |
commit | 760697beca338599a65484389c7abbe54aedb664 (patch) | |
tree | 515735429d2240629a6f048ab1a7fefaf5299e46 /drivers/media/video/ov772x.c | |
parent | 9a74251d8bee7a25fee89a0be3ccea73e01c1a05 (diff) |
V4L/DVB (13659): soc-camera: convert to the new mediabus API
Convert soc-camera core and all soc-camera drivers to the new mediabus
API. This also takes soc-camera client drivers one step closer to also be
usable with generic v4l2-subdev host drivers.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ov772x.c')
-rw-r--r-- | drivers/media/video/ov772x.c | 229 |
1 files changed, 114 insertions, 115 deletions
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index dcb690cb5ae7..3a45e945a528 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <media/v4l2-chip-ident.h> | 24 | #include <media/v4l2-chip-ident.h> |
25 | #include <media/v4l2-subdev.h> | 25 | #include <media/v4l2-subdev.h> |
26 | #include <media/soc_camera.h> | 26 | #include <media/soc_camera.h> |
27 | #include <media/soc_mediabus.h> | ||
27 | #include <media/ov772x.h> | 28 | #include <media/ov772x.h> |
28 | 29 | ||
29 | /* | 30 | /* |
@@ -382,7 +383,8 @@ struct regval_list { | |||
382 | }; | 383 | }; |
383 | 384 | ||
384 | struct ov772x_color_format { | 385 | struct ov772x_color_format { |
385 | const struct soc_camera_data_format *format; | 386 | enum v4l2_mbus_pixelcode code; |
387 | enum v4l2_colorspace colorspace; | ||
386 | u8 dsp3; | 388 | u8 dsp3; |
387 | u8 com3; | 389 | u8 com3; |
388 | u8 com7; | 390 | u8 com7; |
@@ -399,7 +401,7 @@ struct ov772x_win_size { | |||
399 | struct ov772x_priv { | 401 | struct ov772x_priv { |
400 | struct v4l2_subdev subdev; | 402 | struct v4l2_subdev subdev; |
401 | struct ov772x_camera_info *info; | 403 | struct ov772x_camera_info *info; |
402 | const struct ov772x_color_format *fmt; | 404 | const struct ov772x_color_format *cfmt; |
403 | const struct ov772x_win_size *win; | 405 | const struct ov772x_win_size *win; |
404 | int model; | 406 | int model; |
405 | unsigned short flag_vflip:1; | 407 | unsigned short flag_vflip:1; |
@@ -434,93 +436,57 @@ static const struct regval_list ov772x_vga_regs[] = { | |||
434 | }; | 436 | }; |
435 | 437 | ||
436 | /* | 438 | /* |
437 | * supported format list | 439 | * supported color format list |
438 | */ | ||
439 | |||
440 | #define SETFOURCC(type) .name = (#type), .fourcc = (V4L2_PIX_FMT_ ## type) | ||
441 | static const struct soc_camera_data_format ov772x_fmt_lists[] = { | ||
442 | { | ||
443 | SETFOURCC(YUYV), | ||
444 | .depth = 16, | ||
445 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
446 | }, | ||
447 | { | ||
448 | SETFOURCC(YVYU), | ||
449 | .depth = 16, | ||
450 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
451 | }, | ||
452 | { | ||
453 | SETFOURCC(UYVY), | ||
454 | .depth = 16, | ||
455 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
456 | }, | ||
457 | { | ||
458 | SETFOURCC(RGB555), | ||
459 | .depth = 16, | ||
460 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
461 | }, | ||
462 | { | ||
463 | SETFOURCC(RGB555X), | ||
464 | .depth = 16, | ||
465 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
466 | }, | ||
467 | { | ||
468 | SETFOURCC(RGB565), | ||
469 | .depth = 16, | ||
470 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
471 | }, | ||
472 | { | ||
473 | SETFOURCC(RGB565X), | ||
474 | .depth = 16, | ||
475 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
476 | }, | ||
477 | }; | ||
478 | |||
479 | /* | ||
480 | * color format list | ||
481 | */ | 440 | */ |
482 | static const struct ov772x_color_format ov772x_cfmts[] = { | 441 | static const struct ov772x_color_format ov772x_cfmts[] = { |
483 | { | 442 | { |
484 | .format = &ov772x_fmt_lists[0], | 443 | .code = V4L2_MBUS_FMT_YUYV8_2X8_LE, |
485 | .dsp3 = 0x0, | 444 | .colorspace = V4L2_COLORSPACE_JPEG, |
486 | .com3 = SWAP_YUV, | 445 | .dsp3 = 0x0, |
487 | .com7 = OFMT_YUV, | 446 | .com3 = SWAP_YUV, |
447 | .com7 = OFMT_YUV, | ||
488 | }, | 448 | }, |
489 | { | 449 | { |
490 | .format = &ov772x_fmt_lists[1], | 450 | .code = V4L2_MBUS_FMT_YVYU8_2X8_LE, |
491 | .dsp3 = UV_ON, | 451 | .colorspace = V4L2_COLORSPACE_JPEG, |
492 | .com3 = SWAP_YUV, | 452 | .dsp3 = UV_ON, |
493 | .com7 = OFMT_YUV, | 453 | .com3 = SWAP_YUV, |
454 | .com7 = OFMT_YUV, | ||
494 | }, | 455 | }, |
495 | { | 456 | { |
496 | .format = &ov772x_fmt_lists[2], | 457 | .code = V4L2_MBUS_FMT_YUYV8_2X8_BE, |
497 | .dsp3 = 0x0, | 458 | .colorspace = V4L2_COLORSPACE_JPEG, |
498 | .com3 = 0x0, | 459 | .dsp3 = 0x0, |
499 | .com7 = OFMT_YUV, | 460 | .com3 = 0x0, |
461 | .com7 = OFMT_YUV, | ||
500 | }, | 462 | }, |
501 | { | 463 | { |
502 | .format = &ov772x_fmt_lists[3], | 464 | .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, |
503 | .dsp3 = 0x0, | 465 | .colorspace = V4L2_COLORSPACE_SRGB, |
504 | .com3 = SWAP_RGB, | 466 | .dsp3 = 0x0, |
505 | .com7 = FMT_RGB555 | OFMT_RGB, | 467 | .com3 = SWAP_RGB, |
468 | .com7 = FMT_RGB555 | OFMT_RGB, | ||
506 | }, | 469 | }, |
507 | { | 470 | { |
508 | .format = &ov772x_fmt_lists[4], | 471 | .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, |
509 | .dsp3 = 0x0, | 472 | .colorspace = V4L2_COLORSPACE_SRGB, |
510 | .com3 = 0x0, | 473 | .dsp3 = 0x0, |
511 | .com7 = FMT_RGB555 | OFMT_RGB, | 474 | .com3 = 0x0, |
475 | .com7 = FMT_RGB555 | OFMT_RGB, | ||
512 | }, | 476 | }, |
513 | { | 477 | { |
514 | .format = &ov772x_fmt_lists[5], | 478 | .code = V4L2_MBUS_FMT_RGB565_2X8_LE, |
515 | .dsp3 = 0x0, | 479 | .colorspace = V4L2_COLORSPACE_SRGB, |
516 | .com3 = SWAP_RGB, | 480 | .dsp3 = 0x0, |
517 | .com7 = FMT_RGB565 | OFMT_RGB, | 481 | .com3 = SWAP_RGB, |
482 | .com7 = FMT_RGB565 | OFMT_RGB, | ||
518 | }, | 483 | }, |
519 | { | 484 | { |
520 | .format = &ov772x_fmt_lists[6], | 485 | .code = V4L2_MBUS_FMT_RGB565_2X8_BE, |
521 | .dsp3 = 0x0, | 486 | .colorspace = V4L2_COLORSPACE_SRGB, |
522 | .com3 = 0x0, | 487 | .dsp3 = 0x0, |
523 | .com7 = FMT_RGB565 | OFMT_RGB, | 488 | .com3 = 0x0, |
489 | .com7 = FMT_RGB565 | OFMT_RGB, | ||
524 | }, | 490 | }, |
525 | }; | 491 | }; |
526 | 492 | ||
@@ -642,15 +608,15 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) | |||
642 | return 0; | 608 | return 0; |
643 | } | 609 | } |
644 | 610 | ||
645 | if (!priv->win || !priv->fmt) { | 611 | if (!priv->win || !priv->cfmt) { |
646 | dev_err(&client->dev, "norm or win select error\n"); | 612 | dev_err(&client->dev, "norm or win select error\n"); |
647 | return -EPERM; | 613 | return -EPERM; |
648 | } | 614 | } |
649 | 615 | ||
650 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); | 616 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); |
651 | 617 | ||
652 | dev_dbg(&client->dev, "format %s, win %s\n", | 618 | dev_dbg(&client->dev, "format %d, win %s\n", |
653 | priv->fmt->format->name, priv->win->name); | 619 | priv->cfmt->code, priv->win->name); |
654 | 620 | ||
655 | return 0; | 621 | return 0; |
656 | } | 622 | } |
@@ -806,8 +772,8 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) | |||
806 | return win; | 772 | return win; |
807 | } | 773 | } |
808 | 774 | ||
809 | static int ov772x_set_params(struct i2c_client *client, | 775 | static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, |
810 | u32 *width, u32 *height, u32 pixfmt) | 776 | enum v4l2_mbus_pixelcode code) |
811 | { | 777 | { |
812 | struct ov772x_priv *priv = to_ov772x(client); | 778 | struct ov772x_priv *priv = to_ov772x(client); |
813 | int ret = -EINVAL; | 779 | int ret = -EINVAL; |
@@ -817,14 +783,14 @@ static int ov772x_set_params(struct i2c_client *client, | |||
817 | /* | 783 | /* |
818 | * select format | 784 | * select format |
819 | */ | 785 | */ |
820 | priv->fmt = NULL; | 786 | priv->cfmt = NULL; |
821 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { | 787 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { |
822 | if (pixfmt == ov772x_cfmts[i].format->fourcc) { | 788 | if (code == ov772x_cfmts[i].code) { |
823 | priv->fmt = ov772x_cfmts + i; | 789 | priv->cfmt = ov772x_cfmts + i; |
824 | break; | 790 | break; |
825 | } | 791 | } |
826 | } | 792 | } |
827 | if (!priv->fmt) | 793 | if (!priv->cfmt) |
828 | goto ov772x_set_fmt_error; | 794 | goto ov772x_set_fmt_error; |
829 | 795 | ||
830 | /* | 796 | /* |
@@ -894,7 +860,7 @@ static int ov772x_set_params(struct i2c_client *client, | |||
894 | /* | 860 | /* |
895 | * set DSP_CTRL3 | 861 | * set DSP_CTRL3 |
896 | */ | 862 | */ |
897 | val = priv->fmt->dsp3; | 863 | val = priv->cfmt->dsp3; |
898 | if (val) { | 864 | if (val) { |
899 | ret = ov772x_mask_set(client, | 865 | ret = ov772x_mask_set(client, |
900 | DSP_CTRL3, UV_MASK, val); | 866 | DSP_CTRL3, UV_MASK, val); |
@@ -905,7 +871,7 @@ static int ov772x_set_params(struct i2c_client *client, | |||
905 | /* | 871 | /* |
906 | * set COM3 | 872 | * set COM3 |
907 | */ | 873 | */ |
908 | val = priv->fmt->com3; | 874 | val = priv->cfmt->com3; |
909 | if (priv->info->flags & OV772X_FLAG_VFLIP) | 875 | if (priv->info->flags & OV772X_FLAG_VFLIP) |
910 | val |= VFLIP_IMG; | 876 | val |= VFLIP_IMG; |
911 | if (priv->info->flags & OV772X_FLAG_HFLIP) | 877 | if (priv->info->flags & OV772X_FLAG_HFLIP) |
@@ -923,9 +889,9 @@ static int ov772x_set_params(struct i2c_client *client, | |||
923 | /* | 889 | /* |
924 | * set COM7 | 890 | * set COM7 |
925 | */ | 891 | */ |
926 | val = priv->win->com7_bit | priv->fmt->com7; | 892 | val = priv->win->com7_bit | priv->cfmt->com7; |
927 | ret = ov772x_mask_set(client, | 893 | ret = ov772x_mask_set(client, |
928 | COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), | 894 | COM7, SLCT_MASK | FMT_MASK | OFMT_MASK, |
929 | val); | 895 | val); |
930 | if (ret < 0) | 896 | if (ret < 0) |
931 | goto ov772x_set_fmt_error; | 897 | goto ov772x_set_fmt_error; |
@@ -951,7 +917,7 @@ ov772x_set_fmt_error: | |||
951 | 917 | ||
952 | ov772x_reset(client); | 918 | ov772x_reset(client); |
953 | priv->win = NULL; | 919 | priv->win = NULL; |
954 | priv->fmt = NULL; | 920 | priv->cfmt = NULL; |
955 | 921 | ||
956 | return ret; | 922 | return ret; |
957 | } | 923 | } |
@@ -981,54 +947,79 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | |||
981 | return 0; | 947 | return 0; |
982 | } | 948 | } |
983 | 949 | ||
984 | static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 950 | static int ov772x_g_fmt(struct v4l2_subdev *sd, |
951 | struct v4l2_mbus_framefmt *mf) | ||
985 | { | 952 | { |
986 | struct i2c_client *client = sd->priv; | 953 | struct i2c_client *client = sd->priv; |
987 | struct ov772x_priv *priv = to_ov772x(client); | 954 | struct ov772x_priv *priv = to_ov772x(client); |
988 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
989 | 955 | ||
990 | if (!priv->win || !priv->fmt) { | 956 | if (!priv->win || !priv->cfmt) { |
991 | u32 width = VGA_WIDTH, height = VGA_HEIGHT; | 957 | u32 width = VGA_WIDTH, height = VGA_HEIGHT; |
992 | int ret = ov772x_set_params(client, &width, &height, | 958 | int ret = ov772x_set_params(client, &width, &height, |
993 | V4L2_PIX_FMT_YUYV); | 959 | V4L2_MBUS_FMT_YUYV8_2X8_LE); |
994 | if (ret < 0) | 960 | if (ret < 0) |
995 | return ret; | 961 | return ret; |
996 | } | 962 | } |
997 | 963 | ||
998 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 964 | mf->width = priv->win->width; |
999 | 965 | mf->height = priv->win->height; | |
1000 | pix->width = priv->win->width; | 966 | mf->code = priv->cfmt->code; |
1001 | pix->height = priv->win->height; | 967 | mf->colorspace = priv->cfmt->colorspace; |
1002 | pix->pixelformat = priv->fmt->format->fourcc; | 968 | mf->field = V4L2_FIELD_NONE; |
1003 | pix->colorspace = priv->fmt->format->colorspace; | ||
1004 | pix->field = V4L2_FIELD_NONE; | ||
1005 | 969 | ||
1006 | return 0; | 970 | return 0; |
1007 | } | 971 | } |
1008 | 972 | ||
1009 | static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) | 973 | static int ov772x_s_fmt(struct v4l2_subdev *sd, |
974 | struct v4l2_mbus_framefmt *mf) | ||
1010 | { | 975 | { |
1011 | struct i2c_client *client = sd->priv; | 976 | struct i2c_client *client = sd->priv; |
1012 | struct v4l2_pix_format *pix = &f->fmt.pix; | 977 | struct ov772x_priv *priv = to_ov772x(client); |
978 | int ret = ov772x_set_params(client, &mf->width, &mf->height, | ||
979 | mf->code); | ||
980 | |||
981 | if (!ret) | ||
982 | mf->colorspace = priv->cfmt->colorspace; | ||
1013 | 983 | ||
1014 | return ov772x_set_params(client, &pix->width, &pix->height, | 984 | return ret; |
1015 | pix->pixelformat); | ||
1016 | } | 985 | } |
1017 | 986 | ||
1018 | static int ov772x_try_fmt(struct v4l2_subdev *sd, | 987 | static int ov772x_try_fmt(struct v4l2_subdev *sd, |
1019 | struct v4l2_format *f) | 988 | struct v4l2_mbus_framefmt *mf) |
1020 | { | 989 | { |
1021 | struct v4l2_pix_format *pix = &f->fmt.pix; | 990 | struct i2c_client *client = sd->priv; |
991 | struct ov772x_priv *priv = to_ov772x(client); | ||
1022 | const struct ov772x_win_size *win; | 992 | const struct ov772x_win_size *win; |
993 | int i; | ||
1023 | 994 | ||
1024 | /* | 995 | /* |
1025 | * select suitable win | 996 | * select suitable win |
1026 | */ | 997 | */ |
1027 | win = ov772x_select_win(pix->width, pix->height); | 998 | win = ov772x_select_win(mf->width, mf->height); |
999 | |||
1000 | mf->width = win->width; | ||
1001 | mf->height = win->height; | ||
1002 | mf->field = V4L2_FIELD_NONE; | ||
1028 | 1003 | ||
1029 | pix->width = win->width; | 1004 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) |
1030 | pix->height = win->height; | 1005 | if (mf->code == ov772x_cfmts[i].code) |
1031 | pix->field = V4L2_FIELD_NONE; | 1006 | break; |
1007 | |||
1008 | if (i == ARRAY_SIZE(ov772x_cfmts)) { | ||
1009 | /* Unsupported format requested. Propose either */ | ||
1010 | if (priv->cfmt) { | ||
1011 | /* the current one or */ | ||
1012 | mf->colorspace = priv->cfmt->colorspace; | ||
1013 | mf->code = priv->cfmt->code; | ||
1014 | } else { | ||
1015 | /* the default one */ | ||
1016 | mf->colorspace = ov772x_cfmts[0].colorspace; | ||
1017 | mf->code = ov772x_cfmts[0].code; | ||
1018 | } | ||
1019 | } else { | ||
1020 | /* Also return the colorspace */ | ||
1021 | mf->colorspace = ov772x_cfmts[i].colorspace; | ||
1022 | } | ||
1032 | 1023 | ||
1033 | return 0; | 1024 | return 0; |
1034 | } | 1025 | } |
@@ -1057,9 +1048,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd, | |||
1057 | return -ENODEV; | 1048 | return -ENODEV; |
1058 | } | 1049 | } |
1059 | 1050 | ||
1060 | icd->formats = ov772x_fmt_lists; | ||
1061 | icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists); | ||
1062 | |||
1063 | /* | 1051 | /* |
1064 | * check and show product ID and manufacturer ID | 1052 | * check and show product ID and manufacturer ID |
1065 | */ | 1053 | */ |
@@ -1109,13 +1097,24 @@ static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { | |||
1109 | #endif | 1097 | #endif |
1110 | }; | 1098 | }; |
1111 | 1099 | ||
1100 | static int ov772x_enum_fmt(struct v4l2_subdev *sd, int index, | ||
1101 | enum v4l2_mbus_pixelcode *code) | ||
1102 | { | ||
1103 | if ((unsigned int)index >= ARRAY_SIZE(ov772x_cfmts)) | ||
1104 | return -EINVAL; | ||
1105 | |||
1106 | *code = ov772x_cfmts[index].code; | ||
1107 | return 0; | ||
1108 | } | ||
1109 | |||
1112 | static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { | 1110 | static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { |
1113 | .s_stream = ov772x_s_stream, | 1111 | .s_stream = ov772x_s_stream, |
1114 | .g_fmt = ov772x_g_fmt, | 1112 | .g_mbus_fmt = ov772x_g_fmt, |
1115 | .s_fmt = ov772x_s_fmt, | 1113 | .s_mbus_fmt = ov772x_s_fmt, |
1116 | .try_fmt = ov772x_try_fmt, | 1114 | .try_mbus_fmt = ov772x_try_fmt, |
1117 | .cropcap = ov772x_cropcap, | 1115 | .cropcap = ov772x_cropcap, |
1118 | .g_crop = ov772x_g_crop, | 1116 | .g_crop = ov772x_g_crop, |
1117 | .enum_mbus_fmt = ov772x_enum_fmt, | ||
1119 | }; | 1118 | }; |
1120 | 1119 | ||
1121 | static struct v4l2_subdev_ops ov772x_subdev_ops = { | 1120 | static struct v4l2_subdev_ops ov772x_subdev_ops = { |