android_kernel_samsung_msm8226/drivers/media/platform/msm/camera_v2/sensor/sr130pc20_yuv.c

782 lines
23 KiB
C

/* Copyright (c) 2011-2013, The Linux Foundation. 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 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#if 0
#define CONFIG_LOAD_FILE // Enable it for Tunning Binary
#endif
#include "sr130pc20.h"
#if defined (CONFIG_MACH_MILLETWIFIUS_OPEN) || \
defined (CONFIG_MACH_MILLETLTE_VZW) || \
defined (CONFIG_MACH_MILLETLTE_ATT) || \
defined (CONFIG_MACH_MILLETLTE_CAN) || \
defined (CONFIG_MACH_DEGASLTE_SPR) || \
defined (CONFIG_MACH_MILLETLTE_TMO) || \
defined (CONFIG_MACH_DEGASWIFIDTV_LTN)
#include "sr130pc20_yuv_millet_usa.h"
#elif defined (CONFIG_MACH_MATISSEWIFIUS_OPEN) || \
defined (CONFIG_MACH_MATISSELTE_VZW) || \
defined (CONFIG_MACH_MATISSELTE_ATT) || \
defined (CONFIG_MACH_MATISSELTE_USC)
#include "sr130pc20_yuv_matisse_wifi_usa.h"
#elif defined (CONFIG_SEC_MATISSE_PROJECT)
#include "sr130pc20_yuv_matisse.h"
#elif defined (CONFIG_SEC_RUBENS_PROJECT)
#include "sr130pc20_yuv_ruben.h"
#else
#include "sr130pc20_yuv.h"
#endif
#include "msm_sd.h"
#include "camera.h"
#include "msm_cci.h"
#include "msm_camera_dt_util.h"
#ifdef CONFIG_LOAD_FILE
#define SR130PC20_WRITE_LIST(A) \
sr130pc20_regs_from_sd_tunning(A,s_ctrl,#A);
#else
#define SR130PC20_WRITE_LIST(A) \
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_conf_tbl( \
s_ctrl->sensor_i2c_client, A, \
ARRAY_SIZE(A), \
MSM_CAMERA_I2C_BYTE_DATA); CDBG("REGSEQ ****** %s", #A)
#endif
static struct yuv_ctrl sr130pc20_ctrl;
//static int32_t streamon = 0;
static int32_t resolution = MSM_SENSOR_RES_FULL;
#ifdef CONFIG_LOAD_FILE
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
static char *sr130pc20_regs_table;
static int sr130pc20_regs_table_size;
int sr130pc20_regs_from_sd_tunning(struct msm_camera_i2c_reg_conf *settings, struct msm_sensor_ctrl_t *s_ctrl,char * name);
void sr130pc20_regs_table_init(char *filename);
void sr130pc20_regs_table_exit(void);
#endif
// maximum number of chipid and slaveid pairs
// please change accordingly when you add more pairs
#define MAX_NUM_PAIRS 1
// Set of chipid and slaveid pairs not including the latest.
// Order: Latest but one to the oldest
// The latest values will be in the sensor lib file
// index 0 - chipid
// index 1 - slaveid
static uint16_t ids[MAX_NUM_PAIRS][2] = {{0xC1,0x40},};
int sr130pc20_sensor_match_id(struct msm_camera_i2c_client *sensor_i2c_client,
struct msm_camera_slave_info *slave_info,
const char *sensor_name)
{
uint16_t chipid = 0;
int32_t i;
if (!sensor_i2c_client || !slave_info || !sensor_name) {
pr_err("%s:%d failed: %p %p %p\n",__func__, __LINE__,
sensor_i2c_client, slave_info,sensor_name);
return -EINVAL;
}
sensor_i2c_client->i2c_func_tbl->i2c_read(sensor_i2c_client,
slave_info->sensor_id_reg_addr,
&chipid,
sensor_i2c_client->data_type);
if(chipid!=slave_info->sensor_id){
pr_err("%s: chipid read=%x did not match with chipid=%x",
__func__, chipid, slave_info->sensor_id);
for( i=0; i<MAX_NUM_PAIRS; ++i){
chipid = 0;
sensor_i2c_client->cci_client->sid = ids[i][1] >> 1;
sensor_i2c_client->i2c_func_tbl->i2c_read(sensor_i2c_client,
slave_info->sensor_id_reg_addr,
&chipid,
sensor_i2c_client->data_type);
if(chipid == ids[i][0]){
break;
}
pr_err("%s: chipid read=%x did not match with chipid=%x",
__func__, chipid, ids[i][0]);
}
}
CDBG("%s sensor_name =%s slaveid = 0x%X sensorid = 0x%X DATA TYPE = %d\n",
__func__, sensor_name, sensor_i2c_client->cci_client->sid,
slave_info->sensor_id, sensor_i2c_client->data_type);
return 0;
}
int32_t sr130pc20_set_exposure_compensation(struct msm_sensor_ctrl_t *s_ctrl, int mode)
{
int32_t rc = 0;
CDBG("mode = %d", mode);
switch (mode) {
case CAMERA_EV_M4:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_M4);
break;
case CAMERA_EV_M3:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_M3);
break;
case CAMERA_EV_M2:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_M2);
break;
case CAMERA_EV_M1:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_M1);
break;
case CAMERA_EV_DEFAULT:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_default);
break;
case CAMERA_EV_P1:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_P1);
break;
case CAMERA_EV_P2:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_P2);
break;
case CAMERA_EV_P3:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_P3);
break;
case CAMERA_EV_P4:
rc = SR130PC20_WRITE_LIST(sr130pc20_brightness_P4);
break;
default:
pr_err("%s: Setting %d is invalid\n", __func__, mode);
rc = 0;
}
return rc;
}
int32_t sr130pc20_set_white_balance(struct msm_sensor_ctrl_t *s_ctrl, int mode)
{
int32_t rc = 0;
CDBG("mode = %d", mode);
switch (mode) {
case CAMERA_WHITE_BALANCE_AUTO:
rc = SR130PC20_WRITE_LIST(sr130pc20_wb_auto);
break;
case CAMERA_WHITE_BALANCE_INCANDESCENT:
rc = SR130PC20_WRITE_LIST(sr130pc20_wb_tungsten);
break;
case CAMERA_WHITE_BALANCE_FLUORESCENT:
rc = SR130PC20_WRITE_LIST(sr130pc20_wb_fluorescent);
break;
case CAMERA_WHITE_BALANCE_DAYLIGHT:
rc = SR130PC20_WRITE_LIST(sr130pc20_wb_sunny);
break;
case CAMERA_WHITE_BALANCE_CLOUDY_DAYLIGHT:
rc = SR130PC20_WRITE_LIST(sr130pc20_wb_cloudy);
break;
default:
pr_err("%s: Setting %d is invalid\n", __func__, mode);
rc = 0;
}
return rc;
}
int32_t sr130pc20_set_Init_reg(struct msm_sensor_ctrl_t *s_ctrl)
{
if (sr130pc20_ctrl.prev_mode == CAMERA_MODE_INIT) {
if (sr130pc20_ctrl.vtcall_mode == 1) {
SR130PC20_WRITE_LIST(sr130pc20_VT_Init_Reg);
CDBG("VT Init Settings");
}else {
SR130PC20_WRITE_LIST(sr130pc20_Init_Reg);
CDBG("Init settings");
}
SR130PC20_WRITE_LIST(sr130pc20_stop_stream);
CDBG("Stop Stream Settings");
}
return 0;
}
int32_t sr130pc20_set_resolution(struct msm_sensor_ctrl_t *s_ctrl, int mode)
{
int32_t rc = 0;
CDBG("mode = %d", mode);
switch (mode) {
case MSM_SENSOR_RES_FULL:
rc = SR130PC20_WRITE_LIST(sr130pc20_Snapshot);
break;
default:
rc = SR130PC20_WRITE_LIST(sr130pc20_Preview);
pr_err("%s: Setting %d is sr130pc20_Preview\n", __func__, mode);
}
return rc;
}
int32_t sr130pc20_set_effect(struct msm_sensor_ctrl_t *s_ctrl, int mode)
{
int32_t rc = 0;
CDBG("mode = %d", mode);
switch (mode) {
case CAMERA_EFFECT_OFF:
rc = SR130PC20_WRITE_LIST(sr130pc20_effect_none);
break;
case CAMERA_EFFECT_MONO:
rc = SR130PC20_WRITE_LIST(sr130pc20_effect_gray);
break;
case CAMERA_EFFECT_NEGATIVE:
rc = SR130PC20_WRITE_LIST(sr130pc20_effect_negative);
break;
case CAMERA_EFFECT_SEPIA:
rc = SR130PC20_WRITE_LIST(sr130pc20_effect_sepia);
break;
default:
pr_err("%s: Setting %d is invalid\n", __func__, mode);
}
return rc;
}
int32_t sr130pc20_get_exif(struct ioctl_native_cmd * exif_info)
{
exif_info->value_1 = 1; // equals 1 to update the exif value in the user level.
exif_info->value_2 = sr130pc20_ctrl.exif_iso;
exif_info->value_3 = sr130pc20_ctrl.exif_shutterspeed;
return 0;
}
int32_t sr130pc20_set_exif(struct msm_sensor_ctrl_t *s_ctrl )
{
int32_t rc = 0;
uint16_t read_value1 = 0;
uint16_t read_value2 = 0;
uint16_t read_value3 = 0;
uint16_t read_value4 = 0;
uint16_t gain_value = 0;
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write(
s_ctrl->sensor_i2c_client,
0x03,
0x20,
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client, 0x80,
&read_value1,
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client, 0x81,
&read_value2,
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client, 0x82,
&read_value3,
MSM_CAMERA_I2C_BYTE_DATA);
sr130pc20_ctrl.exif_shutterspeed = 24000000 / ((read_value1 << 19)
+ (read_value2 << 11) + (read_value3 << 3));
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write(
s_ctrl->sensor_i2c_client,
0x03,
0x20,
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client, 0xb0,
&read_value4,
MSM_CAMERA_I2C_BYTE_DATA);
gain_value =((read_value4 * 1000) / 32) + 500;
if (gain_value < 1250)
sr130pc20_ctrl.exif_iso= 50;
else if (gain_value < 1750)
sr130pc20_ctrl.exif_iso = 100;
else if (gain_value < 2500)
sr130pc20_ctrl.exif_iso = 200;
else if (gain_value < 3750)
sr130pc20_ctrl.exif_iso = 400;
else if (gain_value < 5500)
sr130pc20_ctrl.exif_iso = 800;
else
sr130pc20_ctrl.exif_iso = 1600;
pr_info("sr130pc20_set_exif: ISO = %d shutter speed = %d",sr130pc20_ctrl.exif_iso,sr130pc20_ctrl.exif_shutterspeed);
return rc;
}
int32_t sr130pc20_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
void __user *argp)
{
struct sensorb_cfg_data *cdata = (struct sensorb_cfg_data *)argp;
int32_t rc = 0;
int32_t i = 0;
mutex_lock(s_ctrl->msm_sensor_mutex);
switch (cdata->cfgtype) {
case CFG_GET_SENSOR_INFO:
CDBG(" CFG_GET_SENSOR_INFO");
memcpy(cdata->cfg.sensor_info.sensor_name,
s_ctrl->sensordata->sensor_name,
sizeof(cdata->cfg.sensor_info.sensor_name));
cdata->cfg.sensor_info.session_id =
s_ctrl->sensordata->sensor_info->session_id;
for (i = 0; i < SUB_MODULE_MAX; i++)
cdata->cfg.sensor_info.subdev_id[i] =
s_ctrl->sensordata->sensor_info->subdev_id[i];
CDBG("sensor name %s",
cdata->cfg.sensor_info.sensor_name);
CDBG("session id %d",
cdata->cfg.sensor_info.session_id);
for (i = 0; i < SUB_MODULE_MAX; i++)
CDBG("subdev_id[%d] %d", i,
cdata->cfg.sensor_info.subdev_id[i]);
break;
case CFG_SET_INIT_SETTING:
CDBG("CFG_SET_INIT_SETTING writing INIT registers: sr130pc20_Init_Reg");
sr130pc20_ctrl.vtcall_mode = 0;
#ifdef CONFIG_LOAD_FILE /* this call should be always called first */
sr130pc20_regs_table_init("/data/sr130pc20_yuv.h");
pr_err("/data/sr352_yuv.h inside CFG_SET_INIT_SETTING");
#endif
break;
case CFG_SET_RESOLUTION:
sr130pc20_set_Init_reg(s_ctrl);
resolution = *((int32_t *)cdata->cfg.setting);
CDBG("CFG_SET_RESOLUTION res = %d" , resolution);
break;
case CFG_SET_STOP_STREAM:
CDBG(" CFG_SET_STOP_STREAM writing stop stream registers: sr130pc20_stop_stream");
if(sr130pc20_ctrl.streamon == 1){
rc = SR130PC20_WRITE_LIST(sr130pc20_stop_stream);
sr130pc20_ctrl.streamon = 0;
}
break;
case CFG_SET_START_STREAM:
CDBG(" CFG_SET_START_STREAM writing start stream registers: sr130pc20_start_stream start");
switch(sr130pc20_ctrl.op_mode) {
case CAMERA_MODE_PREVIEW:
{
CDBG(" CFG_SET_START_STREAM: Preview");
if(sr130pc20_ctrl.prev_mode == CAMERA_MODE_RECORDING) {
SR130PC20_WRITE_LIST(sr130pc20_Init_Reg);
SR130PC20_WRITE_LIST(sr130pc20_stop_stream);
}
if(sr130pc20_ctrl.prev_mode != CAMERA_MODE_CAPTURE) {
sr130pc20_set_effect( s_ctrl , sr130pc20_ctrl.settings.effect);
sr130pc20_set_white_balance( s_ctrl, sr130pc20_ctrl.settings.wb);
sr130pc20_set_exposure_compensation( s_ctrl , sr130pc20_ctrl.settings.exposure );
}
sr130pc20_set_resolution(s_ctrl , resolution );
#if defined(CONFIG_SEC_MILLET_PROJECT) || defined(CONFIG_SEC_MATISSE_PROJECT) || defined (CONFIG_MACH_VICTOR3GDSDTV_LTN)
if(sr130pc20_ctrl.prev_mode == CAMERA_MODE_INIT) {
msleep(200);
}
#endif
}
break;
case CAMERA_MODE_CAPTURE:
{
sr130pc20_set_resolution(s_ctrl , resolution );
sr130pc20_set_exif(s_ctrl);
}
break;
case CAMERA_MODE_RECORDING:
{
SR130PC20_WRITE_LIST(sr130pc20_camcorder_mode);
sr130pc20_set_effect( s_ctrl , sr130pc20_ctrl.settings.effect);
sr130pc20_set_white_balance( s_ctrl, sr130pc20_ctrl.settings.wb);
sr130pc20_set_exposure_compensation( s_ctrl , sr130pc20_ctrl.settings.exposure );
}
break;
}
sr130pc20_ctrl.streamon = 1;
CDBG("CFG_SET_START_STREAM : sr130pc20_start_stream rc = %d", rc);
break;
case CFG_SET_SLAVE_INFO: {
struct msm_camera_sensor_slave_info sensor_slave_info;
struct msm_camera_power_ctrl_t *p_ctrl;
uint16_t size;
int slave_index = 0;
if (copy_from_user(&sensor_slave_info,
(void *)cdata->cfg.setting,
sizeof(sensor_slave_info))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -EFAULT;
break;
}
/* Update sensor slave address */
if (sensor_slave_info.slave_addr) {
s_ctrl->sensor_i2c_client->cci_client->sid =
sensor_slave_info.slave_addr >> 1;
}
/* Update sensor address type */
s_ctrl->sensor_i2c_client->addr_type =
sensor_slave_info.addr_type;
/* Update power up / down sequence */
p_ctrl = &s_ctrl->sensordata->power_info;
size = sensor_slave_info.power_setting_array.size;
if (p_ctrl->power_setting_size < size) {
struct msm_sensor_power_setting *tmp;
tmp = kmalloc(sizeof(*tmp) * size, GFP_KERNEL);
if (!tmp) {
pr_err("%s: failed to alloc mem\n", __func__);
rc = -ENOMEM;
break;
}
kfree(p_ctrl->power_setting);
p_ctrl->power_setting = tmp;
}
p_ctrl->power_setting_size = size;
rc = copy_from_user(p_ctrl->power_setting, (void *)
sensor_slave_info.power_setting_array.power_setting,
size * sizeof(struct msm_sensor_power_setting));
if (rc) {
pr_err("%s:%d failed\n", __func__, __LINE__);
kfree(sensor_slave_info.power_setting_array.
power_setting);
rc = -EFAULT;
break;
}
CDBG("slave_addr = 0x%x, addr_type = %d, sensor_id_reg_addr = 0x%x, sensor_id %x", \
sensor_slave_info.slave_addr, sensor_slave_info.addr_type, \
sensor_slave_info.sensor_id_info.sensor_id_reg_addr, sensor_slave_info.sensor_id_info.sensor_id);
for (slave_index = 0; slave_index <
p_ctrl->power_setting_size; slave_index++) {
CDBG("i %d power setting %d %d %ld %d",
slave_index,
p_ctrl->power_setting[slave_index].seq_type,
p_ctrl->power_setting[slave_index].seq_val,
p_ctrl->power_setting[slave_index].config_val,
p_ctrl->power_setting[slave_index].delay);
}
break;
}
case CFG_WRITE_I2C_ARRAY: {
struct msm_camera_i2c_reg_setting conf_array;
struct msm_camera_i2c_reg_array *reg_setting = NULL;
CDBG(" CFG_WRITE_I2C_ARRAY");
if (copy_from_user(&conf_array,
(void *)cdata->cfg.setting,
sizeof(struct msm_camera_i2c_reg_setting))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -EFAULT;
break;
}
reg_setting = kzalloc(conf_array.size *
(sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
if (!reg_setting) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -ENOMEM;
break;
}
if (copy_from_user(reg_setting, (void *)conf_array.reg_setting,
conf_array.size *
sizeof(struct msm_camera_i2c_reg_array))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
kfree(reg_setting);
rc = -EFAULT;
break;
}
conf_array.reg_setting = reg_setting;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
s_ctrl->sensor_i2c_client, &conf_array);
kfree(reg_setting);
break;
}
case CFG_WRITE_I2C_SEQ_ARRAY: {
struct msm_camera_i2c_seq_reg_setting conf_array;
struct msm_camera_i2c_seq_reg_array *reg_setting = NULL;
CDBG("CFG_WRITE_I2C_SEQ_ARRAYn");
if (copy_from_user(&conf_array,
(void *)cdata->cfg.setting,
sizeof(struct msm_camera_i2c_seq_reg_setting))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -EFAULT;
break;
}
reg_setting = kzalloc(conf_array.size *
(sizeof(struct msm_camera_i2c_seq_reg_array)),
GFP_KERNEL);
if (!reg_setting) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -ENOMEM;
break;
}
if (copy_from_user(reg_setting, (void *)conf_array.reg_setting,
conf_array.size *
sizeof(struct msm_camera_i2c_seq_reg_array))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
kfree(reg_setting);
rc = -EFAULT;
break;
}
conf_array.reg_setting = reg_setting;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_seq_table(s_ctrl->sensor_i2c_client,
&conf_array);
kfree(reg_setting);
break;
}
case CFG_POWER_UP:
CDBG(" CFG_POWER_UP");
sr130pc20_ctrl.streamon = 0;
sr130pc20_ctrl.op_mode = CAMERA_MODE_INIT;
sr130pc20_ctrl.prev_mode = CAMERA_MODE_INIT;
if (s_ctrl->func_tbl->sensor_power_up) {
CDBG("CFG_POWER_UP");
rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl,
&s_ctrl->sensordata->power_info,
s_ctrl->sensor_i2c_client,
s_ctrl->sensordata->slave_info,
s_ctrl->sensordata->sensor_name);
} else
rc = -EFAULT;
break;
case CFG_POWER_DOWN:
CDBG("CFG_POWER_DOWN");
if (s_ctrl->func_tbl->sensor_power_down) {
CDBG("CFG_POWER_DOWN");
rc = s_ctrl->func_tbl->sensor_power_down(
s_ctrl,
&s_ctrl->sensordata->power_info,
s_ctrl->sensor_device_type,
s_ctrl->sensor_i2c_client);
} else
rc = -EFAULT;
#ifdef CONFIG_LOAD_FILE
sr130pc20_regs_table_exit();
#endif
break;
case CFG_SET_STOP_STREAM_SETTING: {
struct msm_camera_i2c_reg_setting *stop_setting =
&s_ctrl->stop_setting;
struct msm_camera_i2c_reg_array *reg_setting = NULL;
CDBG("CFG_SET_STOP_STREAM_SETTING");
if (copy_from_user(stop_setting, (void *)cdata->cfg.setting,
sizeof(struct msm_camera_i2c_reg_setting))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -EFAULT;
break;
}
reg_setting = stop_setting->reg_setting;
stop_setting->reg_setting = kzalloc(stop_setting->size *
(sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
if (!stop_setting->reg_setting) {
pr_err("%s:%d failed\n", __func__, __LINE__);
rc = -ENOMEM;
break;
}
if (copy_from_user(stop_setting->reg_setting,
(void *)reg_setting, stop_setting->size *
sizeof(struct msm_camera_i2c_reg_array))) {
pr_err("%s:%d failed\n", __func__, __LINE__);
kfree(stop_setting->reg_setting);
stop_setting->reg_setting = NULL;
stop_setting->size = 0;
rc = -EFAULT;
break;
}
break;
}
default:
rc = -EFAULT;
break;
}
mutex_unlock(s_ctrl->msm_sensor_mutex);
CDBG("EXIT");
return rc;
}
int32_t sr130pc20_sensor_native_control(struct msm_sensor_ctrl_t *s_ctrl,
void __user *argp)
{
int32_t rc = 0;
struct ioctl_native_cmd *cam_info = (struct ioctl_native_cmd *)argp;
mutex_lock(s_ctrl->msm_sensor_mutex);
/*CDBG("cam_info values = %d : %d : %d : %d : %d\n", cam_info->mode, cam_info->address, cam_info->value_1, cam_info->value_2 , cam_info->value_3);*/
switch (cam_info->mode) {
case EXT_CAM_EV:
sr130pc20_ctrl.settings.exposure = cam_info->value_1;
if(sr130pc20_ctrl.streamon == 1)
sr130pc20_set_exposure_compensation(s_ctrl, sr130pc20_ctrl.settings.exposure);
break;
case EXT_CAM_WB:
sr130pc20_ctrl.settings.wb = cam_info->value_1;
if(sr130pc20_ctrl.streamon == 1)
sr130pc20_set_white_balance(s_ctrl, sr130pc20_ctrl.settings.wb);
break;
case EXT_CAM_EFFECT:
sr130pc20_ctrl.settings.effect = cam_info->value_1;
if(sr130pc20_ctrl.streamon == 1)
sr130pc20_set_effect(s_ctrl, sr130pc20_ctrl.settings.effect);
break;
case EXT_CAM_SENSOR_MODE:
sr130pc20_ctrl.prev_mode = sr130pc20_ctrl.op_mode;
sr130pc20_ctrl.op_mode = cam_info->value_1;
pr_err("EXT_CAM_SENSOR_MODE = %d", sr130pc20_ctrl.op_mode);
case EXT_CAM_EXIF:
sr130pc20_get_exif(cam_info);
if (!copy_to_user((void *)argp,
(const void *)&cam_info,
sizeof(cam_info)))
pr_err("copy failed");
break;
case EXT_CAM_VT_MODE:
CDBG("EXT_CAM_VT_MODE = %d",cam_info->value_1);
sr130pc20_ctrl.vtcall_mode = cam_info->value_1;
break;
default:
rc = -EFAULT;
break;
}
mutex_unlock(s_ctrl->msm_sensor_mutex);
return rc;
}
void sr130pc20_set_default_settings(void)
{
sr130pc20_ctrl.settings.metering = CAMERA_CENTER_WEIGHT;
sr130pc20_ctrl.settings.exposure = CAMERA_EV_DEFAULT;
sr130pc20_ctrl.settings.wb = CAMERA_WHITE_BALANCE_AUTO;
sr130pc20_ctrl.settings.iso = CAMERA_ISO_MODE_AUTO;
sr130pc20_ctrl.settings.effect = CAMERA_EFFECT_OFF;
sr130pc20_ctrl.settings.scenemode = CAMERA_SCENE_AUTO;
}
#ifdef CONFIG_LOAD_FILE
void sr130pc20_regs_table_exit(void)
{
pr_info("%s:%d\n", __func__, __LINE__);
if (sr130pc20_regs_table) {
vfree(sr130pc20_regs_table);
sr130pc20_regs_table = NULL;
}
}
int sr130pc20_regs_from_sd_tunning(struct msm_camera_i2c_reg_conf *settings, struct msm_sensor_ctrl_t *s_ctrl,char * name) {
char *start, *end, *reg;
int addr,rc = 0;
unsigned int value;
char reg_buf[5], data_buf1[5];
*(reg_buf + 4) = '\0';
*(data_buf1 + 4) = '\0';
if (settings != NULL){
pr_err("sr130pc20_regs_from_sd_tunning start address %x start data %x",settings->reg_addr,settings->reg_data);
}
if(sr130pc20_regs_table == NULL) {
pr_err("sr130pc20_regs_table is null ");
return -1;
}
start = strstr(sr130pc20_regs_table, name);
if (start == NULL){
return -1;
}
end = strstr(start, "};");
while (1) {
/* Find Address */
reg = strstr(start, "{0x");
if ((reg == NULL) || (reg > end))
break;
/* Write Value to Address */
if (reg != NULL) {
memcpy(reg_buf, (reg + 1), 4);
memcpy(data_buf1, (reg + 7), 4);
if(kstrtoint(reg_buf, 16, &addr))
pr_err("kstrtoint error");
if(kstrtoint(data_buf1, 16, &value))
pr_err("kstrtoint error");
if (reg)
start = (reg + 14);
if (addr == 0xff){
msleep(value * 10);
pr_err("delay = %d\n", (int)value*10);
}
else{
rc=s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write(s_ctrl->sensor_i2c_client, addr,
value,MSM_CAMERA_I2C_BYTE_DATA);
}
}
}
pr_err("sr130pc20_regs_from_sd_tunning end!");
return rc;
}
void sr130pc20_regs_table_init(char *filename)
{
struct file *filp;
char *dp;
long lsize;
loff_t pos;
int ret;
/*Get the current address space */
mm_segment_t fs = get_fs();
pr_err("%s %d", __func__, __LINE__);
/*Set the current segment to kernel data segment */
set_fs(get_ds());
filp = filp_open(filename, O_RDONLY, 0);
if (IS_ERR_OR_NULL(filp)) {
pr_err("file open error %ld",(long) filp);
return;
}
lsize = filp->f_path.dentry->d_inode->i_size;
pr_err("size : %ld", lsize);
dp = vmalloc(lsize);
if (dp == NULL) {
pr_err("Out of Memory");
filp_close(filp, current->files);
}
pos = 0;
memset(dp, 0, lsize);
ret = vfs_read(filp, (char __user *)dp, lsize, &pos);
if (ret != lsize) {
pr_err("Failed to read file ret = %d\n", ret);
vfree(dp);
filp_close(filp, current->files);
}
/*close the file*/
filp_close(filp, current->files);
/*restore the previous address space*/
set_fs(fs);
pr_err("coming to else part of string compare sr130pc20_regs_table");
sr130pc20_regs_table = dp;
sr130pc20_regs_table_size = lsize;
*((sr130pc20_regs_table + sr130pc20_regs_table_size) - 1) = '\0';
return;
}
#endif