Exemple #1
0
/**
 * m5mols_do_scenemode() - Change current scenemode
 * @mode:	Desired mode of the scenemode
 *
 * WARNING: The execution order is important. Do not change the order.
 */
int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
{
	struct v4l2_subdev *sd = &info->sd;
	struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode];
	int ret;

	if (mode > REG_SCENE_CANDLE)
		return -EINVAL;

	ret = v4l2_ctrl_s_ctrl(info->lock_3a, 0);
	if (!ret)
		ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode);
	if (!ret)
		ret = m5mols_write(sd, AE_EV_PRESET_CAPTURE, mode);
	if (!ret)
		ret = m5mols_write(sd, AE_MODE, scenemode.metering);
	if (!ret)
		ret = m5mols_write(sd, AE_INDEX, scenemode.ev_bias);
	if (!ret)
		ret = m5mols_write(sd, AWB_MODE, scenemode.wb_mode);
	if (!ret)
		ret = m5mols_write(sd, AWB_MANUAL, scenemode.wb_preset);
	if (!ret)
		ret = m5mols_write(sd, MON_CHROMA_EN, scenemode.chroma_en);
	if (!ret)
		ret = m5mols_write(sd, MON_CHROMA_LVL, scenemode.chroma_lvl);
	if (!ret)
		ret = m5mols_write(sd, MON_EDGE_EN, scenemode.edge_en);
	if (!ret)
		ret = m5mols_write(sd, MON_EDGE_LVL, scenemode.edge_lvl);
	if (!ret && is_available_af(info))
		ret = m5mols_write(sd, AF_MODE, scenemode.af_range);
	if (!ret && is_available_af(info))
		ret = m5mols_write(sd, FD_CTL, scenemode.fd_mode);
	if (!ret)
		ret = m5mols_write(sd, MON_TONE_CTL, scenemode.tone);
	if (!ret)
		ret = m5mols_write(sd, AE_ISO, scenemode.iso);
	if (!ret)
		ret = m5mols_set_mode(info, REG_CAPTURE);
	if (!ret)
		ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr);
	if (!ret)
		ret = m5mols_write(sd, CAPP_MCC_MODE, scenemode.mcc);
	if (!ret)
		ret = m5mols_write(sd, CAPP_LIGHT_CTRL, scenemode.light);
	if (!ret)
		ret = m5mols_write(sd, CAPP_FLASH_CTRL, scenemode.flash);
	if (!ret)
		ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode);
	if (!ret)
		ret = m5mols_set_mode(info, REG_MONITOR);

	return ret;
}
static int m5mols_into_monitor(struct v4l2_subdev *sd, int res_size)
{
	int ret;

	ret = m5mols_set_mode(sd, MODE_PARMSET);
	if (!ret)
		ret = i2c_w8_param(sd, CAT1_MONITOR_SIZE, (u8)res_size);
	if (!ret)
		ret = m5mols_set_mode(sd, MODE_PARMSET);

	return ret;
}
Exemple #3
0
int m5mols_start_capture(struct m5mols_info *info)
{
	unsigned int framesize = info->cap.buf_size - M5MOLS_JPEG_TAGS_SIZE;
	struct v4l2_subdev *sd = &info->sd;
	int ret;

	/*
	 * Synchronize the controls, set the capture frame resolution and color
	 * format. The frame capture is initiated during switching from Monitor
	 * to Capture mode.
	 */
	ret = m5mols_set_mode(info, REG_MONITOR);
	if (!ret)
		ret = m5mols_restore_controls(info);
	if (!ret)
		ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
	if (!ret)
		ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
	if (!ret)
		ret = m5mols_write(sd, CAPP_JPEG_SIZE_MAX, framesize);
	if (!ret)
		ret = m5mols_set_mode(info, REG_CAPTURE);
	if (!ret)
		/* Wait until a frame is captured to ISP internal memory */
		ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
	if (ret)
		return ret;

	/*
	 * Initiate the captured data transfer to a MIPI-CSI receiver.
	 */
	ret = m5mols_write(sd, CAPC_SEL_FRAME, 1);
	if (!ret)
		ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN);
	if (!ret) {
		bool captured = false;
		unsigned int size;

		/* Wait for the capture completion interrupt */
		ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
		if (!ret) {
			captured = true;
			ret = m5mols_capture_info(info);
		}
		size = captured ? info->cap.main : 0;
		v4l2_dbg(1, m5mols_debug, sd, "%s: size: %d, thumb.: %d B\n",
			 __func__, size, info->cap.thumb);

		v4l2_subdev_notify(sd, S5P_FIMC_TX_END_NOTIFY, &size);
	}

	return ret;
}
static int m5mols_into_capture(struct v4l2_subdev *sd, int res_size)
{
	struct m5mols_info *info = to_m5mols(sd);
	u32 reg;
	int ret, timeout = 1;
	u32 temp = 0;

	info->captured = false;

	/*
	 * The sequence of preparing Capture mode.
	 * 1. Clear Interrupt bit (for dummy)
	 * 2. Enable Capture bit at Interrupt
	 * 3. Lock AE/AWB
	 * 4. Enter Still Capture mode
	 */

	ret = m5mols_set_mode(sd, MODE_MONITOR);
	if (!ret)
		/* FIXME: setting capture exposure at the middle of a amount. */
		ret = i2c_w16_ae(sd, CAT3_MANUAL_GAIN_CAP, 0x90);
	if (!ret)
		ret = m5mols_set_ae_lock(info, true);
	if (!ret)
		ret = m5mols_set_awb_lock(info, true);
	if (!ret)
		ret = i2c_r8_system(sd, CAT0_INT_FACTOR, &reg);
	if (!ret)
		ret = i2c_w8_system(sd, CAT0_INT_ENABLE, 1 << INT_BIT_CAPTURE);
	if (!ret)
		ret = m5mols_set_mode(sd, MODE_CAPTURE);
	if (!ret)
		timeout = wait_event_interruptible_timeout(info->cap_wait,
				info->captured, msecs_to_jiffies(2000));

	/* disable all interrupt & clear interrupt */
	ret = i2c_w8_system(sd, CAT0_INT_ENABLE, 0x0);
	if (!ret)
		ret = i2c_r8_system(sd, CAT0_INT_FACTOR, &reg);
	if (ret)
		return -EPERM;

	/* If all timeout exhausted, return error. */
	if (!timeout)
		return -ETIMEDOUT;

	ret = i2c_r32_capt_ctrl(sd, CATC_CAP_IMAGE_SIZE, &temp);
	info->captured = false;
	return ret;
}
/**
 * m5mols_s_power - Main sensor power control function
 *
 * To prevent breaking the lens when the sensor is powered off the Soft-Landing
 * algorithm is called where available. The Soft-Landing algorithm availability
 * dependends on the firmware provider.
 */
static int m5mols_s_power(struct v4l2_subdev *sd, int on)
{
	struct m5mols_info *info = to_m5mols(sd);
	int ret;

	mutex_lock(&info->lock);

	if (on) {
		ret = m5mols_sensor_power(info, true);
		if (!ret)
			ret = m5mols_fw_start(sd);
	} else {
		if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
			ret = m5mols_set_mode(info, REG_MONITOR);
			if (!ret)
				ret = m5mols_auto_focus_stop(info);
			if (ret < 0)
				v4l2_warn(sd, "Soft landing lens failed\n");
		}
		ret = m5mols_sensor_power(info, false);

		info->ctrl_sync = 0;
	}

	mutex_unlock(&info->lock);
	return ret;
}
/**
 * m5mols_s_power - Main sensor power control function
 *
 * To prevent breaking the lens when the sensor is powered off the Soft-Landing
 * algorithm is called where available. The Soft-Landing algorithm availability
 * dependends on the firmware provider.
 */
static int m5mols_s_power(struct v4l2_subdev *sd, int on)
{
	struct m5mols_info *info = to_m5mols(sd);
	int ret;

	if (on) {
		ret = m5mols_sensor_power(info, true);
		if (!ret)
			ret = m5mols_fw_start(sd);
		return ret;
	}

	if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
		ret = m5mols_set_mode(info, REG_MONITOR);
		if (!ret)
			ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
		if (!ret)
			ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF);
		if (!ret)
			ret = m5mols_busy_wait(sd, SYSTEM_STATUS, REG_AF_IDLE,
					       0xff, -1);
		if (ret < 0)
			v4l2_warn(sd, "Soft landing lens failed\n");
	}

	ret = m5mols_sensor_power(info, false);
	info->ctrl_sync = 0;

	return ret;
}
/**
 * m5mols_start_monitor - Start the monitor mode
 *
 * Before applying the controls setup the resolution and frame rate
 * in PARAMETER mode, and then switch over to MONITOR mode.
 */
static int m5mols_start_monitor(struct m5mols_info *info)
{
	struct v4l2_subdev *sd = &info->sd;
	int ret;

	ret = m5mols_set_mode(info, REG_PARAMETER);
	if (!ret)
		ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
	if (!ret)
		ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
	if (!ret)
		ret = m5mols_set_mode(info, REG_MONITOR);
	if (!ret)
		ret = m5mols_restore_controls(info);

	return ret;
}
static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct m5mols_info *info = to_m5mols(sd);
	u32 code = info->ffmt[info->res_type].code;

	if (enable) {
		int ret = -EINVAL;

		if (is_code(code, M5MOLS_RESTYPE_MONITOR))
			ret = m5mols_start_monitor(info);
		if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
			ret = m5mols_start_capture(info);

		return ret;
	}

	return m5mols_set_mode(info, REG_PARAMETER);
}
Exemple #9
0
static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct m5mols_info *info = to_m5mols(sd);

	if (enable) {
		if (info->code == to_code(M5MOLS_RES_MON)) {
			v4l2_info(sd, "%s : monitor mode\n", __func__);
			return m5mols_start_monitor(sd);
		}
		if (info->code == to_code(M5MOLS_RES_CAPTURE)) {
			v4l2_info(sd, "%s : capture mode\n", __func__);
			return  m5mols_start_capture(sd);
		}
		return -EINVAL;
	} else {
		if (is_streaming(sd))
			return m5mols_set_mode(sd, MODE_PARMSET);
		return -EINVAL;
	}
}
static int m5mols_start_monitor(struct v4l2_subdev *sd)
{
	return m5mols_set_mode(sd, MODE_MONITOR);
}