--- zzzz-none-000/linux-3.10.107/drivers/media/i2c/soc_camera/ov772x.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/media/i2c/soc_camera/ov772x.c 2021-02-04 17:41:59.000000000 +0000 @@ -26,9 +26,10 @@ #include #include +#include #include -#include #include +#include /* * register offset @@ -360,10 +361,6 @@ #define SCAL0_ACTRL 0x08 /* Auto scaling factor control */ #define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */ -#define VGA_WIDTH 640 -#define VGA_HEIGHT 480 -#define QVGA_WIDTH 320 -#define QVGA_HEIGHT 240 #define OV772X_MAX_WIDTH VGA_WIDTH #define OV772X_MAX_HEIGHT VGA_HEIGHT @@ -379,7 +376,7 @@ */ struct ov772x_color_format { - enum v4l2_mbus_pixelcode code; + u32 code; enum v4l2_colorspace colorspace; u8 dsp3; u8 dsp4; @@ -396,10 +393,10 @@ struct ov772x_priv { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; + struct v4l2_clk *clk; struct ov772x_camera_info *info; const struct ov772x_color_format *cfmt; const struct ov772x_win_size *win; - int model; unsigned short flag_vflip:1; unsigned short flag_hflip:1; /* band_filter = COM8[5] ? 256 - BDBASE : 0 */ @@ -411,7 +408,7 @@ */ static const struct ov772x_color_format ov772x_cfmts[] = { { - .code = V4L2_MBUS_FMT_YUYV8_2X8, + .code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -419,7 +416,7 @@ .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_YVYU8_2X8, + .code = MEDIA_BUS_FMT_YVYU8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = UV_ON, .dsp4 = DSP_OFMT_YUV, @@ -427,7 +424,7 @@ .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_2X8, .colorspace = V4L2_COLORSPACE_JPEG, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -435,7 +432,7 @@ .com7 = OFMT_YUV, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -443,7 +440,7 @@ .com7 = FMT_RGB555 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, + .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -451,7 +448,7 @@ .com7 = FMT_RGB555 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_LE, + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -459,7 +456,7 @@ .com7 = FMT_RGB565 | OFMT_RGB, }, { - .code = V4L2_MBUS_FMT_RGB565_2X8_BE, + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_YUV, @@ -471,7 +468,7 @@ * regardless of the COM7 value. We can thus only support 10-bit * Bayer until someone figures it out. */ - .code = V4L2_MBUS_FMT_SBGGR10_1X10, + .code = MEDIA_BUS_FMT_SBGGR10_1X10, .colorspace = V4L2_COLORSPACE_SRGB, .dsp3 = 0x0, .dsp4 = DSP_OFMT_RAW10, @@ -620,17 +617,6 @@ return -EINVAL; } -static int ov772x_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct ov772x_priv *priv = to_ov772x(sd); - - id->ident = priv->model; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov772x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -668,8 +654,9 @@ { struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov772x_priv *priv = to_ov772x(sd); - return soc_camera_set_power(&client->dev, ssdd, on); + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) @@ -889,11 +876,16 @@ return 0; } -static int ov772x_g_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov772x_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; struct ov772x_priv *priv = to_ov772x(sd); + if (format->pad) + return -EINVAL; + mf->width = priv->win->rect.width; mf->height = priv->win->rect.height; mf->code = priv->cfmt->code; @@ -928,12 +920,17 @@ return 0; } -static int ov772x_try_fmt(struct v4l2_subdev *sd, - struct v4l2_mbus_framefmt *mf) +static int ov772x_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) { + struct v4l2_mbus_framefmt *mf = &format->format; const struct ov772x_color_format *cfmt; const struct ov772x_win_size *win; + if (format->pad) + return -EINVAL; + ov772x_select_params(mf, &cfmt, &win); mf->code = cfmt->code; @@ -942,6 +939,9 @@ mf->field = V4L2_FIELD_NONE; mf->colorspace = cfmt->colorspace; + if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) + return ov772x_s_fmt(sd, mf); + cfg->try_fmt = *mf; return 0; } @@ -965,11 +965,9 @@ switch (VERSION(pid, ver)) { case OV7720: devname = "ov7720"; - priv->model = V4L2_IDENT_OV7720; break; case OV7725: devname = "ov7725"; - priv->model = V4L2_IDENT_OV7725; break; default: dev_err(&client->dev, @@ -997,7 +995,6 @@ }; static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { - .g_chip_ident = ov772x_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov772x_g_register, .s_register = ov772x_s_register, @@ -1005,13 +1002,14 @@ .s_power = ov772x_s_power, }; -static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index, - enum v4l2_mbus_pixelcode *code) +static int ov772x_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) { - if (index >= ARRAY_SIZE(ov772x_cfmts)) + if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts)) return -EINVAL; - *code = ov772x_cfmts[index].code; + code->code = ov772x_cfmts[code->index].code; return 0; } @@ -1032,18 +1030,21 @@ static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { .s_stream = ov772x_s_stream, - .g_mbus_fmt = ov772x_g_fmt, - .s_mbus_fmt = ov772x_s_fmt, - .try_mbus_fmt = ov772x_try_fmt, .cropcap = ov772x_cropcap, .g_crop = ov772x_g_crop, - .enum_mbus_fmt = ov772x_enum_fmt, .g_mbus_config = ov772x_g_mbus_config, }; +static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { + .enum_mbus_code = ov772x_enum_mbus_code, + .get_fmt = ov772x_get_fmt, + .set_fmt = ov772x_set_fmt, +}; + static struct v4l2_subdev_ops ov772x_subdev_ops = { .core = &ov772x_subdev_core_ops, .video = &ov772x_subdev_video_ops, + .pad = &ov772x_subdev_pad_ops, }; /* @@ -1088,13 +1089,22 @@ if (priv->hdl.error) return priv->hdl.error; + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto eclkget; + } + ret = ov772x_video_probe(priv); if (ret < 0) { + v4l2_clk_put(priv->clk); +eclkget: v4l2_ctrl_handler_free(&priv->hdl); } else { priv->cfmt = &ov772x_cfmts[0]; priv->win = &ov772x_win_sizes[0]; } + return ret; } @@ -1102,6 +1112,7 @@ { struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client)); + v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl); return 0;