[media] smiapp: Merge smiapp_init() with smiapp_probe()
authorSakari Ailus <sakari.ailus@linux.intel.com>
Mon, 12 Sep 2016 09:44:35 +0000 (06:44 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Fri, 21 Oct 2016 17:03:52 +0000 (15:03 -0200)
The smiapp_probe() is the sole caller of smiapp_init(). Unify the two.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/i2c/smiapp/smiapp-core.c

index 9d7af8b..384a13b 100644 (file)
@@ -2622,223 +2622,6 @@ static void smiapp_create_subdev(struct smiapp_sensor *sensor,
        v4l2_set_subdevdata(&ssd->sd, client);
 }
 
-static int smiapp_init(struct smiapp_sensor *sensor)
-{
-       struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
-       struct smiapp_pll *pll = &sensor->pll;
-       unsigned int i;
-       int rval;
-
-       sensor->vana = devm_regulator_get(&client->dev, "vana");
-       if (IS_ERR(sensor->vana)) {
-               dev_err(&client->dev, "could not get regulator for vana\n");
-               return PTR_ERR(sensor->vana);
-       }
-
-       sensor->ext_clk = devm_clk_get(&client->dev, NULL);
-       if (IS_ERR(sensor->ext_clk)) {
-               dev_err(&client->dev, "could not get clock (%ld)\n",
-                       PTR_ERR(sensor->ext_clk));
-               return -EPROBE_DEFER;
-       }
-
-       rval = clk_set_rate(sensor->ext_clk,
-                           sensor->hwcfg->ext_clk);
-       if (rval < 0) {
-               dev_err(&client->dev,
-                       "unable to set clock freq to %u\n",
-                       sensor->hwcfg->ext_clk);
-               return rval;
-       }
-
-       sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown",
-                                                   GPIOD_OUT_LOW);
-       if (IS_ERR(sensor->xshutdown))
-               return PTR_ERR(sensor->xshutdown);
-
-       rval = smiapp_power_on(sensor);
-       if (rval)
-               return -ENODEV;
-
-       rval = smiapp_identify_module(sensor);
-       if (rval) {
-               rval = -ENODEV;
-               goto out_power_off;
-       }
-
-       rval = smiapp_get_all_limits(sensor);
-       if (rval) {
-               rval = -ENODEV;
-               goto out_power_off;
-       }
-
-       /*
-        * Handle Sensor Module orientation on the board.
-        *
-        * The application of H-FLIP and V-FLIP on the sensor is modified by
-        * the sensor orientation on the board.
-        *
-        * For SMIAPP_BOARD_SENSOR_ORIENT_180 the default behaviour is to set
-        * both H-FLIP and V-FLIP for normal operation which also implies
-        * that a set/unset operation for user space HFLIP and VFLIP v4l2
-        * controls will need to be internally inverted.
-        *
-        * Rotation also changes the bayer pattern.
-        */
-       if (sensor->hwcfg->module_board_orient ==
-           SMIAPP_MODULE_BOARD_ORIENT_180)
-               sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP |
-                                         SMIAPP_IMAGE_ORIENTATION_VFLIP;
-
-       rval = smiapp_call_quirk(sensor, limits);
-       if (rval) {
-               dev_err(&client->dev, "limits quirks failed\n");
-               goto out_power_off;
-       }
-
-       if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) {
-               u32 val;
-
-               rval = smiapp_read(sensor,
-                                  SMIAPP_REG_U8_BINNING_SUBTYPES, &val);
-               if (rval < 0) {
-                       rval = -ENODEV;
-                       goto out_power_off;
-               }
-               sensor->nbinning_subtypes = min_t(u8, val,
-                                                 SMIAPP_BINNING_SUBTYPES);
-
-               for (i = 0; i < sensor->nbinning_subtypes; i++) {
-                       rval = smiapp_read(
-                               sensor, SMIAPP_REG_U8_BINNING_TYPE_n(i), &val);
-                       if (rval < 0) {
-                               rval = -ENODEV;
-                               goto out_power_off;
-                       }
-                       sensor->binning_subtypes[i] =
-                               *(struct smiapp_binning_subtype *)&val;
-
-                       dev_dbg(&client->dev, "binning %xx%x\n",
-                               sensor->binning_subtypes[i].horizontal,
-                               sensor->binning_subtypes[i].vertical);
-               }
-       }
-       sensor->binning_horizontal = 1;
-       sensor->binning_vertical = 1;
-
-       if (device_create_file(&client->dev, &dev_attr_ident) != 0) {
-               dev_err(&client->dev, "sysfs ident entry creation failed\n");
-               rval = -ENOENT;
-               goto out_power_off;
-       }
-       /* SMIA++ NVM initialization - it will be read from the sensor
-        * when it is first requested by userspace.
-        */
-       if (sensor->minfo.smiapp_version && sensor->hwcfg->nvm_size) {
-               sensor->nvm = devm_kzalloc(&client->dev,
-                               sensor->hwcfg->nvm_size, GFP_KERNEL);
-               if (sensor->nvm == NULL) {
-                       dev_err(&client->dev, "nvm buf allocation failed\n");
-                       rval = -ENOMEM;
-                       goto out_cleanup;
-               }
-
-               if (device_create_file(&client->dev, &dev_attr_nvm) != 0) {
-                       dev_err(&client->dev, "sysfs nvm entry failed\n");
-                       rval = -EBUSY;
-                       goto out_cleanup;
-               }
-       }
-
-       /* We consider this as profile 0 sensor if any of these are zero. */
-       if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||
-           !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||
-           !sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV] ||
-           !sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV]) {
-               sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0;
-       } else if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
-                  != SMIAPP_SCALING_CAPABILITY_NONE) {
-               if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
-                   == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
-                       sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1;
-               else
-                       sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2;
-               sensor->scaler = &sensor->ssds[sensor->ssds_used];
-               sensor->ssds_used++;
-       } else if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
-                  == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
-               sensor->scaler = &sensor->ssds[sensor->ssds_used];
-               sensor->ssds_used++;
-       }
-       sensor->binner = &sensor->ssds[sensor->ssds_used];
-       sensor->ssds_used++;
-       sensor->pixel_array = &sensor->ssds[sensor->ssds_used];
-       sensor->ssds_used++;
-
-       sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
-
-       /* prepare PLL configuration input values */
-       pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
-       pll->csi2.lanes = sensor->hwcfg->lanes;
-       pll->ext_clk_freq_hz = sensor->hwcfg->ext_clk;
-       pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
-       /* Profile 0 sensors have no separate OP clock branch. */
-       if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
-               pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
-
-       smiapp_create_subdev(sensor, sensor->scaler, "scaler", 2);
-       smiapp_create_subdev(sensor, sensor->binner, "binner", 2);
-       smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array", 1);
-
-       dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
-
-       sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
-
-       /* final steps */
-       smiapp_read_frame_fmt(sensor);
-       rval = smiapp_init_controls(sensor);
-       if (rval < 0)
-               goto out_cleanup;
-
-       rval = smiapp_call_quirk(sensor, init);
-       if (rval)
-               goto out_cleanup;
-
-       rval = smiapp_get_mbus_formats(sensor);
-       if (rval) {
-               rval = -ENODEV;
-               goto out_cleanup;
-       }
-
-       rval = smiapp_init_late_controls(sensor);
-       if (rval) {
-               rval = -ENODEV;
-               goto out_cleanup;
-       }
-
-       mutex_lock(&sensor->mutex);
-       rval = smiapp_update_mode(sensor);
-       mutex_unlock(&sensor->mutex);
-       if (rval) {
-               dev_err(&client->dev, "update mode failed\n");
-               goto out_cleanup;
-       }
-
-       sensor->streaming = false;
-       sensor->dev_init_done = true;
-
-       smiapp_power_off(sensor);
-
-       return 0;
-
-out_cleanup:
-       smiapp_cleanup(sensor);
-
-out_power_off:
-       smiapp_power_off(sensor);
-       return rval;
-}
-
 static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 {
        struct smiapp_subdev *ssd = to_smiapp_subdev(sd);
@@ -3061,6 +2844,7 @@ static int smiapp_probe(struct i2c_client *client,
 {
        struct smiapp_sensor *sensor;
        struct smiapp_hwconfig *hwcfg = smiapp_get_hwconfig(&client->dev);
+       unsigned int i;
        int rval;
 
        if (hwcfg == NULL)
@@ -3081,9 +2865,205 @@ static int smiapp_probe(struct i2c_client *client,
        sensor->src->sensor = sensor;
        sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE;
 
-       rval = smiapp_init(sensor);
+       sensor->vana = devm_regulator_get(&client->dev, "vana");
+       if (IS_ERR(sensor->vana)) {
+               dev_err(&client->dev, "could not get regulator for vana\n");
+               return PTR_ERR(sensor->vana);
+       }
+
+       sensor->ext_clk = devm_clk_get(&client->dev, NULL);
+       if (IS_ERR(sensor->ext_clk)) {
+               dev_err(&client->dev, "could not get clock (%ld)\n",
+                       PTR_ERR(sensor->ext_clk));
+               return -EPROBE_DEFER;
+       }
+
+       rval = clk_set_rate(sensor->ext_clk,
+                           sensor->hwcfg->ext_clk);
+       if (rval < 0) {
+               dev_err(&client->dev,
+                       "unable to set clock freq to %u\n",
+                       sensor->hwcfg->ext_clk);
+               return rval;
+       }
+
+       sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown",
+                                                   GPIOD_OUT_LOW);
+       if (IS_ERR(sensor->xshutdown))
+               return PTR_ERR(sensor->xshutdown);
+
+       rval = smiapp_power_on(sensor);
        if (rval)
-               goto out_media_entity_cleanup;
+               return -ENODEV;
+
+       rval = smiapp_identify_module(sensor);
+       if (rval) {
+               rval = -ENODEV;
+               goto out_power_off;
+       }
+
+       rval = smiapp_get_all_limits(sensor);
+       if (rval) {
+               rval = -ENODEV;
+               goto out_power_off;
+       }
+
+       /*
+        * Handle Sensor Module orientation on the board.
+        *
+        * The application of H-FLIP and V-FLIP on the sensor is modified by
+        * the sensor orientation on the board.
+        *
+        * For SMIAPP_BOARD_SENSOR_ORIENT_180 the default behaviour is to set
+        * both H-FLIP and V-FLIP for normal operation which also implies
+        * that a set/unset operation for user space HFLIP and VFLIP v4l2
+        * controls will need to be internally inverted.
+        *
+        * Rotation also changes the bayer pattern.
+        */
+       if (sensor->hwcfg->module_board_orient ==
+           SMIAPP_MODULE_BOARD_ORIENT_180)
+               sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP |
+                                         SMIAPP_IMAGE_ORIENTATION_VFLIP;
+
+       rval = smiapp_call_quirk(sensor, limits);
+       if (rval) {
+               dev_err(&client->dev, "limits quirks failed\n");
+               goto out_power_off;
+       }
+
+       if (sensor->limits[SMIAPP_LIMIT_BINNING_CAPABILITY]) {
+               u32 val;
+
+               rval = smiapp_read(sensor,
+                                  SMIAPP_REG_U8_BINNING_SUBTYPES, &val);
+               if (rval < 0) {
+                       rval = -ENODEV;
+                       goto out_power_off;
+               }
+               sensor->nbinning_subtypes = min_t(u8, val,
+                                                 SMIAPP_BINNING_SUBTYPES);
+
+               for (i = 0; i < sensor->nbinning_subtypes; i++) {
+                       rval = smiapp_read(
+                               sensor, SMIAPP_REG_U8_BINNING_TYPE_n(i), &val);
+                       if (rval < 0) {
+                               rval = -ENODEV;
+                               goto out_power_off;
+                       }
+                       sensor->binning_subtypes[i] =
+                               *(struct smiapp_binning_subtype *)&val;
+
+                       dev_dbg(&client->dev, "binning %xx%x\n",
+                               sensor->binning_subtypes[i].horizontal,
+                               sensor->binning_subtypes[i].vertical);
+               }
+       }
+       sensor->binning_horizontal = 1;
+       sensor->binning_vertical = 1;
+
+       if (device_create_file(&client->dev, &dev_attr_ident) != 0) {
+               dev_err(&client->dev, "sysfs ident entry creation failed\n");
+               rval = -ENOENT;
+               goto out_power_off;
+       }
+       /* SMIA++ NVM initialization - it will be read from the sensor
+        * when it is first requested by userspace.
+        */
+       if (sensor->minfo.smiapp_version && sensor->hwcfg->nvm_size) {
+               sensor->nvm = devm_kzalloc(&client->dev,
+                               sensor->hwcfg->nvm_size, GFP_KERNEL);
+               if (sensor->nvm == NULL) {
+                       dev_err(&client->dev, "nvm buf allocation failed\n");
+                       rval = -ENOMEM;
+                       goto out_cleanup;
+               }
+
+               if (device_create_file(&client->dev, &dev_attr_nvm) != 0) {
+                       dev_err(&client->dev, "sysfs nvm entry failed\n");
+                       rval = -EBUSY;
+                       goto out_cleanup;
+               }
+       }
+
+       /* We consider this as profile 0 sensor if any of these are zero. */
+       if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] ||
+           !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] ||
+           !sensor->limits[SMIAPP_LIMIT_MIN_OP_PIX_CLK_DIV] ||
+           !sensor->limits[SMIAPP_LIMIT_MAX_OP_PIX_CLK_DIV]) {
+               sensor->minfo.smiapp_profile = SMIAPP_PROFILE_0;
+       } else if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
+                  != SMIAPP_SCALING_CAPABILITY_NONE) {
+               if (sensor->limits[SMIAPP_LIMIT_SCALING_CAPABILITY]
+                   == SMIAPP_SCALING_CAPABILITY_HORIZONTAL)
+                       sensor->minfo.smiapp_profile = SMIAPP_PROFILE_1;
+               else
+                       sensor->minfo.smiapp_profile = SMIAPP_PROFILE_2;
+               sensor->scaler = &sensor->ssds[sensor->ssds_used];
+               sensor->ssds_used++;
+       } else if (sensor->limits[SMIAPP_LIMIT_DIGITAL_CROP_CAPABILITY]
+                  == SMIAPP_DIGITAL_CROP_CAPABILITY_INPUT_CROP) {
+               sensor->scaler = &sensor->ssds[sensor->ssds_used];
+               sensor->ssds_used++;
+       }
+       sensor->binner = &sensor->ssds[sensor->ssds_used];
+       sensor->ssds_used++;
+       sensor->pixel_array = &sensor->ssds[sensor->ssds_used];
+       sensor->ssds_used++;
+
+       sensor->scale_m = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
+
+       /* prepare PLL configuration input values */
+       sensor->pll.bus_type = SMIAPP_PLL_BUS_TYPE_CSI2;
+       sensor->pll.csi2.lanes = sensor->hwcfg->lanes;
+       sensor->pll.ext_clk_freq_hz = sensor->hwcfg->ext_clk;
+       sensor->pll.scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN];
+       /* Profile 0 sensors have no separate OP clock branch. */
+       if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0)
+               sensor->pll.flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS;
+
+       smiapp_create_subdev(sensor, sensor->scaler, "scaler", 2);
+       smiapp_create_subdev(sensor, sensor->binner, "binner", 2);
+       smiapp_create_subdev(sensor, sensor->pixel_array, "pixel_array", 1);
+
+       dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
+
+       sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+       /* final steps */
+       smiapp_read_frame_fmt(sensor);
+       rval = smiapp_init_controls(sensor);
+       if (rval < 0)
+               goto out_cleanup;
+
+       rval = smiapp_call_quirk(sensor, init);
+       if (rval)
+               goto out_cleanup;
+
+       rval = smiapp_get_mbus_formats(sensor);
+       if (rval) {
+               rval = -ENODEV;
+               goto out_cleanup;
+       }
+
+       rval = smiapp_init_late_controls(sensor);
+       if (rval) {
+               rval = -ENODEV;
+               goto out_cleanup;
+       }
+
+       mutex_lock(&sensor->mutex);
+       rval = smiapp_update_mode(sensor);
+       mutex_unlock(&sensor->mutex);
+       if (rval) {
+               dev_err(&client->dev, "update mode failed\n");
+               goto out_cleanup;
+       }
+
+       sensor->streaming = false;
+       sensor->dev_init_done = true;
+
+       smiapp_power_off(sensor);
 
        rval = media_entity_pads_init(&sensor->src->sd.entity, 2,
                                 sensor->src->pads);
@@ -3099,6 +3079,11 @@ static int smiapp_probe(struct i2c_client *client,
 out_media_entity_cleanup:
        media_entity_cleanup(&sensor->src->sd.entity);
 
+out_cleanup:
+       smiapp_cleanup(sensor);
+
+out_power_off:
+       smiapp_power_off(sensor);
        return rval;
 }