driver: media: tegra: Update tegra camera_common
Frank Chen [Sat, 16 Jul 2016 00:33:08 +0000 (17:33 -0700)]
1. Undefine standard V4L2 GAIN/Exposure CIDs and
switch to our own custom CIDs.

2. Add helper function to read mode specific info
from device tree.

Jira: CHWI-246

Bug 200168141

DEPENDS ON: <http://git-master/r/1176440>

Change-Id: I7bfd69a030031f8b450472ee9124cf08a030b1a9
Signed-off-by: Frank Chen <frankc@nvidia.com>
Reviewed-on: http://git-master/r/1183834
Reviewed-by: Esen Chen <esenc@nvidia.com>
Tested-by: Esen Chen <esenc@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Jihoon Bang <jbang@nvidia.com>

drivers/media/platform/tegra/camera/camera_common.c
include/media/camera_common.h

index 3116e45..a7f0e52 100644 (file)
@@ -745,3 +745,98 @@ 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);
+               node = of_find_node_by_name(np, temp_str);
+               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);
+               node = of_find_node_by_name(np, temp_str);
+               if (node == NULL) {
+                       dev_err(&client->dev, "Failed to find mode\n");
+                       return -ENODATA;
+               };
+
+               /* read mode width */
+               of_property_read_string(node, "active_w", &str);
+               if (str == NULL) {
+                       dev_err(&client->dev, "Failed to read mode width\n");
+                       return -ENODATA;
+               };
+               err = kstrtoint(str, 10, &pdata->mode_info[i].width);
+               if (err) {
+                       dev_err(&client->dev, "Failed to convert mode width\n");
+                       return -EFAULT;
+               }
+               /* read mode height */
+               of_property_read_string(node, "active_h", &str);
+               if (str == NULL) {
+                       dev_err(&client->dev, "Failed to read mode height\n");
+                       return -ENODATA;
+               };
+               err = kstrtoint(str, 10, &pdata->mode_info[i].height);
+               if (err) {
+                       dev_err(&client->dev, "Failed to convert mode height\n");
+                       return -EFAULT;
+               }
+               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");
+                       return -ENODATA;
+               };
+               err = kstrtoint(str, 10, &pdata->mode_info[i].line_length);
+               if (err) {
+                       dev_err(&client->dev, "Failed to convert mode line_length\n");
+                       return -EFAULT;
+               }
+
+               of_property_read_string(node, "pix_clk_hz", &str);
+               if (str == NULL) {
+                       dev_err(&client->dev, "Failed to read mode pix_clk_hz\n");
+                       return -ENODATA;
+               };
+               err = kstrtoll(str, 10, &pdata->mode_info[i].pixel_clock);
+               if (err) {
+                       dev_err(&client->dev, "Failed to convert mode pix_clk_hz\n");
+                       return -EFAULT;
+               }
+               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);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(camera_common_parse_sensor_mode);
index 6f9ed3e..effb71b 100644 (file)
 #define V4L2_CID_TEGRA_CAMERA_LAST     (V4L2_CID_TEGRA_CAMERA_BASE+8)
 #define V4L2_CID_VI_BYPASS_MODE                (V4L2_CID_TEGRA_CAMERA_BASE+9)
 
+/* undefine default CID for GAIN/EXPOSURE and use NV's version */
+#undef V4L2_CID_GAIN
+#undef V4L2_CID_EXPOSURE
+#define V4L2_CID_GAIN                          (V4L2_CID_TEGRA_CAMERA_BASE+10)
+#define V4L2_CID_EXPOSURE                      (V4L2_CID_TEGRA_CAMERA_BASE+11)
+#define V4L2_CID_FRAME_RATE                    (V4L2_CID_TEGRA_CAMERA_BASE+12)
+
 #define MAX_BUFFER_SIZE                        32
 #define MAX_CID_CONTROLS               16
+#define MAX_NUM_SENSOR_MODES   30
+#define OF_MAX_STR_LEN                 256
+#define OF_SENSORMODE_PREFIX ("mode")
+
+/*
+ * Scaling factor for converting a Q10.22 fixed point value
+ * back to its original floating point value
+ */
+#define FIXED_POINT_SCALING_FACTOR (1ULL << 22)
 
 struct reg_8 {
        u16 addr;
@@ -83,6 +99,13 @@ 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*/
@@ -96,6 +119,7 @@ struct camera_common_pdata {
        struct camera_common_regulators regulators;
        bool use_cam_gpio;
        bool has_eeprom;
+       struct camera_common_mode_info *mode_info;
 };
 
 struct camera_common_eeprom_data {
@@ -230,6 +254,8 @@ 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(