This is an automatic generated email to let you know that the following patch 
were queued:

Subject: media: i2c: imx219: Group functions by purpose
Author:  Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Date:    Sun Sep 24 18:33:03 2023 +0300

Move functions around to group them by purpose, in order to improve
readability. No functional change is intended.

Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Reviewed-by: Dave Stevenson <dave.steven...@raspberrypi.com>
Signed-off-by: Sakari Ailus <sakari.ai...@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>

 drivers/media/i2c/imx219.c | 591 +++++++++++++++++++++++----------------------
 1 file changed, 303 insertions(+), 288 deletions(-)

---

diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index 76551e6db22a..dfc5ce574227 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -385,6 +385,10 @@ static u32 imx219_get_format_code(struct imx219 *imx219, 
u32 code)
        return imx219_mbus_formats[i];
 }
 
+/* 
-----------------------------------------------------------------------------
+ * Controls
+ */
+
 static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct imx219 *imx219 =
@@ -476,130 +480,135 @@ static const struct v4l2_ctrl_ops imx219_ctrl_ops = {
        .s_ctrl = imx219_set_ctrl,
 };
 
-static void imx219_update_pad_format(struct imx219 *imx219,
-                                    const struct imx219_mode *mode,
-                                    struct v4l2_mbus_framefmt *fmt, u32 code)
+static unsigned long imx219_get_pixel_rate(struct imx219 *imx219)
 {
-       /* Bayer order varies with flips */
-       fmt->code = imx219_get_format_code(imx219, code);
-       fmt->width = mode->width;
-       fmt->height = mode->height;
-       fmt->field = V4L2_FIELD_NONE;
-       fmt->colorspace = V4L2_COLORSPACE_RAW;
-       fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
-       fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
-       fmt->xfer_func = V4L2_XFER_FUNC_NONE;
+       return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : 
IMX219_PIXEL_RATE_4LANE;
 }
 
-static int imx219_init_cfg(struct v4l2_subdev *sd,
-                          struct v4l2_subdev_state *state)
+/* Initialize control handlers */
+static int imx219_init_controls(struct imx219 *imx219)
 {
-       struct imx219 *imx219 = to_imx219(sd);
-       struct v4l2_mbus_framefmt *format;
-       struct v4l2_rect *crop;
-
-       /* Initialize the format. */
-       format = v4l2_subdev_get_pad_format(sd, state, 0);
-       imx219_update_pad_format(imx219, &supported_modes[0], format,
-                                MEDIA_BUS_FMT_SRGGB10_1X10);
-
-       /* Initialize the crop rectangle. */
-       crop = v4l2_subdev_get_pad_crop(sd, state, 0);
-       crop->top = IMX219_PIXEL_ARRAY_TOP;
-       crop->left = IMX219_PIXEL_ARRAY_LEFT;
-       crop->width = IMX219_PIXEL_ARRAY_WIDTH;
-       crop->height = IMX219_PIXEL_ARRAY_HEIGHT;
+       struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
+       const struct imx219_mode *mode = &supported_modes[0];
+       struct v4l2_ctrl_handler *ctrl_hdlr;
+       struct v4l2_fwnode_device_properties props;
+       int exposure_max, exposure_def, hblank;
+       int i, ret;
 
-       return 0;
-}
+       ctrl_hdlr = &imx219->ctrl_handler;
+       ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
+       if (ret)
+               return ret;
 
-static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
-                                struct v4l2_subdev_state *sd_state,
-                                struct v4l2_subdev_mbus_code_enum *code)
-{
-       struct imx219 *imx219 = to_imx219(sd);
+       /* By default, PIXEL_RATE is read only */
+       imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
+                                              V4L2_CID_PIXEL_RATE,
+                                              imx219_get_pixel_rate(imx219),
+                                              imx219_get_pixel_rate(imx219), 1,
+                                              imx219_get_pixel_rate(imx219));
 
-       if (code->index >= (ARRAY_SIZE(imx219_mbus_formats) / 4))
-               return -EINVAL;
+       imx219->link_freq =
+               v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops,
+                                      V4L2_CID_LINK_FREQ,
+                                      ARRAY_SIZE(imx219_link_freq_menu) - 1, 0,
+                                      (imx219->lanes == 2) ? 
imx219_link_freq_menu :
+                                      imx219_link_freq_4lane_menu);
+       if (imx219->link_freq)
+               imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
-       code->code = imx219_get_format_code(imx219, 
imx219_mbus_formats[code->index * 4]);
+       /* Initial vblank/hblank/exposure parameters based on current mode */
+       imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
+                                          V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
+                                          IMX219_VTS_MAX - mode->height, 1,
+                                          mode->vts_def - mode->height);
+       hblank = IMX219_PPL_DEFAULT - mode->width;
+       imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
+                                          V4L2_CID_HBLANK, hblank, hblank,
+                                          1, hblank);
+       if (imx219->hblank)
+               imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+       exposure_max = mode->vts_def - 4;
+       exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
+               exposure_max : IMX219_EXPOSURE_DEFAULT;
+       imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
+                                            V4L2_CID_EXPOSURE,
+                                            IMX219_EXPOSURE_MIN, exposure_max,
+                                            IMX219_EXPOSURE_STEP,
+                                            exposure_def);
 
-       return 0;
-}
+       v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+                         IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX,
+                         IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT);
 
-static int imx219_enum_frame_size(struct v4l2_subdev *sd,
-                                 struct v4l2_subdev_state *sd_state,
-                                 struct v4l2_subdev_frame_size_enum *fse)
-{
-       struct imx219 *imx219 = to_imx219(sd);
-       u32 code;
+       v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+                         IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX,
+                         IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT);
 
-       if (fse->index >= ARRAY_SIZE(supported_modes))
-               return -EINVAL;
+       imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
+                                         V4L2_CID_HFLIP, 0, 1, 1, 0);
+       if (imx219->hflip)
+               imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
 
-       code = imx219_get_format_code(imx219, fse->code);
-       if (fse->code != code)
-               return -EINVAL;
+       imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
+                                         V4L2_CID_VFLIP, 0, 1, 1, 0);
+       if (imx219->vflip)
+               imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
 
-       fse->min_width = supported_modes[fse->index].width;
-       fse->max_width = fse->min_width;
-       fse->min_height = supported_modes[fse->index].height;
-       fse->max_height = fse->min_height;
+       v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops,
+                                    V4L2_CID_TEST_PATTERN,
+                                    ARRAY_SIZE(imx219_test_pattern_menu) - 1,
+                                    0, 0, imx219_test_pattern_menu);
+       for (i = 0; i < 4; i++) {
+               /*
+                * The assumption is that
+                * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
+                * V4L2_CID_TEST_PATTERN_BLUE   == V4L2_CID_TEST_PATTERN_RED + 2
+                * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
+                */
+               v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
+                                 V4L2_CID_TEST_PATTERN_RED + i,
+                                 IMX219_TESTP_COLOUR_MIN,
+                                 IMX219_TESTP_COLOUR_MAX,
+                                 IMX219_TESTP_COLOUR_STEP,
+                                 IMX219_TESTP_COLOUR_MAX);
+               /* The "Solid color" pattern is white by default */
+       }
 
-       return 0;
-}
+       if (ctrl_hdlr->error) {
+               ret = ctrl_hdlr->error;
+               dev_err(&client->dev, "%s control init failed (%d)\n",
+                       __func__, ret);
+               goto error;
+       }
 
-static int imx219_set_pad_format(struct v4l2_subdev *sd,
-                                struct v4l2_subdev_state *sd_state,
-                                struct v4l2_subdev_format *fmt)
-{
-       struct imx219 *imx219 = to_imx219(sd);
-       const struct imx219_mode *mode;
-       int exposure_max, exposure_def, hblank;
-       struct v4l2_mbus_framefmt *format;
-       struct v4l2_rect *crop;
+       ret = v4l2_fwnode_device_parse(&client->dev, &props);
+       if (ret)
+               goto error;
 
-       mode = v4l2_find_nearest_size(supported_modes,
-                                     ARRAY_SIZE(supported_modes),
-                                     width, height,
-                                     fmt->format.width, fmt->format.height);
+       ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops,
+                                             &props);
+       if (ret)
+               goto error;
 
-       imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code);
+       imx219->sd.ctrl_handler = ctrl_hdlr;
 
-       format = v4l2_subdev_get_pad_format(sd, sd_state, 0);
-       crop = v4l2_subdev_get_pad_crop(sd, sd_state, 0);
+       return 0;
 
-       *format = fmt->format;
-       *crop = mode->crop;
+error:
+       v4l2_ctrl_handler_free(ctrl_hdlr);
 
-       if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-               /* Update limits and set FPS to default */
-               __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
-                                        IMX219_VTS_MAX - mode->height, 1,
-                                        mode->vts_def - mode->height);
-               __v4l2_ctrl_s_ctrl(imx219->vblank,
-                                  mode->vts_def - mode->height);
-               /* Update max exposure while meeting expected vblanking */
-               exposure_max = mode->vts_def - 4;
-               exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
-                       exposure_max : IMX219_EXPOSURE_DEFAULT;
-               __v4l2_ctrl_modify_range(imx219->exposure,
-                                        imx219->exposure->minimum,
-                                        exposure_max, imx219->exposure->step,
-                                        exposure_def);
-               /*
-                * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
-                * depends on mode->width only, and is not changeble in any
-                * way other than changing the mode.
-                */
-               hblank = IMX219_PPL_DEFAULT - mode->width;
-               __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1,
-                                        hblank);
-       }
+       return ret;
+}
 
-       return 0;
+static void imx219_free_controls(struct imx219 *imx219)
+{
+       v4l2_ctrl_handler_free(imx219->sd.ctrl_handler);
 }
 
+/* 
-----------------------------------------------------------------------------
+ * Subdev operations
+ */
+
 static int imx219_set_framefmt(struct imx219 *imx219,
                               struct v4l2_subdev_state *state)
 {
@@ -664,37 +673,6 @@ static int imx219_set_framefmt(struct imx219 *imx219,
        return ret;
 }
 
-static int imx219_get_selection(struct v4l2_subdev *sd,
-                               struct v4l2_subdev_state *sd_state,
-                               struct v4l2_subdev_selection *sel)
-{
-       switch (sel->target) {
-       case V4L2_SEL_TGT_CROP: {
-               sel->r = *v4l2_subdev_get_pad_crop(sd, sd_state, 0);
-               return 0;
-       }
-
-       case V4L2_SEL_TGT_NATIVE_SIZE:
-               sel->r.top = 0;
-               sel->r.left = 0;
-               sel->r.width = IMX219_NATIVE_WIDTH;
-               sel->r.height = IMX219_NATIVE_HEIGHT;
-
-               return 0;
-
-       case V4L2_SEL_TGT_CROP_DEFAULT:
-       case V4L2_SEL_TGT_CROP_BOUNDS:
-               sel->r.top = IMX219_PIXEL_ARRAY_TOP;
-               sel->r.left = IMX219_PIXEL_ARRAY_LEFT;
-               sel->r.width = IMX219_PIXEL_ARRAY_WIDTH;
-               sel->r.height = IMX219_PIXEL_ARRAY_HEIGHT;
-
-               return 0;
-       }
-
-       return -EINVAL;
-}
-
 static int imx219_configure_lanes(struct imx219 *imx219)
 {
        return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE,
@@ -799,86 +777,159 @@ unlock:
        return ret;
 }
 
-/* Power/clock management functions */
-static int imx219_power_on(struct device *dev)
+static void imx219_update_pad_format(struct imx219 *imx219,
+                                    const struct imx219_mode *mode,
+                                    struct v4l2_mbus_framefmt *fmt, u32 code)
 {
-       struct v4l2_subdev *sd = dev_get_drvdata(dev);
-       struct imx219 *imx219 = to_imx219(sd);
-       int ret;
+       /* Bayer order varies with flips */
+       fmt->code = imx219_get_format_code(imx219, code);
+       fmt->width = mode->width;
+       fmt->height = mode->height;
+       fmt->field = V4L2_FIELD_NONE;
+       fmt->colorspace = V4L2_COLORSPACE_RAW;
+       fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
+       fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+       fmt->xfer_func = V4L2_XFER_FUNC_NONE;
+}
 
-       ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
-                                   imx219->supplies);
-       if (ret) {
-               dev_err(dev, "%s: failed to enable regulators\n",
-                       __func__);
-               return ret;
-       }
+static int imx219_init_cfg(struct v4l2_subdev *sd,
+                          struct v4l2_subdev_state *state)
+{
+       struct imx219 *imx219 = to_imx219(sd);
+       struct v4l2_mbus_framefmt *format;
+       struct v4l2_rect *crop;
 
-       ret = clk_prepare_enable(imx219->xclk);
-       if (ret) {
-               dev_err(dev, "%s: failed to enable clock\n",
-                       __func__);
-               goto reg_off;
-       }
+       /* Initialize the format. */
+       format = v4l2_subdev_get_pad_format(sd, state, 0);
+       imx219_update_pad_format(imx219, &supported_modes[0], format,
+                                MEDIA_BUS_FMT_SRGGB10_1X10);
 
-       gpiod_set_value_cansleep(imx219->reset_gpio, 1);
-       usleep_range(IMX219_XCLR_MIN_DELAY_US,
-                    IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
+       /* Initialize the crop rectangle. */
+       crop = v4l2_subdev_get_pad_crop(sd, state, 0);
+       crop->top = IMX219_PIXEL_ARRAY_TOP;
+       crop->left = IMX219_PIXEL_ARRAY_LEFT;
+       crop->width = IMX219_PIXEL_ARRAY_WIDTH;
+       crop->height = IMX219_PIXEL_ARRAY_HEIGHT;
 
        return 0;
+}
 
-reg_off:
-       regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
+static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_state *sd_state,
+                                struct v4l2_subdev_mbus_code_enum *code)
+{
+       struct imx219 *imx219 = to_imx219(sd);
 
-       return ret;
+       if (code->index >= (ARRAY_SIZE(imx219_mbus_formats) / 4))
+               return -EINVAL;
+
+       code->code = imx219_get_format_code(imx219, 
imx219_mbus_formats[code->index * 4]);
+
+       return 0;
 }
 
-static int imx219_power_off(struct device *dev)
+static int imx219_enum_frame_size(struct v4l2_subdev *sd,
+                                 struct v4l2_subdev_state *sd_state,
+                                 struct v4l2_subdev_frame_size_enum *fse)
 {
-       struct v4l2_subdev *sd = dev_get_drvdata(dev);
        struct imx219 *imx219 = to_imx219(sd);
+       u32 code;
 
-       gpiod_set_value_cansleep(imx219->reset_gpio, 0);
-       regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
-       clk_disable_unprepare(imx219->xclk);
+       if (fse->index >= ARRAY_SIZE(supported_modes))
+               return -EINVAL;
+
+       code = imx219_get_format_code(imx219, fse->code);
+       if (fse->code != code)
+               return -EINVAL;
+
+       fse->min_width = supported_modes[fse->index].width;
+       fse->max_width = fse->min_width;
+       fse->min_height = supported_modes[fse->index].height;
+       fse->max_height = fse->min_height;
 
        return 0;
 }
 
-static int imx219_get_regulators(struct imx219 *imx219)
+static int imx219_set_pad_format(struct v4l2_subdev *sd,
+                                struct v4l2_subdev_state *sd_state,
+                                struct v4l2_subdev_format *fmt)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-       unsigned int i;
+       struct imx219 *imx219 = to_imx219(sd);
+       const struct imx219_mode *mode;
+       int exposure_max, exposure_def, hblank;
+       struct v4l2_mbus_framefmt *format;
+       struct v4l2_rect *crop;
 
-       for (i = 0; i < IMX219_NUM_SUPPLIES; i++)
-               imx219->supplies[i].supply = imx219_supply_name[i];
+       mode = v4l2_find_nearest_size(supported_modes,
+                                     ARRAY_SIZE(supported_modes),
+                                     width, height,
+                                     fmt->format.width, fmt->format.height);
 
-       return devm_regulator_bulk_get(&client->dev,
-                                      IMX219_NUM_SUPPLIES,
-                                      imx219->supplies);
+       imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code);
+
+       format = v4l2_subdev_get_pad_format(sd, sd_state, 0);
+       crop = v4l2_subdev_get_pad_crop(sd, sd_state, 0);
+
+       *format = fmt->format;
+       *crop = mode->crop;
+
+       if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+               /* Update limits and set FPS to default */
+               __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
+                                        IMX219_VTS_MAX - mode->height, 1,
+                                        mode->vts_def - mode->height);
+               __v4l2_ctrl_s_ctrl(imx219->vblank,
+                                  mode->vts_def - mode->height);
+               /* Update max exposure while meeting expected vblanking */
+               exposure_max = mode->vts_def - 4;
+               exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
+                       exposure_max : IMX219_EXPOSURE_DEFAULT;
+               __v4l2_ctrl_modify_range(imx219->exposure,
+                                        imx219->exposure->minimum,
+                                        exposure_max, imx219->exposure->step,
+                                        exposure_def);
+               /*
+                * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
+                * depends on mode->width only, and is not changeble in any
+                * way other than changing the mode.
+                */
+               hblank = IMX219_PPL_DEFAULT - mode->width;
+               __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1,
+                                        hblank);
+       }
+
+       return 0;
 }
 
-/* Verify chip ID */
-static int imx219_identify_module(struct imx219 *imx219)
+static int imx219_get_selection(struct v4l2_subdev *sd,
+                               struct v4l2_subdev_state *sd_state,
+                               struct v4l2_subdev_selection *sel)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-       int ret;
-       u64 val;
-
-       ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL);
-       if (ret) {
-               dev_err(&client->dev, "failed to read chip id %x\n",
-                       IMX219_CHIP_ID);
-               return ret;
+       switch (sel->target) {
+       case V4L2_SEL_TGT_CROP: {
+               sel->r = *v4l2_subdev_get_pad_crop(sd, sd_state, 0);
+               return 0;
        }
 
-       if (val != IMX219_CHIP_ID) {
-               dev_err(&client->dev, "chip id mismatch: %x!=%llx\n",
-                       IMX219_CHIP_ID, val);
-               return -EIO;
+       case V4L2_SEL_TGT_NATIVE_SIZE:
+               sel->r.top = 0;
+               sel->r.left = 0;
+               sel->r.width = IMX219_NATIVE_WIDTH;
+               sel->r.height = IMX219_NATIVE_HEIGHT;
+
+               return 0;
+
+       case V4L2_SEL_TGT_CROP_DEFAULT:
+       case V4L2_SEL_TGT_CROP_BOUNDS:
+               sel->r.top = IMX219_PIXEL_ARRAY_TOP;
+               sel->r.left = IMX219_PIXEL_ARRAY_LEFT;
+               sel->r.width = IMX219_PIXEL_ARRAY_WIDTH;
+               sel->r.height = IMX219_PIXEL_ARRAY_HEIGHT;
+
+               return 0;
        }
 
-       return 0;
+       return -EINVAL;
 }
 
 static const struct v4l2_subdev_core_ops imx219_core_ops = {
@@ -906,129 +957,93 @@ static const struct v4l2_subdev_ops imx219_subdev_ops = {
 };
 
 
-static unsigned long imx219_get_pixel_rate(struct imx219 *imx219)
-{
-       return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : 
IMX219_PIXEL_RATE_4LANE;
-}
+/* 
-----------------------------------------------------------------------------
+ * Power management
+ */
 
-/* Initialize control handlers */
-static int imx219_init_controls(struct imx219 *imx219)
+static int imx219_power_on(struct device *dev)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
-       const struct imx219_mode *mode = &supported_modes[0];
-       struct v4l2_ctrl_handler *ctrl_hdlr;
-       struct v4l2_fwnode_device_properties props;
-       int exposure_max, exposure_def, hblank;
-       int i, ret;
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
+       struct imx219 *imx219 = to_imx219(sd);
+       int ret;
 
-       ctrl_hdlr = &imx219->ctrl_handler;
-       ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
-       if (ret)
+       ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
+                                   imx219->supplies);
+       if (ret) {
+               dev_err(dev, "%s: failed to enable regulators\n",
+                       __func__);
                return ret;
+       }
 
-       /* By default, PIXEL_RATE is read only */
-       imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
-                                              V4L2_CID_PIXEL_RATE,
-                                              imx219_get_pixel_rate(imx219),
-                                              imx219_get_pixel_rate(imx219), 1,
-                                              imx219_get_pixel_rate(imx219));
+       ret = clk_prepare_enable(imx219->xclk);
+       if (ret) {
+               dev_err(dev, "%s: failed to enable clock\n",
+                       __func__);
+               goto reg_off;
+       }
 
-       imx219->link_freq =
-               v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops,
-                                      V4L2_CID_LINK_FREQ,
-                                      ARRAY_SIZE(imx219_link_freq_menu) - 1, 0,
-                                      (imx219->lanes == 2) ? 
imx219_link_freq_menu :
-                                      imx219_link_freq_4lane_menu);
-       if (imx219->link_freq)
-               imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+       gpiod_set_value_cansleep(imx219->reset_gpio, 1);
+       usleep_range(IMX219_XCLR_MIN_DELAY_US,
+                    IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
 
-       /* Initial vblank/hblank/exposure parameters based on current mode */
-       imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
-                                          V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
-                                          IMX219_VTS_MAX - mode->height, 1,
-                                          mode->vts_def - mode->height);
-       hblank = IMX219_PPL_DEFAULT - mode->width;
-       imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
-                                          V4L2_CID_HBLANK, hblank, hblank,
-                                          1, hblank);
-       if (imx219->hblank)
-               imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-       exposure_max = mode->vts_def - 4;
-       exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
-               exposure_max : IMX219_EXPOSURE_DEFAULT;
-       imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
-                                            V4L2_CID_EXPOSURE,
-                                            IMX219_EXPOSURE_MIN, exposure_max,
-                                            IMX219_EXPOSURE_STEP,
-                                            exposure_def);
+       return 0;
 
-       v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
-                         IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX,
-                         IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT);
+reg_off:
+       regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
 
-       v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
-                         IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX,
-                         IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT);
+       return ret;
+}
 
-       imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
-                                         V4L2_CID_HFLIP, 0, 1, 1, 0);
-       if (imx219->hflip)
-               imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+static int imx219_power_off(struct device *dev)
+{
+       struct v4l2_subdev *sd = dev_get_drvdata(dev);
+       struct imx219 *imx219 = to_imx219(sd);
 
-       imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
-                                         V4L2_CID_VFLIP, 0, 1, 1, 0);
-       if (imx219->vflip)
-               imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+       gpiod_set_value_cansleep(imx219->reset_gpio, 0);
+       regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
+       clk_disable_unprepare(imx219->xclk);
 
-       v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops,
-                                    V4L2_CID_TEST_PATTERN,
-                                    ARRAY_SIZE(imx219_test_pattern_menu) - 1,
-                                    0, 0, imx219_test_pattern_menu);
-       for (i = 0; i < 4; i++) {
-               /*
-                * The assumption is that
-                * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
-                * V4L2_CID_TEST_PATTERN_BLUE   == V4L2_CID_TEST_PATTERN_RED + 2
-                * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
-                */
-               v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
-                                 V4L2_CID_TEST_PATTERN_RED + i,
-                                 IMX219_TESTP_COLOUR_MIN,
-                                 IMX219_TESTP_COLOUR_MAX,
-                                 IMX219_TESTP_COLOUR_STEP,
-                                 IMX219_TESTP_COLOUR_MAX);
-               /* The "Solid color" pattern is white by default */
-       }
+       return 0;
+}
 
-       if (ctrl_hdlr->error) {
-               ret = ctrl_hdlr->error;
-               dev_err(&client->dev, "%s control init failed (%d)\n",
-                       __func__, ret);
-               goto error;
-       }
+/* 
-----------------------------------------------------------------------------
+ * Probe & remove
+ */
 
-       ret = v4l2_fwnode_device_parse(&client->dev, &props);
-       if (ret)
-               goto error;
+static int imx219_get_regulators(struct imx219 *imx219)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
+       unsigned int i;
 
-       ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops,
-                                             &props);
-       if (ret)
-               goto error;
+       for (i = 0; i < IMX219_NUM_SUPPLIES; i++)
+               imx219->supplies[i].supply = imx219_supply_name[i];
 
-       imx219->sd.ctrl_handler = ctrl_hdlr;
+       return devm_regulator_bulk_get(&client->dev,
+                                      IMX219_NUM_SUPPLIES,
+                                      imx219->supplies);
+}
 
-       return 0;
+/* Verify chip ID */
+static int imx219_identify_module(struct imx219 *imx219)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
+       int ret;
+       u64 val;
 
-error:
-       v4l2_ctrl_handler_free(ctrl_hdlr);
+       ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL);
+       if (ret) {
+               dev_err(&client->dev, "failed to read chip id %x\n",
+                       IMX219_CHIP_ID);
+               return ret;
+       }
 
-       return ret;
-}
+       if (val != IMX219_CHIP_ID) {
+               dev_err(&client->dev, "chip id mismatch: %x!=%llx\n",
+                       IMX219_CHIP_ID, val);
+               return -EIO;
+       }
 
-static void imx219_free_controls(struct imx219 *imx219)
-{
-       v4l2_ctrl_handler_free(imx219->sd.ctrl_handler);
+       return 0;
 }
 
 static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219)

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to