]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
tegra: camera: sensor props controls
authorDavid Wang <davidw@nvidia.com>
Fri, 14 Apr 2017 01:59:46 +0000 (18:59 -0700)
committermobile promotions <svcmobile_promotions@nvidia.com>
Tue, 17 Oct 2017 07:47:38 +0000 (00:47 -0700)
Updated channel driver with sensor props control to
access sensor properties read from DT.

CRTC-1082
Bug 1981695

Change-Id: I5e83ad5ca87f6a03d6420714b84fe29fdef913e9
Signed-off-by: David Wang <davidw@nvidia.com>
Reviewed-on: http://git-master/r/1462742
GVS: Gerrit_Virtual_Submit
Reviewed-by: Wenjia Zhou <wenjiaz@nvidia.com>
Reviewed-by: Bhanu Murthy V <bmurthyv@nvidia.com>
(cherry picked from commit 1205cc4b666844a46eff59ccce5402fcf2ecfa87)
Reviewed-on: https://git-master.nvidia.com/r/1576558
Reviewed-by: Josh Kergan <jkergan@nvidia.com>
Tested-by: Josh Kergan <jkergan@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Jihoon Bang <jbang@nvidia.com>
drivers/media/i2c/imx185.c
drivers/media/i2c/imx185_mode_tbls.h
drivers/media/i2c/imx274.c
drivers/media/platform/tegra/camera/camera_common.c
drivers/media/platform/tegra/camera/sensor_common.c
drivers/media/platform/tegra/camera/vi/channel.c
drivers/media/platform/tegra/camera/vi/mc_common.h
drivers/media/platform/tegra/camera/vi/vi4_fops.c
include/media/camera_common.h
include/media/sensor_common.h
include/media/tegra-v4l2-camera.h

index 08c8f5576d7fd2c019ad84b5c04f7dc0116ee59a..08cc60f41e2c62481bef8c0ca215619bc21d1c40 100644 (file)
@@ -562,18 +562,19 @@ static int imx185_set_frame_rate(struct imx185 *priv, s64 val)
 {
        imx185_reg reg_list[3];
        int err;
-       s64 frame_length;
-       struct camera_common_mode_info *mode = priv->pdata->mode_info;
+       u32 frame_length;
        struct camera_common_data *s_data = priv->s_data;
+       const struct sensor_mode_properties *mode =
+               &s_data->sensor_props.sensor_modes[s_data->mode];
        struct v4l2_control control;
        int hdr_en;
        int i = 0;
 
-       frame_length = mode[s_data->mode].pixel_clock *
+       frame_length = mode->signal_properties.pixel_clock.val *
                FIXED_POINT_SCALING_FACTOR /
-               mode[s_data->mode].line_length / val;
+               mode->image_properties.line_length / val;
 
-       priv->frame_length = (u32) frame_length;
+       priv->frame_length = frame_length;
        if (priv->frame_length > IMX185_MAX_FRAME_LENGTH)
                priv->frame_length = IMX185_MAX_FRAME_LENGTH;
 
@@ -650,16 +651,18 @@ static int imx185_set_exposure(struct imx185 *priv, s64 val)
 
 static int imx185_set_coarse_time(struct imx185 *priv, s64 val)
 {
-       struct camera_common_mode_info *mode = priv->pdata->mode_info;
        struct camera_common_data *s_data = priv->s_data;
+       const struct sensor_mode_properties *mode =
+               &s_data->sensor_props.sensor_modes[s_data->mode];
        imx185_reg reg_list[3];
        int err;
        u32 coarse_time_shs1;
        u32 reg_shs1;
        int i = 0;
 
-       coarse_time_shs1 = mode[s_data->mode].pixel_clock * val /
-               mode[s_data->mode].line_length / FIXED_POINT_SCALING_FACTOR;
+       coarse_time_shs1 = mode->signal_properties.pixel_clock.val *
+               val / mode->image_properties.line_length /
+               FIXED_POINT_SCALING_FACTOR;
 
        if (priv->frame_length == 0)
                priv->frame_length = IMX185_MIN_FRAME_LENGTH;
@@ -689,8 +692,9 @@ fail:
 
 static int imx185_set_coarse_time_hdr(struct imx185 *priv, s64 val)
 {
-       struct camera_common_mode_info *mode = priv->pdata->mode_info;
        struct camera_common_data *s_data = priv->s_data;
+       const struct sensor_mode_properties *mode =
+               &s_data->sensor_props.sensor_modes[s_data->mode];
        imx185_reg reg_list_shs1[3];
        imx185_reg reg_list_shs2[3];
        u32 coarse_time_shs1;
@@ -706,8 +710,8 @@ static int imx185_set_coarse_time_hdr(struct imx185 *priv, s64 val)
        priv->last_wdr_et_val = val;
 
        /*WDR, update SHS1 as short ET, and SHS2 is 16x of short*/
-       coarse_time_shs1 = mode[s_data->mode].pixel_clock * val /
-               mode[s_data->mode].line_length /
+       coarse_time_shs1 = mode->signal_properties.pixel_clock.val *
+               val / mode->image_properties.line_length /
                FIXED_POINT_SCALING_FACTOR / 16;
        if (coarse_time_shs1 < IMX185_MIN_SHS1_1080P_HDR)
                coarse_time_shs1 = IMX185_MIN_SHS1_1080P_HDR;
@@ -914,8 +918,7 @@ error:
 
 MODULE_DEVICE_TABLE(of, imx185_of_match);
 
-static struct camera_common_pdata *imx185_parse_dt(struct imx185 *priv,
-                               struct i2c_client *client,
+static struct camera_common_pdata *imx185_parse_dt(struct i2c_client *client,
                                struct camera_common_data *s_data)
 {
        struct device_node *np = client->dev.of_node;
@@ -954,8 +957,7 @@ static struct camera_common_pdata *imx185_parse_dt(struct imx185 *priv,
                board_priv_pdata->reset_gpio = 0;
        }
 
-       err = camera_common_parse_sensor_mode(client, board_priv_pdata);
-       if (err)
+       if (s_data->sensor_props.num_modes == 0)
                dev_err(&client->dev, "Failed to load mode info %d\n", err);
 
        return board_priv_pdata;
@@ -1012,7 +1014,7 @@ static int imx185_probe(struct i2c_client *client,
        }
 
        if (client->dev.of_node)
-               priv->pdata = imx185_parse_dt(priv, client, common_data);
+               priv->pdata = imx185_parse_dt(client, common_data);
        if (!priv->pdata) {
                dev_err(&client->dev, "unable to get platform data\n");
                return -EFAULT;
index f40e080c488e241a4cf179ae8a8026991dfb8fa9..bcfd0f8d68129cca92b7e8def0ef74396f69fed1 100644 (file)
@@ -994,6 +994,10 @@ static const int imx185_60fps[] = {
        60,
 };
 
+/*
+ * WARNING: frmfmt ordering need to match mode definition in
+ * device tree!
+ */
 static const struct camera_common_frmfmt imx185_frmfmt[] = {
        {{1920, 1080}, imx185_30fps, 1, 0,
                        IMX185_MODE_1920X1080_CROP_30FPS},
@@ -1005,5 +1009,6 @@ static const struct camera_common_frmfmt imx185_frmfmt[] = {
                        IMX185_MODE_1920X1080_CROP_10BIT_60FPS},
        {{1920, 1080}, imx185_30fps, 1, 1,
                        IMX185_MODE_1920X1080_CROP_HDR_30FPS},
+       /* Add modes with no device tree support after below */
 };
 #endif /* __IMX185_I2C_TABLES__ */
index 5e2c99e31d186ffab9fc01d42b55c849cf215b56..278989b2b1e1f36573ec4dfe092576d37b86a22f 100644 (file)
@@ -821,7 +821,8 @@ error:
 
 MODULE_DEVICE_TABLE(of, imx274_of_match);
 
-static struct camera_common_pdata *imx274_parse_dt(struct i2c_client *client)
+static struct camera_common_pdata *imx274_parse_dt(struct i2c_client *client,
+                               const struct camera_common_data *s_data)
 {
        struct device_node *node = client->dev.of_node;
        struct camera_common_pdata *board_priv_pdata;
@@ -929,7 +930,7 @@ static int imx274_probe(struct i2c_client *client,
                return -ENODEV;
        }
 
-       priv->pdata = imx274_parse_dt(client);
+       priv->pdata = imx274_parse_dt(client, common_data);
        if (!priv->pdata) {
                dev_err(&client->dev, " unable to get platform data\n");
                return -EFAULT;
index c0fabbd2ba0541a6553614cb102a23f0b54c2b6c..3f8a1898a5508bc8510608d5b9737f736372f426 100644 (file)
@@ -797,115 +797,4 @@ fail:
 
        return err;
 }
-
-int camera_common_parse_sensor_mode(struct i2c_client *client,
-                       struct camera_common_pdata *pdata)
-{
-       struct device_node *np = client->dev.of_node;
-       char temp_str[OF_MAX_STR_LEN];
-       const char *str;
-       struct device_node *node;
-       int num_modes = 0;
-       int err, i;
-
-       /* get number of modes */
-       for (i = 0; num_modes < MAX_NUM_SENSOR_MODES; i++) {
-               snprintf(temp_str, sizeof(temp_str), "%s%d",
-                       OF_SENSORMODE_PREFIX, i);
-               of_node_get(np);
-               node = of_get_child_by_name(np, temp_str);
-               of_node_put(node);
-               if (node == NULL)
-                       break;
-               num_modes++;
-       }
-
-       pdata->mode_info = devm_kzalloc(&client->dev,
-               num_modes * sizeof(struct camera_common_mode_info),
-               GFP_KERNEL);
-       if (!pdata->mode_info) {
-               dev_err(&client->dev, "Failed to allocate memory for mode info\n");
-               return -ENOMEM;
-       }
-       memset(pdata->mode_info, 0, num_modes *
-              sizeof(struct camera_common_mode_info));
-
-       /* parse mode info */
-       for (i = 0; i < num_modes; i++) {
-               snprintf(temp_str, sizeof(temp_str), "%s%d",
-                       OF_SENSORMODE_PREFIX, i);
-               of_node_get(np);
-               node = of_get_child_by_name(np, temp_str);
-               if (node == NULL) {
-                       dev_err(&client->dev, "Failed to find mode\n");
-                       err = -ENODATA;
-                       goto fail;
-               };
-
-               /* read mode width */
-               of_property_read_string(node, "active_w", &str);
-               if (str == NULL) {
-                       dev_err(&client->dev, "Failed to read mode width\n");
-                       err = -ENODATA;
-                       goto fail;
-               };
-               err = kstrtoint(str, 10, &pdata->mode_info[i].width);
-               if (err) {
-                       dev_err(&client->dev, "Failed to convert mode width\n");
-                       err = -EFAULT;
-                       goto fail;
-               }
-               /* read mode height */
-               of_property_read_string(node, "active_h", &str);
-               if (str == NULL) {
-                       dev_err(&client->dev, "Failed to read mode height\n");
-                       err = -ENODATA;
-                       goto fail;
-               };
-               err = kstrtoint(str, 10, &pdata->mode_info[i].height);
-               if (err) {
-                       dev_err(&client->dev, "Failed to convert mode height\n");
-                       err = -EFAULT;
-                       goto fail;
-               }
-               dev_info(&client->dev, "%s: mode %d x %d:\n", __func__,
-                       pdata->mode_info[i].width, pdata->mode_info[i].height);
-
-               of_property_read_string(node, "line_length", &str);
-               if (str == NULL) {
-                       dev_err(&client->dev, "Failed to read mode line_length\n");
-                       err = -ENODATA;
-                       goto fail;
-               };
-               err = kstrtoint(str, 10, &pdata->mode_info[i].line_length);
-               if (err) {
-                       dev_err(&client->dev, "Failed to convert mode line_length\n");
-                       err = -EFAULT;
-                       goto fail;
-               }
-
-               of_property_read_string(node, "pix_clk_hz", &str);
-               if (str == NULL) {
-                       dev_err(&client->dev, "Failed to read mode pix_clk_hz\n");
-                       err = -ENODATA;
-                       goto fail;
-               };
-               err = kstrtoll(str, 10, &pdata->mode_info[i].pixel_clock);
-               if (err) {
-                       dev_err(&client->dev, "Failed to convert mode pix_clk_hz\n");
-                       err = -EFAULT;
-                       goto fail;
-               }
-               dev_info(&client->dev, "%s: line_length = %d, pixel_clock = %llu\n",
-                       __func__, pdata->mode_info[i].line_length,
-                       pdata->mode_info[i].pixel_clock);
-               of_node_put(node);
-       }
-
-       return 0;
-
-fail:
-       of_node_put(node);
-       return err;
-}
-EXPORT_SYMBOL(camera_common_parse_sensor_mode);
+EXPORT_SYMBOL_GPL(camera_common_focuser_init);
index fda415bbea3277cac8e3ebac959ed9a41cce077c..a5f97ede88e37a022e0dbae08073165d7227c25a 100644 (file)
@@ -68,8 +68,12 @@ static int sensor_common_parse_signal_props(
                &signal->num_lanes);
        read_property_u32(node, "mclk_khz",
                &signal->mclk_freq);
-       read_property_u64(node, "pix_clk_hz",
+       err = read_property_u64(node, "pix_clk_hz",
                &signal->pixel_clock.val);
+       if (err) {
+               dev_err(dev, "%s:pix_clk_hz property missing\n", __func__);
+               return err;
+       }
        read_property_u32(node, "cil_settletime",
                &signal->cil_settletime);
        /* initialize default if this prop not available */
@@ -294,6 +298,9 @@ int sensor_common_init_sensor_properties(
        int num_modes = 0;
        int err, i;
 
+       if (sensor == NULL)
+               return -EINVAL;
+
        /* get number of modes */
        for (i = 0; num_modes < MAX_NUM_SENSOR_MODES; i++) {
                snprintf(temp_str, sizeof(temp_str), "%s%d",
@@ -318,10 +325,8 @@ int sensor_common_init_sensor_properties(
        if (!sensor->sensor_modes) {
                dev_err(dev, "Failed to allocate memory for sensor modes\n");
                err = -ENOMEM;
-               goto fail;
+               goto alloc_fail;
        }
-       memset(sensor->sensor_modes, 0, num_modes *
-              sizeof(struct sensor_mode_properties));
 
        for (i = 0; i < num_modes; i++) {
                snprintf(temp_str, sizeof(temp_str), "%s%d",
@@ -329,36 +334,42 @@ int sensor_common_init_sensor_properties(
                of_node_get(np);
                node = of_get_child_by_name(np, temp_str);
                if (node == NULL) {
-                       dev_err(dev, "Failed to find mode\n");
+                       dev_err(dev, "Failed to find %s\n", temp_str);
                        err = -ENODATA;
                        goto fail;
                };
 
+               dev_dbg(dev, "parsing for %s props\n", temp_str);
+
                err = sensor_common_parse_signal_props(dev, node,
                        &sensor->sensor_modes[i].signal_properties);
                if (err) {
-                       dev_err(dev, "Failed to read signal properties\n");
+                       dev_err(dev, "Failed to read %s signal props\n",
+                               temp_str);
                        goto fail;
                }
 
                err = sensor_common_parse_image_props(dev, node,
                        &sensor->sensor_modes[i].image_properties);
                if (err) {
-                       dev_err(dev, "Failed to read image properties\n");
+                       dev_err(dev, "Failed to read %s image props\n",
+                               temp_str);
                        goto fail;
                }
 
                err = sensor_common_parse_dv_timings(dev, node,
                        &sensor->sensor_modes[i].dv_timings);
                if (err) {
-                       dev_err(dev, "Failed to read DV timings\n");
+                       dev_err(dev, "Failed to read %s DV timings\n",
+                               temp_str);
                        goto fail;
                }
 
                err = sensor_common_parse_control_props(dev, node,
                        &sensor->sensor_modes[i].control_properties);
                if (err) {
-                       dev_err(dev, "Failed to read control properties\n");
+                       dev_err(dev, "Failed to read %s control props\n",
+                               temp_str);
                        goto fail;
                }
                of_node_put(node);
@@ -367,6 +378,8 @@ int sensor_common_init_sensor_properties(
        return 0;
 
 fail:
+       devm_kfree(dev, sensor->sensor_modes);
+alloc_fail:
        of_node_put(node);
        return err;
 }
index 65835504aa25e71127f50b81e46fdf6b455eec66..3234d752c2226fe5a7fdc0b50460c0ae71e25e5f 100644 (file)
@@ -889,7 +889,8 @@ int tegra_channel_s_ctrl(struct v4l2_ctrl *ctrl)
                chan->write_ispformat = ctrl->val;
                break;
        default:
-               dev_err(&chan->video.dev, "%s:Not valid ctrl\n", __func__);
+               dev_err(&chan->video.dev, "%s: Invalid ctrl %u\n",
+                       __func__, ctrl->id);
                return -EINVAL;
        }
 
@@ -944,8 +945,137 @@ static const struct v4l2_ctrl_config common_custom_ctrls[] = {
                .menu_skip_mask = 0,
                .qmenu_int = size_align_ctrl_qmenu,
        },
+       {
+               .ops = &channel_ctrl_ops,
+               .id = TEGRA_CAMERA_CID_SENSOR_MODES,
+               .name = "Sensor Modes",
+               .type = V4L2_CTRL_TYPE_INTEGER,
+               .flags = V4L2_CTRL_FLAG_READ_ONLY,
+               .min = 0,
+               .max = MAX_NUM_SENSOR_MODES,
+               .def = MAX_NUM_SENSOR_MODES,
+               .step = 1,
+       },
+       {
+               .ops = &channel_ctrl_ops,
+               .id = TEGRA_CAMERA_CID_SENSOR_SIGNAL_PROPERTIES,
+               .name = "Sensor Signal Properties",
+               .type = V4L2_CTRL_TYPE_U32,
+               .flags = V4L2_CTRL_FLAG_HAS_PAYLOAD |
+                        V4L2_CTRL_FLAG_READ_ONLY,
+               .min = 0,
+               .max = 0xFFFFFFFF,
+               .step = 1,
+               .def = 0,
+               .dims = { MAX_NUM_SENSOR_MODES,
+                         SENSOR_SIGNAL_PROPERTIES_CID_SIZE },
+       },
+       {
+               .ops = &channel_ctrl_ops,
+               .id = TEGRA_CAMERA_CID_SENSOR_IMAGE_PROPERTIES,
+               .name = "Sensor Image Properties",
+               .type = V4L2_CTRL_TYPE_U32,
+               .flags = V4L2_CTRL_FLAG_HAS_PAYLOAD |
+                        V4L2_CTRL_FLAG_READ_ONLY,
+               .min = 0,
+               .max = 0xFFFFFFFF,
+               .step = 1,
+               .def = 0,
+               .dims = { MAX_NUM_SENSOR_MODES,
+                         SENSOR_IMAGE_PROPERTIES_CID_SIZE },
+       },
+       {
+               .ops = &channel_ctrl_ops,
+               .id = TEGRA_CAMERA_CID_SENSOR_CONTROL_PROPERTIES,
+               .name = "Sensor Control Properties",
+               .type = V4L2_CTRL_TYPE_U32,
+               .flags = V4L2_CTRL_FLAG_HAS_PAYLOAD |
+                        V4L2_CTRL_FLAG_READ_ONLY,
+               .min = 0,
+               .max = 0xFFFFFFFF,
+               .step = 1,
+               .def = 0,
+               .dims = { MAX_NUM_SENSOR_MODES,
+                         SENSOR_CONTROL_PROPERTIES_CID_SIZE },
+       },
+       {
+               .ops = &channel_ctrl_ops,
+               .id = TEGRA_CAMERA_CID_SENSOR_DV_TIMINGS,
+               .name = "Sensor DV Timings",
+               .type = V4L2_CTRL_TYPE_U32,
+               .flags = V4L2_CTRL_FLAG_HAS_PAYLOAD |
+                        V4L2_CTRL_FLAG_READ_ONLY,
+               .min = 0,
+               .max = 0xFFFFFFFF,
+               .step = 1,
+               .def = 0,
+               .dims = { MAX_NUM_SENSOR_MODES,
+                         SENSOR_DV_TIMINGS_CID_SIZE },
+       },
 };
 
+#define GET_TEGRA_CAMERA_CTRL(id, c)                                   \
+do {                                                                   \
+       c = v4l2_ctrl_find(&chan->ctrl_handler, TEGRA_CAMERA_CID_##id); \
+       if (!c) {                                                       \
+               dev_err(chan->vi->dev, "%s: could not find ctrl %s\n",  \
+                       __func__, "##id");                              \
+               return -EINVAL;                                         \
+       }                                                               \
+} while (0)
+
+static int tegra_channel_sensorprops_setup(struct tegra_channel *chan)
+{
+       const struct i2c_client *client =
+                       v4l2_get_subdevdata(chan->subdev_on_csi);
+       const struct camera_common_data *s_data =
+                       to_camera_common_data(client);
+       const struct sensor_mode_properties *modes;
+       struct v4l2_ctrl *ctrl_modes;
+       struct v4l2_ctrl *ctrl_signalprops;
+       struct v4l2_ctrl *ctrl_imageprops;
+       struct v4l2_ctrl *ctrl_controlprops;
+       struct v4l2_ctrl *ctrl_dvtimings;
+       u32 i;
+
+       GET_TEGRA_CAMERA_CTRL(SENSOR_MODES, ctrl_modes);
+       GET_TEGRA_CAMERA_CTRL(SENSOR_SIGNAL_PROPERTIES, ctrl_signalprops);
+       GET_TEGRA_CAMERA_CTRL(SENSOR_IMAGE_PROPERTIES, ctrl_imageprops);
+       GET_TEGRA_CAMERA_CTRL(SENSOR_CONTROL_PROPERTIES, ctrl_controlprops);
+       GET_TEGRA_CAMERA_CTRL(SENSOR_DV_TIMINGS, ctrl_dvtimings);
+
+       ctrl_modes->val = s_data->sensor_props.num_modes;
+       ctrl_modes->cur.val = s_data->sensor_props.num_modes;
+
+       modes = s_data->sensor_props.sensor_modes;
+       for (i = 0; i < s_data->sensor_props.num_modes; i++) {
+               void *ptr = NULL;
+               u32 size;
+
+               size = sizeof(struct sensor_signal_properties);
+               ptr = ctrl_signalprops->p_new.p + (i * size);
+               memcpy(ptr, &modes[i].signal_properties, size);
+
+               size = sizeof(struct sensor_image_properties);
+               ptr = ctrl_imageprops->p_new.p + (i * size);
+               memcpy(ptr, &modes[i].image_properties, size);
+
+               size = sizeof(struct sensor_control_properties);
+               ptr = ctrl_controlprops->p_new.p + (i * size);
+               memcpy(ptr, &modes[i].control_properties, size);
+
+               size = sizeof(struct sensor_dv_timings);
+               ptr = ctrl_dvtimings->p_new.p + (i * size);
+               memcpy(ptr, &modes[i].dv_timings, size);
+       }
+       ctrl_signalprops->p_cur.p = ctrl_signalprops->p_new.p;
+       ctrl_imageprops->p_cur.p = ctrl_imageprops->p_new.p;
+       ctrl_controlprops->p_cur.p = ctrl_controlprops->p_new.p;
+       ctrl_dvtimings->p_cur.p = ctrl_dvtimings->p_new.p;
+
+       return 0;
+}
+
 static int tegra_channel_setup_controls(struct tegra_channel *chan)
 {
        int num_sd = 0;
@@ -993,11 +1123,50 @@ static int tegra_channel_setup_controls(struct tegra_channel *chan)
        }
 
        /* setup the controls */
-       return v4l2_ctrl_handler_setup(&chan->ctrl_handler);
+       ret = v4l2_ctrl_handler_setup(&chan->ctrl_handler);
+       if (ret < 0)
+               goto error;
+
+       return 0;
+
+error:
+       v4l2_ctrl_handler_free(&chan->ctrl_handler);
+       return ret;
+}
+
+static void tegra_channel_free_sensor_properties(
+               const struct v4l2_subdev *sensor_sd)
+{
+       struct device *sensor_dev = sensor_sd->dev;
+       const struct i2c_client *client = v4l2_get_subdevdata(sensor_sd);
+       struct camera_common_data *s_data = to_camera_common_data(client);
+
+       if (sensor_dev == NULL || s_data == NULL)
+               return;
+
+       if (s_data->sensor_props.sensor_modes)
+               devm_kfree(sensor_dev, s_data->sensor_props.sensor_modes);
+
+       s_data->sensor_props.sensor_modes = NULL;
+}
+
+static int tegra_channel_init_sensor_properties(
+               const struct v4l2_subdev *sensor_sd)
+{
+       struct device *sensor_dev = sensor_sd->dev;
+       const struct i2c_client *client = v4l2_get_subdevdata(sensor_sd);
+       struct camera_common_data *s_data = to_camera_common_data(client);
+
+       if (sensor_dev == NULL || s_data == NULL)
+               return -EINVAL;
+
+       return sensor_common_init_sensor_properties(sensor_dev,
+               sensor_dev->of_node, &s_data->sensor_props);
 }
 
 int tegra_channel_init_subdevices(struct tegra_channel *chan)
 {
+       int ret = 0;
        struct media_entity *entity;
        struct media_pad *pad;
        struct v4l2_subdev *sd;
@@ -1056,7 +1225,39 @@ int tegra_channel_init_subdevices(struct tegra_channel *chan)
        if (chan->num_subdevs)
                tegra_channel_fmts_bitmap_init(chan);
 
-       return tegra_channel_setup_controls(chan);
+       ret = tegra_channel_setup_controls(chan);
+       if (ret < 0) {
+               dev_err(chan->vi->dev, "%s: failed to setup controls\n",
+                       __func__);
+               goto fail;
+       }
+
+       /*
+        * If subdev on csi is csi or channel is in pg mode
+        * then don't look for sensor props
+        */
+       if (strstr(chan->subdev_on_csi->name, "nvcsi") != NULL ||
+                       chan->pg_mode)
+               return 0;
+
+       ret = tegra_channel_init_sensor_properties(chan->subdev_on_csi);
+       if (ret < 0) {
+               dev_err(chan->vi->dev,
+                       "%s: failed to initialize sensor props\n", __func__);
+               goto fail;
+       }
+
+       ret = tegra_channel_sensorprops_setup(chan);
+       if (ret < 0) {
+               dev_err(chan->vi->dev, "%s: failed to setup sensor props\n",
+                       __func__);
+               goto fail;
+       }
+
+       return 0;
+fail:
+       tegra_channel_free_sensor_properties(chan->subdev_on_csi);
+       return ret;
 }
 
 static int
index c078846a8adf0de6a268d6d19dd5683c88d014f1..d4b2da1f95a37d72ce037b0ffdc06fb3a4e47bb9 100644 (file)
 
 #include <media/media-device.h>
 #include <media/media-entity.h>
+#include <media/sensor_common.h>
 #include <media/v4l2-async.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-dev.h>
 #include <media/videobuf2-core.h>
+
 #include <linux/workqueue.h>
 
 #include "core.h"
index ca84a3dfef66096162b91fea3e77976a43c1a05d..89553bc9046d4124792323ef93da2bc4a3288159 100644 (file)
@@ -759,7 +759,6 @@ int vi4_channel_start_streaming(struct vb2_queue *vq, u32 count)
        struct v4l2_subdev *sd;
        struct i2c_client *client;
        struct device_node *node;
-       struct sensor_properties sensor_props;
        struct sensor_mode_properties *sensor_mode;
        struct camera_common_data *s_data;
        unsigned int emb_buf_size = 0;
@@ -781,60 +780,63 @@ int vi4_channel_start_streaming(struct vb2_queue *vq, u32 count)
        chan->capture_state = CAPTURE_IDLE;
        spin_unlock_irqrestore(&chan->capture_state_lock, flags);
 
-       sd = chan->subdev_on_csi;
-       client = v4l2_get_subdevdata(sd);
-       node = client->dev.of_node;
-       s_data = to_camera_common_data(client);
-
-       /* get sensor properties from DT */
-       if (node != NULL) {
-               ret = sensor_common_init_sensor_properties(sd->dev, node, &sensor_props);
-               if (ret < 0)
-                       goto error_capture_setup;
+       if (!chan->pg_mode) {
+               sd = chan->subdev_on_csi;
+               client = v4l2_get_subdevdata(sd);
+               node = client->dev.of_node;
+               s_data = to_camera_common_data(client);
+               if (s_data == NULL) {
+                       dev_err(&chan->video.dev,
+                               "Camera common data missing!\n");
+                       return -EINVAL;
+               }
 
-               if (sensor_props.num_modes) {
-                       if (s_data != NULL)
-                               sensor_mode = &sensor_props.sensor_modes[s_data->mode];
-                       else
-                               sensor_mode = &sensor_props.sensor_modes[0];
+               /* get sensor properties from DT */
+               if (node != NULL) {
+                       sensor_mode = &s_data->sensor_props
+                                       .sensor_modes[s_data->mode];
 
                        chan->embedded_data_width =
                                sensor_mode->image_properties.width;
                        chan->embedded_data_height =
-                               sensor_mode->image_properties.embedded_metadata_height;
-
+                               sensor_mode->image_properties
+                                       .embedded_metadata_height;
                        /* rounding up to page size */
                        emb_buf_size =
                                round_up(
-                                       chan->embedded_data_width * chan->embedded_data_height * BPP_MEM,
+                                       chan->embedded_data_width *
+                                               chan->embedded_data_height *
+                                               BPP_MEM,
                                        PAGE_SIZE);
                }
-       }
 
-       /* Allocate buffer for Embedded Data if need to*/
-       if (emb_buf_size > chan->vi->emb_buf_size) {
-               /*
-                * if old buffer is smaller than what we need,
-                * release the old buffer and re-allocate a bigger
-                * one below
-                */
-               if (chan->vi->emb_buf_size > 0) {
-                       dma_free_coherent(chan->vi->dev,
-                               chan->vi->emb_buf_size,
-                               chan->vi->emb_buf_addr, chan->vi->emb_buf);
-                       chan->vi->emb_buf_size = 0;
-               }
 
-               chan->vi->emb_buf_addr =
-                       dma_alloc_coherent(chan->vi->dev,
-                               emb_buf_size,
-                               &chan->vi->emb_buf, GFP_KERNEL);
-               if (!chan->vi->emb_buf_addr) {
-                       dev_err(&chan->video.dev,
-                                       "Can't allocate memory for embedded data\n");
-                       goto error_capture_setup;
+               /* Allocate buffer for Embedded Data if need to*/
+               if (emb_buf_size > chan->vi->emb_buf_size) {
+                       /*
+                        * if old buffer is smaller than what we need,
+                        * release the old buffer and re-allocate a bigger
+                        * one below
+                        */
+                       if (chan->vi->emb_buf_size > 0) {
+                               dma_free_coherent(chan->vi->dev,
+                                       chan->vi->emb_buf_size,
+                                       chan->vi->emb_buf_addr,
+                                       chan->vi->emb_buf);
+                               chan->vi->emb_buf_size = 0;
+                       }
+
+                       chan->vi->emb_buf_addr =
+                               dma_alloc_coherent(chan->vi->dev,
+                                       emb_buf_size,
+                                       &chan->vi->emb_buf, GFP_KERNEL);
+                       if (!chan->vi->emb_buf_addr) {
+                               dev_err(&chan->video.dev,
+                                 "Can't allocate memory for embedded data\n");
+                               goto error_capture_setup;
+                       }
+                       chan->vi->emb_buf_size = emb_buf_size;
                }
-               chan->vi->emb_buf_size = emb_buf_size;
        }
 
        for (i = 0; i < chan->valid_ports; i++) {
index 5c5a17e345b0f2647e649fb4093936aabcf4136b..ec59b695a4041495e70521213a51fa0a376e21b9 100644 (file)
 #ifndef __camera_common__
 #define __camera_common__
 
+#include <linux/clk.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
 #include <linux/i2c.h>
+#include <linux/kernel.h>
 #include <linux/regmap.h>
-#include <linux/clk.h>
 #include <linux/regulator/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
+#include <linux/v4l2-mediabus.h>
 
-#include <linux/kernel.h>
-#include <linux/debugfs.h>
-
+#include <media/nvc_focus.h>
+#include <media/sensor_common.h>
+#include <media/soc_camera.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-ctrls.h>
-#include <linux/v4l2-mediabus.h>
 #include <media/soc_camera.h>
 #include <media/nvc_focus.h>
 
@@ -105,13 +107,6 @@ struct camera_common_regulators {
        const char *vcmvdd;
 };
 
-struct camera_common_mode_info {
-       u32     width;
-       u32 height;
-       u32 line_length;
-       u64 pixel_clock;
-};
-
 struct camera_common_pdata {
        const char *mclk_name; /* NULL for default default_mclk */
        const char *parentclk_name; /* NULL for no parent clock*/
@@ -124,7 +119,6 @@ struct camera_common_pdata {
        struct camera_common_regulators regulators;
        bool use_cam_gpio;
        bool has_eeprom;
-       struct camera_common_mode_info *mode_info;
        bool v_flip;
        bool h_mirror;
 };
@@ -211,6 +205,8 @@ struct camera_common_data {
        struct v4l2_subdev                      subdev;
        struct v4l2_ctrl                        **ctrls;
 
+       struct sensor_properties                sensor_props;
+
        void    *priv;
        int     numctrls;
        int     csi_port;
@@ -276,8 +272,6 @@ int camera_common_parse_clocks(struct i2c_client *client,
                        struct camera_common_pdata *pdata);
 int camera_common_parse_ports(struct i2c_client *client,
                              struct camera_common_data *s_data);
-int camera_common_parse_sensor_mode(struct i2c_client *client,
-                       struct camera_common_pdata *pdata);
 
 int camera_common_debugfs_show(struct seq_file *s, void *unused);
 ssize_t camera_common_debugfs_write(
index 744f5b31751f00c7d227095d2f3f9109f1e78b07..79cc19840401bcd915f2b5a36398bd137fc5e5b0 100644 (file)
@@ -38,6 +38,7 @@
 #include <media/tegra-v4l2-camera.h>
 
 struct sensor_properties {
+       /* sensor_modes points to an array of mode properties */
        struct sensor_mode_properties *sensor_modes;
        u32 num_modes;
 };
index 95dacde49360baf8f516370bba8955c1bd8d7ea8..5c5e2da7597e04f805d6582d7caa1b00d2c040b3 100644 (file)
 #define TEGRA_CAMERA_CID_EEPROM_DATA           (TEGRA_CAMERA_CID_BASE+5)
 #define TEGRA_CAMERA_CID_OTP_DATA              (TEGRA_CAMERA_CID_BASE+6)
 #define TEGRA_CAMERA_CID_FUSE_ID               (TEGRA_CAMERA_CID_BASE+7)
-#define TEGRA_CAMERA_CID_TEGRA_CAMERA_LAST     (TEGRA_CAMERA_CID_BASE+8)
-#define TEGRA_CAMERA_CID_SENSOR_MODE_ID                (TEGRA_CAMERA_CID_BASE+10)
+#define TEGRA_CAMERA_CID_SENSOR_MODE_ID                (TEGRA_CAMERA_CID_BASE+8)
 
-#define TEGRA_CAMERA_CID_GAIN                  (TEGRA_CAMERA_CID_BASE+11)
-#define TEGRA_CAMERA_CID_EXPOSURE              (TEGRA_CAMERA_CID_BASE+12)
-#define TEGRA_CAMERA_CID_FRAME_RATE            (TEGRA_CAMERA_CID_BASE+13)
+#define TEGRA_CAMERA_CID_GAIN                  (TEGRA_CAMERA_CID_BASE+9)
+#define TEGRA_CAMERA_CID_EXPOSURE              (TEGRA_CAMERA_CID_BASE+10)
+#define TEGRA_CAMERA_CID_FRAME_RATE            (TEGRA_CAMERA_CID_BASE+11)
 
 #define TEGRA_CAMERA_CID_VI_BYPASS_MODE                (TEGRA_CAMERA_CID_BASE+100)
 #define TEGRA_CAMERA_CID_OVERRIDE_ENABLE       (TEGRA_CAMERA_CID_BASE+101)
 #define TEGRA_CAMERA_CID_VI_SIZE_ALIGN         (TEGRA_CAMERA_CID_BASE+103)
 #define TEGRA_CAMERA_CID_WRITE_ISPFORMAT       (TEGRA_CAMERA_CID_BASE+104)
 
+#define TEGRA_CAMERA_CID_SENSOR_SIGNAL_PROPERTIES  (TEGRA_CAMERA_CID_BASE+105)
+#define TEGRA_CAMERA_CID_SENSOR_IMAGE_PROPERTIES   (TEGRA_CAMERA_CID_BASE+106)
+#define TEGRA_CAMERA_CID_SENSOR_CONTROL_PROPERTIES (TEGRA_CAMERA_CID_BASE+107)
+#define TEGRA_CAMERA_CID_SENSOR_DV_TIMINGS         (TEGRA_CAMERA_CID_BASE+108)
+
+/**
+ * This is temporary with the current v4l2 infrastructure
+ * currently discussing with upstream maintainers our proposals and
+ * better approaches to resolve this
+ */
+#define TEGRA_CAMERA_CID_SENSOR_MODES          (TEGRA_CAMERA_CID_BASE + 130)
+
 #define MAX_BUFFER_SIZE                        32
 #define MAX_CID_CONTROLS               16
 #define MAX_NUM_SENSOR_MODES           30