From 19e9893e5d92c25bd0c4b90a9f799ff52dfe5221 Mon Sep 17 00:00:00 2001 From: David Cohen Date: Fri, 2 Dec 2011 18:12:33 +0200 Subject: [PATCH] [PORT FROM R2] atomisp: mt9e013: add fuseid data to sensor's private data BZ: 21906 ORIG-BZ: 15475 FUSEID information is necessary to userspace. This patch adds FUSEID to sensor's private data. Change-Id: I12eb18309de497db8d9983dc4c632e5339cd2096 Orig-Change-Id: Ic9995c477d9930e87ef958a73d3ac9b64d39b29c Signed-off-by: David Cohen Reviewed-on: http://android.intel.com:8080/27052 Reviewed-by: Jong-a-lock, Robert Reviewed-by: Tuppurainen, Miikka Reviewed-by: Koskinen, Ilkka Tested-by: Koski, Anttu Reviewed-by: buildbot Tested-by: buildbot Reviewed-on: http://android.intel.com:8080/33538 Reviewed-by: Lampila, KalleX Reviewed-by: Gross, Mark Reviewed-by: Koski, Anttu --- drivers/media/video/mt9e013.c | 68 +++++++++++++++++++++++++++++++++++++------ drivers/media/video/mt9e013.h | 5 +++- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/mt9e013.c b/drivers/media/video/mt9e013.c index 8d3818c..ccae716 100644 --- a/drivers/media/video/mt9e013.c +++ b/drivers/media/video/mt9e013.c @@ -837,39 +837,83 @@ static void *mt9e013_otp_read(struct v4l2_subdev *sd) return buf; } +static u8 *mt9e013_fuseid_read(struct v4l2_subdev *sd) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + u8 data[MT9E013_FUSEID_SIZE]; + u8 *fuseid; + int ret, i; + + ret = mt9e013_read_reg_array(client, MT9E013_FUSEID_SIZE, + MT9E013_FUSEID_START_ADDR, &data); + if (ret < 0) { + v4l2_err(client, "%s: error reading FUSEID.\n", __func__); + return ERR_PTR(ret); + } + + fuseid = kmalloc(sizeof(*fuseid) * MT9E013_FUSEID_SIZE, GFP_KERNEL); + + if (!fuseid) { + v4l2_err(client, "%s: no memory available when reading " + "FUSEID.\n", __func__); + return ERR_PTR(-ENOMEM); + } + + /* FUSEID is in reverse order */ + for (i = 0; i < MT9E013_FUSEID_SIZE; i++) + fuseid[i] = data[MT9E013_FUSEID_SIZE - i - 1]; + + return fuseid; +} + static int mt9e013_g_priv_int_data(struct v4l2_subdev *sd, struct v4l2_private_int_data *priv) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9e013_device *dev = to_mt9e013_sensor(sd); + u8 *to = priv->data; u32 read_size = priv->size; int ret; /* No OTP data available on sensor */ - if (!dev->otp_data) + if (!dev->otp_data || !dev->fuseid) return -EIO; - if (!priv) - return -EINVAL; - - /* Return correct size */ - priv->size = MT9E013_OTP_DATA_SIZE; - /* No need to copy data if size is 0 */ if (!read_size) - return 0; + goto out; /* Correct read_size value only if bigger than maximum */ if (read_size > MT9E013_OTP_DATA_SIZE) read_size = MT9E013_OTP_DATA_SIZE; - ret = copy_to_user(priv->data, dev->otp_data, read_size); + ret = copy_to_user(to, dev->otp_data, read_size); if (ret) { v4l2_err(client, "%s: failed to copy OTP data to user\n", __func__); return -EFAULT; } + /* No room for FUSEID */ + if (priv->size <= MT9E013_OTP_DATA_SIZE) + goto out; + + read_size = priv->size - MT9E013_OTP_DATA_SIZE; + if (read_size > MT9E013_FUSEID_SIZE) + read_size = MT9E013_FUSEID_SIZE; + to += MT9E013_OTP_DATA_SIZE; + + ret = copy_to_user(to, dev->fuseid, read_size); + if (ret) { + v4l2_err(client, "%s: failed to copy FUSEID to user\n", + __func__); + return -EFAULT; + } + +out: + /* Return correct size */ + priv->size = MT9E013_OTP_DATA_SIZE + MT9E013_FUSEID_SIZE; + return 0; } @@ -1827,6 +1871,7 @@ static int mt9e013_s_config(struct v4l2_subdev *sd, u16 sensor_id; int ret; void *otp_data; + void *fuseid; if (pdata == NULL) return -ENODEV; @@ -1861,6 +1906,10 @@ static int mt9e013_s_config(struct v4l2_subdev *sd, if (!IS_ERR(otp_data)) dev->otp_data = otp_data; + fuseid = mt9e013_fuseid_read(sd); + if (!IS_ERR(fuseid)) + dev->fuseid = fuseid; + /* power off sensor */ ret = mt9e013_s_power(sd, 0); mutex_unlock(&dev->input_lock); @@ -2093,6 +2142,7 @@ static int mt9e013_remove(struct i2c_client *client) dev->platform_data->csi_cfg(sd, 0); v4l2_device_unregister_subdev(sd); kfree(dev->otp_data); + kfree(dev->fuseid); kfree(dev); return 0; diff --git a/drivers/media/video/mt9e013.h b/drivers/media/video/mt9e013.h index 96a6812..144cb19 100644 --- a/drivers/media/video/mt9e013.h +++ b/drivers/media/video/mt9e013.h @@ -358,6 +358,8 @@ struct mt9e013_format { struct s_register_setting *regs; }; +#define MT9E013_FUSEID_SIZE 8 +#define MT9E013_FUSEID_START_ADDR 0x31f4 /* mt9e013 device structure */ struct mt9e013_device { @@ -386,6 +388,7 @@ struct mt9e013_device { s16 number_of_steps; struct mutex input_lock; /* serialize sensor's ioctl */ void *otp_data; + void *fuseid; /* Older VCMs could not maintain the focus position in standby mode. */ bool keeps_focus_pos; }; @@ -606,7 +609,7 @@ static const struct mt9e013_reg mt9e013_init_vcm[] = { {MT9E013_TOK_TERM, {0}, 0} }; -#define RESET_REGISTER {MT9E013_16BIT, {0x301A}, 0x4A18} +#define RESET_REGISTER {MT9E013_16BIT, {0x301A}, 0x4A38} static const struct mt9e013_reg mt9e013_reset_register[] = { RESET_REGISTER, {MT9E013_TOK_TERM, {0}, 0} -- 2.7.4