static int sensor_ctrl_rg_weight(struct v4l2_subdev *sd, int val)
{
	struct sensor_info *info = to_sensor(sd);
	u8 *value = (u8 *)&val;
	int ret = 0;

	sensor_dbg("val = %d", val);

	if (info->status == STATUS_STREAMING) {
		ret = sensor_add_request(sd, SENSOR_REG_VIS_GAIN_RED, value[1]);
		if (ret < 0) {
			sensor_err("Failed to add request(RED)");
			goto ret;
		}
		ret = sensor_add_request(sd, SENSOR_REG_VIS_GAIN_GREEN, value[0]);
		if (ret < 0) {
			sensor_err("Failed to add request(GREEN)");
			goto ret;
		}
	} else {
		ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_GAIN_RED, (u8)value[1], I2C_8BIT);
		if (ret < 0) {
			sensor_err("file to write reg(ret = %d)", ret);
			goto ret;
		}
		ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_GAIN_GREEN, (u8)value[0], I2C_8BIT);
		if (ret < 0) {
			sensor_err("file to write reg(ret = %d)", ret);
			goto ret;
		}
	}

ret:
	return ret;
}
/*
 * sensor_straming - start and stop streaming.
 */
int sensor_streaming(struct v4l2_subdev *sd, enum sensor_status state)
{
	struct sensor_info *info = to_sensor(sd);
	int ret = 0;

	if (state == info->status) {
		sensor_err("sensor is already stream %s",
			state == STATUS_STREAMING ? "on" : "off");
		return ret;
	}

	ret = vision_sensor_write_reg(sd, 0x4100, (u8)state, I2C_8BIT);
	if (ret < 0) {
		sensor_err("file to write reg(ret = %d)", ret);
		return ret;
	}

	if (state == STATUS_STANDBY) {
		ret = sensor_drain_request(sd, true);
		if (ret < 0) {
			sensor_err("fail to drain request");
			return ret;
		}
	}

	info->status = state;

	return ret;
}
static int sensor_add_request(struct v4l2_subdev *sd, u32 addr, u8 val)
{
	struct sensor_info *info = to_sensor(sd);

	if (info->req_head == NULL) {
		info->req_head = kzalloc(sizeof(struct sensor_req_list), GFP_ATOMIC);
		if (info->req_head == NULL) {
			sensor_err("Failed to allocate new requeset\n");
			return -ENOMEM;
		}
		info->req_tail = info->req_head;

		info->req_head->next = NULL;
		info->req_head->addr = addr;
		info->req_head->value = val;
	} else if (info->req_tail->next == NULL) {
		info->req_tail->next = kzalloc(sizeof(struct sensor_req_list), GFP_ATOMIC);
		if (info->req_tail->next == NULL) {
			sensor_err("Failed to allocate new requeset\n");
			return -ENOMEM;
		}
		info->req_tail = info->req_tail->next;

		info->req_tail->next = NULL;
		info->req_tail->addr = addr;
		info->req_tail->value = val;
	} else {
		sensor_err("Failed to add request, abnormal state!");
		return -1;
	}

	return 0;
}
/*
 * sensor_power - handle sensor power up/down.
 *
 * @enable: If it is true, power up. If is not, power down.
 */
static int sensor_power(struct sensor_info *info, bool enable)
{
	struct v4l2_subdev *sd = &info->sd;
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct device *cdev = &client->dev;
	const struct exynos_fimc_is_sensor_platform_data *pdata = cdev->platform_data;
	int ret = 0;

	if (enable) {
		if (is_powerup(sd))
			return 0;

		if (pdata->clk_on) {
			pdata->clk_on(cdev, FLITE_ID_C);
		} else {
			sensor_err("failed to clk_on\n");
			return -1;
		}
		info->power = true;
	} else {
		if (!is_powerup(sd))
			return 0;

		if (pdata->clk_off) {
			pdata->clk_off(cdev, FLITE_ID_C);
		} else {
			sensor_err("failed to clk_off\n");
			return -1;
		}
		info->power = false;
	}

	return ret;
}
int vision_sensor_write_reg(struct v4l2_subdev *sd,
		u32 addr, u8 val, enum sensor_i2c_size size)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct i2c_msg msg[1];
	u8 *array = (u8*)&addr;
	u8 wbuf[3];
	int ret;

	if (!client->adapter) {
		sensor_err("Could not find adapter!\n");
		return -ENODEV;
	}

	if (size != I2C_8BIT && size != I2C_16BIT && size != I2C_32BIT) {
		sensor_err("Wrong data size\n");
		return -EINVAL;
	}

	msg->addr = client->addr;
	msg->flags = 0;
	msg->len = 3;
	msg->buf = wbuf;
	wbuf[0] = array[1];
	wbuf[1] = array[0];
	wbuf[2] = val;

	ret = i2c_transfer(client->adapter, msg, 1);
	if (ret < 0) {
		sensor_err("i2c treansfer fail");
		return ret;
	}

	return 0;
}
static int sensor_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
	struct sensor_info *info = to_sensor(sd);
	int ret = 0;
	struct platform_device *pdev;
	int irq = 0;

	v4l2_dbg(1, sensor_debug, sd, "%s", __func__);

	ret = sensor_set_clock(sd, FLITE_ID_C);
	if (ret < 0) {
		sensor_err("sensor set clock fail");
		return ret;
	}

	ret = sensor_init_controls(info);
	if (ret < 0) {
		sensor_err("sensor init contols fail");
		return ret;
	}

	fh->vfh.ctrl_handler = &info->handle;
	sensor_init_formats(sd, fh);

	pdev = get_mipi_csis_pdev(FLITE_ID_C);
	irq = platform_get_irq(pdev, 0);
	v4l2_dbg(1, sensor_debug, sd, "%s : mipi irq num : %d", __func__, irq);

	enable_irq(irq);

	return 0;
}
static int sensor_ctrl_frame_rate(struct v4l2_subdev *sd, int val)
{
	struct sensor_info *info = to_sensor(sd);
	u8 *value = (u8 *)&val;
	int ret = 0;

	sensor_dbg("val = %d", val);

	if (info->status == STATUS_STREAMING) {
		ret = sensor_add_request(sd, SENSOR_REG_VIS_DURATION_MSB, value[1]);
		if (ret < 0) {
			sensor_err("Failed to add request(MSB)");
			goto ret;
		}
		ret = sensor_add_request(sd, SENSOR_REG_VIS_DURATION_LSB, value[0]);
		if (ret < 0) {
			sensor_err("Failed to add request(LSB)");
			goto ret;
		}
	} else {
		ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_DURATION_MSB, (u8)value[1], I2C_8BIT);
		if (ret < 0) {
			sensor_err("file to write reg(ret = %d)", ret);
			goto ret;
		}
		ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_DURATION_LSB, (u8)value[0], I2C_8BIT);
		if (ret < 0) {
			sensor_err("file to write reg(ret = %d)", ret);
			goto ret;
		}
	}

ret:
	return ret;
}
Example #8
0
static int sensor_s_power(struct v4l2_subdev *sd, int on)
{
	struct sensor_info *info = to_sensor(sd);
	int ret;

	if (on) {

		/*
		 * HACK
		 * s_power of flite make mux to change to ipll and then
		 * mclk for vision should be cacaluate again after mux setting changes
		 * vision clock source is channel 2
		 */
		ret = sensor_set_clock(sd, FLITE_ID_C);
		if (ret < 0)
			sensor_err("sensor set clock fail");

		ret = sensor_power(info, true);
		if (!ret)
			ret = sensor_setup_default(sd);
	} else {
		ret = sensor_power(info, false);
	}

	return ret;
}
static int sensor_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct v4l2_subdev *sd = to_sd(ctrl);
	u32 cmd = ctrl->id;
	s32 value = ctrl->val;
	int ret = 0;

	switch (cmd) {
	case V4L2_CID_SENSOR_SET_AE_TARGET:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_ae_target(sd, value);
		break;
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_1x1_2:
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_1x3_4:
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_2x1_2:
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_2x3_4:
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_3x1_2:
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_3x3_4:
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_4x1_2:
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_4x3_4:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_ae_weight(sd, cmd, value);
		break;
	case V4L2_CID_SENSOR_SET_RG_WEIGHT:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_rg_weight(sd, value);
		break;
	case V4L2_CID_SENSOR_SET_AE_SPEED:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_ae_speed(sd, value);
		break;
	case V4L2_CID_SENSOR_SET_SHUTTER:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_shutter(sd, value);
		break;
	case V4L2_CID_SENSOR_SET_GAIN:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_gain(sd, value);
		break;
	case V4L2_CID_SENSOR_SET_BIT_CONVERTING:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_bit_converting(sd, value);
		break;
	case V4L2_CID_SENSOR_SET_AUTO_EXPOSURE:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_auto_exposure(sd, value);
		break;
	case V4L2_CID_SENSOR_SET_FRAME_RATE:
		sensor_dbg("ctrl.id = %x, val=%x", cmd, value);
		ret = sensor_ctrl_frame_rate(sd, value);
		break;
	default :
		sensor_err("Unknown CID(%x)", cmd);
		ret = -1;
		break;
	}

	return ret;
}
/*
 * vision_sensor_read_reg/vision_sensor_write_reg - handle sensor's I2C communications.
 *
 * The I2C command packet of sensor is made up 3 kinds of I2C bytes(category,
 * command, bytes). Reference exynos_sensor.h.
 *
 * The packet is needed 2, when read through I2C.
 * The packet is needed 1, when written through I2C.
 *
 * I2C packet common order(including both reading/writing)
 *   1st : Slave addr
 *   2nd : READ/WRITE (R - 0x01, W - 0x02)
 *   3rd : Size
 *   4th : Data
 */
int vision_sensor_read_reg(struct v4l2_subdev *sd,
		u32 addr, u8 *val, enum sensor_i2c_size size)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct i2c_msg msg[2];
	u8 *array = (u8*)&addr;
	u8 wbuf[2];
	int ret;

	if (!client->adapter) {
		sensor_err("Could not find adapter!\n");
		return -ENODEV;
	}

	if (size != I2C_8BIT && size != I2C_16BIT && size != I2C_32BIT) {
		sensor_err("Wrong data size\n");
		return -EINVAL;
	}

	/* 1. I2C operation for writing. */
	msg[0].addr = client->addr;
	msg[0].flags = 0; /* write : 0, read : 1 */
	msg[0].len = 2;
	msg[0].buf = wbuf;
	/* TODO : consider other size of buffer */
	wbuf[0] = array[1];
	wbuf[1] = array[0];

	/* 2. I2C operation for reading data. */
	msg[1].addr = client->addr;
	msg[1].flags = I2C_M_RD;
	msg[1].len = 1;
	msg[1].buf = val;

	ret = i2c_transfer(client->adapter, msg, 2);
	if (ret < 0) {
		sensor_err("i2c treansfer fail");
		return ret;
	}

	return 0;
}
static int sensor_ctrl_auto_exposure(struct v4l2_subdev *sd, int val)
{
	struct sensor_info *info = to_sensor(sd);
	u8 *value = (u8 *)&val;
	int ret = 0;

	sensor_dbg("val = %d", val);

	if (info->status == STATUS_STREAMING) {
		ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_OFF, value[0]);
		if (ret < 0)
			sensor_err("Failed to add request");
	} else {
		ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_OFF, (u8)value[0], I2C_8BIT);
		if (ret < 0)
			sensor_err("file to write reg(ret = %d)", ret);
	}

	return ret;
}
/*
 * sensor_init_controls - initialization using v4l2_ctrl.
 */
static int sensor_init_controls(struct sensor_info *info)
{
	struct v4l2_subdev *sd = &info->sd;
	int num_of_ctl_hint = ARRAY_SIZE(ctrl_private);

	/* set the controls using v4l2 control frameworks */
	v4l2_ctrl_handler_init(&info->handle, num_of_ctl_hint);

	/* Vision mode only support simple AE */
	info->ae_target = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[0], NULL);
	info->ae_weight[0] = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[1], NULL);
	info->ae_weight[1] = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[2], NULL);
	info->ae_weight[2] = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[3], NULL);
	info->ae_weight[3] = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[4], NULL);
	info->ae_weight[4] = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[5], NULL);
	info->ae_weight[5] = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[6], NULL);
	info->ae_weight[6] = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[7], NULL);
	info->ae_weight[7] = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[8], NULL);
	info->rg_weight = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[9], NULL);
	info->ae_speed = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[10], NULL);
	info->shutter = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[11], NULL);
	info->gain = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[12], NULL);
	info->bit_converting = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[13], NULL);
	info->autoexposure = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[14], NULL);
	info->framerate = v4l2_ctrl_new_custom(&info->handle,
			&ctrl_private[15], NULL);

	sd->ctrl_handler = &info->handle;

	if (info->handle.error) {
		sensor_err("Failed to init controls, %d\n", info->handle.error);
		v4l2_ctrl_handler_free(&info->handle);
		return info->handle.error;
	}

	return 0;
}
static void sensor_handler(void *data, int arg)
{
	struct v4l2_subdev *sd = data;
	struct sensor_info *info = to_sensor(sd);

	sensor_dbg("%s: irq(%d), info->status(%d)", __func__, arg, info->status);

	switch (arg) {
	case FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART:
		sensor_dbg("Flite frame start");
		tasklet_schedule(&info->tasklet_flite_str);
		break;
	case FLITE_REG_CISTATUS_IRQ_SRC_FRMEND:
		sensor_dbg("Flite frame end");
		schedule_work(&info->work);
		break;
	default :
		sensor_err("unknown irq(%d)", arg);
		break;
	}
}
static void tasklet_func_flite_end(unsigned long data)
{
	struct sensor_info *info = (struct sensor_info *)data;
	struct sensor_req_list *req = NULL;
	int ret = 0;

	req = sensor_get_request(&info->sd);
	while (req) {
		sensor_dbg("addr(%.8x), val(%x)", req->addr, req->value);
		ret = vision_sensor_write_reg(&info->sd, req->addr, (u8)req->value, I2C_8BIT);

		kfree(req);
		req = NULL;
		if (ret < 0) {
			sensor_err("file to write reg(ret = %d)", ret);
			break;
		}

		req = sensor_get_request(&info->sd);
	}
}
static void sensor_irq_work(struct work_struct *work)
{
	struct sensor_info *info = container_of(work, struct sensor_info, work);
	struct sensor_req_list *req = NULL;
	int ret = 0;

	req = sensor_get_request(&info->sd);
	while (req) {
		sensor_dbg("addr(%.8x), val(%x)", req->addr, req->value);
		ret = vision_sensor_write_reg(&info->sd, req->addr, (u8)req->value, I2C_8BIT);

		kfree(req);
		req = NULL;
		if (ret < 0) {
			sensor_err("file to write reg(ret = %d)", ret);
			break;
		}

		req = sensor_get_request(&info->sd);
	}
}
static int sensor_drain_request(struct v4l2_subdev *sd, bool isValid)
{
	struct sensor_info *info = to_sensor(sd);
	struct sensor_req_list *req = NULL;
	int ret = 0;

	req = sensor_get_request(&info->sd);
	while (req) {
		if (isValid)
			ret = vision_sensor_write_reg(&info->sd, req->addr, (u8)req->value, I2C_8BIT);

		kfree(req);
		req = NULL;
		if (ret < 0) {
			sensor_err("file to write reg(ret = %d)", ret);
			break;
		}

		req = sensor_get_request(&info->sd);
	}

	return ret;
}
static int sensor_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	const struct exynos_fimc_is_sensor_platform_data *pdata =
		client->dev.platform_data;
	struct sensor_info *info;
	struct v4l2_subdev *sd;
	int ret = 0;

	if (pdata == NULL) {
		sensor_err("No platform data\n");
		return -EINVAL;
	}

	if (!gpio_is_valid(pdata->gpio_rst)) {
		sensor_err("No valid nRST gpio pin.\n");
		return -EINVAL;
	}

	info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL);
	if (info == NULL) {
		sensor_err("Failed to allocate info\n");
		return -ENOMEM;
	}

	info->pdata = pdata;

	tasklet_init(&info->tasklet_flite_str, tasklet_func_flite_str,
		(unsigned long)info);

	tasklet_init(&info->tasklet_flite_end, tasklet_func_flite_end,
		(unsigned long)info);

	INIT_WORK(&info->work, sensor_irq_work);
	if (info->pdata->irq) {
		ret = request_irq(info->pdata->irq, sensor_irq_handler,
				  IRQF_TRIGGER_RISING, MOD_NAME, &info->sd);
		if (ret) {
			sensor_err("Failed to request irq: %d\n", ret);
			return ret;
		}
	}

	ret = gpio_request(info->pdata->gpio_rst, "GPIO_CAM_VT_nRST");
	if (ret) {
		sensor_err("Failed to set gpio, %d\n", ret);
		goto out_gpio;
	}

/*
	s3c_gpio_setpull(info->pdata->gpio_rst, S3C_GPIO_PULL_NONE);

	gpio_direction_output(info->pdata->gpio_rst, 0);
	gpio_direction_output(info->pdata->gpio_rst, 1);
*/

	gpio_free(info->pdata->gpio_rst);

	sd = &info->sd;

	v4l2_i2c_subdev_init(sd, client, &sensor_ops);
	info->pad.flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
	if (ret < 0)
		goto out_reg;

	sensor_init_formats(sd, NULL);

	strlcpy(sd->name, MOD_NAME, sizeof(sd->name));
	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
	sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
	sd->internal_ops = &sensor_v4l2_internal_ops;
	sd->entity.ops = &sensor_media_ops;

	sd->host_priv = sensor_handler;

	info->req_head = NULL;
	info->req_tail = NULL;

	v4l2_info(sd, "%s : sensor driver probed success\n", __func__);

	return 0;

out_reg:
out_gpio:
	gpio_free(info->pdata->gpio_rst);
	kfree(info);

	return ret;
}
static int sensor_ctrl_ae_weight(struct v4l2_subdev *sd, int cmd, int val)
{
	struct sensor_info *info = to_sensor(sd);
	u8 *value = (u8 *)&val;
	int ret = 0;

	sensor_dbg("cmd = %x val = %d", cmd, val);

	switch (cmd) {
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_1x1_2:
		if (info->status == STATUS_STREAMING) {
			ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_1x1_2, value[0]);
		} else {
			ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_1x1_2, (u8)value[0], I2C_8BIT);
		}
		break;
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_1x3_4:
		if (info->status == STATUS_STREAMING) {
			ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_1x3_4, value[0]);
		} else {
			ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_1x3_4, (u8)value[0], I2C_8BIT);
		}
		break;
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_2x1_2:
		if (info->status == STATUS_STREAMING) {
			ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_2x1_2, value[0]);
		} else {
			ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_2x1_2, (u8)value[0], I2C_8BIT);
		}
		break;
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_2x3_4:
		if (info->status == STATUS_STREAMING) {
			ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_2x3_4, value[0]);
		} else {
			ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_2x3_4, (u8)value[0], I2C_8BIT);
		}
		break;
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_3x1_2:
		if (info->status == STATUS_STREAMING) {
			ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_3x1_2, value[0]);
		} else {
			ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_3x1_2, (u8)value[0], I2C_8BIT);
		}
		break;
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_3x3_4:
		if (info->status == STATUS_STREAMING) {
			ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_3x3_4, value[0]);
		} else {
			ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_3x3_4, (u8)value[0], I2C_8BIT);
		}
		break;
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_4x1_2:
		if (info->status == STATUS_STREAMING) {
			ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_4x1_2, value[0]);
		} else {
			ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_4x1_2, (u8)value[0], I2C_8BIT);
		}
		break;
	case V4L2_CID_SENSOR_SET_AE_WEIGHT_4x3_4:
		if (info->status == STATUS_STREAMING) {
			ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_4x3_4, value[0]);
		} else {
			ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_4x3_4, (u8)value[0], I2C_8BIT);
		}
		break;
	default :
		sensor_err("Unknown CID");
		ret = -EINVAL;
		break;
	}

	if (ret < 0)
		sensor_err("Failed to set ae weight(CID:%x)", cmd);

	return ret;
}