summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Breczinski <pbreczinski@nvidia.com>2012-12-06 15:17:50 -0800
committerHarshada Kale <hkale@nvidia.com>2013-06-12 05:02:46 -0700
commit74c042d0666dd32f6f0a314bcbf618c08cafbd11 (patch)
treecac455555c53e857ef0a4c54d8c2e449aa0e5850
parent753d1b6a2a7b8d360e868d28637411d77ebf5ac4 (diff)
media: video: tegra: fuse id support
Adds support to read fuse ID from OTP memory on ov2710, ov9726, ov9772, ar0832, and imx091 sensors. Also includes macro-enabled fuse ID programming for ov2710. Adjusts data structure used by fuse ID ioctl to include a field for fuse ID size. Required by nvcamera version 1.8.0 Required by NVCS version 4.10.0 Bug 1198663 Change-Id: Ib3bb0e100e49aea2c6ce13cd069862476d7f4bb6 Signed-off-by: Phil Breczinski <pbreczinski@nvidia.com> Reviewed-on: http://git-master/r/169187 (cherry picked from commit 0ce57617ee1f735759333a589aa2890559053fe0) Reviewed-on: http://git-master/r/232254 Reviewed-by: Brian Bamsch <bbamsch@nvidia.com> Tested-by: Brian Bamsch <bbamsch@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Jon Mayo <jmayo@nvidia.com>
-rw-r--r--drivers/media/video/tegra/ar0832_main.c85
-rw-r--r--drivers/media/video/tegra/imx091.c39
-rw-r--r--drivers/media/video/tegra/imx132.c25
-rw-r--r--drivers/media/video/tegra/imx135.c14
-rw-r--r--drivers/media/video/tegra/ov2710.c75
-rw-r--r--drivers/media/video/tegra/ov5650.c26
-rw-r--r--drivers/media/video/tegra/ov9726.c50
-rw-r--r--drivers/media/video/tegra/ov9772.c40
-rw-r--r--include/media/ar0832_main.h5
-rw-r--r--include/media/imx132.h10
-rw-r--r--include/media/imx135.h8
-rw-r--r--include/media/nvc.h6
-rw-r--r--include/media/ov2710.h3
-rw-r--r--include/media/ov5650.h9
-rw-r--r--include/media/ov9726.h3
15 files changed, 337 insertions, 61 deletions
diff --git a/drivers/media/video/tegra/ar0832_main.c b/drivers/media/video/tegra/ar0832_main.c
index c8859acc5929..58d07b53d41f 100644
--- a/drivers/media/video/tegra/ar0832_main.c
+++ b/drivers/media/video/tegra/ar0832_main.c
@@ -1,7 +1,7 @@
/*
* ar0832_main.c - Aptina AR0832 8M Bayer type sensor driver
*
-* Copyright (c) 2011, NVIDIA, All Rights Reserved.
+* Copyright (c) 2011-2013, NVIDIA CORPORATION, All Rights Reserved.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
@@ -24,13 +24,14 @@
#include <linux/module.h>
#include <media/ar0832_main.h>
-
+#include <media/nvc.h>
#define POS_ACTUAL_LOW 0
#define POS_ACTUAL_HIGH 255
-#define SETTLE_TIME 100
-#define AR0832_SLEW_RATE_DISABLED 0
-#define AR0832_SLEW_RATE_SLOWEST 7
+#define SETTLE_TIME 100
+#define AR0832_SLEW_RATE_DISABLED 0
+#define AR0832_SLEW_RATE_SLOWEST 7
+#define AR0832_FUSE_ID_SIZE 16
struct ar0832_sensor_info {
@@ -63,6 +64,7 @@ struct ar0832_dev {
int is_stereo;
u16 sensor_id_data;
struct dentry *debugdir;
+ struct nvc_fuseid fuse_id;
};
#define UpperByte16to8(x) ((u8)((x & 0xFF00) >> 8))
@@ -2116,6 +2118,63 @@ static long ar0832_set_focuser_capabilities(struct ar0832_dev *dev,
return 0;
}
+static int ar0832_get_fuseid(struct ar0832_dev *dev)
+{
+ int ret = 0;
+ int i, timeout;
+ __u16 bak;
+ struct i2c_client *i2c_client = dev->i2c_client;
+
+ if (dev->fuse_id.size)
+ return 0;
+
+ ret = ar0832_write_reg16(i2c_client, 0x3052, 0x2704);
+ ret |= ar0832_read_reg16(i2c_client, 0x3054, &bak);
+ ret |= ar0832_write_reg16(i2c_client, 0x3054, bak | 0x0100);
+ ret |= ar0832_read_reg16(i2c_client, 0x3050, &bak);
+ ret |= ar0832_write_reg16(i2c_client, 0x3050, bak & 0x00ff);
+ ret |= ar0832_write_reg16(i2c_client, 0x3054, 0x0008);
+ ret |= ar0832_read_reg16(i2c_client, 0x304a, &bak);
+ ret |= ar0832_write_reg16(i2c_client, 0x304a, bak | 0x0010);
+
+ timeout = 0;
+ while (!(bak & 0x0020)) {
+ ret |= ar0832_read_reg16(i2c_client, 0x304a, &bak);
+ timeout += 1;
+ if (timeout >= 100) {
+ pr_info("ar0832: fuse ID read timed out\n");
+ return -EFAULT;
+ }
+ }
+
+ if (bak & 0x0040)
+ pr_info("ar0832: fuse ID read successfully\n");
+ else {
+ pr_info("ar0832: fuse ID read failed\n");
+ return -EFAULT;
+ }
+
+ /* OTP memory on ar0832 is larger than we are checking - may
+ * may want to change which bytes are read in the future
+ */
+ dev->fuse_id.size = AR0832_FUSE_ID_SIZE;
+ for (i = 0; i < 8; i++) {
+ if (i * 2 < dev->fuse_id.size) {
+ ret |= ar0832_read_reg16(i2c_client, 0x3800 + i, &bak);
+ dev->fuse_id.data[i * 2] =
+ (__u8)((bak >> 8) & 0x00ff);
+ if (i * 2 + 1 < dev->fuse_id.size)
+ dev->fuse_id.data[i * 2 + 1] =
+ (__u8)(bak & 0x00ff);
+ }
+ }
+
+ if (ret)
+ dev->fuse_id.size = 0;
+
+ return ret;
+}
+
static long ar0832_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -2283,6 +2342,22 @@ static long ar0832_ioctl(struct file *file,
}
return 0;
+ case AR0832_IOCTL_GET_FUSEID:
+ {
+ err = ar0832_get_fuseid(dev);
+ if (err) {
+ pr_err("%s %d %d\n", __func__, __LINE__, err);
+ return err;
+ }
+ if (copy_to_user((void __user *)arg,
+ &dev->fuse_id,
+ sizeof(struct nvc_fuseid))) {
+ pr_info("%s %d\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ return 0;
+ }
+
default:
dev_err(&i2c_client->dev, "(error) %s NONE IOCTL\n",
__func__);
diff --git a/drivers/media/video/tegra/imx091.c b/drivers/media/video/tegra/imx091.c
index 4137f0387622..59cde73af54d 100644
--- a/drivers/media/video/tegra/imx091.c
+++ b/drivers/media/video/tegra/imx091.c
@@ -44,6 +44,7 @@
#define IMX091_LENS_VIEW_ANGLE_V 60400 /* / _INT2FLOAT_DIVISOR */
#define IMX091_WAIT_MS 3
#define IMX091_I2C_TABLE_MAX_ENTRIES 400
+#define IMX091_FUSE_ID_SIZE 8
static u16 imx091_ids[] = {
0x0091,
@@ -88,6 +89,7 @@ struct imx091_info {
struct dentry *debugfs_root;
u16 i2c_reg;
#endif
+ struct nvc_fuseid fuse_id;
};
struct imx091_reg {
@@ -2273,6 +2275,27 @@ static int imx091_param_wr(struct imx091_info *info, unsigned long arg)
}
}
+static int imx091_get_fuse_id(struct imx091_info *info)
+{
+ int ret, i;
+
+ if (info->fuse_id.size)
+ return 0;
+
+ ret = imx091_i2c_wr8(info, 0x34C9, 0x10);
+
+ for (i = 0; i < IMX091_FUSE_ID_SIZE ; i++) {
+ ret |= imx091_i2c_rd8(info,
+ 0x3580 + i,
+ &info->fuse_id.data[i]);
+ }
+
+ if (!ret)
+ info->fuse_id.size = i;
+
+ return ret;
+}
+
static long imx091_ioctl(struct file *file,
unsigned int cmd,
unsigned long arg)
@@ -2289,6 +2312,22 @@ static long imx091_ioctl(struct file *file,
int err;
switch (cmd) {
+ case NVC_IOCTL_FUSE_ID:
+ err = imx091_get_fuse_id(info);
+
+ if (err) {
+ pr_err("%s %d %d\n", __func__, __LINE__, err);
+ return err;
+ }
+ if (copy_to_user((void __user *)arg,
+ &info->fuse_id,
+ sizeof(struct nvc_fuseid))) {
+ pr_err("%s: %d: fail copy fuse id to user space\n",
+ __func__, __LINE__);
+ return -EFAULT;
+ }
+ return 0;
+
case NVC_IOCTL_PARAM_WR:
err = imx091_param_wr(info, arg);
return err;
diff --git a/drivers/media/video/tegra/imx132.c b/drivers/media/video/tegra/imx132.c
index d2e3abf656d5..2dcb211cdbcd 100644
--- a/drivers/media/video/tegra/imx132.c
+++ b/drivers/media/video/tegra/imx132.c
@@ -24,6 +24,10 @@
#include <linux/uaccess.h>
#include <linux/regulator/consumer.h>
#include <media/imx132.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <media/nvc.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -39,7 +43,7 @@ struct imx132_info {
struct miscdevice miscdev_info;
int mode;
struct imx132_power_rail power;
- struct imx132_sensordata sensor_data;
+ struct nvc_fuseid fuse_id;
struct i2c_client *i2c_client;
struct imx132_platform_data *pdata;
atomic_t in_use;
@@ -48,6 +52,7 @@ struct imx132_info {
#define IMX132_TABLE_WAIT_MS 0
#define IMX132_TABLE_END 1
#define IMX132_WAIT_MS 5
+#define IMX132_FUSE_ID_SIZE 8
static struct imx132_reg mode_1976x1200[] = {
/* Stand by */
@@ -505,13 +510,13 @@ imx132_set_group_hold(struct imx132_info *info, struct imx132_ae *ae)
return 0;
}
-static int imx132_get_sensor_id(struct imx132_info *info)
+static int imx132_get_fuse_id(struct imx132_info *info)
{
int ret = 0;
int i;
u8 bak = 0;
- if (info->sensor_data.fuse_id_size)
+ if (info->fuse_id.size)
return 0;
/*
@@ -520,13 +525,13 @@ static int imx132_get_sensor_id(struct imx132_info *info)
*/
ret |= imx132_write_reg(info->i2c_client, 0x34C9, 0x10);
- for (i = 0; i < NUM_OF_SENSOR_ID_SPECIFIC_REG ; i++) {
+ for (i = 0; i < IMX132_FUSE_ID_SIZE ; i++) {
ret |= imx132_read_reg(info->i2c_client, 0x3580 + i, &bak);
- info->sensor_data.fuse_id[i] = bak;
+ info->fuse_id.data[i] = bak;
}
if (!ret)
- info->sensor_data.fuse_id_size = i;
+ info->fuse_id.size = i;
return ret;
}
@@ -572,9 +577,9 @@ imx132_ioctl(struct file *file,
}
return 0;
}
- case IMX132_IOCTL_GET_SENSORDATA:
+ case IMX132_IOCTL_GET_FUSEID:
{
- err = imx132_get_sensor_id(info);
+ err = imx132_get_fuse_id(info);
if (err) {
dev_err(dev, "%s:Failed to get fuse id info.\n",
@@ -582,8 +587,8 @@ imx132_ioctl(struct file *file,
return err;
}
if (copy_to_user((void __user *)arg,
- &info->sensor_data,
- sizeof(struct imx132_sensordata))) {
+ &info->fuse_id,
+ sizeof(struct nvc_fuseid))) {
dev_info(dev, "%s:Fail copy fuse id to user space\n",
__func__);
return -EFAULT;
diff --git a/drivers/media/video/tegra/imx135.c b/drivers/media/video/tegra/imx135.c
index efff02e05fd5..0e123fe6915d 100644
--- a/drivers/media/video/tegra/imx135.c
+++ b/drivers/media/video/tegra/imx135.c
@@ -40,7 +40,7 @@ struct imx135_info {
struct miscdevice miscdev_info;
int mode;
struct imx135_power_rail power;
- struct imx135_sensordata sensor_data;
+ struct nvc_fuseid fuse_id;
struct i2c_client *i2c_client;
struct imx135_platform_data *pdata;
struct mutex imx135_camera_lock;
@@ -2056,7 +2056,7 @@ static int imx135_get_sensor_id(struct imx135_info *info)
u8 bak = 0;
pr_info("%s\n", __func__);
- if (info->sensor_data.fuse_id_size)
+ if (info->fuse_id.size)
return 0;
/* Note 1: If the sensor does not have power at this point
@@ -2066,11 +2066,11 @@ static int imx135_get_sensor_id(struct imx135_info *info)
ret |= imx135_write_reg(info->i2c_client, 0x3B00, 0x01);
for (i = 0; i < 9 ; i++) {
ret |= imx135_read_reg(info->i2c_client, 0x3B24 + i, &bak);
- info->sensor_data.fuse_id[i] = bak;
+ info->fuse_id.data[i] = bak;
}
if (!ret)
- info->sensor_data.fuse_id_size = i;
+ info->fuse_id.size = i;
/* Note 2: Need to clean up any action carried out in Note 1 */
@@ -2123,7 +2123,7 @@ imx135_ioctl(struct file *file,
}
return 0;
}
- case IMX135_IOCTL_GET_SENSORDATA:
+ case IMX135_IOCTL_GET_FUSEID:
{
err = imx135_get_sensor_id(info);
@@ -2131,8 +2131,8 @@ imx135_ioctl(struct file *file,
pr_err("%s:Failed to get fuse id info.\n", __func__);
return err;
}
- if (copy_to_user((void __user *)arg, &info->sensor_data,
- sizeof(struct imx135_sensordata))) {
+ if (copy_to_user((void __user *)arg, &info->fuse_id,
+ sizeof(struct nvc_fuseid))) {
pr_info("%s:Failed to copy fuse id to user space\n",
__func__);
return -EFAULT;
diff --git a/drivers/media/video/tegra/ov2710.c b/drivers/media/video/tegra/ov2710.c
index a0ad166bd36c..28c041befb3a 100644
--- a/drivers/media/video/tegra/ov2710.c
+++ b/drivers/media/video/tegra/ov2710.c
@@ -1,7 +1,7 @@
/*
* ov2710.c - ov2710 sensor driver
*
- * Copyright (c) 2011, NVIDIA, All Rights Reserved.
+ * Copyright (c) 2011-2013, NVIDIA CORPORATION, All Rights Reserved.
*
* Contributors:
* erik lilliebjerg <elilliebjerg@nvidia.com>
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <media/ov2710.h>
+#include <media/nvc.h>
#define SIZEOF_I2C_TRANSBUF 32
@@ -35,8 +36,15 @@ struct ov2710_info {
struct i2c_client *i2c_client;
struct ov2710_platform_data *pdata;
u8 i2c_trans_buf[SIZEOF_I2C_TRANSBUF];
+ struct nvc_fuseid fuse_id;
};
+#define OV2710_FUSE_ID_SIZE 5
+
+#define OV2710_FUSE_ID_PROGRAM_ENABLE 0
+#define OV2710_FUSE_ID_PROGRAM_TARGET (0x3d00 + 0)
+#define OV2710_FUSE_ID_PROGRAM_VALUE 0x00
+
#define OV2710_TABLE_WAIT_MS 0
#define OV2710_TABLE_END 1
#define OV2710_MAX_RETRIES 3
@@ -618,6 +626,55 @@ static int ov2710_get_status(struct ov2710_info *info, u8 *status)
}
+static int ov2710_get_fuse_id(struct ov2710_info *info)
+{
+ int err, i;
+
+#if OV2710_FUSE_ID_PROGRAM_ENABLE
+/* Program the OTP fuse id memory on the sensor.
+ * NOTE: This cannot be reversed.
+ */
+ err = ov2710_write_reg(info->i2c_client, 0x3d10, 0x00);
+ for (i = 0; i < 16; i++)
+ err = ov2710_write_reg(info->i2c_client, 0x3d00 + i, 0x00);
+ err = ov2710_write_reg(info->i2c_client, 0x3d10, 0x01);
+ msleep(20);
+ err = ov2710_write_reg(info->i2c_client, 0x3d10, 0x00);
+ msleep(20);
+ for (i = 0; i < 16; i++)
+ ov2710_read_reg(info->i2c_client,
+ 0x3d00 + i,
+ &(info->fuse_id.data[i]));
+ pr_info("ov2710: fuse id: program reg 0x%x to 0x%x\n",
+ OV2710_FUSE_ID_PROGRAM_TARGET,
+ OV2710_FUSE_ID_PROGRAM_VALUE);
+ err = ov2710_write_reg(info->i2c_client,
+ OV2710_FUSE_ID_PROGRAM_TARGET,
+ OV2710_FUSE_ID_PROGRAM_VALUE);
+ err = ov2710_write_reg(info->i2c_client, 0x3d10, 0x02);
+ msleep(20);
+ err = ov2710_write_reg(info->i2c_client, 0x3d10, 0x03);
+#endif
+
+ if (info->fuse_id.size)
+ return 0;
+
+ err = ov2710_write_reg(info->i2c_client, 0x3d10, 0x01);
+ err = ov2710_write_reg(info->i2c_client, 0x3d10, 0x00);
+
+ for (i = 0; i < OV2710_FUSE_ID_SIZE; i++) {
+ err |= ov2710_read_reg(info->i2c_client,
+ 0x3d00 + i,
+ &(info->fuse_id.data[i]));
+ }
+
+ if (!err)
+ info->fuse_id.size = i;
+
+ return err;
+}
+
+
static long ov2710_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -666,6 +723,22 @@ static long ov2710_ioctl(struct file *file,
}
return 0;
}
+ case OV2710_IOCTL_GET_FUSEID:
+ {
+ err = ov2710_get_fuse_id(info);
+ if (err) {
+ pr_err("%s %d %d\n", __func__, __LINE__, err);
+ return err;
+ }
+ if (copy_to_user((void __user *)arg,
+ &info->fuse_id,
+ sizeof(struct nvc_fuseid))) {
+ pr_err("%s: %d: fail copy fuse id to user space\n",
+ __func__, __LINE__);
+ return -EFAULT;
+ }
+ return 0;
+ }
default:
return -EINVAL;
}
diff --git a/drivers/media/video/tegra/ov5650.c b/drivers/media/video/tegra/ov5650.c
index 1ef23a403486..35cec0805936 100644
--- a/drivers/media/video/tegra/ov5650.c
+++ b/drivers/media/video/tegra/ov5650.c
@@ -2,6 +2,7 @@
* ov5650.c - ov5650 sensor driver
*
* Copyright (C) 2011 Google Inc.
+ * Copyright (c) 2013, NVIDIA CORPORATION. All Rights Reserved.
*
* Contributors:
* Rebecca Schultz Zavin <rebecca@android.com>
@@ -23,6 +24,7 @@
#include <media/ov5650.h>
#include <video/tegra_camera.h>
+#include <media/nvc.h>
#define SIZEOF_I2C_TRANSBUF 32
@@ -41,7 +43,7 @@ struct ov5650_info {
enum StereoCameraMode camera_mode;
struct ov5650_sensor left;
struct ov5650_sensor right;
- struct ov5650_sensordata sensor_data;
+ struct nvc_fuseid fuse_id;
struct mutex mutex_le;
struct mutex mutex_ri;
int power_refcnt_le;
@@ -54,6 +56,7 @@ static struct ov5650_info *stereo_ov5650_info;
#define OV5650_TABLE_WAIT_MS 0
#define OV5650_TABLE_END 1
#define OV5650_MAX_RETRIES 3
+#define OV5650_FUSE_ID_SIZE 5
static struct ov5650_reg tp_none_seq[] = {
{0x5046, 0x00},
@@ -1293,27 +1296,27 @@ static int ov5650_set_power(struct ov5650_info *info, int powerLevel)
return 0;
}
-static int ov5650_get_sensor_id(struct ov5650_info *info)
+static int ov5650_get_fuseid(struct ov5650_info *info)
{
int ret = 0;
int i;
u8 bak;
pr_info("%s\n", __func__);
- if (info->sensor_data.fuse_id_size)
+ if (info->fuse_id.size)
return 0;
ov5650_set_power(info, 1);
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < OV5650_FUSE_ID_SIZE; i++) {
ret |= ov5650_write_reg_helper(info, 0x3d00, i);
ret |= ov5650_read_reg_helper(info, 0x3d04,
&bak);
- info->sensor_data.fuse_id[i] = bak;
+ info->fuse_id.data[i] = bak;
}
if (!ret)
- info->sensor_data.fuse_id_size = i;
+ info->fuse_id.size = i;
ov5650_set_power(info, 0);
return ret;
@@ -1393,17 +1396,18 @@ static long ov5650_ioctl(struct file *file,
}
return ov5650_set_group_hold(info, &ae);
}
- case OV5650_IOCTL_GET_SENSORDATA:
+ case OV5650_IOCTL_GET_FUSEID:
{
- err = ov5650_get_sensor_id(info);
+ err = ov5650_get_fuseid(info);
if (err) {
pr_err("%s %d %d\n", __func__, __LINE__, err);
return err;
}
if (copy_to_user((void __user *)arg,
- &info->sensor_data,
- sizeof(struct ov5650_sensordata))) {
- pr_info("%s %d\n", __func__, __LINE__);
+ &info->fuse_id,
+ sizeof(struct nvc_fuseid))) {
+ pr_err("%s: %d: fail copy fuse id to user space\n",
+ __func__, __LINE__);
return -EFAULT;
}
return 0;
diff --git a/drivers/media/video/tegra/ov9726.c b/drivers/media/video/tegra/ov9726.c
index 129591b9af10..04a87a5c1f2a 100644
--- a/drivers/media/video/tegra/ov9726.c
+++ b/drivers/media/video/tegra/ov9726.c
@@ -1,7 +1,7 @@
/*
* ov9726.c - ov9726 sensor driver
*
- * Copyright (c) 2011, NVIDIA, All Rights Reserved.
+ * Copyright (c) 2011-2013, NVIDIA CORPORATION, All Rights Reserved.
*
* Contributors:
* Charlie Huang <chahuang@nvidia.com>
@@ -25,6 +25,9 @@
#include <linux/module.h>
#include <media/ov9726.h>
+#include <media/nvc.h>
+
+#define OV9726_FUSE_ID_SIZE 5
struct ov9726_power_rail {
struct regulator *sen_1v8_reg;
@@ -39,6 +42,7 @@ struct ov9726_devinfo {
atomic_t in_use;
__u32 mode;
struct ov9726_reg grphold_temp[10];
+ struct nvc_fuseid fuse_id;
};
static struct ov9726_reg mode_1280x720[] = {
@@ -699,6 +703,34 @@ ov9726_set_mode_exit:
return err;
}
+static int ov9726_get_fuse_id(struct ov9726_devinfo *dev)
+{
+ int ret, i;
+ __u8 bak;
+ struct i2c_client *i2c_client = dev->i2c_client;
+
+ if (dev->fuse_id.size)
+ return 0;
+
+ ret = ov9726_write_reg8(i2c_client, 0x3d21, 0x01);
+
+ bak = 0x80;
+ while (bak & 0x80)
+ ret |= ov9726_read_reg8(i2c_client, 0x3d21, &bak);
+
+ for (i = 0; i < OV9726_FUSE_ID_SIZE; i++) {
+ ret |= ov9726_read_reg8(i2c_client,
+ 0x3d00 + i,
+ &dev->fuse_id.data[i]);
+ }
+ ret = ov9726_write_reg8(i2c_client, 0x3d21, 0x00);
+
+ if (!ret)
+ dev->fuse_id.size = i;
+
+ return ret;
+}
+
static long
ov9726_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
@@ -754,6 +786,22 @@ ov9726_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
break;
}
+ case OV9726_IOCTL_GET_FUSEID:
+ {
+ err = ov9726_get_fuse_id(dev);
+ if (err) {
+ pr_err("%s %d %d\n", __func__, __LINE__, err);
+ return err;
+ }
+ if (copy_to_user((void __user *)arg,
+ &dev->fuse_id,
+ sizeof(struct nvc_fuseid))) {
+ pr_err("%s: %d: fail copy fuse id to user space\n",
+ __func__, __LINE__);
+ return -EFAULT;
+ }
+ return 0;
+ }
default:
err = -EINVAL;
break;
diff --git a/drivers/media/video/tegra/ov9772.c b/drivers/media/video/tegra/ov9772.c
index 1bdad09d1fd2..9b6041baed29 100644
--- a/drivers/media/video/tegra/ov9772.c
+++ b/drivers/media/video/tegra/ov9772.c
@@ -141,6 +141,7 @@
#include <linux/module.h>
#include <media/ov9772.h>
+#include <media/nvc.h>
#define OV9772_ID 0x9772
#define OV9772_SENSOR_TYPE NVC_IMAGER_TYPE_RAW
@@ -159,6 +160,7 @@
#define OV9772_LENS_VIEW_ANGLE_H 60000 /* / _INT2FLOAT_DIVISOR */
#define OV9772_LENS_VIEW_ANGLE_V 60000 /* / _INT2FLOAT_DIVISOR */
#define OV9772_I2C_TABLE_MAX_ENTRIES 400
+#define OV9772_FUSE_ID_SIZE 5
/* comment out definition to disable mode */
#define OV9772_ENABLE_1284x724
@@ -198,6 +200,7 @@ struct ov9772_info {
struct nvc_imager_static_nvc sdata;
u8 i2c_buf[OV9772_SIZEOF_I2C_BUF];
u8 bin_en;
+ struct nvc_fuseid fuse_id;
};
struct ov9772_reg {
@@ -1822,6 +1825,27 @@ static int ov9772_param_wr(struct ov9772_info *info, unsigned long arg)
}
}
+static int ov9772_get_fuse_id(struct ov9772_info *info)
+{
+ int err, i;
+
+ if (info->fuse_id.size)
+ return 0;
+
+ err = ov9772_i2c_wr8(info, 0x3d81, 0x01);
+
+ for (i = 0; i < OV9772_FUSE_ID_SIZE; i++) {
+ err |= ov9772_i2c_rd8(info,
+ 0x3d00 + i,
+ &info->fuse_id.data[i]);
+ }
+
+ if (!err)
+ info->fuse_id.size = OV9772_FUSE_ID_SIZE;
+
+ return err;
+}
+
static long ov9772_ioctl(struct file *file,
unsigned int cmd,
unsigned long arg)
@@ -1838,6 +1862,22 @@ static long ov9772_ioctl(struct file *file,
int err;
switch (cmd) {
+ case NVC_IOCTL_FUSE_ID:
+ err = ov9772_get_fuse_id(info);
+ if (err) {
+ pr_err("%s %d %d\n", __func__, __LINE__, err);
+ return err;
+ }
+ if (copy_to_user((void __user *)arg,
+ &info->fuse_id,
+ sizeof(struct nvc_fuseid))) {
+ pr_err("%s: %d: fail copy fuse id to user space\n",
+ __func__, __LINE__);
+ return -EFAULT;
+ }
+
+ return 0;
+
case NVC_IOCTL_PARAM_WR:
err = ov9772_param_wr(info, arg);
return err;
diff --git a/include/media/ar0832_main.h b/include/media/ar0832_main.h
index 3cc1afcb941a..eebd0144c321 100644
--- a/include/media/ar0832_main.h
+++ b/include/media/ar0832_main.h
@@ -1,7 +1,7 @@
/*
* ar0832_main.h
*
-* Copyright (c) 2011, NVIDIA, All Rights Reserved.
+* Copyright (c) 2011-2013, NVIDIA CORPORATION, All Rights Reserved.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
@@ -30,6 +30,8 @@
#define AR0832_IOCTL_GET_SENSOR_ID _IOR('o', 0x12, __u16)
#define AR0832_FOCUSER_IOCTL_SET_CONFIG _IOW('o', 0x13, struct nv_focuser_config)
+#define AR0832_IOCTL_GET_FUSEID _IOR('o', 0x14, struct nvc_fuseid)
+
#define AR0832_SENSOR_ID_8141 0x1006
#define AR0832_SENSOR_ID_8140 0x3006
@@ -87,7 +89,6 @@ struct ar0832_stereo_region {
struct ar0832_point image_end;
};
-
#ifdef __KERNEL__
struct ar0832_platform_data {
int (*power_on)(struct device *, int is_stereo);
diff --git a/include/media/imx132.h b/include/media/imx132.h
index 01d7c67d94b7..3d6237398be9 100644
--- a/include/media/imx132.h
+++ b/include/media/imx132.h
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2012 NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2012-2013 NVIDIA CORPORATION. All rights reserved.
*
* NVIDIA Corporation and its licensors retain all intellectual property
* and proprietary rights in and to this software and related documentation
@@ -18,7 +18,7 @@
#define IMX132_IOCTL_SET_FRAME_LENGTH _IOW('o', 3, __u32)
#define IMX132_IOCTL_SET_COARSE_TIME _IOW('o', 4, __u32)
#define IMX132_IOCTL_SET_GAIN _IOW('o', 5, __u16)
-#define IMX132_IOCTL_GET_SENSORDATA _IOR('o', 6, struct imx132_sensordata)
+#define IMX132_IOCTL_GET_FUSEID _IOR('o', 6, struct nvc_fuseid)
#define IMX132_IOCTL_SET_GROUP_HOLD _IOW('o', 7, struct imx132_ae)
/* IMX132 registers */
@@ -31,7 +31,6 @@
#define NUM_OF_FRAME_LEN_REG 2
#define NUM_OF_COARSE_TIME_REG 2
-#define NUM_OF_SENSOR_ID_SPECIFIC_REG 8
struct imx132_mode {
int xres;
int yres;
@@ -49,11 +48,6 @@ struct imx132_ae {
__u8 gain_enable;
};
-struct imx132_sensordata {
- __u32 fuse_id_size;
- __u8 fuse_id[16];
-};
-
#ifdef __KERNEL__
struct imx132_power_rail {
struct regulator *dvdd;
diff --git a/include/media/imx135.h b/include/media/imx135.h
index a7c00b054145..738e0eea9e09 100644
--- a/include/media/imx135.h
+++ b/include/media/imx135.h
@@ -20,7 +20,7 @@
#define IMX135_IOCTL_SET_FRAME_LENGTH _IOW('o', 3, __u32)
#define IMX135_IOCTL_SET_COARSE_TIME _IOW('o', 4, __u32)
#define IMX135_IOCTL_SET_GAIN _IOW('o', 5, __u16)
-#define IMX135_IOCTL_GET_SENSORDATA _IOR('o', 6, struct imx135_sensordata)
+#define IMX135_IOCTL_GET_FUSEID _IOR('o', 6, struct nvc_fuseid)
#define IMX135_IOCTL_SET_GROUP_HOLD _IOW('o', 7, struct imx135_ae)
#define IMX135_IOCTL_SET_HDR_COARSE_TIME _IOW('o', 8, struct imx135_hdr)
#define IMX135_IOCTL_SET_POWER _IOW('o', 20, __u32)
@@ -53,11 +53,6 @@ struct imx135_ae {
__u8 gain_enable;
};
-struct imx135_sensordata {
- __u32 fuse_id_size;
- __u8 fuse_id[16];
-};
-
struct imx135_flash_control {
u8 enable;
u8 edge_trig_en;
@@ -66,7 +61,6 @@ struct imx135_flash_control {
u16 delay_frm;
};
-
#ifdef __KERNEL__
struct imx135_power_rail {
struct regulator *dvdd;
diff --git a/include/media/nvc.h b/include/media/nvc.h
index 4158469758bf..4e722f31d6ab 100644
--- a/include/media/nvc.h
+++ b/include/media/nvc.h
@@ -169,6 +169,7 @@ enum nvc_params_isp {
#define NVC_IOCTL_PARAM_RD _IOWR('o', 105, struct nvc_param)
#define NVC_IOCTL_PARAM_ISP_RD _IOWR('o', 200, struct nvc_param_isp)
#define NVC_IOCTL_PARAM_ISP_WR _IOWR('o', 201, struct nvc_param_isp)
+#define NVC_IOCTL_FUSE_ID _IOWR('o', 202, struct nvc_fuseid)
#ifdef __KERNEL__
@@ -282,6 +283,11 @@ struct nvc_gpio {
bool flag; /* scratch flag for driver implementation */
};
+struct nvc_fuseid {
+ __u32 size;
+ __u8 data[16];
+};
+
#endif /* __KERNEL__ */
#endif /* __NVC_H__ */
diff --git a/include/media/ov2710.h b/include/media/ov2710.h
index a3e070b5ade4..85b03ed9541a 100644
--- a/include/media/ov2710.h
+++ b/include/media/ov2710.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Motorola, Inc.
- * Copyright (C) 2011 NVIDIA Corporation.
+ * Copyright (C) 2011-2013 NVIDIA CORPORATION. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -28,6 +28,7 @@
#define OV2710_IOCTL_SET_GAIN _IOW('o', 4, __u16)
#define OV2710_IOCTL_GET_STATUS _IOR('o', 5, __u8)
#define OV2710_IOCTL_SET_GROUP_HOLD _IOW('o', 6, struct ov2710_ae)
+#define OV2710_IOCTL_GET_FUSEID _IOW('o', 7, struct nvc_fuseid)
struct ov2710_mode {
int xres;
diff --git a/include/media/ov5650.h b/include/media/ov5650.h
index f1f2f67acd56..d9f5a848ca6c 100644
--- a/include/media/ov5650.h
+++ b/include/media/ov5650.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Motorola, Inc.
- * Copyright (C) 2011 NVIDIA Corporation.
+ * Copyright (C) 2011-2013 NVIDIA CORPORATION. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -32,7 +32,7 @@
#define OV5650_IOCTL_SET_GROUP_HOLD _IOW('o', 8, struct ov5650_ae)
#define OV5650_IOCTL_SET_CAMERA_MODE _IOW('o', 10, __u32)
#define OV5650_IOCTL_SYNC_SENSORS _IOW('o', 11, __u32)
-#define OV5650_IOCTL_GET_SENSORDATA _IOR('o', 12, struct ov5650_sensordata)
+#define OV5650_IOCTL_GET_FUSEID _IOR('o', 12, struct nvc_fuseid)
/* OV5650 registers */
#define OV5650_SRM_GRUP_ACCESS (0x3212)
@@ -65,11 +65,6 @@ enum ov5650_test_pattern {
TEST_PATTERN_CHECKERBOARD
};
-struct ov5650_sensordata {
- __u32 fuse_id_size;
- __u8 fuse_id[16];
-};
-
struct ov5650_mode {
int xres;
int yres;
diff --git a/include/media/ov9726.h b/include/media/ov9726.h
index e942000380b4..795d03519e92 100644
--- a/include/media/ov9726.h
+++ b/include/media/ov9726.h
@@ -1,7 +1,7 @@
/*
* ov9726.h
*
-* Copyright (c) 2011, NVIDIA, All Rights Reserved.
+* Copyright (c) 2011-2013, NVIDIA CORPORATION, All Rights Reserved.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
@@ -21,6 +21,7 @@
#define OV9726_IOCTL_SET_GAIN _IOW('o', 4, __u16)
#define OV9726_IOCTL_GET_STATUS _IOR('o', 5, __u8)
#define OV9726_IOCTL_SET_GROUP_HOLD _IOW('o', 6, struct ov9726_ae)
+#define OV9726_IOCTL_GET_FUSEID _IOR('o', 7, struct nvc_fuseid)
struct ov9726_mode {
int mode_id;