static int sensor_sr200_init(struct v4l2_subdev *subdev, u32 val)
{
	int ret = 0;
	u8 id;

	struct sr200_state *state = to_state(subdev);
	struct i2c_client *client = to_client(subdev);

	cam_info("%s : E \n", __func__);

	state->system_clock = 146 * 1000 * 1000;
	state->line_length_pck = 146 * 1000 * 1000;

#ifdef CONFIG_LOAD_FILE
	ret = sr200_regs_table_init();
	CHECK_ERR_MSG(ret, "[CONFIG_LOAD_FILE] init fail \n");
#endif

	sensor_sr200_apply_set(subdev, "sr200_Init_Reg", &sr200_regset_table.init);
	sensor_sr200_apply_set(subdev, "sr200_stop_stream", &sr200_regset_table.stop_stream);
	fimc_is_sr200_read8(client, 0x4, &id);

	state->initialized = 1;
	state->power_on =  SR200_HW_POWER_ON;
	state->runmode = RUNMODE_INIT;
	state->preview.update_frmsize = 1;

	cam_info("%s(id : %X) : X \n", __func__, id);

	return ret;
}
int32_t sr200pc20_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);

	CDBG("ENTER \n ");

	switch (cdata->cfgtype) {
	case CFG_GET_SENSOR_INFO:
		CDBG("CFG_GET_SENSOR_INFO\n");
		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("%s:%d sensor name %s\n", __func__, __LINE__,
			cdata->cfg.sensor_info.sensor_name);
		CDBG("%s:%d session id %d\n", __func__, __LINE__,
			cdata->cfg.sensor_info.session_id);
		for (i = 0; i < SUB_MODULE_MAX; i++)
			CDBG("%s:%d subdev_id[%d] %d\n", __func__, __LINE__, i,
				cdata->cfg.sensor_info.subdev_id[i]);
		break;
	case CFG_SET_INIT_SETTING:
		CDBG("CFG_SET_INIT_SETTING\n");
#ifdef CONFIG_LOAD_FILE /* this call should be always called first */
		sr200_regs_table_init("/data/sr200pc20_yuv_t8.h");
		pr_err("/data/sr200pc20_yuv_t8.h inside CFG_SET_INIT_SETTING");
#endif
		rc = sr200pc20_WRT_LIST(s_ctrl,sr200pc20_Init_Reg);
#if 0
		rc = sr200pc20_WRT_LIST(s_ctrl,sr200pc20_stop_stream);
#endif
		break;
	case CFG_SET_RESOLUTION:
		sr200pc20_ctrl.settings.resolution = *((int32_t  *)cdata->cfg.setting);
		CDBG("CFG_SET_RESOLUTION - res = %d\n" , sr200pc20_ctrl.settings.resolution);
		CDBG("sr200pc20_ctrl.op_mode = %d\n " , sr200pc20_ctrl.op_mode);
		break;
	case CFG_SET_STOP_STREAM:
		CDBG("CFG_SET_STOP_STREAM - res = %d\n ", sr200pc20_ctrl.settings.resolution);
		if(streamon == 1){
			CDBG("CFG_SET_STOP_STREAM *** res = %d - streamon == 1\n " , sr200pc20_ctrl.settings.resolution);
#if 0
			CDBG(" CFG_SET_STOP_STREAM writing stop stream registers: sr200pc20_stop_stream \n");
			rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
			i2c_write_conf_tbl(
				s_ctrl->sensor_i2c_client, sr200pc20_stop_stream,
				ARRAY_SIZE(sr200pc20_stop_stream),
				MSM_CAMERA_I2C_BYTE_DATA);
			//rc = sr200pc20_WRT_LIST(s_ctrl,sr200pc20_stop_stream);
#endif
			rc=0;
			streamon = 0;
		}
		break;
	case CFG_SET_START_STREAM:
		CDBG("CFG_SET_START_STREAM\n");
		CDBG("sr200pc20_ctrl.op_mode = %d,sr200pc20_ctrl.prev_mode = %d \n", sr200pc20_ctrl.op_mode, sr200pc20_ctrl.prev_mode);
                switch (sr200pc20_ctrl.op_mode) {
                case CAMERA_MODE_PREVIEW:
                        if (sr200pc20_ctrl.prev_mode != CAMERA_MODE_CAPTURE) {
                            switch (sr200pc20_ctrl.prev_mode) {
                            case CAMERA_MODE_INIT:
                                    scene_mode_chg = 1;
                                    sr200pc20_set_scene_mode(s_ctrl, sr200pc20_ctrl.settings.scenemode);
                                    sr200pc20_set_effect( s_ctrl , sr200pc20_ctrl.settings.effect);
                                    sr200pc20_set_white_balance( s_ctrl, sr200pc20_ctrl.settings.wb);
                                    sr200pc20_set_exposure_compensation( s_ctrl , sr200pc20_ctrl.settings.exposure );
                                    sr200pc20_set_metering(s_ctrl, sr200pc20_ctrl.settings.metering);
                                    break;
                            case CAMERA_MODE_RECORDING:
                                    sr200pc20_WRT_LIST(s_ctrl,sr200pc20_Init_Reg);
                                    scene_mode_chg = 1;
                                    sr200pc20_set_scene_mode(s_ctrl, sr200pc20_ctrl.settings.scenemode);
                                    sr200pc20_set_effect( s_ctrl , sr200pc20_ctrl.settings.effect);
                                    sr200pc20_set_white_balance( s_ctrl, sr200pc20_ctrl.settings.wb);
                                    sr200pc20_set_exposure_compensation( s_ctrl , sr200pc20_ctrl.settings.exposure);
                                    sr200pc20_set_metering(s_ctrl, sr200pc20_ctrl.settings.metering);
                                    break;
                            case CAMERA_MODE_PREVIEW:
                                    sr200pc20_set_scene_mode(s_ctrl, sr200pc20_ctrl.settings.scenemode);
                                    break;
                            default:
                                    pr_err("Invalid previous mode");
                                    break;
                            }
                        }
                        if (sr200pc20_ctrl.op_mode != sr200pc20_ctrl.prev_mode) {
                            sr200pc20_set_resolution(s_ctrl , sr200pc20_ctrl.settings.resolution);
                        }
                        streamon = 1;
                        break;
                case CAMERA_MODE_CAPTURE:
                case CAMERA_MODE_RECORDING:
                        if (sr200pc20_ctrl.op_mode != sr200pc20_ctrl.prev_mode) {
                            sr200pc20_set_resolution(s_ctrl , sr200pc20_ctrl.settings.resolution );
                        }
                        streamon = 1;
                        break;
                default:
                        pr_err("%s: CFG_SET_START_STREAM - %d INVALID mode\n", __func__, sr200pc20_ctrl.op_mode);
                        break;
                }
		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;
		CDBG("CFG_SET_SLAVE_INFO\n");
		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("%s sensor id %x\n", __func__,
			sensor_slave_info.slave_addr);
		CDBG("%s sensor addr type %d\n", __func__,
			sensor_slave_info.addr_type);
		CDBG("%s sensor reg %x\n", __func__,
			sensor_slave_info.sensor_id_info.sensor_id_reg_addr);
		CDBG("%s sensor id %x\n", __func__,
			sensor_slave_info.sensor_id_info.sensor_id);
		for (slave_index = 0; slave_index <
			p_ctrl->power_setting_size; slave_index++) {
			CDBG("%s i %d power setting %d %d %ld %d\n", __func__,
				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\n");

		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_ARRAY\n");

		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\n");
		streamon = 0;
		sr200pc20_ctrl.op_mode = CAMERA_MODE_INIT;
		sr200pc20_ctrl.prev_mode = CAMERA_MODE_INIT;
		sr200pc20_ctrl.settings.metering = CAMERA_CENTER_WEIGHT;
		sr200pc20_ctrl.settings.exposure = CAMERA_EV_DEFAULT;
		sr200pc20_ctrl.settings.wb = CAMERA_WHITE_BALANCE_AUTO;
		sr200pc20_ctrl.settings.iso = CAMERA_ISO_MODE_AUTO;
		sr200pc20_ctrl.settings.effect = CAMERA_EFFECT_OFF;
		sr200pc20_ctrl.settings.scenemode = CAMERA_SCENE_AUTO;
		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\n");
		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;
		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\n");

		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:
		break;
	}