diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-07-18 09:58:20 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 16:09:44 -0400 |
commit | 69c80dc90146463bf9a6820e5c0432fad8e0d0c1 (patch) | |
tree | baac41a919d4ea798ee4da07e782087ca2a875ae | |
parent | ca9ef7fa21d6cf26e22c9ff1e00a5abeb2106555 (diff) |
[media] ov772x: Don't fail in s_fmt if the requested format isn't supported
Select a default format instead.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/i2c/soc_camera/ov772x.c | 83 |
1 files changed, 43 insertions, 40 deletions
diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c index 3f6e4bf209de..c7bb988e295e 100644 --- a/drivers/media/i2c/soc_camera/ov772x.c +++ b/drivers/media/i2c/soc_camera/ov772x.c | |||
@@ -581,11 +581,6 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) | |||
581 | return 0; | 581 | return 0; |
582 | } | 582 | } |
583 | 583 | ||
584 | if (!priv->win || !priv->cfmt) { | ||
585 | dev_err(&client->dev, "norm or win select error\n"); | ||
586 | return -EPERM; | ||
587 | } | ||
588 | |||
589 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); | 584 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); |
590 | 585 | ||
591 | dev_dbg(&client->dev, "format %d, win %s\n", | 586 | dev_dbg(&client->dev, "format %d, win %s\n", |
@@ -710,31 +705,33 @@ static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) | |||
710 | return win; | 705 | return win; |
711 | } | 706 | } |
712 | 707 | ||
713 | static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, | 708 | static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf, |
714 | enum v4l2_mbus_pixelcode code) | 709 | const struct ov772x_color_format **cfmt, |
710 | const struct ov772x_win_size **win) | ||
715 | { | 711 | { |
716 | struct ov772x_priv *priv = to_ov772x(client); | 712 | unsigned int i; |
717 | int ret = -EINVAL; | 713 | |
718 | u8 val; | 714 | /* Select a format. */ |
719 | int i; | 715 | *cfmt = &ov772x_cfmts[0]; |
720 | 716 | ||
721 | /* | ||
722 | * select format | ||
723 | */ | ||
724 | priv->cfmt = NULL; | ||
725 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { | 717 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { |
726 | if (code == ov772x_cfmts[i].code) { | 718 | if (mf->code == ov772x_cfmts[i].code) { |
727 | priv->cfmt = ov772x_cfmts + i; | 719 | *cfmt = &ov772x_cfmts[i]; |
728 | break; | 720 | break; |
729 | } | 721 | } |
730 | } | 722 | } |
731 | if (!priv->cfmt) | ||
732 | goto ov772x_set_fmt_error; | ||
733 | 723 | ||
734 | /* | 724 | /* Select a window size. */ |
735 | * select win | 725 | *win = ov772x_select_win(mf->width, mf->height); |
736 | */ | 726 | } |
737 | priv->win = ov772x_select_win(*width, *height); | 727 | |
728 | static int ov772x_set_params(struct ov772x_priv *priv, | ||
729 | const struct ov772x_color_format *cfmt, | ||
730 | const struct ov772x_win_size *win) | ||
731 | { | ||
732 | struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); | ||
733 | int ret; | ||
734 | u8 val; | ||
738 | 735 | ||
739 | /* | 736 | /* |
740 | * reset hardware | 737 | * reset hardware |
@@ -791,14 +788,14 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, | |||
791 | /* | 788 | /* |
792 | * set size format | 789 | * set size format |
793 | */ | 790 | */ |
794 | ret = ov772x_write_array(client, priv->win->regs); | 791 | ret = ov772x_write_array(client, win->regs); |
795 | if (ret < 0) | 792 | if (ret < 0) |
796 | goto ov772x_set_fmt_error; | 793 | goto ov772x_set_fmt_error; |
797 | 794 | ||
798 | /* | 795 | /* |
799 | * set DSP_CTRL3 | 796 | * set DSP_CTRL3 |
800 | */ | 797 | */ |
801 | val = priv->cfmt->dsp3; | 798 | val = cfmt->dsp3; |
802 | if (val) { | 799 | if (val) { |
803 | ret = ov772x_mask_set(client, | 800 | ret = ov772x_mask_set(client, |
804 | DSP_CTRL3, UV_MASK, val); | 801 | DSP_CTRL3, UV_MASK, val); |
@@ -809,7 +806,7 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, | |||
809 | /* | 806 | /* |
810 | * set COM3 | 807 | * set COM3 |
811 | */ | 808 | */ |
812 | val = priv->cfmt->com3; | 809 | val = cfmt->com3; |
813 | if (priv->info->flags & OV772X_FLAG_VFLIP) | 810 | if (priv->info->flags & OV772X_FLAG_VFLIP) |
814 | val |= VFLIP_IMG; | 811 | val |= VFLIP_IMG; |
815 | if (priv->info->flags & OV772X_FLAG_HFLIP) | 812 | if (priv->info->flags & OV772X_FLAG_HFLIP) |
@@ -827,7 +824,7 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, | |||
827 | /* | 824 | /* |
828 | * set COM7 | 825 | * set COM7 |
829 | */ | 826 | */ |
830 | val = priv->win->com7_bit | priv->cfmt->com7; | 827 | val = win->com7_bit | cfmt->com7; |
831 | ret = ov772x_mask_set(client, | 828 | ret = ov772x_mask_set(client, |
832 | COM7, SLCT_MASK | FMT_MASK | OFMT_MASK, | 829 | COM7, SLCT_MASK | FMT_MASK | OFMT_MASK, |
833 | val); | 830 | val); |
@@ -846,16 +843,11 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height, | |||
846 | goto ov772x_set_fmt_error; | 843 | goto ov772x_set_fmt_error; |
847 | } | 844 | } |
848 | 845 | ||
849 | *width = priv->win->width; | ||
850 | *height = priv->win->height; | ||
851 | |||
852 | return ret; | 846 | return ret; |
853 | 847 | ||
854 | ov772x_set_fmt_error: | 848 | ov772x_set_fmt_error: |
855 | 849 | ||
856 | ov772x_reset(client); | 850 | ov772x_reset(client); |
857 | priv->win = NULL; | ||
858 | priv->cfmt = NULL; | ||
859 | 851 | ||
860 | return ret; | 852 | return ret; |
861 | } | 853 | } |
@@ -899,18 +891,29 @@ static int ov772x_g_fmt(struct v4l2_subdev *sd, | |||
899 | return 0; | 891 | return 0; |
900 | } | 892 | } |
901 | 893 | ||
902 | static int ov772x_s_fmt(struct v4l2_subdev *sd, | 894 | static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) |
903 | struct v4l2_mbus_framefmt *mf) | ||
904 | { | 895 | { |
905 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
906 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); | 896 | struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev); |
907 | int ret = ov772x_set_params(client, &mf->width, &mf->height, | 897 | const struct ov772x_color_format *cfmt; |
908 | mf->code); | 898 | const struct ov772x_win_size *win; |
899 | int ret; | ||
909 | 900 | ||
910 | if (!ret) | 901 | ov772x_select_params(mf, &cfmt, &win); |
911 | mf->colorspace = priv->cfmt->colorspace; | ||
912 | 902 | ||
913 | return ret; | 903 | ret = ov772x_set_params(priv, cfmt, win); |
904 | if (ret < 0) | ||
905 | return ret; | ||
906 | |||
907 | priv->win = win; | ||
908 | priv->cfmt = cfmt; | ||
909 | |||
910 | mf->code = cfmt->code; | ||
911 | mf->width = win->width; | ||
912 | mf->height = win->height; | ||
913 | mf->field = V4L2_FIELD_NONE; | ||
914 | mf->colorspace = cfmt->colorspace; | ||
915 | |||
916 | return 0; | ||
914 | } | 917 | } |
915 | 918 | ||
916 | static int ov772x_try_fmt(struct v4l2_subdev *sd, | 919 | static int ov772x_try_fmt(struct v4l2_subdev *sd, |